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

Side by Side Diff: ios/chrome/browser/ui/preload_controller.mm

Issue 2775623002: [ios] WebStateList owns all WebState it manages. (Closed)
Patch Set: Fix gn check Created 3 years, 8 months 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
« no previous file with comments | « ios/chrome/browser/ui/preload_controller.h ('k') | ios/chrome/browser/ui/tab_switcher/DEPS » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <UIKit/UIKit.h> 5 #import <UIKit/UIKit.h>
6 6
7 #include "ios/chrome/browser/ui/preload_controller.h" 7 #include "ios/chrome/browser/ui/preload_controller.h"
8 8
9 #include "base/ios/device_util.h" 9 #include "base/ios/device_util.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/mac/scoped_nsobject.h"
11 #include "base/metrics/field_trial.h" 12 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
13 #include "base/strings/sys_string_conversions.h" 14 #include "base/strings/sys_string_conversions.h"
14 #include "components/prefs/pref_service.h" 15 #include "components/prefs/pref_service.h"
15 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" 16 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
16 #include "ios/chrome/browser/pref_names.h" 17 #include "ios/chrome/browser/pref_names.h"
18 #import "ios/chrome/browser/tabs/legacy_tab_helper.h"
17 #import "ios/chrome/browser/tabs/tab.h" 19 #import "ios/chrome/browser/tabs/tab.h"
20 #import "ios/chrome/browser/tabs/tab_helper_util.h"
21 #import "ios/chrome/browser/tabs/tab_private.h"
18 #include "ios/chrome/browser/ui/preload_controller_delegate.h" 22 #include "ios/chrome/browser/ui/preload_controller_delegate.h"
19 #include "ios/chrome/browser/ui/prerender_final_status.h" 23 #include "ios/chrome/browser/ui/prerender_final_status.h"
20 #import "ios/web/public/web_state/ui/crw_native_content.h" 24 #import "ios/web/public/web_state/ui/crw_native_content.h"
21 #include "ios/web/public/web_thread.h" 25 #include "ios/web/public/web_thread.h"
22 #import "ios/web/web_state/ui/crw_web_controller.h" 26 #import "ios/web/web_state/ui/crw_web_controller.h"
23 #import "net/base/mac/url_conversions.h" 27 #import "net/base/mac/url_conversions.h"
24 #include "net/url_request/url_fetcher.h" 28 #include "net/url_request/url_fetcher.h"
25 #include "net/url_request/url_fetcher_delegate.h" 29 #include "net/url_request/url_fetcher_delegate.h"
26 #include "ui/base/page_transition_types.h" 30 #include "ui/base/page_transition_types.h"
27 31
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 public: 98 public:
95 explicit PrefetchDelegate(PreloadController* owner) : owner_(owner) {} 99 explicit PrefetchDelegate(PreloadController* owner) : owner_(owner) {}
96 void OnURLFetchComplete(const net::URLFetcher* source) override { 100 void OnURLFetchComplete(const net::URLFetcher* source) override {
97 [owner_ prefetchDidComplete:source]; 101 [owner_ prefetchDidComplete:source];
98 } 102 }
99 103
100 private: 104 private:
101 PreloadController* owner_; // weak 105 PreloadController* owner_; // weak
102 }; 106 };
103 107
104 @implementation PreloadController 108 @implementation PreloadController {
109 ios::ChromeBrowserState* browserState_; // Weak.
110
111 // The WebState used for prerendering.
112 std::unique_ptr<web::WebState> webState_;
113
114 // The URL that is prerendered in |webState_|. This can be different from
115 // the value returned by WebState last committed navigation item, for example
116 // in cases where there was a redirect.
117 //
118 // When choosing whether or not to use a prerendered Tab,
119 // BrowserViewController compares the URL being loaded by the omnibox with the
120 // URL of the prerendered Tab. Comparing against the Tab's currently URL
121 // could return false negatives in cases of redirect, hence the need to store
122 // the originally prerendered URL.
123 GURL prerenderedURL_;
124
125 // The URL that is scheduled to be prerendered, its associated transition and
126 // referrer. |scheduledTransition_| and |scheduledReferrer_| are not valid
127 // when |scheduledURL_| is empty.
128 GURL scheduledURL_;
129 ui::PageTransition scheduledTransition_;
130 web::Referrer scheduledReferrer_;
131
132 // The most-recently prefetched URL, or nil if there have been no prefetched
133 // URLs.
134 GURL prefetchedURL_;
135
136 // The URLFetcher and associated delegate used to prefetch URLs. The delegate
137 // simply forwards callbacks from URLFetcher back to the PrerenderController.
138 std::unique_ptr<PrefetchDelegate> prefetcherDelegate_;
139 std::unique_ptr<net::URLFetcher> prefetcher_;
140
141 // Bridge to listen to pref changes.
142 std::unique_ptr<PrefObserverBridge> observerBridge_;
143 // Registrar for pref changes notifications.
144 PrefChangeRegistrar prefChangeRegistrar_;
145 // Observer for the WWAN setting. Contains a valid object only if the
146 // instant setting is set to wifi-only.
147 std::unique_ptr<ConnectionTypeObserverBridge> connectionTypeObserverBridge_;
148
149 // Whether or not the preference is enabled.
150 BOOL enabled_;
151 // Whether or not prerendering is only when on wifi.
152 BOOL wifiOnly_;
153 // Whether or not the current connection is using WWAN.
154 BOOL usingWWAN_;
155
156 // Number of successful prerenders (i.e. the user viewed the prerendered page)
157 // during the lifetime of this controller.
158 int successfulPrerendersPerSessionCount_;
159
160 id<PreloadControllerDelegate> delegate_; // weak
161 }
105 162
106 @synthesize prerenderedURL = prerenderedURL_; 163 @synthesize prerenderedURL = prerenderedURL_;
107 @synthesize prefetchedURL = prefetchedURL_; 164 @synthesize prefetchedURL = prefetchedURL_;
108 @synthesize delegate = delegate_; 165 @synthesize delegate = delegate_;
109 166
110 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState { 167 - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState {
111 DCHECK(browserState); 168 DCHECK(browserState);
112 DCHECK_CURRENTLY_ON(web::WebThread::UI); 169 DCHECK_CURRENTLY_ON(web::WebThread::UI);
113 if ((self = [super init])) { 170 if ((self = [super init])) {
114 browserState_ = browserState; 171 browserState_ = browserState;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 265
209 - (void)cancelPrerender { 266 - (void)cancelPrerender {
210 [self cancelPrerenderForReason:PRERENDER_FINAL_STATUS_CANCELLED]; 267 [self cancelPrerenderForReason:PRERENDER_FINAL_STATUS_CANCELLED];
211 } 268 }
212 269
213 - (void)cancelPrerenderForReason:(PrerenderFinalStatus)reason { 270 - (void)cancelPrerenderForReason:(PrerenderFinalStatus)reason {
214 [self removeScheduledPrerenderRequests]; 271 [self removeScheduledPrerenderRequests];
215 [self destroyPreviewContentsForReason:reason]; 272 [self destroyPreviewContentsForReason:reason];
216 } 273 }
217 274
218 - (Tab*)releasePrerenderContents { 275 - (std::unique_ptr<web::WebState>)releasePrerenderContents {
219 successfulPrerendersPerSessionCount_++; 276 successfulPrerendersPerSessionCount_++;
220 UMA_HISTOGRAM_ENUMERATION(kPrerenderFinalStatusHistogramName, 277 UMA_HISTOGRAM_ENUMERATION(kPrerenderFinalStatusHistogramName,
221 PRERENDER_FINAL_STATUS_USED, 278 PRERENDER_FINAL_STATUS_USED,
222 PRERENDER_FINAL_STATUS_MAX); 279 PRERENDER_FINAL_STATUS_MAX);
223 [self removeScheduledPrerenderRequests]; 280 [self removeScheduledPrerenderRequests];
224 prerenderedURL_ = GURL(); 281 prerenderedURL_ = GURL();
225 [[tab_ webController] setNativeProvider:nil]; 282
226 [tab_ setDelegate:nil]; 283 if (webState_) {
227 return [tab_.release() autorelease]; 284 Tab* tab = LegacyTabHelper::GetTabForWebState(webState_.get());
285 [[tab webController] setNativeProvider:nil];
286 [tab setDelegate:nil];
287 }
288
289 return std::move(webState_);
228 } 290 }
229 291
230 - (void)connectionTypeChanged:(net::NetworkChangeNotifier::ConnectionType)type { 292 - (void)connectionTypeChanged:(net::NetworkChangeNotifier::ConnectionType)type {
231 DCHECK_CURRENTLY_ON(web::WebThread::UI); 293 DCHECK_CURRENTLY_ON(web::WebThread::UI);
232 usingWWAN_ = net::NetworkChangeNotifier::IsConnectionCellular(type); 294 usingWWAN_ = net::NetworkChangeNotifier::IsConnectionCellular(type);
233 if (wifiOnly_ && usingWWAN_) 295 if (wifiOnly_ && usingWWAN_)
234 [self cancelPrerender]; 296 [self cancelPrerender];
235 } 297 }
236 298
237 - (void)onPreferenceChanged:(const std::string&)preferenceName { 299 - (void)onPreferenceChanged:(const std::string&)preferenceName {
(...skipping 27 matching lines...) Expand all
265 327
266 - (void)didReceiveMemoryWarning { 328 - (void)didReceiveMemoryWarning {
267 [self cancelPrerenderForReason:PRERENDER_FINAL_STATUS_MEMORY_LIMIT_EXCEEDED]; 329 [self cancelPrerenderForReason:PRERENDER_FINAL_STATUS_MEMORY_LIMIT_EXCEEDED];
268 } 330 }
269 331
270 #pragma mark - 332 #pragma mark -
271 #pragma mark CRWNativeContentProvider implementation 333 #pragma mark CRWNativeContentProvider implementation
272 334
273 // Delegate the call to the original native provider. 335 // Delegate the call to the original native provider.
274 - (BOOL)hasControllerForURL:(const GURL&)url { 336 - (BOOL)hasControllerForURL:(const GURL&)url {
275 return [[tab_ webController].nativeProvider hasControllerForURL:url]; 337 if (!webState_)
338 return NO;
339 Tab* tab = LegacyTabHelper::GetTabForWebState(webState_.get());
340 return [[tab webController].nativeProvider hasControllerForURL:url];
276 } 341 }
277 342
278 // Override the CRWNativeContentProvider methods to cancel any prerenders that 343 // Override the CRWNativeContentProvider methods to cancel any prerenders that
279 // require native content. 344 // require native content.
280 - (id<CRWNativeContent>)controllerForURL:(const GURL&)url 345 - (id<CRWNativeContent>)controllerForURL:(const GURL&)url
281 webState:(web::WebState*)webState { 346 webState:(web::WebState*)webState {
282 [self schedulePrerenderCancel]; 347 [self schedulePrerenderCancel];
283 return nil; 348 return nil;
284 } 349 }
285 350
(...skipping 30 matching lines...) Expand all
316 [self destroyPreviewContents]; 381 [self destroyPreviewContents];
317 prerenderedURL_ = scheduledURL_; 382 prerenderedURL_ = scheduledURL_;
318 scheduledURL_ = GURL(); 383 scheduledURL_ = GURL();
319 384
320 DCHECK(prerenderedURL_.is_valid()); 385 DCHECK(prerenderedURL_.is_valid());
321 if (!prerenderedURL_.is_valid()) { 386 if (!prerenderedURL_.is_valid()) {
322 [self destroyPreviewContents]; 387 [self destroyPreviewContents];
323 return; 388 return;
324 } 389 }
325 390
326 Tab* tab = 391 web::WebState::CreateParams createParams(browserState_);
327 [Tab preloadingTabWithBrowserState:browserState_ 392 webState_ = web::WebState::Create(createParams);
328 url:prerenderedURL_ 393 AttachTabHelpers(webState_.get());
329 referrer:scheduledReferrer_
330 transition:scheduledTransition_
331 provider:self
332 opener:nil
333 desktopUserAgent:[delegate_ shouldUseDesktopUserAgent]
334 configuration:^(Tab* tab) {
335 [tab setIsPrerenderTab:YES];
336 [tab setDelegate:self];
337 }];
338 394
339 // Create and set up the prerender. 395 Tab* tab = LegacyTabHelper::GetTabForWebState(webState_.get());
340 tab_.reset([tab retain]); 396 DCHECK(tab);
397
398 [[tab webController] setNativeProvider:self];
399 [[tab webController] setWebUsageEnabled:YES];
400 [tab setIsPrerenderTab:YES];
401 [tab setDelegate:self];
402
403 web::NavigationManager::WebLoadParams loadParams(prerenderedURL_);
404 loadParams.referrer = scheduledReferrer_;
405 loadParams.transition_type = scheduledTransition_;
406 if ([delegate_ shouldUseDesktopUserAgent]) {
407 loadParams.user_agent_override_option =
408 web::NavigationManager::UserAgentOverrideOption::DESKTOP;
409 }
410 [[tab webController] loadWithParams:loadParams];
341 411
342 // Trigger the page to start loading. 412 // Trigger the page to start loading.
343 [tab_ view]; 413 [tab view];
344 } 414 }
345 415
346 - (const GURL)urlToPrefetchURL:(const GURL&)url { 416 - (const GURL)urlToPrefetchURL:(const GURL&)url {
347 GURL::Replacements replacements; 417 GURL::Replacements replacements;
348 418
349 // Add prefetch indicator to query params. 419 // Add prefetch indicator to query params.
350 std::string query = url.query(); 420 std::string query = url.query();
351 if (!query.empty()) { 421 if (!query.empty()) {
352 query.append("&"); 422 query.append("&");
353 } 423 }
(...skipping 18 matching lines...) Expand all
372 << "Prefetching URL got response code " << source->GetResponseCode(); 442 << "Prefetching URL got response code " << source->GetResponseCode();
373 } 443 }
374 prefetcher_.reset(); 444 prefetcher_.reset();
375 } 445 }
376 446
377 - (void)destroyPreviewContents { 447 - (void)destroyPreviewContents {
378 [self destroyPreviewContentsForReason:PRERENDER_FINAL_STATUS_CANCELLED]; 448 [self destroyPreviewContentsForReason:PRERENDER_FINAL_STATUS_CANCELLED];
379 } 449 }
380 450
381 - (void)destroyPreviewContentsForReason:(PrerenderFinalStatus)reason { 451 - (void)destroyPreviewContentsForReason:(PrerenderFinalStatus)reason {
382 if (!tab_.get()) 452 if (!webState_)
383 return; 453 return;
384 454
385 UMA_HISTOGRAM_ENUMERATION(kPrerenderFinalStatusHistogramName, reason, 455 UMA_HISTOGRAM_ENUMERATION(kPrerenderFinalStatusHistogramName, reason,
386 PRERENDER_FINAL_STATUS_MAX); 456 PRERENDER_FINAL_STATUS_MAX);
387 [[tab_ webController] setNativeProvider:nil]; 457
388 [tab_ setDelegate:nil]; 458 Tab* tab = LegacyTabHelper::GetTabForWebState(webState_.get());
389 [tab_ close]; 459 [[tab webController] setNativeProvider:nil];
390 tab_.reset(); 460 webState_.reset();
461
391 prerenderedURL_ = GURL(); 462 prerenderedURL_ = GURL();
392 } 463 }
393 464
394 - (void)schedulePrerenderCancel { 465 - (void)schedulePrerenderCancel {
395 // TODO(rohitrao): Instead of cancelling the prerender, should we mark it as 466 // TODO(rohitrao): Instead of cancelling the prerender, should we mark it as
396 // failed instead? That way, subsequent prerender requests for the same URL 467 // failed instead? That way, subsequent prerender requests for the same URL
397 // will not kick off new prerenders. b/5944421 468 // will not kick off new prerenders. b/5944421
398 [self removeScheduledPrerenderRequests]; 469 [self removeScheduledPrerenderRequests];
399 [self performSelector:@selector(cancelPrerender) withObject:nil afterDelay:0]; 470 [self performSelector:@selector(cancelPrerender) withObject:nil afterDelay:0];
400 } 471 }
401 472
402 - (void)removeScheduledPrerenderRequests { 473 - (void)removeScheduledPrerenderRequests {
403 [NSObject cancelPreviousPerformRequestsWithTarget:self]; 474 [NSObject cancelPreviousPerformRequestsWithTarget:self];
404 scheduledURL_ = GURL(); 475 scheduledURL_ = GURL();
405 } 476 }
406 477
407 #pragma mark - TabDelegate 478 #pragma mark - TabDelegate
408 479
409 - (void)discardPrerender { 480 - (void)discardPrerender {
410 [self schedulePrerenderCancel]; 481 [self schedulePrerenderCancel];
411 } 482 }
412 483
413 @end 484 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/preload_controller.h ('k') | ios/chrome/browser/ui/tab_switcher/DEPS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698