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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java

Issue 2748013004: CustomTabs: Base version for prerender switch (Closed)
Patch Set: Small fixes Created 3 years, 9 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 package org.chromium.chrome.browser.customtabs; 5 package org.chromium.chrome.browser.customtabs;
6 6
7 import android.app.ActivityManager; 7 import android.app.ActivityManager;
8 import android.app.Application; 8 import android.app.Application;
9 import android.app.PendingIntent; 9 import android.app.PendingIntent;
10 import android.content.Context; 10 import android.content.Context;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 private static final String TAG = "ChromeConnection"; 76 private static final String TAG = "ChromeConnection";
77 private static final String LOG_SERVICE_REQUESTS = "custom-tabs-log-service- requests"; 77 private static final String LOG_SERVICE_REQUESTS = "custom-tabs-log-service- requests";
78 78
79 @VisibleForTesting 79 @VisibleForTesting
80 static final String PAGE_LOAD_METRICS_CALLBACK = "NavigationMetrics"; 80 static final String PAGE_LOAD_METRICS_CALLBACK = "NavigationMetrics";
81 81
82 // For testing only, DO NOT USE. 82 // For testing only, DO NOT USE.
83 @VisibleForTesting 83 @VisibleForTesting
84 static final String DEBUG_OVERRIDE_KEY = 84 static final String DEBUG_OVERRIDE_KEY =
85 "android.support.customtabs.maylaunchurl.DEBUG_OVERRIDE"; 85 "android.support.customtabs.maylaunchurl.DEBUG_OVERRIDE";
86 private static final int NO_OVERRIDE = 0; 86 @VisibleForTesting
87 static final int NO_OVERRIDE = 0;
87 @VisibleForTesting 88 @VisibleForTesting
88 static final int NO_PRERENDERING = 1; 89 static final int NO_PRERENDERING = 1;
89 @VisibleForTesting 90 @VisibleForTesting
90 static final int PREFETCH_ONLY = 2; 91 static final int PREFETCH_ONLY = 2;
91 92
92 private static AtomicReference<CustomTabsConnection> sInstance = new AtomicR eference<>(); 93 private static AtomicReference<CustomTabsConnection> sInstance = new AtomicR eference<>();
93 94
94 /** Holds the parameters for the current speculation. */ 95 /** Holds the parameters for the current speculation. */
95 @VisibleForTesting 96 @VisibleForTesting
96 static final class SpeculationParams { 97 static final class SpeculationParams {
97 public final CustomTabsSessionToken session; 98 public final CustomTabsSessionToken session;
98 public final String url; 99 public final String url;
100 public final int debugOverrideValue;
ahemery1 2017/03/21 15:15:57 Replaces prefetchOnly to have a record of what the
Benoit L 2017/03/21 15:56:41 I would prefer a name like "mode", or something al
99 101
100 // Only for prerender. 102 // Only for prerender.
101 public final WebContents webContents; 103 public final WebContents webContents;
102 public final String referrer; 104 public final String referrer;
103 public final Bundle extras; 105 public final Bundle extras;
104 106
105 public final boolean prefetchOnly; 107 static SpeculationParams forPrefetch(CustomTabsSessionToken session, Str ing url) {
ahemery1 2017/03/21 15:15:58 Just reordered.
Benoit L 2017/03/21 15:56:41 why? Not an issue, but why reordering code?
108 return new SpeculationParams(session, url, PREFETCH_ONLY, null, null , null);
109 }
106 110
107 static SpeculationParams forPrerender(CustomTabsSessionToken session, St ring url, 111 static SpeculationParams forPrerender(CustomTabsSessionToken session, St ring url,
108 WebContents webcontents, String referrer, Bundle extras) { 112 WebContents webcontents, String referrer, Bundle extras) {
109 return new SpeculationParams(session, url, webcontents, referrer, ex tras, false); 113 return new SpeculationParams(session, url, NO_OVERRIDE, webcontents, referrer, extras);
110 }
111
112 static SpeculationParams forPrefetch(CustomTabsSessionToken session, Str ing url) {
113 return new SpeculationParams(session, url, null, null, null, true);
114 } 114 }
115 115
116 private SpeculationParams(CustomTabsSessionToken session, String url, 116 private SpeculationParams(CustomTabsSessionToken session, String url,
117 WebContents webContents, String referrer, Bundle extras, boolean prefetchOnly) { 117 int debugOverrideValue, WebContents webContents, String referrer , Bundle extras) {
118 this.session = session; 118 this.session = session;
119 this.url = url; 119 this.url = url;
120 this.debugOverrideValue = debugOverrideValue;
120 this.webContents = webContents; 121 this.webContents = webContents;
121 this.referrer = referrer; 122 this.referrer = referrer;
122 this.extras = extras; 123 this.extras = extras;
123 this.prefetchOnly = prefetchOnly;
124 } 124 }
125 } 125 }
126 126
127 @VisibleForTesting 127 @VisibleForTesting
128 SpeculationParams mSpeculation; 128 SpeculationParams mSpeculation;
129 protected final Application mApplication; 129 protected final Application mApplication;
130 protected final ClientManager mClientManager; 130 protected final ClientManager mClientManager;
131 private final boolean mLogRequests; 131 private final boolean mLogRequests;
132 private final AtomicBoolean mWarmupHasBeenCalled = new AtomicBoolean(); 132 private final AtomicBoolean mWarmupHasBeenCalled = new AtomicBoolean();
133 private final AtomicBoolean mWarmupHasBeenFinished = new AtomicBoolean(); 133 private final AtomicBoolean mWarmupHasBeenFinished = new AtomicBoolean();
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 int debugOverrideValue = NO_OVERRIDE; 326 int debugOverrideValue = NO_OVERRIDE;
327 if (extras != null) debugOverrideValue = extras.getInt(DEBUG_OVERRIDE_KE Y, NO_OVERRIDE); 327 if (extras != null) debugOverrideValue = extras.getInt(DEBUG_OVERRIDE_KE Y, NO_OVERRIDE);
328 328
329 boolean didStartPrerender = false, didStartPrefetch = false; 329 boolean didStartPrerender = false, didStartPrefetch = false;
330 boolean mayPrerender = mayPrerender(session); 330 boolean mayPrerender = mayPrerender(session);
331 if (mayPrerender) { 331 if (mayPrerender) {
332 if (debugOverrideValue == PREFETCH_ONLY) { 332 if (debugOverrideValue == PREFETCH_ONLY) {
333 didStartPrefetch = new ResourcePrefetchPredictor(profile).startP refetching(url); 333 didStartPrefetch = new ResourcePrefetchPredictor(profile).startP refetching(url);
334 if (didStartPrefetch) mSpeculation = SpeculationParams.forPrefet ch(session, url); 334 if (didStartPrefetch) mSpeculation = SpeculationParams.forPrefet ch(session, url);
335 } else if (debugOverrideValue != NO_PRERENDERING) { 335 } else if (debugOverrideValue != NO_PRERENDERING) {
336 // Last one wins and cancels the previous prerender.
ahemery1 2017/03/21 15:15:57 This was moved from inside the prerenderUrl() func
Benoit L 2017/03/21 15:56:41 nit: Is it possible to isolate the changes between
337 cancelPrerender(null);
336 didStartPrerender = prerenderUrl(session, url, extras, uid); 338 didStartPrerender = prerenderUrl(session, url, extras, uid);
337 } 339 }
338 } 340 }
339 preconnectUrls(otherLikelyBundles); 341 preconnectUrls(otherLikelyBundles);
340 if (!didStartPrefetch) warmupManager.maybePreconnectUrlAndSubResources(p rofile, url); 342 if (!didStartPrefetch) warmupManager.maybePreconnectUrlAndSubResources(p rofile, url);
341 if (!didStartPrerender) warmupManager.createSpareWebContents(); 343 if (!didStartPrerender) warmupManager.createSpareWebContents();
342 } 344 }
343 345
344 /** 346 /**
345 * Low confidence mayLaunchUrl() call, that is: 347 * Low confidence mayLaunchUrl() call, that is:
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 * @param url The URL the WebContents is for. 582 * @param url The URL the WebContents is for.
581 * @param referrer The referrer to use for |url|. 583 * @param referrer The referrer to use for |url|.
582 * @return The prerendered WebContents, or null. 584 * @return The prerendered WebContents, or null.
583 */ 585 */
584 WebContents takePrerenderedUrl(CustomTabsSessionToken session, String url, S tring referrer) { 586 WebContents takePrerenderedUrl(CustomTabsSessionToken session, String url, S tring referrer) {
585 ThreadUtils.assertOnUiThread(); 587 ThreadUtils.assertOnUiThread();
586 if (mSpeculation == null || session == null || !session.equals(mSpeculat ion.session)) { 588 if (mSpeculation == null || session == null || !session.equals(mSpeculat ion.session)) {
587 return null; 589 return null;
588 } 590 }
589 591
590 if (mSpeculation.prefetchOnly) { 592 if (mSpeculation.debugOverrideValue == PREFETCH_ONLY) {
591 Profile profile = Profile.getLastUsedProfile(); 593 Profile profile = Profile.getLastUsedProfile();
592 new ResourcePrefetchPredictor(profile).stopPrefetching(mSpeculation. url); 594 new ResourcePrefetchPredictor(profile).stopPrefetching(mSpeculation. url);
593 mSpeculation = null; 595 mSpeculation = null;
594 return null; 596 return null;
595 } 597 }
596 598
597 WebContents webContents = mSpeculation.webContents; 599 WebContents webContents = mSpeculation.webContents;
598 String prerenderedUrl = mSpeculation.url; 600 String prerenderedUrl = mSpeculation.url;
599 String prerenderReferrer = mSpeculation.referrer; 601 String prerenderReferrer = mSpeculation.referrer;
600 if (referrer == null) referrer = ""; 602 if (referrer == null) referrer = "";
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 // tabs. Then PrivacyManager should be used to make the below check. 896 // tabs. Then PrivacyManager should be used to make the below check.
895 if (!PrefServiceBridge.getInstance().getNetworkPredictionEnabled()) retu rn false; 897 if (!PrefServiceBridge.getInstance().getNetworkPredictionEnabled()) retu rn false;
896 if (DataReductionProxySettings.getInstance().isDataReductionProxyEnabled ()) return false; 898 if (DataReductionProxySettings.getInstance().isDataReductionProxyEnabled ()) return false;
897 ConnectivityManager cm = 899 ConnectivityManager cm =
898 (ConnectivityManager) mApplication.getApplicationContext().getSy stemService( 900 (ConnectivityManager) mApplication.getApplicationContext().getSy stemService(
899 Context.CONNECTIVITY_SERVICE); 901 Context.CONNECTIVITY_SERVICE);
900 return !cm.isActiveNetworkMetered() || shouldPrerenderOnCellularForSessi on(session); 902 return !cm.isActiveNetworkMetered() || shouldPrerenderOnCellularForSessi on(session);
901 } 903 }
902 904
903 /** Cancels a prerender for a given session, or any session if null. */ 905 /** Cancels a prerender for a given session, or any session if null. */
906 @VisibleForTesting
904 void cancelPrerender(CustomTabsSessionToken session) { 907 void cancelPrerender(CustomTabsSessionToken session) {
908 if (mSpeculation == null) return;
909 if (session != null && !session.equals(mSpeculation.session)) return;
910 switch (mSpeculation.debugOverrideValue) {
911 case NO_OVERRIDE:
912 cancelNoOverridePrerender(session);
913 break;
914 default:
915 return;
916 }
917 }
918
919 private void cancelNoOverridePrerender(CustomTabsSessionToken session) {
905 ThreadUtils.assertOnUiThread(); 920 ThreadUtils.assertOnUiThread();
906 if (mSpeculation != null && (session == null || session.equals(mSpeculat ion.session)) 921 if (mSpeculation.webContents == null) return;
907 && mSpeculation.webContents != null) { 922 mExternalPrerenderHandler.cancelCurrentPrerender();
908 mExternalPrerenderHandler.cancelCurrentPrerender(); 923 mSpeculation.webContents.destroy();
909 mSpeculation.webContents.destroy(); 924 mSpeculation = null;
910 mSpeculation = null;
911 }
912 } 925 }
913 926
914 /** 927 /**
915 * Tries to request a prerender for a given URL. 928 * Tries to request a prerender for a given URL.
916 * 929 *
917 * @param session Session the request comes from. 930 * @param session Session the request comes from.
918 * @param url URL to prerender. 931 * @param url URL to prerender.
919 * @param extras extra parameters. 932 * @param extras extra parameters.
920 * @param uid UID of the caller. 933 * @param uid UID of the caller.
921 * @return true if a prerender has been initiated. 934 * @return true if a prerender has been initiated.
922 */ 935 */
923 private boolean prerenderUrl( 936 private boolean prerenderUrl(
924 CustomTabsSessionToken session, String url, Bundle extras, int uid) { 937 CustomTabsSessionToken session, String url, Bundle extras, int uid) {
925 ThreadUtils.assertOnUiThread(); 938 ThreadUtils.assertOnUiThread();
926 // Ignores mayPrerender() for an empty URL, since it cancels an existing prerender.
927 if (!mayPrerender(session) && !TextUtils.isEmpty(url)) return false;
ahemery1 2017/03/21 15:15:57 Unnecessary duplicate.
928 if (!mWarmupHasBeenCalled.get()) return false; 939 if (!mWarmupHasBeenCalled.get()) return false;
929 // Last one wins and cancels the previous prerender. 940
930 cancelPrerender(null);
931 if (TextUtils.isEmpty(url)) return false;
ahemery1 2017/03/21 15:15:57 Extracted because behavior is more general than ju
932 boolean throttle = !shouldPrerenderOnCellularForSession(session); 941 boolean throttle = !shouldPrerenderOnCellularForSession(session);
933 if (throttle && !mClientManager.isPrerenderingAllowed(uid)) return false ; 942 if (throttle && !mClientManager.isPrerenderingAllowed(uid)) return false ;
934 943
935 // A prerender will be requested. Time to destroy the spare WebContents. 944 // A prerender will be requested. Time to destroy the spare WebContents.
936 WarmupManager.getInstance().destroySpareWebContents(); 945 WarmupManager.getInstance().destroySpareWebContents();
937 946
938 Intent extrasIntent = new Intent(); 947 Intent extrasIntent = new Intent();
939 if (extras != null) extrasIntent.putExtras(extras); 948 if (extras != null) extrasIntent.putExtras(extras);
940 if (IntentHandler.getExtraHeadersFromIntent(extrasIntent) != null) retur n false; 949 if (IntentHandler.getExtraHeadersFromIntent(extrasIntent) != null) retur n false;
941 if (mExternalPrerenderHandler == null) { 950 if (mExternalPrerenderHandler == null) {
942 mExternalPrerenderHandler = new ExternalPrerenderHandler(); 951 mExternalPrerenderHandler = new ExternalPrerenderHandler();
943 } 952 }
944 Rect contentBounds = ExternalPrerenderHandler.estimateContentSize(mAppli cation, true); 953 Rect contentBounds = ExternalPrerenderHandler.estimateContentSize(mAppli cation, true);
945 String referrer = IntentHandler.getReferrerUrlIncludingExtraHeaders(extr asIntent); 954 String referrer = IntentHandler.getReferrerUrlIncludingExtraHeaders(extr asIntent);
946 if (referrer == null && getReferrerForSession(session) != null) { 955 if (referrer == null && getReferrerForSession(session) != null) {
947 referrer = getReferrerForSession(session).getUrl(); 956 referrer = getReferrerForSession(session).getUrl();
948 } 957 }
949 if (referrer == null) referrer = ""; 958 if (referrer == null) referrer = "";
950 Pair<WebContents, WebContents> webContentsPair = mExternalPrerenderHandl er.addPrerender( 959 Pair<WebContents, WebContents> webContentsPair =
951 Profile.getLastUsedProfile(), url, referrer, 960 mExternalPrerenderHandler.addPrerender(Profile.getLastUsedProfil e(), url, referrer,
952 contentBounds, 961 contentBounds, shouldPrerenderOnCellularForSession(sessi on));
953 shouldPrerenderOnCellularForSession(session));
954 if (webContentsPair == null) return false; 962 if (webContentsPair == null) return false;
955 WebContents dummyWebContents = webContentsPair.first; 963 WebContents dummyWebContents = webContentsPair.first;
956 if (webContentsPair.second != null) { 964 if (webContentsPair.second != null) {
957 mClientManager.resetPostMessageHandlerForSession(session, webContent sPair.second); 965 mClientManager.resetPostMessageHandlerForSession(session, webContent sPair.second);
958 } 966 }
959 if (throttle) mClientManager.registerPrerenderRequest(uid, url); 967 if (throttle) mClientManager.registerPrerenderRequest(uid, url);
960 mSpeculation = SpeculationParams.forPrerender( 968 mSpeculation =
961 session, url, dummyWebContents, referrer, extras); 969 SpeculationParams.forPrerender(session, url, dummyWebContents, r eferrer, extras);
962 970
963 RecordHistogram.recordBooleanHistogram("CustomTabs.PrerenderSessionUsesD efaultParameters", 971 RecordHistogram.recordBooleanHistogram("CustomTabs.PrerenderSessionUsesD efaultParameters",
964 mClientManager.usesDefaultSessionParameters(session)); 972 mClientManager.usesDefaultSessionParameters(session));
965 973
966 return true; 974 return true;
967 } 975 }
968 976
969 @VisibleForTesting 977 @VisibleForTesting
970 void resetThrottling(Context context, int uid) { 978 void resetThrottling(Context context, int uid) {
971 mClientManager.resetThrottling(uid); 979 mClientManager.resetThrottling(uid);
972 } 980 }
973 981
974 @VisibleForTesting 982 @VisibleForTesting
975 void ban(Context context, int uid) { 983 void ban(Context context, int uid) {
976 mClientManager.ban(uid); 984 mClientManager.ban(uid);
977 } 985 }
978 986
979 @VisibleForTesting 987 @VisibleForTesting
980 void setForcePrerender(boolean force) { 988 void setForcePrerender(boolean force) {
981 mForcePrerenderForTesting = force; 989 mForcePrerenderForTesting = force;
982 } 990 }
983 } 991 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698