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

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

Issue 2394253002: Fix the snapshot_cache unittests. (Closed)
Patch Set: Fixed test. Created 4 years, 1 month 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
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"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/mac/bind_objc_block.h" 15 #include "base/mac/bind_objc_block.h"
16 #include "base/mac/scoped_cftyperef.h" 16 #include "base/mac/scoped_cftyperef.h"
17 #include "base/strings/sys_string_conversions.h" 17 #include "base/strings/sys_string_conversions.h"
18 #include "base/task_runner_util.h" 18 #include "base/task_runner_util.h"
19 #include "base/threading/thread_restrictions.h" 19 #include "base/threading/thread_restrictions.h"
20 #include "ios/chrome/browser/experimental_flags.h" 20 #include "ios/chrome/browser/experimental_flags.h"
21 #import "ios/chrome/browser/snapshots/snapshot_cache_internal.h"
21 #include "ios/chrome/browser/ui/ui_util.h" 22 #include "ios/chrome/browser/ui/ui_util.h"
22 #import "ios/chrome/browser/ui/uikit_ui_util.h" 23 #import "ios/chrome/browser/ui/uikit_ui_util.h"
23 #include "ios/web/public/web_thread.h" 24 #include "ios/web/public/web_thread.h"
24 25
25 @interface SnapshotCache () 26 @interface SnapshotCache ()
26 + (base::FilePath)imagePathForSessionID:(NSString*)sessionID;
27 + (base::FilePath)greyImagePathForSessionID:(NSString*)sessionID;
28 // Returns the directory where the thumbnails are saved. 27 // Returns the directory where the thumbnails are saved.
29 + (base::FilePath)cacheDirectory; 28 + (base::FilePath)cacheDirectory;
30 // Returns the directory where the thumbnails were stored in M28 and earlier. 29 // Returns the directory where the thumbnails were stored in M28 and earlier.
31 - (base::FilePath)oldCacheDirectory; 30 - (base::FilePath)oldCacheDirectory;
32 // Remove all UIImages from |imageDictionary_|. 31 // Remove all UIImages from |imageDictionary_|.
33 - (void)handleEnterBackground; 32 - (void)handleEnterBackground;
34 // Remove all but adjacent UIImages from |imageDictionary_|. 33 // Remove all but adjacent UIImages from |imageDictionary_|.
35 - (void)handleLowMemory; 34 - (void)handleLowMemory;
36 // Restore adjacent UIImages to |imageDictionary_|. 35 // Restore adjacent UIImages to |imageDictionary_|.
37 - (void)handleBecomeActive; 36 - (void)handleBecomeActive;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 + (SnapshotCache*)sharedInstance { 136 + (SnapshotCache*)sharedInstance {
138 static SnapshotCache* instance = [[SnapshotCache alloc] init]; 137 static SnapshotCache* instance = [[SnapshotCache alloc] init];
139 return instance; 138 return instance;
140 } 139 }
141 140
142 - (id)init { 141 - (id)init {
143 if ((self = [super init])) { 142 if ((self = [super init])) {
144 DCHECK_CURRENTLY_ON(web::WebThread::UI); 143 DCHECK_CURRENTLY_ON(web::WebThread::UI);
145 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]); 144 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]);
146 145
147 // Always use the LRUCache when the tab switcher is enabled. 146 if ([self usesLRUCache]) {
148 if (experimental_flags::IsTabSwitcherEnabled() ||
149 experimental_flags::IsLRUSnapshotCacheEnabled()) {
150 lruCache_.reset( 147 lruCache_.reset(
151 [[LRUCache alloc] initWithCacheSize:kLRUCacheMaxCapacity]); 148 [[LRUCache alloc] initWithCacheSize:kLRUCacheMaxCapacity]);
152 } else { 149 } else {
153 imageDictionary_.reset( 150 imageDictionary_.reset(
154 [[NSMutableDictionary alloc] initWithCapacity:kCacheInitialCapacity]); 151 [[NSMutableDictionary alloc] initWithCapacity:kCacheInitialCapacity]);
155 } 152 }
156 153 [[NSNotificationCenter defaultCenter]
157 if (!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) { 154 addObserver:self
158 [[NSNotificationCenter defaultCenter] 155 selector:@selector(handleLowMemory)
159 addObserver:self 156 name:UIApplicationDidReceiveMemoryWarningNotification
160 selector:@selector(handleLowMemory) 157 object:nil];
161 name:UIApplicationDidReceiveMemoryWarningNotification 158 [[NSNotificationCenter defaultCenter]
162 object:nil]; 159 addObserver:self
163 [[NSNotificationCenter defaultCenter] 160 selector:@selector(handleEnterBackground)
164 addObserver:self 161 name:UIApplicationDidEnterBackgroundNotification
165 selector:@selector(handleEnterBackground) 162 object:nil];
166 name:UIApplicationDidEnterBackgroundNotification 163 [[NSNotificationCenter defaultCenter]
167 object:nil]; 164 addObserver:self
168 [[NSNotificationCenter defaultCenter] 165 selector:@selector(handleBecomeActive)
169 addObserver:self 166 name:UIApplicationDidBecomeActiveNotification
170 selector:@selector(handleBecomeActive) 167 object:nil];
171 name:UIApplicationDidBecomeActiveNotification
172 object:nil];
173 }
174 } 168 }
175 return self; 169 return self;
176 } 170 }
177 171
178 - (void)dealloc { 172 - (void)dealloc {
179 if (!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) { 173 [[NSNotificationCenter defaultCenter]
180 [[NSNotificationCenter defaultCenter] 174 removeObserver:self
181 removeObserver:self 175 name:UIApplicationDidReceiveMemoryWarningNotification
182 name:UIApplicationDidReceiveMemoryWarningNotification 176 object:nil];
183 object:nil]; 177 [[NSNotificationCenter defaultCenter]
184 [[NSNotificationCenter defaultCenter] 178 removeObserver:self
185 removeObserver:self 179 name:UIApplicationDidEnterBackgroundNotification
186 name:UIApplicationDidEnterBackgroundNotification 180 object:nil];
187 object:nil]; 181 [[NSNotificationCenter defaultCenter]
188 [[NSNotificationCenter defaultCenter] 182 removeObserver:self
189 removeObserver:self 183 name:UIApplicationDidBecomeActiveNotification
190 name:UIApplicationDidBecomeActiveNotification 184 object:nil];
191 object:nil];
192 }
193 [super dealloc]; 185 [super dealloc];
194 } 186 }
195 187
196 + (CGFloat)snapshotScaleForDevice { 188 + (CGFloat)snapshotScaleForDevice {
197 // On handset, the color snapshot is used for the stack view, so the scale of 189 // On handset, the color snapshot is used for the stack view, so the scale of
198 // the snapshot images should match the scale of the device. 190 // the snapshot images should match the scale of the device.
199 // On tablet, the color snapshot is only used to generate the grey snapshot, 191 // On tablet, the color snapshot is only used to generate the grey snapshot,
200 // which does not have to be high quality, so use scale of 1.0 on all tablets. 192 // which does not have to be high quality, so use scale of 1.0 on all tablets.
201 if (IsIPadIdiom()) { 193 if (IsIPadIdiom()) {
202 return 1.0; 194 return 1.0;
203 } 195 }
204 // Cap snapshot resolution to 2x to reduce the amount of memory they use. 196 // Cap snapshot resolution to 2x to reduce the amount of memory they use.
205 return MIN([UIScreen mainScreen].scale, 2.0); 197 return MIN([UIScreen mainScreen].scale, 2.0);
206 } 198 }
207 199
208 - (void)retrieveImageForSessionID:(NSString*)sessionID 200 - (void)retrieveImageForSessionID:(NSString*)sessionID
209 callback:(void (^)(UIImage*))callback { 201 callback:(void (^)(UIImage*))callback {
210 DCHECK_CURRENTLY_ON(web::WebThread::UI); 202 DCHECK_CURRENTLY_ON(web::WebThread::UI);
211 DCHECK(sessionID); 203 DCHECK(sessionID);
212 204
213 // Cache on iPad is enabled only when the tab switcher is enabled. 205 if (![self inMemoryCacheIsEnabled] && !callback)
214 if ((IsIPadIdiom() && !experimental_flags::IsTabSwitcherEnabled()) &&
215 !callback)
216 return; 206 return;
217 207
218 UIImage* img = nil; 208 UIImage* img = nil;
219 if (lruCache_) 209 if (lruCache_)
220 img = [lruCache_ objectForKey:sessionID]; 210 img = [lruCache_ objectForKey:sessionID];
221 else 211 else
222 img = [imageDictionary_ objectForKey:sessionID]; 212 img = [imageDictionary_ objectForKey:sessionID];
223 213
224 if (img) { 214 if (img) {
225 if (callback) 215 if (callback)
226 callback(img); 216 callback(img);
227 return; 217 return;
228 } 218 }
229 219
230 base::PostTaskAndReplyWithResult( 220 base::PostTaskAndReplyWithResult(
231 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE_USER_BLOCKING) 221 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE_USER_BLOCKING)
232 .get(), 222 .get(),
233 FROM_HERE, base::BindBlock(^base::scoped_nsobject<UIImage>() { 223 FROM_HERE, base::BindBlock(^base::scoped_nsobject<UIImage>() {
234 // Retrieve the image on a high priority thread. 224 // Retrieve the image on a high priority thread.
235 return base::scoped_nsobject<UIImage>([ReadImageFromDisk( 225 return base::scoped_nsobject<UIImage>([ReadImageFromDisk(
236 [SnapshotCache imagePathForSessionID:sessionID]) retain]); 226 [SnapshotCache imagePathForSessionID:sessionID]) retain]);
237 }), 227 }),
238 base::BindBlock(^(base::scoped_nsobject<UIImage> image) { 228 base::BindBlock(^(base::scoped_nsobject<UIImage> image) {
239 // Cache on iPad is enabled only when the tab switcher is enabled. 229 if ([self inMemoryCacheIsEnabled] && image) {
240 if ((!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) &&
241 image) {
242 if (lruCache_) 230 if (lruCache_)
243 [lruCache_ setObject:image forKey:sessionID]; 231 [lruCache_ setObject:image forKey:sessionID];
244 else 232 else
245 [imageDictionary_ setObject:image forKey:sessionID]; 233 [imageDictionary_ setObject:image forKey:sessionID];
246 } 234 }
247 if (callback) 235 if (callback)
248 callback(image); 236 callback(image);
249 })); 237 }));
250 } 238 }
251 239
252 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID { 240 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID {
253 DCHECK_CURRENTLY_ON(web::WebThread::UI); 241 DCHECK_CURRENTLY_ON(web::WebThread::UI);
254 if (!img || !sessionID) 242 if (!img || !sessionID)
255 return; 243 return;
256 244
257 // Cache on iPad is enabled only when the tab switcher is enabled. 245 if ([self inMemoryCacheIsEnabled]) {
258 if (!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) {
259 if (lruCache_) 246 if (lruCache_)
260 [lruCache_ setObject:img forKey:sessionID]; 247 [lruCache_ setObject:img forKey:sessionID];
261 else 248 else
262 [imageDictionary_ setObject:img forKey:sessionID]; 249 [imageDictionary_ setObject:img forKey:sessionID];
263 } 250 }
264 // Save the image to disk. 251 // Save the image to disk.
265 web::WebThread::PostBlockingPoolSequencedTask( 252 web::WebThread::PostBlockingPoolSequencedTask(
266 kSequenceToken, FROM_HERE, 253 kSequenceToken, FROM_HERE,
267 base::BindBlock(^{ 254 base::BindBlock(^{
268 base::scoped_nsobject<UIImage> image([img retain]); 255 base::scoped_nsobject<UIImage> image([img retain]);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 return; 366 return;
380 backgroundingImageSessionId_.reset([sessionID copy]); 367 backgroundingImageSessionId_.reset([sessionID copy]);
381 if (lruCache_) { 368 if (lruCache_) {
382 backgroundingColorImage_.reset([[lruCache_ objectForKey:sessionID] retain]); 369 backgroundingColorImage_.reset([[lruCache_ objectForKey:sessionID] retain]);
383 } else { 370 } else {
384 backgroundingColorImage_.reset( 371 backgroundingColorImage_.reset(
385 [[imageDictionary_ objectForKey:sessionID] retain]); 372 [[imageDictionary_ objectForKey:sessionID] retain]);
386 } 373 }
387 } 374 }
388 375
376 - (BOOL)inMemoryCacheIsEnabled {
377 // In-memory cache on iPad is enabled only when the tab switcher is enabled.
378 return !IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled();
379 }
380
381 - (BOOL)usesLRUCache {
382 // Always use the LRUCache when the tab switcher is enabled.
383 return experimental_flags::IsTabSwitcherEnabled() ||
384 experimental_flags::IsLRUSnapshotCacheEnabled();
385 }
386
389 - (void)handleLowMemory { 387 - (void)handleLowMemory {
390 DCHECK(!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled());
391 DCHECK_CURRENTLY_ON(web::WebThread::UI); 388 DCHECK_CURRENTLY_ON(web::WebThread::UI);
392 base::scoped_nsobject<NSMutableDictionary> dictionary( 389 base::scoped_nsobject<NSMutableDictionary> dictionary(
393 [[NSMutableDictionary alloc] initWithCapacity:2]); 390 [[NSMutableDictionary alloc] initWithCapacity:2]);
394 for (NSString* sessionID in pinnedIDs_) { 391 for (NSString* sessionID in pinnedIDs_) {
395 UIImage* image = nil; 392 UIImage* image = nil;
396 if (lruCache_) 393 if (lruCache_)
397 image = [lruCache_ objectForKey:sessionID]; 394 image = [lruCache_ objectForKey:sessionID];
398 else 395 else
399 image = [imageDictionary_ objectForKey:sessionID]; 396 image = [imageDictionary_ objectForKey:sessionID];
400 if (image) 397 if (image)
401 [dictionary setObject:image forKey:sessionID]; 398 [dictionary setObject:image forKey:sessionID];
402 } 399 }
403 if (lruCache_) { 400 if (lruCache_) {
404 [lruCache_ removeAllObjects]; 401 [lruCache_ removeAllObjects];
405 for (NSString* sessionID in pinnedIDs_) 402 for (NSString* sessionID in pinnedIDs_)
406 [lruCache_ setObject:[dictionary objectForKey:sessionID] 403 [lruCache_ setObject:[dictionary objectForKey:sessionID]
407 forKey:sessionID]; 404 forKey:sessionID];
408 } else { 405 } else {
409 imageDictionary_ = dictionary; 406 imageDictionary_ = dictionary;
410 } 407 }
411 } 408 }
412 409
413 - (void)handleEnterBackground { 410 - (void)handleEnterBackground {
414 DCHECK(!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled());
415 DCHECK_CURRENTLY_ON(web::WebThread::UI); 411 DCHECK_CURRENTLY_ON(web::WebThread::UI);
416 [imageDictionary_ removeAllObjects]; 412 [imageDictionary_ removeAllObjects];
417 [lruCache_ removeAllObjects]; 413 [lruCache_ removeAllObjects];
418 } 414 }
419 415
420 - (void)handleBecomeActive { 416 - (void)handleBecomeActive {
421 DCHECK(!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled());
422 DCHECK_CURRENTLY_ON(web::WebThread::UI); 417 DCHECK_CURRENTLY_ON(web::WebThread::UI);
423 for (NSString* sessionID in pinnedIDs_) 418 for (NSString* sessionID in pinnedIDs_)
424 [self retrieveImageForSessionID:sessionID callback:nil]; 419 [self retrieveImageForSessionID:sessionID callback:nil];
425 } 420 }
426 421
427 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID { 422 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID {
428 DCHECK_CURRENTLY_ON(web::WebThread::UI); 423 DCHECK_CURRENTLY_ON(web::WebThread::UI);
429 if (greyImage) 424 if (greyImage)
430 [greyImageDictionary_ setObject:greyImage forKey:sessionID]; 425 [greyImageDictionary_ setObject:greyImage forKey:sessionID];
431 if ([sessionID isEqualToString:mostRecentGreySessionId_]) { 426 if ([sessionID isEqualToString:mostRecentGreySessionId_]) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 web::WebThread::PostBlockingPoolTask( 557 web::WebThread::PostBlockingPoolTask(
563 FROM_HERE, base::Bind(&ConvertAndSaveGreyImage, colorImagePath, 558 FROM_HERE, base::Bind(&ConvertAndSaveGreyImage, colorImagePath,
564 greyImagePath, backgroundingColorImage_)); 559 greyImagePath, backgroundingColorImage_));
565 } 560 }
566 561
567 @end 562 @end
568 563
569 @implementation SnapshotCache (TestingAdditions) 564 @implementation SnapshotCache (TestingAdditions)
570 565
571 - (BOOL)hasImageInMemory:(NSString*)sessionID { 566 - (BOOL)hasImageInMemory:(NSString*)sessionID {
572 if (experimental_flags::IsLRUSnapshotCacheEnabled()) 567 if ([self usesLRUCache])
573 return [lruCache_ objectForKey:sessionID] != nil; 568 return [lruCache_ objectForKey:sessionID] != nil;
574 else 569 else
575 return [imageDictionary_ objectForKey:sessionID] != nil; 570 return [imageDictionary_ objectForKey:sessionID] != nil;
576 } 571 }
572
577 - (BOOL)hasGreyImageInMemory:(NSString*)sessionID { 573 - (BOOL)hasGreyImageInMemory:(NSString*)sessionID {
578 return [greyImageDictionary_ objectForKey:sessionID] != nil; 574 return [greyImageDictionary_ objectForKey:sessionID] != nil;
579 } 575 }
580 576
581 - (NSUInteger)lruCacheMaxSize { 577 - (NSUInteger)lruCacheMaxSize {
582 return [lruCache_ maxCacheSize]; 578 return [lruCache_ maxCacheSize];
583 } 579 }
584 580
585 @end 581 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/snapshots/OWNERS ('k') | ios/chrome/browser/snapshots/snapshot_cache_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698