OLD | NEW |
---|---|
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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 private static final int NO_OVERRIDE = 0; |
87 @VisibleForTesting | 87 @VisibleForTesting |
88 static final int NO_PRERENDERING = 1; | 88 static final int NO_PRERENDERING = 1; |
89 @VisibleForTesting | 89 @VisibleForTesting |
90 static final int PREFETCH_ONLY = 2; | 90 static final int PREFETCH_ONLY = 2; |
91 | 91 |
92 @VisibleForTesting | |
93 static final String PRERENDER_MODE_KEY = "android.support.customtabs.PREREND ER_MODE"; | |
94 @VisibleForTesting | |
95 static final int DEFAULT_PRERENDER = 0; | |
ahemery
2017/03/16 17:28:35
Not sure of the name
| |
96 | |
92 private static AtomicReference<CustomTabsConnection> sInstance = new AtomicR eference<>(); | 97 private static AtomicReference<CustomTabsConnection> sInstance = new AtomicR eference<>(); |
93 | 98 |
94 /** Holds the parameters for the current speculation. */ | 99 /** Holds the parameters for the current speculation. */ |
95 @VisibleForTesting | 100 @VisibleForTesting |
96 static final class SpeculationParams { | 101 static final class SpeculationParams { |
97 public final CustomTabsSessionToken session; | 102 public final CustomTabsSessionToken session; |
98 public final String url; | 103 public final String url; |
99 | 104 |
100 // Only for prerender. | 105 // Only for prerender. |
101 public final WebContents webContents; | 106 public final WebContents webContents; |
(...skipping 17 matching lines...) Expand all Loading... | |
119 this.url = url; | 124 this.url = url; |
120 this.webContents = webContents; | 125 this.webContents = webContents; |
121 this.referrer = referrer; | 126 this.referrer = referrer; |
122 this.extras = extras; | 127 this.extras = extras; |
123 this.prefetchOnly = prefetchOnly; | 128 this.prefetchOnly = prefetchOnly; |
124 } | 129 } |
125 } | 130 } |
126 | 131 |
127 @VisibleForTesting | 132 @VisibleForTesting |
128 SpeculationParams mSpeculation; | 133 SpeculationParams mSpeculation; |
134 @VisibleForTesting | |
135 int mPrerenderMode; | |
129 protected final Application mApplication; | 136 protected final Application mApplication; |
130 protected final ClientManager mClientManager; | 137 protected final ClientManager mClientManager; |
131 private final boolean mLogRequests; | 138 private final boolean mLogRequests; |
132 private final AtomicBoolean mWarmupHasBeenCalled = new AtomicBoolean(); | 139 private final AtomicBoolean mWarmupHasBeenCalled = new AtomicBoolean(); |
133 private final AtomicBoolean mWarmupHasBeenFinished = new AtomicBoolean(); | 140 private final AtomicBoolean mWarmupHasBeenFinished = new AtomicBoolean(); |
134 private ExternalPrerenderHandler mExternalPrerenderHandler; | 141 private ExternalPrerenderHandler mExternalPrerenderHandler; |
135 private boolean mForcePrerenderForTesting; | 142 private boolean mForcePrerenderForTesting; |
136 | 143 |
137 // Conversion between native TimeTicks and SystemClock.uptimeMillis(). | 144 // Conversion between native TimeTicks and SystemClock.uptimeMillis(). |
138 private long mNativeTickOffsetUs; | 145 private long mNativeTickOffsetUs; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
326 int debugOverrideValue = NO_OVERRIDE; | 333 int debugOverrideValue = NO_OVERRIDE; |
327 if (extras != null) debugOverrideValue = extras.getInt(DEBUG_OVERRIDE_KE Y, NO_OVERRIDE); | 334 if (extras != null) debugOverrideValue = extras.getInt(DEBUG_OVERRIDE_KE Y, NO_OVERRIDE); |
328 | 335 |
329 boolean didStartPrerender = false, didStartPrefetch = false; | 336 boolean didStartPrerender = false, didStartPrefetch = false; |
330 boolean mayPrerender = mayPrerender(session); | 337 boolean mayPrerender = mayPrerender(session); |
331 if (mayPrerender) { | 338 if (mayPrerender) { |
332 if (debugOverrideValue == PREFETCH_ONLY) { | 339 if (debugOverrideValue == PREFETCH_ONLY) { |
333 didStartPrefetch = new ResourcePrefetchPredictor(profile).startP refetching(url); | 340 didStartPrefetch = new ResourcePrefetchPredictor(profile).startP refetching(url); |
334 if (didStartPrefetch) mSpeculation = SpeculationParams.forPrefet ch(session, url); | 341 if (didStartPrefetch) mSpeculation = SpeculationParams.forPrefet ch(session, url); |
335 } else if (debugOverrideValue != NO_PRERENDERING) { | 342 } else if (debugOverrideValue != NO_PRERENDERING) { |
336 didStartPrerender = prerenderUrl(session, url, extras, uid); | 343 didStartPrerender = startPrerender(session, url, extras, uid); |
337 } | 344 } |
338 } | 345 } |
339 preconnectUrls(otherLikelyBundles); | 346 preconnectUrls(otherLikelyBundles); |
340 if (!didStartPrefetch) warmupManager.maybePreconnectUrlAndSubResources(p rofile, url); | 347 if (!didStartPrefetch) warmupManager.maybePreconnectUrlAndSubResources(p rofile, url); |
341 if (!didStartPrerender) warmupManager.createSpareWebContents(); | 348 if (!didStartPrerender) warmupManager.createSpareWebContents(); |
342 } | 349 } |
343 | 350 |
344 /** | 351 /** |
345 * Low confidence mayLaunchUrl() call, that is: | 352 * Low confidence mayLaunchUrl() call, that is: |
346 * - Preconnects to the ordered list of URLs. | 353 * - Preconnects to the ordered list of URLs. |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
893 // connection type as well, we should either change that or add another check for custom | 900 // connection type as well, we should either change that or add another check for custom |
894 // tabs. Then PrivacyManager should be used to make the below check. | 901 // tabs. Then PrivacyManager should be used to make the below check. |
895 if (!PrefServiceBridge.getInstance().getNetworkPredictionEnabled()) retu rn false; | 902 if (!PrefServiceBridge.getInstance().getNetworkPredictionEnabled()) retu rn false; |
896 if (DataReductionProxySettings.getInstance().isDataReductionProxyEnabled ()) return false; | 903 if (DataReductionProxySettings.getInstance().isDataReductionProxyEnabled ()) return false; |
897 ConnectivityManager cm = | 904 ConnectivityManager cm = |
898 (ConnectivityManager) mApplication.getApplicationContext().getSy stemService( | 905 (ConnectivityManager) mApplication.getApplicationContext().getSy stemService( |
899 Context.CONNECTIVITY_SERVICE); | 906 Context.CONNECTIVITY_SERVICE); |
900 return !cm.isActiveNetworkMetered() || shouldPrerenderOnCellularForSessi on(session); | 907 return !cm.isActiveNetworkMetered() || shouldPrerenderOnCellularForSessi on(session); |
901 } | 908 } |
902 | 909 |
910 @VisibleForTesting | |
911 void cancelPrerender(CustomTabsSessionToken session) { | |
ahemery
2017/03/16 17:28:35
Generic function to cancel the prerendering of a U
| |
912 switch (mPrerenderMode) { | |
913 case DEFAULT_PRERENDER: | |
914 cancelWebContentsPrerender(session); | |
915 break; | |
916 default: | |
917 return; | |
918 } | |
919 } | |
920 | |
903 /** Cancels a prerender for a given session, or any session if null. */ | 921 /** Cancels a prerender for a given session, or any session if null. */ |
904 void cancelPrerender(CustomTabsSessionToken session) { | 922 private void cancelWebContentsPrerender(CustomTabsSessionToken session) { |
ahemery
2017/03/16 17:28:35
Version targeting what we know typically as "prere
| |
905 ThreadUtils.assertOnUiThread(); | 923 ThreadUtils.assertOnUiThread(); |
906 if (mSpeculation != null && (session == null || session.equals(mSpeculat ion.session)) | 924 if (mSpeculation != null && (session == null || session.equals(mSpeculat ion.session)) |
907 && mSpeculation.webContents != null) { | 925 && mSpeculation.webContents != null) { |
908 mExternalPrerenderHandler.cancelCurrentPrerender(); | 926 mExternalPrerenderHandler.cancelCurrentPrerender(); |
909 mSpeculation.webContents.destroy(); | 927 mSpeculation.webContents.destroy(); |
910 mSpeculation = null; | 928 mSpeculation = null; |
911 } | 929 } |
912 } | 930 } |
913 | 931 |
932 private boolean startPrerender( | |
ahemery
2017/03/16 17:28:35
Generic function to start prerendering a URL
| |
933 CustomTabsSessionToken session, String url, Bundle extras, int uid) { | |
934 // Last one wins and cancels the previous prerender. | |
935 cancelPrerender(null); | |
936 switch (mPrerenderMode) { | |
937 case DEFAULT_PRERENDER: | |
938 return prerenderUrl(session, url, extras, uid); | |
939 default: | |
940 return false; | |
941 } | |
942 } | |
943 | |
914 /** | 944 /** |
915 * Tries to request a prerender for a given URL. | 945 * Tries to request a prerender for a given URL. |
916 * | 946 * |
917 * @param session Session the request comes from. | 947 * @param session Session the request comes from. |
918 * @param url URL to prerender. | 948 * @param url URL to prerender. |
919 * @param extras extra parameters. | 949 * @param extras extra parameters. |
920 * @param uid UID of the caller. | 950 * @param uid UID of the caller. |
921 * @return true if a prerender has been initiated. | 951 * @return true if a prerender has been initiated. |
922 */ | 952 */ |
923 private boolean prerenderUrl( | 953 private boolean prerenderUrl( |
924 CustomTabsSessionToken session, String url, Bundle extras, int uid) { | 954 CustomTabsSessionToken session, String url, Bundle extras, int uid) { |
925 ThreadUtils.assertOnUiThread(); | 955 ThreadUtils.assertOnUiThread(); |
926 // Ignores mayPrerender() for an empty URL, since it cancels an existing prerender. | |
ahemery
2017/03/16 17:28:35
This is already done in maylaunchUrl and it makes
| |
927 if (!mayPrerender(session) && !TextUtils.isEmpty(url)) return false; | |
928 if (!mWarmupHasBeenCalled.get()) return false; | 956 if (!mWarmupHasBeenCalled.get()) return false; |
929 // Last one wins and cancels the previous prerender. | 957 |
930 cancelPrerender(null); | |
931 if (TextUtils.isEmpty(url)) return false; | |
932 boolean throttle = !shouldPrerenderOnCellularForSession(session); | 958 boolean throttle = !shouldPrerenderOnCellularForSession(session); |
933 if (throttle && !mClientManager.isPrerenderingAllowed(uid)) return false ; | 959 if (throttle && !mClientManager.isPrerenderingAllowed(uid)) return false ; |
934 | 960 |
935 // A prerender will be requested. Time to destroy the spare WebContents. | 961 // A prerender will be requested. Time to destroy the spare WebContents. |
936 WarmupManager.getInstance().destroySpareWebContents(); | 962 WarmupManager.getInstance().destroySpareWebContents(); |
937 | 963 |
938 Intent extrasIntent = new Intent(); | 964 Intent extrasIntent = new Intent(); |
939 if (extras != null) extrasIntent.putExtras(extras); | 965 if (extras != null) extrasIntent.putExtras(extras); |
940 if (IntentHandler.getExtraHeadersFromIntent(extrasIntent) != null) retur n false; | 966 if (IntentHandler.getExtraHeadersFromIntent(extrasIntent) != null) retur n false; |
941 if (mExternalPrerenderHandler == null) { | 967 if (mExternalPrerenderHandler == null) { |
942 mExternalPrerenderHandler = new ExternalPrerenderHandler(); | 968 mExternalPrerenderHandler = new ExternalPrerenderHandler(); |
943 } | 969 } |
944 Rect contentBounds = ExternalPrerenderHandler.estimateContentSize(mAppli cation, true); | 970 Rect contentBounds = ExternalPrerenderHandler.estimateContentSize(mAppli cation, true); |
945 String referrer = IntentHandler.getReferrerUrlIncludingExtraHeaders(extr asIntent); | 971 String referrer = IntentHandler.getReferrerUrlIncludingExtraHeaders(extr asIntent); |
946 if (referrer == null && getReferrerForSession(session) != null) { | 972 if (referrer == null && getReferrerForSession(session) != null) { |
947 referrer = getReferrerForSession(session).getUrl(); | 973 referrer = getReferrerForSession(session).getUrl(); |
948 } | 974 } |
949 if (referrer == null) referrer = ""; | 975 if (referrer == null) referrer = ""; |
950 Pair<WebContents, WebContents> webContentsPair = mExternalPrerenderHandl er.addPrerender( | 976 Pair<WebContents, WebContents> webContentsPair = |
ahemery
2017/03/16 17:28:35
Auto formatting
| |
951 Profile.getLastUsedProfile(), url, referrer, | 977 mExternalPrerenderHandler.addPrerender(Profile.getLastUsedProfil e(), url, referrer, |
952 contentBounds, | 978 contentBounds, shouldPrerenderOnCellularForSession(sessi on)); |
953 shouldPrerenderOnCellularForSession(session)); | |
954 if (webContentsPair == null) return false; | 979 if (webContentsPair == null) return false; |
955 WebContents dummyWebContents = webContentsPair.first; | 980 WebContents dummyWebContents = webContentsPair.first; |
956 if (webContentsPair.second != null) { | 981 if (webContentsPair.second != null) { |
957 mClientManager.resetPostMessageHandlerForSession(session, webContent sPair.second); | 982 mClientManager.resetPostMessageHandlerForSession(session, webContent sPair.second); |
958 } | 983 } |
959 if (throttle) mClientManager.registerPrerenderRequest(uid, url); | 984 if (throttle) mClientManager.registerPrerenderRequest(uid, url); |
960 mSpeculation = SpeculationParams.forPrerender( | 985 mSpeculation = |
ahemery
2017/03/16 17:28:35
Auto formatting
| |
961 session, url, dummyWebContents, referrer, extras); | 986 SpeculationParams.forPrerender(session, url, dummyWebContents, r eferrer, extras); |
962 | 987 |
963 RecordHistogram.recordBooleanHistogram("CustomTabs.PrerenderSessionUsesD efaultParameters", | 988 RecordHistogram.recordBooleanHistogram("CustomTabs.PrerenderSessionUsesD efaultParameters", |
964 mClientManager.usesDefaultSessionParameters(session)); | 989 mClientManager.usesDefaultSessionParameters(session)); |
965 | 990 |
966 return true; | 991 return true; |
967 } | 992 } |
968 | 993 |
969 @VisibleForTesting | 994 @VisibleForTesting |
970 void resetThrottling(Context context, int uid) { | 995 void resetThrottling(Context context, int uid) { |
971 mClientManager.resetThrottling(uid); | 996 mClientManager.resetThrottling(uid); |
972 } | 997 } |
973 | 998 |
974 @VisibleForTesting | 999 @VisibleForTesting |
975 void ban(Context context, int uid) { | 1000 void ban(Context context, int uid) { |
976 mClientManager.ban(uid); | 1001 mClientManager.ban(uid); |
977 } | 1002 } |
978 | 1003 |
979 @VisibleForTesting | 1004 @VisibleForTesting |
980 void setForcePrerender(boolean force) { | 1005 void setForcePrerender(boolean force) { |
981 mForcePrerenderForTesting = force; | 1006 mForcePrerenderForTesting = force; |
982 } | 1007 } |
1008 | |
1009 @VisibleForTesting | |
1010 void setPrerenderMode(int mode) { | |
ahemery
2017/03/16 17:28:35
The new switch that enables toggling between usual
| |
1011 if (mPrerenderMode != mode) { | |
1012 // Remove all existing speculations when switching mode | |
1013 cancelPrerender(null); | |
1014 mPrerenderMode = mode; | |
1015 } | |
1016 } | |
983 } | 1017 } |
OLD | NEW |