| Index: ios/chrome/browser/ui/preload_controller.mm
|
| diff --git a/ios/chrome/browser/ui/preload_controller.mm b/ios/chrome/browser/ui/preload_controller.mm
|
| index 173117cc4091f0bb23beeaac3ae7984f88bd883a..f5e30e6fd749ca24c0803c4e869b12f9d9bfbf41 100644
|
| --- a/ios/chrome/browser/ui/preload_controller.mm
|
| +++ b/ios/chrome/browser/ui/preload_controller.mm
|
| @@ -8,13 +8,17 @@
|
|
|
| #include "base/ios/device_util.h"
|
| #include "base/logging.h"
|
| +#include "base/mac/scoped_nsobject.h"
|
| #include "base/metrics/field_trial.h"
|
| #include "base/metrics/histogram_macros.h"
|
| #include "base/strings/sys_string_conversions.h"
|
| #include "components/prefs/pref_service.h"
|
| #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
|
| #include "ios/chrome/browser/pref_names.h"
|
| +#import "ios/chrome/browser/tabs/legacy_tab_helper.h"
|
| #import "ios/chrome/browser/tabs/tab.h"
|
| +#import "ios/chrome/browser/tabs/tab_helper_util.h"
|
| +#import "ios/chrome/browser/tabs/tab_private.h"
|
| #include "ios/chrome/browser/ui/preload_controller_delegate.h"
|
| #include "ios/chrome/browser/ui/prerender_final_status.h"
|
| #import "ios/web/public/web_state/ui/crw_native_content.h"
|
| @@ -101,7 +105,60 @@ class PrefetchDelegate : public net::URLFetcherDelegate {
|
| PreloadController* owner_; // weak
|
| };
|
|
|
| -@implementation PreloadController
|
| +@implementation PreloadController {
|
| + ios::ChromeBrowserState* browserState_; // Weak.
|
| +
|
| + // The WebState used for prerendering.
|
| + std::unique_ptr<web::WebState> webState_;
|
| +
|
| + // The URL that is prerendered in |webState_|. This can be different from
|
| + // the value returned by WebState last committed navigation item, for example
|
| + // in cases where there was a redirect.
|
| + //
|
| + // When choosing whether or not to use a prerendered Tab,
|
| + // BrowserViewController compares the URL being loaded by the omnibox with the
|
| + // URL of the prerendered Tab. Comparing against the Tab's currently URL
|
| + // could return false negatives in cases of redirect, hence the need to store
|
| + // the originally prerendered URL.
|
| + GURL prerenderedURL_;
|
| +
|
| + // The URL that is scheduled to be prerendered, its associated transition and
|
| + // referrer. |scheduledTransition_| and |scheduledReferrer_| are not valid
|
| + // when |scheduledURL_| is empty.
|
| + GURL scheduledURL_;
|
| + ui::PageTransition scheduledTransition_;
|
| + web::Referrer scheduledReferrer_;
|
| +
|
| + // The most-recently prefetched URL, or nil if there have been no prefetched
|
| + // URLs.
|
| + GURL prefetchedURL_;
|
| +
|
| + // The URLFetcher and associated delegate used to prefetch URLs. The delegate
|
| + // simply forwards callbacks from URLFetcher back to the PrerenderController.
|
| + std::unique_ptr<PrefetchDelegate> prefetcherDelegate_;
|
| + std::unique_ptr<net::URLFetcher> prefetcher_;
|
| +
|
| + // Bridge to listen to pref changes.
|
| + std::unique_ptr<PrefObserverBridge> observerBridge_;
|
| + // Registrar for pref changes notifications.
|
| + PrefChangeRegistrar prefChangeRegistrar_;
|
| + // Observer for the WWAN setting. Contains a valid object only if the
|
| + // instant setting is set to wifi-only.
|
| + std::unique_ptr<ConnectionTypeObserverBridge> connectionTypeObserverBridge_;
|
| +
|
| + // Whether or not the preference is enabled.
|
| + BOOL enabled_;
|
| + // Whether or not prerendering is only when on wifi.
|
| + BOOL wifiOnly_;
|
| + // Whether or not the current connection is using WWAN.
|
| + BOOL usingWWAN_;
|
| +
|
| + // Number of successful prerenders (i.e. the user viewed the prerendered page)
|
| + // during the lifetime of this controller.
|
| + int successfulPrerendersPerSessionCount_;
|
| +
|
| + id<PreloadControllerDelegate> delegate_; // weak
|
| +}
|
|
|
| @synthesize prerenderedURL = prerenderedURL_;
|
| @synthesize prefetchedURL = prefetchedURL_;
|
| @@ -215,16 +272,21 @@ class PrefetchDelegate : public net::URLFetcherDelegate {
|
| [self destroyPreviewContentsForReason:reason];
|
| }
|
|
|
| -- (Tab*)releasePrerenderContents {
|
| +- (std::unique_ptr<web::WebState>)releasePrerenderContents {
|
| successfulPrerendersPerSessionCount_++;
|
| UMA_HISTOGRAM_ENUMERATION(kPrerenderFinalStatusHistogramName,
|
| PRERENDER_FINAL_STATUS_USED,
|
| PRERENDER_FINAL_STATUS_MAX);
|
| [self removeScheduledPrerenderRequests];
|
| prerenderedURL_ = GURL();
|
| - [[tab_ webController] setNativeProvider:nil];
|
| - [tab_ setDelegate:nil];
|
| - return [tab_.release() autorelease];
|
| +
|
| + if (webState_) {
|
| + Tab* tab = LegacyTabHelper::GetTabForWebState(webState_.get());
|
| + [[tab webController] setNativeProvider:nil];
|
| + [tab setDelegate:nil];
|
| + }
|
| +
|
| + return std::move(webState_);
|
| }
|
|
|
| - (void)connectionTypeChanged:(net::NetworkChangeNotifier::ConnectionType)type {
|
| @@ -272,7 +334,10 @@ class PrefetchDelegate : public net::URLFetcherDelegate {
|
|
|
| // Delegate the call to the original native provider.
|
| - (BOOL)hasControllerForURL:(const GURL&)url {
|
| - return [[tab_ webController].nativeProvider hasControllerForURL:url];
|
| + if (!webState_)
|
| + return NO;
|
| + Tab* tab = LegacyTabHelper::GetTabForWebState(webState_.get());
|
| + return [[tab webController].nativeProvider hasControllerForURL:url];
|
| }
|
|
|
| // Override the CRWNativeContentProvider methods to cancel any prerenders that
|
| @@ -323,24 +388,29 @@ class PrefetchDelegate : public net::URLFetcherDelegate {
|
| return;
|
| }
|
|
|
| - Tab* tab =
|
| - [Tab preloadingTabWithBrowserState:browserState_
|
| - url:prerenderedURL_
|
| - referrer:scheduledReferrer_
|
| - transition:scheduledTransition_
|
| - provider:self
|
| - opener:nil
|
| - desktopUserAgent:[delegate_ shouldUseDesktopUserAgent]
|
| - configuration:^(Tab* tab) {
|
| - [tab setIsPrerenderTab:YES];
|
| - [tab setDelegate:self];
|
| - }];
|
| -
|
| - // Create and set up the prerender.
|
| - tab_.reset([tab retain]);
|
| + web::WebState::CreateParams createParams(browserState_);
|
| + webState_ = web::WebState::Create(createParams);
|
| + AttachTabHelpers(webState_.get());
|
| +
|
| + Tab* tab = LegacyTabHelper::GetTabForWebState(webState_.get());
|
| + DCHECK(tab);
|
| +
|
| + [[tab webController] setNativeProvider:self];
|
| + [[tab webController] setWebUsageEnabled:YES];
|
| + [tab setIsPrerenderTab:YES];
|
| + [tab setDelegate:self];
|
| +
|
| + web::NavigationManager::WebLoadParams loadParams(prerenderedURL_);
|
| + loadParams.referrer = scheduledReferrer_;
|
| + loadParams.transition_type = scheduledTransition_;
|
| + if ([delegate_ shouldUseDesktopUserAgent]) {
|
| + loadParams.user_agent_override_option =
|
| + web::NavigationManager::UserAgentOverrideOption::DESKTOP;
|
| + }
|
| + [[tab webController] loadWithParams:loadParams];
|
|
|
| // Trigger the page to start loading.
|
| - [tab_ view];
|
| + [tab view];
|
| }
|
|
|
| - (const GURL)urlToPrefetchURL:(const GURL&)url {
|
| @@ -379,15 +449,16 @@ class PrefetchDelegate : public net::URLFetcherDelegate {
|
| }
|
|
|
| - (void)destroyPreviewContentsForReason:(PrerenderFinalStatus)reason {
|
| - if (!tab_.get())
|
| + if (!webState_)
|
| return;
|
|
|
| UMA_HISTOGRAM_ENUMERATION(kPrerenderFinalStatusHistogramName, reason,
|
| PRERENDER_FINAL_STATUS_MAX);
|
| - [[tab_ webController] setNativeProvider:nil];
|
| - [tab_ setDelegate:nil];
|
| - [tab_ close];
|
| - tab_.reset();
|
| +
|
| + Tab* tab = LegacyTabHelper::GetTabForWebState(webState_.get());
|
| + [[tab webController] setNativeProvider:nil];
|
| + webState_.reset();
|
| +
|
| prerenderedURL_ = GURL();
|
| }
|
|
|
|
|