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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "ios/chrome/browser/snapshots/web_controller_snapshot_helper.h"
6
7 #import "base/ios/weak_nsobject.h"
8 #import "base/mac/scoped_nsobject.h"
9 #import "ios/chrome/browser/snapshots/snapshot_manager.h"
10 #import "ios/chrome/browser/tabs/tab.h"
11 #import "ios/chrome/browser/ui/fullscreen_controller.h"
12 #import "ios/chrome/browser/ui/uikit_ui_util.h"
13 #import "ios/web/web_state/ui/crw_web_controller.h"
14
15 @interface WebControllerSnapshotHelper ()
16
17 // Takes a snapshot image for the WebController's current page. Returns an
18 // autoreleased image cropped and scaled appropriately. Returns a default image
19 // if a snapshot cannot be generated.
20 - (UIImage*)generateSnapshotOrDefaultForWebController:
21 (CRWWebController*)webController
22 withOverlays:(NSArray*)overlays
23 visibleFrameOnly:(BOOL)visibleFrameOnly;
24
25 // Returns the cached snapshot if there is one matching the given parameters.
26 // Returns nil otherwise or if there is no |_coalescingSnapshotContext|.
27 - (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
28 visibleFrameOnly:(BOOL)visibleFrameOnly;
29
30 // Caches |snapshot| for the given |overlays| and |visibleFrameOnly|. Does
31 // nothing if there is no |_coalescingSnapshotContext|.
32 - (void)setCachedSnapshot:(UIImage*)snapshot
33 withOverlays:(NSArray*)overlays
34 visibleFrameOnly:(BOOL)visibleFrameOnly;
35 @end
36
37 // Class that contains information used when caching snapshots of a web page.
38 @interface CoalescingSnapshotContext : NSObject
39
40 // Returns the cached snapshot if there is one matching the given parameters.
41 // Returns nil otherwise.
42 - (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
43 visibleFrameOnly:(BOOL)visibleFrameOnly;
44
45 // Caches |snapshot| for the given |overlays| and |visibleFrameOnly|.
46 - (void)setCachedSnapshot:(UIImage*)snapshot
47 withOverlays:(NSArray*)overlays
48 visibleFrameOnly:(BOOL)visibleFrameOnly;
49
50 @end
51
52 @implementation CoalescingSnapshotContext {
53 base::scoped_nsobject<UIImage> _cachedSnapshot;
54 }
55
56 // Returns whether a snapshot should be cached in a page loaded context.
57 // Note: Returns YES if |overlays| is nil or empty and if |visibleFrameOnly| is
58 // YES as this is the only case when the snapshot taken by the CRWWebController
59 // is reused.
60 - (BOOL)shouldCacheSnapshotWithOverlays:(NSArray*)overlays
61 visibleFrameOnly:(BOOL)visibleFrameOnly {
62 return ![overlays count] && visibleFrameOnly;
63 }
64
65 - (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
66 visibleFrameOnly:(BOOL)visibleFrameOnly {
67 if ([self shouldCacheSnapshotWithOverlays:overlays
68 visibleFrameOnly:visibleFrameOnly]) {
69 return _cachedSnapshot;
70 }
71 return nil;
72 }
73
74 - (void)setCachedSnapshot:(UIImage*)snapshot
75 withOverlays:(NSArray*)overlays
76 visibleFrameOnly:(BOOL)visibleFrameOnly {
77 if ([self shouldCacheSnapshotWithOverlays:overlays
78 visibleFrameOnly:visibleFrameOnly]) {
79 DCHECK(!_cachedSnapshot);
80 _cachedSnapshot.reset([snapshot retain]);
81 }
82 }
83
84 @end
85
86 @implementation WebControllerSnapshotHelper {
87 base::scoped_nsobject<CoalescingSnapshotContext> _coalescingSnapshotContext;
88 base::scoped_nsobject<SnapshotManager> _snapshotManager;
89 base::WeakNSObject<CRWWebController> _webController;
90 // Owns this WebControllerSnapshotHelper.
91 base::WeakNSObject<Tab> _tab;
92 }
93
94 - (instancetype)init {
95 NOTREACHED();
96 return nil;
97 }
98
99 - (instancetype)initWithSnapshotManager:(SnapshotManager*)snapshotManager
100 tab:(Tab*)tab {
101 self = [super init];
102 if (self) {
103 DCHECK(snapshotManager);
104 DCHECK(tab);
105 DCHECK([tab currentSessionID]);
106 DCHECK([tab webController]);
107 _snapshotManager.reset([snapshotManager retain]);
108 _webController.reset([tab webController]);
109 _tab.reset(tab);
110 }
111 return self;
112 }
113
114 - (void)setSnapshotCoalescingEnabled:(BOOL)snapshotCoalescingEnabled {
115 if (snapshotCoalescingEnabled) {
116 DCHECK(!_coalescingSnapshotContext);
117 _coalescingSnapshotContext.reset([[CoalescingSnapshotContext alloc] init]);
118 } else {
119 DCHECK(_coalescingSnapshotContext);
120 _coalescingSnapshotContext.reset();
121 }
122 }
123
124 - (UIImage*)generateSnapshotOrDefaultForWebController:
125 (CRWWebController*)webController
126 withOverlays:(NSArray*)overlays
127 visibleFrameOnly:(BOOL)visibleFrameOnly {
128 UIImage* result = [self generateSnapshotForWebController:webController
129 withOverlays:overlays
130 visibleFrameOnly:visibleFrameOnly];
131 return result ? result : [[self class] defaultSnapshotImage];
132 }
133
134 - (void)retrieveSnapshotForWebController:(CRWWebController*)webController
135 sessionID:(NSString*)sessionID
136 withOverlays:(NSArray*)overlays
137 callback:(void (^)(UIImage* image))callback {
138 [_snapshotManager
139 retrieveImageForSessionID:sessionID
140 callback:^(UIImage* image) {
141 if (image) {
142 callback(image);
143 } else {
144 callback([self
145 updateSnapshotForWebController:webController
146 sessionID:sessionID
147 withOverlays:overlays
148 visibleFrameOnly:YES]);
149 }
150 }];
151 }
152
153 - (void)retrieveGreySnapshotForWebController:(CRWWebController*)webController
154 sessionID:(NSString*)sessionID
155 withOverlays:(NSArray*)overlays
156 callback:
157 (void (^)(UIImage* image))callback {
158 [_snapshotManager
159 retrieveGreyImageForSessionID:sessionID
160 callback:^(UIImage* image) {
161 if (image) {
162 callback(image);
163 } else {
164 callback(GreyImage([self
165 updateSnapshotForWebController:webController
166 sessionID:sessionID
167 withOverlays:overlays
168 visibleFrameOnly:YES]));
169 }
170 }];
171 }
172
173 - (UIImage*)updateSnapshotForWebController:(CRWWebController*)webController
174 sessionID:(NSString*)sessionID
175 withOverlays:(NSArray*)overlays
176 visibleFrameOnly:(BOOL)visibleFrameOnly {
177 // TODO(crbug.com/661641): This is a temporary solution to make sure the
178 // webController retained by us is the same being passed in in this method.
179 // Remove this when all uses of the "CRWWebController" are dropped from the
180 // methods names since it is already retained by us and not necessary to be
181 // passed in.
182 DCHECK_EQ([_tab webController], webController);
183 UIImage* snapshot =
184 [self generateSnapshotOrDefaultForWebController:webController
185 withOverlays:overlays
186 visibleFrameOnly:visibleFrameOnly];
187 // If the snapshot is the default one, return it without caching it.
188 if (snapshot == [[self class] defaultSnapshotImage])
189 return snapshot;
190
191 UIImage* snapshotToCache = nil;
192 // TODO(crbug.com/370994): Remove all code that references a Tab's delegates
193 // from this file.
194 if (visibleFrameOnly || ![_tab fullScreenControllerDelegate]) {
195 snapshotToCache = snapshot;
196 } else {
197 // Crops the bottom of the fullscreen snapshot.
198 CGRect cropRect =
199 CGRectMake(0, [[_tab fullScreenControllerDelegate] headerHeight],
200 [snapshot size].width, [snapshot size].height);
201 snapshotToCache = CropImage(snapshot, cropRect);
202 }
203 [_snapshotManager setImage:snapshotToCache withSessionID:sessionID];
204 return snapshot;
205 }
206
207 - (UIImage*)generateSnapshotForWebController:(CRWWebController*)webController
208 withOverlays:(NSArray*)overlays
209 visibleFrameOnly:(BOOL)visibleFrameOnly {
210 if (![webController canUseViewForGeneratingOverlayPlaceholderView])
211 return nil;
212 CGRect visibleFrame = (visibleFrameOnly ? [_tab snapshotContentArea]
213 : [webController.view bounds]);
214 if (CGRectIsEmpty(visibleFrame))
215 return nil;
216 UIImage* snapshot = [self cachedSnapshotWithOverlays:overlays
217 visibleFrameOnly:visibleFrameOnly];
218 if (!snapshot) {
219 [_tab willUpdateSnapshot];
220 snapshot = [_snapshotManager generateSnapshotForView:webController.view
221 withRect:visibleFrame
222 overlays:overlays];
223 [self setCachedSnapshot:snapshot
224 withOverlays:overlays
225 visibleFrameOnly:visibleFrameOnly];
226 }
227 return snapshot;
228 }
229
230 // TODO(crbug.com/661642): This code is shared with SnapshotManager. Remove this
231 // and add it as part of WebDelegate delegate API such that a default image is
232 // returned immediately.
233 + (UIImage*)defaultSnapshotImage {
234 static UIImage* defaultImage = nil;
235
236 if (!defaultImage) {
237 CGRect frame = CGRectMake(0, 0, 2, 2);
238 UIGraphicsBeginImageContext(frame.size);
239 [[UIColor whiteColor] setFill];
240 CGContextFillRect(UIGraphicsGetCurrentContext(), frame);
241
242 UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
243 UIGraphicsEndImageContext();
244
245 defaultImage =
246 [[result stretchableImageWithLeftCapWidth:1 topCapHeight:1] retain];
247 }
248 return defaultImage;
249 }
250
251 - (void)setCachedSnapshot:(UIImage*)snapshot
252 withOverlays:(NSArray*)overlays
253 visibleFrameOnly:(BOOL)visibleFrameOnly {
254 return [_coalescingSnapshotContext setCachedSnapshot:snapshot
255 withOverlays:overlays
256 visibleFrameOnly:visibleFrameOnly];
257 }
258
259 - (UIImage*)cachedSnapshotWithOverlays:(NSArray*)overlays
260 visibleFrameOnly:(BOOL)visibleFrameOnly {
261 return
262 [_coalescingSnapshotContext cachedSnapshotWithOverlays:overlays
263 visibleFrameOnly:visibleFrameOnly];
264 }
265
266 @end
OLDNEW
« 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