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/mac/bind_objc_block.h" | |
11 #include "base/files/file_enumerator.h" | 10 #include "base/files/file_enumerator.h" |
12 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
13 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
14 #include "base/location.h" | 13 #include "base/location.h" |
15 #include "base/logging.h" | 14 #include "base/logging.h" |
16 #include "base/mac/bind_objc_block.h" | 15 #include "base/mac/bind_objc_block.h" |
17 #include "base/mac/scoped_cftyperef.h" | 16 #include "base/mac/scoped_cftyperef.h" |
18 #include "base/strings/sys_string_conversions.h" | 17 #include "base/strings/sys_string_conversions.h" |
19 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" |
20 #include "base/threading/thread_restrictions.h" | 19 #include "base/threading/thread_restrictions.h" |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 } | 136 } |
138 | 137 |
139 - (id)init { | 138 - (id)init { |
140 if ((self = [super init])) { | 139 if ((self = [super init])) { |
141 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 140 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
142 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]); | 141 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]); |
143 | 142 |
144 // TODO(andybons): In the case where the cache grows, it is expensive. | 143 // TODO(andybons): In the case where the cache grows, it is expensive. |
145 // Make sure this doesn't suck when there are more than ten tabs. | 144 // Make sure this doesn't suck when there are more than ten tabs. |
146 imageDictionary_.reset( | 145 imageDictionary_.reset( |
147 [[NSMutableDictionary alloc] initWithCapacity:kCacheInitialCapacity]); | 146 [[NSMutableDictionary alloc] initWithCapacity:kCacheInitialCapacity]); |
noyau (Ping after 24h)
2015/05/19 21:36:35
No need to allocate this on tablets.
sdefresne
2015/05/20 13:15:12
Done.
| |
148 [[NSNotificationCenter defaultCenter] | 147 [[NSNotificationCenter defaultCenter] |
149 addObserver:self | 148 addObserver:self |
150 selector:@selector(handleLowMemory) | 149 selector:@selector(handleLowMemory) |
151 name:UIApplicationDidReceiveMemoryWarningNotification | 150 name:UIApplicationDidReceiveMemoryWarningNotification |
152 object:nil]; | 151 object:nil]; |
153 [[NSNotificationCenter defaultCenter] | 152 [[NSNotificationCenter defaultCenter] |
154 addObserver:self | 153 addObserver:self |
155 selector:@selector(handleEnterBackground) | 154 selector:@selector(handleEnterBackground) |
156 name:UIApplicationDidEnterBackgroundNotification | 155 name:UIApplicationDidEnterBackgroundNotification |
157 object:nil]; | 156 object:nil]; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 UIImage* img = [imageDictionary_ objectForKey:sessionID]; | 198 UIImage* img = [imageDictionary_ objectForKey:sessionID]; |
200 if (img) { | 199 if (img) { |
201 if (callback) | 200 if (callback) |
202 callback(img); | 201 callback(img); |
203 return; | 202 return; |
204 } | 203 } |
205 | 204 |
206 base::PostTaskAndReplyWithResult( | 205 base::PostTaskAndReplyWithResult( |
207 web::WebThread::GetMessageLoopProxyForThread( | 206 web::WebThread::GetMessageLoopProxyForThread( |
208 web::WebThread::FILE_USER_BLOCKING).get(), | 207 web::WebThread::FILE_USER_BLOCKING).get(), |
209 FROM_HERE, | 208 FROM_HERE, base::BindBlock(^base::scoped_nsobject<UIImage>() { |
210 base::BindBlock(^base::scoped_nsobject<UIImage>() { | |
211 // Retrieve the image on a high priority thread. | 209 // Retrieve the image on a high priority thread. |
212 return base::scoped_nsobject<UIImage>([ReadImageFromDisk( | 210 return base::scoped_nsobject<UIImage>([ReadImageFromDisk( |
213 [SnapshotCache imagePathForSessionID:sessionID]) retain]); | 211 [SnapshotCache imagePathForSessionID:sessionID]) retain]); |
214 }), | 212 }), |
215 base::BindBlock(^(base::scoped_nsobject<UIImage> image) { | 213 base::BindBlock(^(base::scoped_nsobject<UIImage> image) { |
216 if (image) | 214 // The iPad tab switcher is currently using its own memory cache so the |
215 // image is not stored in memory here if running on iPad. | |
216 // The same logic is used on image writes (code below). | |
217 if (!IsIPadIdiom() && image) | |
217 [imageDictionary_ setObject:image forKey:sessionID]; | 218 [imageDictionary_ setObject:image forKey:sessionID]; |
218 if (callback) | 219 if (callback) |
219 callback(image); | 220 callback(image); |
noyau (Ping after 24h)
2015/05/19 21:36:34
Why would we retrieve the image if the callback is
sdefresne
2015/05/20 13:15:12
Changed the method to be a no-op on iPad if there
| |
220 })); | 221 })); |
221 } | 222 } |
222 | 223 |
223 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID { | 224 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID { |
224 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 225 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
225 if (!img || !sessionID) | 226 if (!img || !sessionID) |
226 return; | 227 return; |
227 | 228 |
228 // Color snapshots are not used on tablets, so don't keep them in memory. | 229 // The iPad tab switcher is currently using its own memory cache so the image |
230 // is not stored in memory here if running on iPad. | |
231 // The same logic is used on image reads (code above). | |
229 if (!IsIPadIdiom()) { | 232 if (!IsIPadIdiom()) { |
230 [imageDictionary_ setObject:img forKey:sessionID]; | 233 [imageDictionary_ setObject:img forKey:sessionID]; |
231 } | 234 } |
232 // Save the image to disk. | 235 // Save the image to disk. |
233 web::WebThread::PostBlockingPoolSequencedTask( | 236 web::WebThread::PostBlockingPoolSequencedTask( |
234 kSequenceToken, FROM_HERE, | 237 kSequenceToken, FROM_HERE, |
235 base::BindBlock(^{ | 238 base::BindBlock(^{ |
236 base::scoped_nsobject<UIImage> image([img retain]); | 239 base::scoped_nsobject<UIImage> image([img retain]); |
237 WriteImageToDisk(image, | 240 WriteImageToDisk(image, |
238 [SnapshotCache imagePathForSessionID:sessionID]); | 241 [SnapshotCache imagePathForSessionID:sessionID]); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 | 351 |
349 - (void)handleLowMemory { | 352 - (void)handleLowMemory { |
350 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 353 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
351 NSMutableDictionary* dictionary = | 354 NSMutableDictionary* dictionary = |
352 [[NSMutableDictionary alloc] initWithCapacity:2]; | 355 [[NSMutableDictionary alloc] initWithCapacity:2]; |
353 for (NSString* sessionID in pinnedIDs_) { | 356 for (NSString* sessionID in pinnedIDs_) { |
354 UIImage* image = [imageDictionary_ objectForKey:sessionID]; | 357 UIImage* image = [imageDictionary_ objectForKey:sessionID]; |
355 if (image) | 358 if (image) |
356 [dictionary setObject:image forKey:sessionID]; | 359 [dictionary setObject:image forKey:sessionID]; |
357 } | 360 } |
358 imageDictionary_.reset(dictionary); | 361 imageDictionary_.reset(dictionary); |
noyau (Ping after 24h)
2015/05/19 21:36:35
Same here, no need to even run anything here on ip
sdefresne
2015/05/20 13:15:12
Done.
| |
359 } | 362 } |
360 | 363 |
361 - (void)handleEnterBackground { | 364 - (void)handleEnterBackground { |
362 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 365 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
363 [imageDictionary_ removeAllObjects]; | 366 [imageDictionary_ removeAllObjects]; |
364 } | 367 } |
365 | 368 |
366 - (void)handleBecomeActive { | 369 - (void)handleBecomeActive { |
367 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 370 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
368 for (NSString* sessionID in pinnedIDs_) | 371 for (NSString* sessionID in pinnedIDs_) |
369 [self retrieveImageForSessionID:sessionID callback:nil]; | 372 [self retrieveImageForSessionID:sessionID callback:nil]; |
noyau (Ping after 24h)
2015/05/19 21:36:35
Not on ipad…
sdefresne
2015/05/20 13:15:12
Done.
| |
370 } | 373 } |
371 | 374 |
372 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID { | 375 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID { |
373 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); | 376 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); |
374 if (greyImage) | 377 if (greyImage) |
375 [greyImageDictionary_ setObject:greyImage forKey:sessionID]; | 378 [greyImageDictionary_ setObject:greyImage forKey:sessionID]; |
376 if ([sessionID isEqualToString:mostRecentGreySessionId_]) { | 379 if ([sessionID isEqualToString:mostRecentGreySessionId_]) { |
377 mostRecentGreyBlock_.get()(greyImage); | 380 mostRecentGreyBlock_.get()(greyImage); |
378 [self clearGreySessionInfo]; | 381 [self clearGreySessionInfo]; |
379 } | 382 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
500 backgroundingImageSessionId_.reset(); | 503 backgroundingImageSessionId_.reset(); |
501 } | 504 } |
502 } | 505 } |
503 | 506 |
504 web::WebThread::PostBlockingPoolTask( | 507 web::WebThread::PostBlockingPoolTask( |
505 FROM_HERE, base::Bind(&ConvertAndSaveGreyImage, colorImagePath, | 508 FROM_HERE, base::Bind(&ConvertAndSaveGreyImage, colorImagePath, |
506 greyImagePath, backgroundingColorImage_)); | 509 greyImagePath, backgroundingColorImage_)); |
507 } | 510 } |
508 | 511 |
509 @end | 512 @end |
OLD | NEW |