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

Unified Diff: ios/chrome/browser/snapshots/web_controller_snapshot_helper.mm

Issue 2585233003: Upstream Chrome on iOS source code [2/11]. (Closed)
Patch Set: Created 4 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ios/chrome/browser/snapshots/web_controller_snapshot_helper.h ('k') | ios/chrome/browser/tabs/tab.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ios/chrome/browser/snapshots/web_controller_snapshot_helper.mm
diff --git a/ios/chrome/browser/snapshots/web_controller_snapshot_helper.mm b/ios/chrome/browser/snapshots/web_controller_snapshot_helper.mm
new file mode 100644
index 0000000000000000000000000000000000000000..8ff35086c3e364196d02300c1fc2810be77f88cb
--- /dev/null
+++ b/ios/chrome/browser/snapshots/web_controller_snapshot_helper.mm
@@ -0,0 +1,266 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/snapshots/web_controller_snapshot_helper.h"
+
+#import "base/ios/weak_nsobject.h"
+#import "base/mac/scoped_nsobject.h"
+#import "ios/chrome/browser/snapshots/snapshot_manager.h"
+#import "ios/chrome/browser/tabs/tab.h"
+#import "ios/chrome/browser/ui/fullscreen_controller.h"
+#import "ios/chrome/browser/ui/uikit_ui_util.h"
+#import "ios/web/web_state/ui/crw_web_controller.h"
+
+@interface WebControllerSnapshotHelper ()
+
+// Takes a snapshot image for the WebController's current page. Returns an
+// autoreleased image cropped and scaled appropriately. Returns a default image
+// if a snapshot cannot be generated.
+- (UIImage*)generateSnapshotOrDefaultForWebController:
+ (CRWWebController*)webController
+ withOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly;
+
+// Returns the cached snapshot if there is one matching the given parameters.
+// Returns nil otherwise or if there is no |_coalescingSnapshotContext|.
+- (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly;
+
+// Caches |snapshot| for the given |overlays| and |visibleFrameOnly|. Does
+// nothing if there is no |_coalescingSnapshotContext|.
+- (void)setCachedSnapshot:(UIImage*)snapshot
+ withOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly;
+@end
+
+// Class that contains information used when caching snapshots of a web page.
+@interface CoalescingSnapshotContext : NSObject
+
+// Returns the cached snapshot if there is one matching the given parameters.
+// Returns nil otherwise.
+- (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly;
+
+// Caches |snapshot| for the given |overlays| and |visibleFrameOnly|.
+- (void)setCachedSnapshot:(UIImage*)snapshot
+ withOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly;
+
+@end
+
+@implementation CoalescingSnapshotContext {
+ base::scoped_nsobject<UIImage> _cachedSnapshot;
+}
+
+// Returns whether a snapshot should be cached in a page loaded context.
+// Note: Returns YES if |overlays| is nil or empty and if |visibleFrameOnly| is
+// YES as this is the only case when the snapshot taken by the CRWWebController
+// is reused.
+- (BOOL)shouldCacheSnapshotWithOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly {
+ return ![overlays count] && visibleFrameOnly;
+}
+
+- (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly {
+ if ([self shouldCacheSnapshotWithOverlays:overlays
+ visibleFrameOnly:visibleFrameOnly]) {
+ return _cachedSnapshot;
+ }
+ return nil;
+}
+
+- (void)setCachedSnapshot:(UIImage*)snapshot
+ withOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly {
+ if ([self shouldCacheSnapshotWithOverlays:overlays
+ visibleFrameOnly:visibleFrameOnly]) {
+ DCHECK(!_cachedSnapshot);
+ _cachedSnapshot.reset([snapshot retain]);
+ }
+}
+
+@end
+
+@implementation WebControllerSnapshotHelper {
+ base::scoped_nsobject<CoalescingSnapshotContext> _coalescingSnapshotContext;
+ base::scoped_nsobject<SnapshotManager> _snapshotManager;
+ base::WeakNSObject<CRWWebController> _webController;
+ // Owns this WebControllerSnapshotHelper.
+ base::WeakNSObject<Tab> _tab;
+}
+
+- (instancetype)init {
+ NOTREACHED();
+ return nil;
+}
+
+- (instancetype)initWithSnapshotManager:(SnapshotManager*)snapshotManager
+ tab:(Tab*)tab {
+ self = [super init];
+ if (self) {
+ DCHECK(snapshotManager);
+ DCHECK(tab);
+ DCHECK([tab currentSessionID]);
+ DCHECK([tab webController]);
+ _snapshotManager.reset([snapshotManager retain]);
+ _webController.reset([tab webController]);
+ _tab.reset(tab);
+ }
+ return self;
+}
+
+- (void)setSnapshotCoalescingEnabled:(BOOL)snapshotCoalescingEnabled {
+ if (snapshotCoalescingEnabled) {
+ DCHECK(!_coalescingSnapshotContext);
+ _coalescingSnapshotContext.reset([[CoalescingSnapshotContext alloc] init]);
+ } else {
+ DCHECK(_coalescingSnapshotContext);
+ _coalescingSnapshotContext.reset();
+ }
+}
+
+- (UIImage*)generateSnapshotOrDefaultForWebController:
+ (CRWWebController*)webController
+ withOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly {
+ UIImage* result = [self generateSnapshotForWebController:webController
+ withOverlays:overlays
+ visibleFrameOnly:visibleFrameOnly];
+ return result ? result : [[self class] defaultSnapshotImage];
+}
+
+- (void)retrieveSnapshotForWebController:(CRWWebController*)webController
+ sessionID:(NSString*)sessionID
+ withOverlays:(NSArray*)overlays
+ callback:(void (^)(UIImage* image))callback {
+ [_snapshotManager
+ retrieveImageForSessionID:sessionID
+ callback:^(UIImage* image) {
+ if (image) {
+ callback(image);
+ } else {
+ callback([self
+ updateSnapshotForWebController:webController
+ sessionID:sessionID
+ withOverlays:overlays
+ visibleFrameOnly:YES]);
+ }
+ }];
+}
+
+- (void)retrieveGreySnapshotForWebController:(CRWWebController*)webController
+ sessionID:(NSString*)sessionID
+ withOverlays:(NSArray*)overlays
+ callback:
+ (void (^)(UIImage* image))callback {
+ [_snapshotManager
+ retrieveGreyImageForSessionID:sessionID
+ callback:^(UIImage* image) {
+ if (image) {
+ callback(image);
+ } else {
+ callback(GreyImage([self
+ updateSnapshotForWebController:webController
+ sessionID:sessionID
+ withOverlays:overlays
+ visibleFrameOnly:YES]));
+ }
+ }];
+}
+
+- (UIImage*)updateSnapshotForWebController:(CRWWebController*)webController
+ sessionID:(NSString*)sessionID
+ withOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly {
+ // TODO(crbug.com/661641): This is a temporary solution to make sure the
+ // webController retained by us is the same being passed in in this method.
+ // Remove this when all uses of the "CRWWebController" are dropped from the
+ // methods names since it is already retained by us and not necessary to be
+ // passed in.
+ DCHECK_EQ([_tab webController], webController);
+ UIImage* snapshot =
+ [self generateSnapshotOrDefaultForWebController:webController
+ withOverlays:overlays
+ visibleFrameOnly:visibleFrameOnly];
+ // If the snapshot is the default one, return it without caching it.
+ if (snapshot == [[self class] defaultSnapshotImage])
+ return snapshot;
+
+ UIImage* snapshotToCache = nil;
+ // TODO(crbug.com/370994): Remove all code that references a Tab's delegates
+ // from this file.
+ if (visibleFrameOnly || ![_tab fullScreenControllerDelegate]) {
+ snapshotToCache = snapshot;
+ } else {
+ // Crops the bottom of the fullscreen snapshot.
+ CGRect cropRect =
+ CGRectMake(0, [[_tab fullScreenControllerDelegate] headerHeight],
+ [snapshot size].width, [snapshot size].height);
+ snapshotToCache = CropImage(snapshot, cropRect);
+ }
+ [_snapshotManager setImage:snapshotToCache withSessionID:sessionID];
+ return snapshot;
+}
+
+- (UIImage*)generateSnapshotForWebController:(CRWWebController*)webController
+ withOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly {
+ if (![webController canUseViewForGeneratingOverlayPlaceholderView])
+ return nil;
+ CGRect visibleFrame = (visibleFrameOnly ? [_tab snapshotContentArea]
+ : [webController.view bounds]);
+ if (CGRectIsEmpty(visibleFrame))
+ return nil;
+ UIImage* snapshot = [self cachedSnapshotWithOverlays:overlays
+ visibleFrameOnly:visibleFrameOnly];
+ if (!snapshot) {
+ [_tab willUpdateSnapshot];
+ snapshot = [_snapshotManager generateSnapshotForView:webController.view
+ withRect:visibleFrame
+ overlays:overlays];
+ [self setCachedSnapshot:snapshot
+ withOverlays:overlays
+ visibleFrameOnly:visibleFrameOnly];
+ }
+ return snapshot;
+}
+
+// TODO(crbug.com/661642): This code is shared with SnapshotManager. Remove this
+// and add it as part of WebDelegate delegate API such that a default image is
+// returned immediately.
++ (UIImage*)defaultSnapshotImage {
+ static UIImage* defaultImage = nil;
+
+ if (!defaultImage) {
+ CGRect frame = CGRectMake(0, 0, 2, 2);
+ UIGraphicsBeginImageContext(frame.size);
+ [[UIColor whiteColor] setFill];
+ CGContextFillRect(UIGraphicsGetCurrentContext(), frame);
+
+ UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+
+ defaultImage =
+ [[result stretchableImageWithLeftCapWidth:1 topCapHeight:1] retain];
+ }
+ return defaultImage;
+}
+
+- (void)setCachedSnapshot:(UIImage*)snapshot
+ withOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly {
+ return [_coalescingSnapshotContext setCachedSnapshot:snapshot
+ withOverlays:overlays
+ visibleFrameOnly:visibleFrameOnly];
+}
+
+- (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
+ visibleFrameOnly:(BOOL)visibleFrameOnly {
+ return
+ [_coalescingSnapshotContext cachedSnapshotWithOverlays:overlays
+ visibleFrameOnly:visibleFrameOnly];
+}
+
+@end
« no previous file with comments | « ios/chrome/browser/snapshots/web_controller_snapshot_helper.h ('k') | ios/chrome/browser/tabs/tab.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698