Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(785)

Side by Side Diff: ios/chrome/browser/snapshots/snapshot_cache.mm

Issue 1141423002: [iOS] Fixed tab snapshot cache refresh issues on iPad. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/snapshots/snapshot_cache.h" 5 #import "ios/chrome/browser/snapshots/snapshot_cache.h"
6 6
7 #import <UIKit/UIKit.h> 7 #import <UIKit/UIKit.h>
8 8
9 #include "base/critical_closure.h" 9 #include "base/critical_closure.h"
10 #include "base/files/file_enumerator.h" 10 #include "base/files/file_enumerator.h"
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 + (SnapshotCache*)sharedInstance { 133 + (SnapshotCache*)sharedInstance {
134 static SnapshotCache* instance = [[SnapshotCache alloc] init]; 134 static SnapshotCache* instance = [[SnapshotCache alloc] init];
135 return instance; 135 return instance;
136 } 136 }
137 137
138 - (id)init { 138 - (id)init {
139 if ((self = [super init])) { 139 if ((self = [super init])) {
140 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 140 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
141 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]); 141 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]);
142 142
143 // TODO(andybons): In the case where the cache grows, it is expensive. 143 if (!IsIPadIdiom()) {
144 // Make sure this doesn't suck when there are more than ten tabs. 144 // TODO(jbbegue): In the case where the cache grows, it is expensive.
145 imageDictionary_.reset( 145 // Make sure this doesn't suck when there are more than ten tabs.
146 [[NSMutableDictionary alloc] initWithCapacity:kCacheInitialCapacity]); 146 imageDictionary_.reset(
147 [[NSNotificationCenter defaultCenter] 147 [[NSMutableDictionary alloc] initWithCapacity:kCacheInitialCapacity]);
148 addObserver:self 148 [[NSNotificationCenter defaultCenter]
149 selector:@selector(handleLowMemory) 149 addObserver:self
150 name:UIApplicationDidReceiveMemoryWarningNotification 150 selector:@selector(handleLowMemory)
151 object:nil]; 151 name:UIApplicationDidReceiveMemoryWarningNotification
152 [[NSNotificationCenter defaultCenter] 152 object:nil];
153 addObserver:self 153 [[NSNotificationCenter defaultCenter]
154 selector:@selector(handleEnterBackground) 154 addObserver:self
155 name:UIApplicationDidEnterBackgroundNotification 155 selector:@selector(handleEnterBackground)
156 object:nil]; 156 name:UIApplicationDidEnterBackgroundNotification
157 [[NSNotificationCenter defaultCenter] 157 object:nil];
158 addObserver:self 158 [[NSNotificationCenter defaultCenter]
159 selector:@selector(handleBecomeActive) 159 addObserver:self
160 name:UIApplicationDidBecomeActiveNotification 160 selector:@selector(handleBecomeActive)
161 object:nil]; 161 name:UIApplicationDidBecomeActiveNotification
162 object:nil];
163 }
162 } 164 }
163 return self; 165 return self;
164 } 166 }
165 167
166 - (void)dealloc { 168 - (void)dealloc {
167 [[NSNotificationCenter defaultCenter] 169 if (!IsIPadIdiom()) {
168 removeObserver:self 170 [[NSNotificationCenter defaultCenter]
169 name:UIApplicationDidReceiveMemoryWarningNotification 171 removeObserver:self
170 object:nil]; 172 name:UIApplicationDidReceiveMemoryWarningNotification
171 [[NSNotificationCenter defaultCenter] 173 object:nil];
172 removeObserver:self 174 [[NSNotificationCenter defaultCenter]
173 name:UIApplicationDidEnterBackgroundNotification 175 removeObserver:self
174 object:nil]; 176 name:UIApplicationDidEnterBackgroundNotification
175 [[NSNotificationCenter defaultCenter] 177 object:nil];
176 removeObserver:self 178 [[NSNotificationCenter defaultCenter]
177 name:UIApplicationDidBecomeActiveNotification 179 removeObserver:self
178 object:nil]; 180 name:UIApplicationDidBecomeActiveNotification
181 object:nil];
182 }
179 [super dealloc]; 183 [super dealloc];
180 } 184 }
181 185
182 + (CGFloat)snapshotScaleForDevice { 186 + (CGFloat)snapshotScaleForDevice {
183 // On handset, the color snapshot is used for the stack view, so the scale of 187 // On handset, the color snapshot is used for the stack view, so the scale of
184 // the snapshot images should match the scale of the device. 188 // the snapshot images should match the scale of the device.
185 // On tablet, the color snapshot is only used to generate the grey snapshot, 189 // On tablet, the color snapshot is only used to generate the grey snapshot,
186 // which does not have to be high quality, so use scale of 1.0 on all tablets. 190 // which does not have to be high quality, so use scale of 1.0 on all tablets.
187 if (IsIPadIdiom()) { 191 if (IsIPadIdiom()) {
188 return 1.0; 192 return 1.0;
189 } 193 }
190 // Cap snapshot resolution to 2x to reduce the amount of memory they use. 194 // Cap snapshot resolution to 2x to reduce the amount of memory they use.
191 return MIN([UIScreen mainScreen].scale, 2.0); 195 return MIN([UIScreen mainScreen].scale, 2.0);
192 } 196 }
193 197
194 - (void)retrieveImageForSessionID:(NSString*)sessionID 198 - (void)retrieveImageForSessionID:(NSString*)sessionID
195 callback:(void (^)(UIImage*))callback { 199 callback:(void (^)(UIImage*))callback {
196 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 200 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
197 DCHECK(sessionID); 201 DCHECK(sessionID);
202 // iPad does not cache images, so if there is no callback we can avoid an
203 // expensive read from storage.
204 if (IsIPadIdiom() && !callback)
205 return;
206
198 UIImage* img = [imageDictionary_ objectForKey:sessionID]; 207 UIImage* img = [imageDictionary_ objectForKey:sessionID];
199 if (img) { 208 if (img) {
200 if (callback) 209 if (callback)
201 callback(img); 210 callback(img);
202 return; 211 return;
203 } 212 }
204 213
205 base::PostTaskAndReplyWithResult( 214 base::PostTaskAndReplyWithResult(
206 web::WebThread::GetMessageLoopProxyForThread( 215 web::WebThread::GetMessageLoopProxyForThread(
207 web::WebThread::FILE_USER_BLOCKING).get(), 216 web::WebThread::FILE_USER_BLOCKING).get(),
208 FROM_HERE, 217 FROM_HERE, base::BindBlock(^base::scoped_nsobject<UIImage>() {
209 base::BindBlock(^base::scoped_nsobject<UIImage>() {
210 // Retrieve the image on a high priority thread. 218 // Retrieve the image on a high priority thread.
211 return base::scoped_nsobject<UIImage>([ReadImageFromDisk( 219 return base::scoped_nsobject<UIImage>([ReadImageFromDisk(
212 [SnapshotCache imagePathForSessionID:sessionID]) retain]); 220 [SnapshotCache imagePathForSessionID:sessionID]) retain]);
213 }), 221 }),
214 base::BindBlock(^(base::scoped_nsobject<UIImage> image) { 222 base::BindBlock(^(base::scoped_nsobject<UIImage> image) {
215 if (image) 223 // The iPad tab switcher is currently using its own memory cache so the
224 // image is not stored in memory here if running on iPad.
225 // The same logic is used on image writes (code below).
226 if (!IsIPadIdiom() && image)
216 [imageDictionary_ setObject:image forKey:sessionID]; 227 [imageDictionary_ setObject:image forKey:sessionID];
217 if (callback) 228 if (callback)
218 callback(image); 229 callback(image);
219 })); 230 }));
220 } 231 }
221 232
222 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID { 233 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID {
223 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 234 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
224 if (!img || !sessionID) 235 if (!img || !sessionID)
225 return; 236 return;
226 237
227 // Color snapshots are not used on tablets, so don't keep them in memory. 238 // The iPad tab switcher is currently using its own memory cache so the image
239 // is not stored in memory here if running on iPad.
240 // The same logic is used on image reads (code above).
228 if (!IsIPadIdiom()) { 241 if (!IsIPadIdiom()) {
229 [imageDictionary_ setObject:img forKey:sessionID]; 242 [imageDictionary_ setObject:img forKey:sessionID];
230 } 243 }
231 // Save the image to disk. 244 // Save the image to disk.
232 web::WebThread::PostBlockingPoolSequencedTask( 245 web::WebThread::PostBlockingPoolSequencedTask(
233 kSequenceToken, FROM_HERE, 246 kSequenceToken, FROM_HERE,
234 base::BindBlock(^{ 247 base::BindBlock(^{
235 base::scoped_nsobject<UIImage> image([img retain]); 248 base::scoped_nsobject<UIImage> image([img retain]);
236 WriteImageToDisk(image, 249 WriteImageToDisk(image,
237 [SnapshotCache imagePathForSessionID:sessionID]); 250 [SnapshotCache imagePathForSessionID:sessionID]);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 - (void)willBeSavedGreyWhenBackgrounding:(NSString*)sessionID { 352 - (void)willBeSavedGreyWhenBackgrounding:(NSString*)sessionID {
340 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 353 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
341 if (!sessionID) 354 if (!sessionID)
342 return; 355 return;
343 backgroundingImageSessionId_.reset([sessionID copy]); 356 backgroundingImageSessionId_.reset([sessionID copy]);
344 backgroundingColorImage_.reset( 357 backgroundingColorImage_.reset(
345 [[imageDictionary_ objectForKey:sessionID] retain]); 358 [[imageDictionary_ objectForKey:sessionID] retain]);
346 } 359 }
347 360
348 - (void)handleLowMemory { 361 - (void)handleLowMemory {
362 DCHECK(!IsIPadIdiom());
349 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 363 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
350 NSMutableDictionary* dictionary = 364 NSMutableDictionary* dictionary =
351 [[NSMutableDictionary alloc] initWithCapacity:2]; 365 [[NSMutableDictionary alloc] initWithCapacity:2];
352 for (NSString* sessionID in pinnedIDs_) { 366 for (NSString* sessionID in pinnedIDs_) {
353 UIImage* image = [imageDictionary_ objectForKey:sessionID]; 367 UIImage* image = [imageDictionary_ objectForKey:sessionID];
354 if (image) 368 if (image)
355 [dictionary setObject:image forKey:sessionID]; 369 [dictionary setObject:image forKey:sessionID];
356 } 370 }
357 imageDictionary_.reset(dictionary); 371 imageDictionary_.reset(dictionary);
358 } 372 }
359 373
360 - (void)handleEnterBackground { 374 - (void)handleEnterBackground {
375 DCHECK(!IsIPadIdiom());
361 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 376 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
362 [imageDictionary_ removeAllObjects]; 377 [imageDictionary_ removeAllObjects];
363 } 378 }
364 379
365 - (void)handleBecomeActive { 380 - (void)handleBecomeActive {
381 DCHECK(!IsIPadIdiom());
366 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 382 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
367 for (NSString* sessionID in pinnedIDs_) 383 for (NSString* sessionID in pinnedIDs_)
368 [self retrieveImageForSessionID:sessionID callback:nil]; 384 [self retrieveImageForSessionID:sessionID callback:nil];
369 } 385 }
370 386
371 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID { 387 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID {
372 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 388 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
373 if (greyImage) 389 if (greyImage)
374 [greyImageDictionary_ setObject:greyImage forKey:sessionID]; 390 [greyImageDictionary_ setObject:greyImage forKey:sessionID];
375 if ([sessionID isEqualToString:mostRecentGreySessionId_]) { 391 if ([sessionID isEqualToString:mostRecentGreySessionId_]) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 backgroundingImageSessionId_.reset(); 515 backgroundingImageSessionId_.reset();
500 } 516 }
501 } 517 }
502 518
503 web::WebThread::PostBlockingPoolTask( 519 web::WebThread::PostBlockingPoolTask(
504 FROM_HERE, base::Bind(&ConvertAndSaveGreyImage, colorImagePath, 520 FROM_HERE, base::Bind(&ConvertAndSaveGreyImage, colorImagePath,
505 greyImagePath, backgroundingColorImage_)); 521 greyImagePath, backgroundingColorImage_));
506 } 522 }
507 523
508 @end 524 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698