Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 + (SnapshotCache*)sharedInstance { | 137 + (SnapshotCache*)sharedInstance { |
| 138 static SnapshotCache* instance = [[SnapshotCache alloc] init]; | 138 static SnapshotCache* instance = [[SnapshotCache alloc] init]; |
| 139 return instance; | 139 return instance; |
| 140 } | 140 } |
| 141 | 141 |
| 142 - (id)init { | 142 - (id)init { |
| 143 if ((self = [super init])) { | 143 if ((self = [super init])) { |
| 144 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 144 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 145 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]); | 145 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]); |
| 146 | 146 |
| 147 if (!IsIPadIdiom()) { | 147 // Always use the LRUCache when the tab switcher is enabled. |
| 148 if (experimental_flags::IsLRUSnapshotCacheEnabled()) { | 148 if (experimental_flags::IsTabSwitcherEnabled() || |
|
msarda
2016/01/13 16:25:27
As discussed offline, this will potentially exclud
jbbegue (google)
2016/01/14 12:38:24
This is what we want. The iPad should only use the
| |
| 149 lruCache_.reset( | 149 experimental_flags::IsLRUSnapshotCacheEnabled()) { |
| 150 [[LRUCache alloc] initWithCacheSize:kLRUCacheMaxCapacity]); | 150 lruCache_.reset( |
| 151 } else { | 151 [[LRUCache alloc] initWithCacheSize:kLRUCacheMaxCapacity]); |
| 152 imageDictionary_.reset([[NSMutableDictionary alloc] | 152 } else { |
| 153 initWithCapacity:kCacheInitialCapacity]); | 153 imageDictionary_.reset( |
| 154 } | 154 [[NSMutableDictionary alloc] initWithCapacity:kCacheInitialCapacity]); |
| 155 } | |
| 155 | 156 |
| 157 if (!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) { | |
| 156 [[NSNotificationCenter defaultCenter] | 158 [[NSNotificationCenter defaultCenter] |
| 157 addObserver:self | 159 addObserver:self |
| 158 selector:@selector(handleLowMemory) | 160 selector:@selector(handleLowMemory) |
| 159 name:UIApplicationDidReceiveMemoryWarningNotification | 161 name:UIApplicationDidReceiveMemoryWarningNotification |
| 160 object:nil]; | 162 object:nil]; |
| 161 [[NSNotificationCenter defaultCenter] | 163 [[NSNotificationCenter defaultCenter] |
| 162 addObserver:self | 164 addObserver:self |
| 163 selector:@selector(handleEnterBackground) | 165 selector:@selector(handleEnterBackground) |
| 164 name:UIApplicationDidEnterBackgroundNotification | 166 name:UIApplicationDidEnterBackgroundNotification |
| 165 object:nil]; | 167 object:nil]; |
| 166 [[NSNotificationCenter defaultCenter] | 168 [[NSNotificationCenter defaultCenter] |
| 167 addObserver:self | 169 addObserver:self |
| 168 selector:@selector(handleBecomeActive) | 170 selector:@selector(handleBecomeActive) |
| 169 name:UIApplicationDidBecomeActiveNotification | 171 name:UIApplicationDidBecomeActiveNotification |
| 170 object:nil]; | 172 object:nil]; |
| 171 } | 173 } |
| 172 } | 174 } |
| 173 return self; | 175 return self; |
| 174 } | 176 } |
| 175 | 177 |
| 176 - (void)dealloc { | 178 - (void)dealloc { |
| 177 if (!IsIPadIdiom()) { | 179 if (!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) { |
| 178 [[NSNotificationCenter defaultCenter] | 180 [[NSNotificationCenter defaultCenter] |
| 179 removeObserver:self | 181 removeObserver:self |
| 180 name:UIApplicationDidReceiveMemoryWarningNotification | 182 name:UIApplicationDidReceiveMemoryWarningNotification |
| 181 object:nil]; | 183 object:nil]; |
| 182 [[NSNotificationCenter defaultCenter] | 184 [[NSNotificationCenter defaultCenter] |
| 183 removeObserver:self | 185 removeObserver:self |
| 184 name:UIApplicationDidEnterBackgroundNotification | 186 name:UIApplicationDidEnterBackgroundNotification |
| 185 object:nil]; | 187 object:nil]; |
| 186 [[NSNotificationCenter defaultCenter] | 188 [[NSNotificationCenter defaultCenter] |
| 187 removeObserver:self | 189 removeObserver:self |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 200 return 1.0; | 202 return 1.0; |
| 201 } | 203 } |
| 202 // Cap snapshot resolution to 2x to reduce the amount of memory they use. | 204 // Cap snapshot resolution to 2x to reduce the amount of memory they use. |
| 203 return MIN([UIScreen mainScreen].scale, 2.0); | 205 return MIN([UIScreen mainScreen].scale, 2.0); |
| 204 } | 206 } |
| 205 | 207 |
| 206 - (void)retrieveImageForSessionID:(NSString*)sessionID | 208 - (void)retrieveImageForSessionID:(NSString*)sessionID |
| 207 callback:(void (^)(UIImage*))callback { | 209 callback:(void (^)(UIImage*))callback { |
| 208 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 210 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 209 DCHECK(sessionID); | 211 DCHECK(sessionID); |
| 210 // iPad does not cache images, so if there is no callback we can avoid an | 212 |
| 211 // expensive read from storage. | 213 // Cache on iPad is enabled only when the tab switcher is enabled. |
| 212 if (IsIPadIdiom() && !callback) | 214 if (IsIPadIdiom() && !experimental_flags::IsTabSwitcherEnabled()) |
|
msarda
2016/01/13 16:25:27
Optional: Consider adding a function IsCacheEnable
jbbegue (google)
2016/01/14 12:38:24
You are right I'll do that in another CL.
| |
| 215 return; | |
| 216 | |
| 217 if (!callback) | |
| 213 return; | 218 return; |
| 214 | 219 |
| 215 UIImage* img = nil; | 220 UIImage* img = nil; |
| 216 if (lruCache_) | 221 if (lruCache_) |
| 217 img = [lruCache_ objectForKey:sessionID]; | 222 img = [lruCache_ objectForKey:sessionID]; |
| 218 else | 223 else |
| 219 img = [imageDictionary_ objectForKey:sessionID]; | 224 img = [imageDictionary_ objectForKey:sessionID]; |
| 220 | 225 |
| 221 if (img) { | 226 if (img) { |
| 222 if (callback) | 227 if (callback) |
| 223 callback(img); | 228 callback(img); |
| 224 return; | 229 return; |
| 225 } | 230 } |
| 226 | 231 |
| 227 base::PostTaskAndReplyWithResult( | 232 base::PostTaskAndReplyWithResult( |
| 228 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE_USER_BLOCKING) | 233 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE_USER_BLOCKING) |
| 229 .get(), | 234 .get(), |
| 230 FROM_HERE, base::BindBlock(^base::scoped_nsobject<UIImage>() { | 235 FROM_HERE, base::BindBlock(^base::scoped_nsobject<UIImage>() { |
| 231 // Retrieve the image on a high priority thread. | 236 // Retrieve the image on a high priority thread. |
| 232 return base::scoped_nsobject<UIImage>([ReadImageFromDisk( | 237 return base::scoped_nsobject<UIImage>([ReadImageFromDisk( |
| 233 [SnapshotCache imagePathForSessionID:sessionID]) retain]); | 238 [SnapshotCache imagePathForSessionID:sessionID]) retain]); |
| 234 }), | 239 }), |
| 235 base::BindBlock(^(base::scoped_nsobject<UIImage> image) { | 240 base::BindBlock(^(base::scoped_nsobject<UIImage> image) { |
| 236 // The iPad tab switcher is currently using its own memory cache so the | 241 // Cache on iPad is enabled only when the tab switcher is enabled. |
| 237 // image is not stored in memory here if running on iPad. | 242 if ((!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) && |
| 238 // The same logic is used on image writes (code below). | 243 image) { |
| 239 if (!IsIPadIdiom() && image) { | |
| 240 if (lruCache_) | 244 if (lruCache_) |
| 241 [lruCache_ setObject:image forKey:sessionID]; | 245 [lruCache_ setObject:image forKey:sessionID]; |
| 242 else | 246 else |
| 243 [imageDictionary_ setObject:image forKey:sessionID]; | 247 [imageDictionary_ setObject:image forKey:sessionID]; |
| 244 } | 248 } |
| 245 if (callback) | 249 if (callback) |
| 246 callback(image); | 250 callback(image); |
| 247 })); | 251 })); |
| 248 } | 252 } |
| 249 | 253 |
| 250 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID { | 254 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID { |
| 251 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 255 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 252 if (!img || !sessionID) | 256 if (!img || !sessionID) |
| 253 return; | 257 return; |
| 254 | 258 |
| 255 // The iPad tab switcher is currently using its own memory cache so the image | 259 // Cache on iPad is enabled only when the tab switcher is enabled. |
| 256 // is not stored in memory here if running on iPad. | 260 if (!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) { |
| 257 // The same logic is used on image reads (code above). | |
| 258 if (!IsIPadIdiom()) { | |
| 259 if (lruCache_) | 261 if (lruCache_) |
| 260 [lruCache_ setObject:img forKey:sessionID]; | 262 [lruCache_ setObject:img forKey:sessionID]; |
| 261 else | 263 else |
| 262 [imageDictionary_ setObject:img forKey:sessionID]; | 264 [imageDictionary_ setObject:img forKey:sessionID]; |
| 263 } | 265 } |
| 264 // Save the image to disk. | 266 // Save the image to disk. |
| 265 web::WebThread::PostBlockingPoolSequencedTask( | 267 web::WebThread::PostBlockingPoolSequencedTask( |
| 266 kSequenceToken, FROM_HERE, | 268 kSequenceToken, FROM_HERE, |
| 267 base::BindBlock(^{ | 269 base::BindBlock(^{ |
| 268 base::scoped_nsobject<UIImage> image([img retain]); | 270 base::scoped_nsobject<UIImage> image([img retain]); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 backgroundingImageSessionId_.reset([sessionID copy]); | 382 backgroundingImageSessionId_.reset([sessionID copy]); |
| 381 if (lruCache_) { | 383 if (lruCache_) { |
| 382 backgroundingColorImage_.reset([[lruCache_ objectForKey:sessionID] retain]); | 384 backgroundingColorImage_.reset([[lruCache_ objectForKey:sessionID] retain]); |
| 383 } else { | 385 } else { |
| 384 backgroundingColorImage_.reset( | 386 backgroundingColorImage_.reset( |
| 385 [[imageDictionary_ objectForKey:sessionID] retain]); | 387 [[imageDictionary_ objectForKey:sessionID] retain]); |
| 386 } | 388 } |
| 387 } | 389 } |
| 388 | 390 |
| 389 - (void)handleLowMemory { | 391 - (void)handleLowMemory { |
| 390 DCHECK(!IsIPadIdiom()); | 392 DCHECK(!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()); |
| 391 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 393 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 392 NSMutableDictionary* dictionary = | 394 NSMutableDictionary* dictionary = |
| 393 [[NSMutableDictionary alloc] initWithCapacity:2]; | 395 [[NSMutableDictionary alloc] initWithCapacity:2]; |
| 394 for (NSString* sessionID in pinnedIDs_) { | 396 for (NSString* sessionID in pinnedIDs_) { |
| 395 UIImage* image = nil; | 397 UIImage* image = nil; |
| 396 if (lruCache_) | 398 if (lruCache_) |
| 397 image = [lruCache_ objectForKey:sessionID]; | 399 image = [lruCache_ objectForKey:sessionID]; |
| 398 else | 400 else |
| 399 image = [imageDictionary_ objectForKey:sessionID]; | 401 image = [imageDictionary_ objectForKey:sessionID]; |
| 400 if (image) | 402 if (image) |
| 401 [dictionary setObject:image forKey:sessionID]; | 403 [dictionary setObject:image forKey:sessionID]; |
| 402 } | 404 } |
| 403 if (lruCache_) { | 405 if (lruCache_) { |
| 404 [lruCache_ removeAllObjects]; | 406 [lruCache_ removeAllObjects]; |
| 405 for (NSString* sessionID in pinnedIDs_) | 407 for (NSString* sessionID in pinnedIDs_) |
| 406 [lruCache_ setObject:dictionary[sessionID] forKey:sessionID]; | 408 [lruCache_ setObject:dictionary[sessionID] forKey:sessionID]; |
| 407 } else { | 409 } else { |
| 408 imageDictionary_.reset(dictionary); | 410 imageDictionary_.reset(dictionary); |
| 409 } | 411 } |
| 410 } | 412 } |
| 411 | 413 |
| 412 - (void)handleEnterBackground { | 414 - (void)handleEnterBackground { |
| 413 DCHECK(!IsIPadIdiom()); | 415 DCHECK(!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()); |
| 414 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 416 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 415 [imageDictionary_ removeAllObjects]; | 417 [imageDictionary_ removeAllObjects]; |
| 416 [lruCache_ removeAllObjects]; | 418 [lruCache_ removeAllObjects]; |
| 417 } | 419 } |
| 418 | 420 |
| 419 - (void)handleBecomeActive { | 421 - (void)handleBecomeActive { |
| 420 DCHECK(!IsIPadIdiom()); | 422 DCHECK(!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()); |
| 421 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 423 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 422 for (NSString* sessionID in pinnedIDs_) | 424 for (NSString* sessionID in pinnedIDs_) |
| 423 [self retrieveImageForSessionID:sessionID callback:nil]; | 425 [self retrieveImageForSessionID:sessionID callback:nil]; |
| 424 } | 426 } |
| 425 | 427 |
| 426 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID { | 428 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID { |
| 427 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 429 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
| 428 if (greyImage) | 430 if (greyImage) |
| 429 [greyImageDictionary_ setObject:greyImage forKey:sessionID]; | 431 [greyImageDictionary_ setObject:greyImage forKey:sessionID]; |
| 430 if ([sessionID isEqualToString:mostRecentGreySessionId_]) { | 432 if ([sessionID isEqualToString:mostRecentGreySessionId_]) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 } | 577 } |
| 576 - (BOOL)hasGreyImageInMemory:(NSString*)sessionID { | 578 - (BOOL)hasGreyImageInMemory:(NSString*)sessionID { |
| 577 return [greyImageDictionary_ objectForKey:sessionID] != nil; | 579 return [greyImageDictionary_ objectForKey:sessionID] != nil; |
| 578 } | 580 } |
| 579 | 581 |
| 580 - (NSUInteger)lruCacheMaxSize { | 582 - (NSUInteger)lruCacheMaxSize { |
| 581 return [lruCache_ maxCacheSize]; | 583 return [lruCache_ maxCacheSize]; |
| 582 } | 584 } |
| 583 | 585 |
| 584 @end | 586 @end |
| OLD | NEW |