summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYusuf Ozuysal <yusufo@google.com>2016-03-23 11:56:23 -0700
committerYusuf Ozuysal <yusufo@google.com>2016-03-23 18:58:51 +0000
commitbd6059010bec5db11cf9afd89121bf215d8d6096 (patch)
tree17b764de74049a815cfee510cbc0e1ea46ab257e
parent69265543161dfde54f47f9bfc8597d5d8235d9c1 (diff)
downloadchromium_src-bd6059010bec5db11cf9afd89121bf215d8d6096.zip
chromium_src-bd6059010bec5db11cf9afd89121bf215d8d6096.tar.gz
chromium_src-bd6059010bec5db11cf9afd89121bf215d8d6096.tar.bz2
Update prerender policy for custom tabs
- Explicitly early return if the prerender privacy setting is set to off - If the setting is on then prerendering on mobile is off by default - Add calls and session params to override the above default if needed BUG=592635 Review URL: https://codereview.chromium.org/1830653003 . Cr-Commit-Position: refs/branch-heads/2661@{#365} Cr-Branched-From: ef6f6ae5e4c96622286b563658d5cd62a6cf1197-refs/heads/master@{#378081}
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java2
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java19
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java18
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java15
-rw-r--r--chrome/android/javatests/src/org/chromium/chrome/browser/prerender/ExternalPrerenderRequestTest.java10
-rw-r--r--chrome/browser/prerender/external_prerender_handler_android.cc28
-rw-r--r--chrome/browser/prerender/external_prerender_handler_android.h3
-rw-r--r--chrome/browser/prerender/prerender_histograms.cc4
-rw-r--r--chrome/browser/prerender/prerender_manager.cc39
-rw-r--r--chrome/browser/prerender/prerender_manager.h13
-rw-r--r--chrome/browser/prerender/prerender_origin.cc1
-rw-r--r--chrome/browser/prerender/prerender_origin.h1
-rw-r--r--chrome/browser/prerender/prerender_unittest.cc66
-rw-r--r--chrome/test/android/javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java3
-rw-r--r--tools/metrics/histograms/histograms.xml2
15 files changed, 194 insertions, 30 deletions
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java
index 7747d58..bb235d8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java
@@ -131,7 +131,7 @@ public final class WarmupManager {
}
mPrerenderedWebContents = mExternalPrerenderHandler.addPrerender(
- Profile.getLastUsedProfile(), url, referrer, widthPix, heightPix);
+ Profile.getLastUsedProfile(), url, referrer, widthPix, heightPix, false);
if (mPrerenderedWebContents != null) mPrerendered = true;
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java
index 5624ca4..4cadc39 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java
@@ -54,6 +54,7 @@ class ClientManager {
public final IBinder.DeathRecipient deathRecipient;
public boolean mIgnoreFragments;
private boolean mShouldHideDomain;
+ private boolean mShouldPrerenderOnCellular;
private ServiceConnection mKeepAliveConnection;
private String mPredictedUrl;
private long mLastMayLaunchUrlTimestamp;
@@ -270,7 +271,23 @@ class ClientManager {
/** Sets whether the fragment should be ignored for prerender matching. */
public synchronized void setIgnoreFragmentsForSession(IBinder session, boolean value) {
SessionParams params = mSessionParams.get(session);
- params.mIgnoreFragments = value;
+ if (params != null) params.mIgnoreFragments = value;
+ }
+
+ /**
+ * @return Whether prerender should be turned on for cellular networks for given session.
+ */
+ public synchronized boolean shouldPrerenderOnCellularForSession(IBinder session) {
+ SessionParams params = mSessionParams.get(session);
+ return params != null ? params.mShouldPrerenderOnCellular : false;
+ }
+
+ /**
+ * Sets whether prerender should be turned on for mobile networks for given session.
+ */
+ public synchronized void setPrerenderCellularForSession(IBinder session, boolean prerender) {
+ SessionParams params = mSessionParams.get(session);
+ if (params != null) params.mShouldPrerenderOnCellular = prerender;
}
/** Tries to bind to a client to keep it alive, and returns true for success. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
index 5181588..8ed88b9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -44,6 +44,7 @@ import org.chromium.chrome.browser.WarmupManager;
import org.chromium.chrome.browser.WebContentsFactory;
import org.chromium.chrome.browser.device.DeviceClassManager;
import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
+import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager;
import org.chromium.chrome.browser.prerender.ExternalPrerenderHandler;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.util.IntentUtils;
@@ -284,7 +285,7 @@ public class CustomTabsConnection extends ICustomTabsService.Stub {
WarmupManager.getInstance().maybePreconnectUrlAndSubResources(
Profile.getLastUsedProfile(), url);
boolean didStartPrerender = false;
- if (!noPrerendering && mayPrerender()) {
+ if (!noPrerendering && mayPrerender(session)) {
didStartPrerender = prerenderUrl(session, url, extras, uid);
}
preconnectUrls(otherLikelyBundles);
@@ -510,6 +511,11 @@ public class CustomTabsConnection extends ICustomTabsService.Stub {
return mClientManager.shouldHideDomainForSession(session);
}
+ /** @see ClientManager#shouldPrerenderOnCellularForSession(IBinder) */
+ public boolean shouldPrerenderOnCellularForSession(IBinder session) {
+ return mClientManager.shouldPrerenderOnCellularForSession(session);
+ }
+
/** See {@link ClientManager#getClientPackageNameForSession(IBinder)} */
public String getClientPackageNameForSession(IBinder session) {
return mClientManager.getClientPackageNameForSession(session);
@@ -654,13 +660,14 @@ public class CustomTabsConnection extends ICustomTabsService.Stub {
mClientManager.cleanupAll();
}
- private boolean mayPrerender() {
+ private boolean mayPrerender(IBinder session) {
if (FieldTrialList.findFullName("CustomTabs").equals("DisablePrerender")) return false;
if (!DeviceClassManager.enablePrerendering()) return false;
+ if (!PrivacyPreferencesManager.getInstance(mApplication).shouldPrerender()) return false;
ConnectivityManager cm =
(ConnectivityManager) mApplication.getApplicationContext().getSystemService(
Context.CONNECTIVITY_SERVICE);
- return !cm.isActiveNetworkMetered();
+ return !cm.isActiveNetworkMetered() || shouldPrerenderOnCellularForSession(session);
}
/** Cancels a prerender for a given session, or any session if null. */
@@ -689,7 +696,7 @@ public class CustomTabsConnection extends ICustomTabsService.Stub {
// limitation, or remove ChromePrerenderService.
WarmupManager.getInstance().disallowPrerendering();
// Ignores mayPrerender() for an empty URL, since it cancels an existing prerender.
- if (!mayPrerender() && !TextUtils.isEmpty(url)) return false;
+ if (!mayPrerender(session) && !TextUtils.isEmpty(url)) return false;
if (!mWarmupHasBeenCalled.get()) return false;
// Last one wins and cancels the previous prerender.
cancelPrerender(null);
@@ -713,7 +720,8 @@ public class CustomTabsConnection extends ICustomTabsService.Stub {
}
if (referrer == null) referrer = "";
WebContents webContents = mExternalPrerenderHandler.addPrerender(
- Profile.getLastUsedProfile(), url, referrer, contentSize.x, contentSize.y);
+ Profile.getLastUsedProfile(), url, referrer, contentSize.x, contentSize.y,
+ shouldPrerenderOnCellularForSession(session));
if (webContents == null) return false;
mClientManager.registerPrerenderRequest(uid, url);
mPrerender = new PrerenderedUrlParams(session, webContents, url, referrer, extras);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java
index 0066586..fa94115 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/prerender/ExternalPrerenderHandler.java
@@ -33,13 +33,15 @@ public class ExternalPrerenderHandler {
* @param referrer The referrer for the prerender request.
* @param width The width for the content view (render widget host view) for the prerender.
* @param height The height for the content view (render widget host view) for the prerender.
+ * @param prerenderOnCellular Whether the prerender should happen if the device has a cellular
+ * connection.
* @return The {@link WebContents} that is linked to this prerender. {@code null} if
* unsuccessful.
*/
public WebContents addPrerender(Profile profile, String url, String referrer, int width,
- int height) {
+ int height, boolean prerenderOnCellular) {
WebContents webContents = WebContentsFactory.createWebContents(false, false);
- if (addPrerender(profile, webContents, url, referrer, width, height)) {
+ if (addPrerender(profile, webContents, url, referrer, width, height, prerenderOnCellular)) {
return webContents;
}
if (webContents != null) webContents.destroy();
@@ -56,12 +58,14 @@ public class ExternalPrerenderHandler {
* @param referrer The referrer for the prerender request.
* @param width The width for the content view (render widget host view) for the prerender.
* @param height The height for the content view (render widget host view) for the prerender.
+ * @param prerenderOnCellular Whether the prerender should happen if the device has a cellular
+ * connection.
* @return Whether the prerender was successful.
*/
public boolean addPrerender(Profile profile, WebContents webContents, String url,
- String referrer, int width, int height) {
+ String referrer, int width, int height, boolean prerenderOnCellular) {
return nativeAddPrerender(mNativeExternalPrerenderHandler, profile, webContents,
- url, referrer, width, height);
+ url, referrer, width, height, prerenderOnCellular);
}
/**
@@ -101,7 +105,8 @@ public class ExternalPrerenderHandler {
private static native long nativeInit();
private static native boolean nativeAddPrerender(
long nativeExternalPrerenderHandlerAndroid, Profile profile,
- WebContents webContents, String url, String referrer, int width, int height);
+ WebContents webContents, String url, String referrer,
+ int width, int height, boolean prerenderOnCellular);
private static native boolean nativeHasPrerenderedUrl(
Profile profile, String url, WebContents webContents);
private static native boolean nativeHasPrerenderedAndFinishedLoadingUrl(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/prerender/ExternalPrerenderRequestTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/prerender/ExternalPrerenderRequestTest.java
index de527e9..1c3da15 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/prerender/ExternalPrerenderRequestTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/prerender/ExternalPrerenderRequestTest.java
@@ -79,7 +79,7 @@ public class ExternalPrerenderRequestTest extends ChromeActivityTestCaseBase<Chr
* Test adding a prerender and canceling that to add a new one.
*/
public void testAddPrerenderAndCancel() throws InterruptedException {
- WebContents webContents = mHandler.addPrerender(mProfile, mGoogleUrl, "", 0, 0);
+ WebContents webContents = mHandler.addPrerender(mProfile, mGoogleUrl, "", 0, 0, false);
assertTrue(ExternalPrerenderHandler.hasPrerenderedUrl(
mProfile, mGoogleUrl, webContents));
@@ -88,7 +88,7 @@ public class ExternalPrerenderRequestTest extends ChromeActivityTestCaseBase<Chr
mProfile, mGoogleUrl, webContents));
webContents.destroy();
Thread.sleep(PRERENDER_DELAY_MS);
- webContents = mHandler.addPrerender(mProfile, mYoutubeUrl, "", 0, 0);
+ webContents = mHandler.addPrerender(mProfile, mYoutubeUrl, "", 0, 0, false);
assertTrue(ExternalPrerenderHandler.hasPrerenderedUrl(
mProfile, mYoutubeUrl, webContents));
}
@@ -102,7 +102,7 @@ public class ExternalPrerenderRequestTest extends ChromeActivityTestCaseBase<Chr
*/
public void testCancelPrerender() {
mHandler.cancelCurrentPrerender();
- WebContents webContents = mHandler.addPrerender(mProfile, mGoogleUrl, "", 0, 0);
+ WebContents webContents = mHandler.addPrerender(mProfile, mGoogleUrl, "", 0, 0, false);
assertTrue(ExternalPrerenderHandler.hasPrerenderedUrl(
mProfile, mGoogleUrl, webContents));
}
@@ -115,11 +115,11 @@ public class ExternalPrerenderRequestTest extends ChromeActivityTestCaseBase<Chr
* Test adding two prerenders without canceling the first one.
*/
public void testAddingPrerendersInaRow() throws InterruptedException {
- WebContents webContents = mHandler.addPrerender(mProfile, mGoogleUrl, "", 0, 0);
+ WebContents webContents = mHandler.addPrerender(mProfile, mGoogleUrl, "", 0, 0, false);
assertTrue(ExternalPrerenderHandler.hasPrerenderedUrl(
mProfile, mGoogleUrl, webContents));
Thread.sleep(PRERENDER_DELAY_MS);
- WebContents newWebContents = mHandler.addPrerender(mProfile, mYoutubeUrl, "", 0, 0);
+ WebContents newWebContents = mHandler.addPrerender(mProfile, mYoutubeUrl, "", 0, 0, false);
assertTrue(ExternalPrerenderHandler.hasPrerenderedUrl(
mProfile, mYoutubeUrl, newWebContents));
}
diff --git a/chrome/browser/prerender/external_prerender_handler_android.cc b/chrome/browser/prerender/external_prerender_handler_android.cc
index 2981f73..22925ef 100644
--- a/chrome/browser/prerender/external_prerender_handler_android.cc
+++ b/chrome/browser/prerender/external_prerender_handler_android.cc
@@ -15,8 +15,8 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_android.h"
#include "content/public/browser/web_contents.h"
-
#include "jni/ExternalPrerenderHandler_jni.h"
+#include "net/base/network_change_notifier.h"
using base::android::ConvertJavaStringToUTF16;
@@ -57,7 +57,8 @@ bool ExternalPrerenderHandlerAndroid::AddPrerender(
const JavaParamRef<jstring>& jurl,
const JavaParamRef<jstring>& jreferrer,
jint width,
- jint height) {
+ jint height,
+ jboolean prerender_on_cellular) {
Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile);
GURL url = GURL(ConvertJavaStringToUTF16(env, jurl));
@@ -77,12 +78,23 @@ bool ExternalPrerenderHandlerAndroid::AddPrerender(
if (prerender_handle_.get()) {
prerender_handle_->OnNavigateAway();
}
- prerender_handle_.reset(
- prerender_manager->AddPrerenderFromExternalRequest(
- url,
- referrer,
- web_contents->GetController().GetDefaultSessionStorageNamespace(),
- gfx::Size(width, height)));
+ if (prerender_on_cellular && net::NetworkChangeNotifier::IsConnectionCellular(
+ net::NetworkChangeNotifier::GetConnectionType())) {
+ prerender_handle_.reset(
+ prerender_manager->AddPrerenderOnCellularFromExternalRequest(
+ url,
+ referrer,
+ web_contents->GetController().GetDefaultSessionStorageNamespace(),
+ gfx::Size(width, height)));
+ } else {
+ prerender_handle_.reset(
+ prerender_manager->AddPrerenderFromExternalRequest(
+ url,
+ referrer,
+ web_contents->GetController().GetDefaultSessionStorageNamespace(),
+ gfx::Size(width, height)));
+ }
+
if (!prerender_handle_)
return false;
return true;
diff --git a/chrome/browser/prerender/external_prerender_handler_android.h b/chrome/browser/prerender/external_prerender_handler_android.h
index 6aae904..3b1ef82 100644
--- a/chrome/browser/prerender/external_prerender_handler_android.h
+++ b/chrome/browser/prerender/external_prerender_handler_android.h
@@ -35,7 +35,8 @@ class ExternalPrerenderHandlerAndroid {
const base::android::JavaParamRef<jstring>& url,
const base::android::JavaParamRef<jstring>& referrer,
jint width,
- jint height);
+ jint height,
+ jboolean prerender_on_cellular);
// Cancel the prerender associated with the prerender_handle_
void CancelCurrentPrerender(
diff --git a/chrome/browser/prerender/prerender_histograms.cc b/chrome/browser/prerender/prerender_histograms.cc
index b7401d0..6e46198 100644
--- a/chrome/browser/prerender/prerender_histograms.cc
+++ b/chrome/browser/prerender/prerender_histograms.cc
@@ -54,6 +54,8 @@ std::string GetHistogramName(Origin origin, bool is_wash,
return ComposeHistogramName("webnext", name);
case ORIGIN_GWS_PRERENDER:
return ComposeHistogramName("gws", name);
+ case ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR:
+ return ComposeHistogramName("externalrequestforced", name);
default:
NOTREACHED();
break;
@@ -105,6 +107,8 @@ do { \
HISTOGRAM; \
} else if (origin == ORIGIN_LINK_REL_NEXT) { \
HISTOGRAM; \
+ } else if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR) { \
+ HISTOGRAM; \
} else { \
HISTOGRAM; \
} \
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index 4bb07b2..1e3e536 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -298,7 +298,19 @@ PrerenderHandle* PrerenderManager::AddPrerenderFromExternalRequest(
const content::Referrer& referrer,
SessionStorageNamespace* session_storage_namespace,
const gfx::Size& size) {
- return AddPrerender(ORIGIN_EXTERNAL_REQUEST, url, referrer, size,
+ return AddPrerender(
+ ORIGIN_EXTERNAL_REQUEST, url, referrer, size, session_storage_namespace);
+}
+
+PrerenderHandle* PrerenderManager::AddPrerenderOnCellularFromExternalRequest(
+ const GURL& url,
+ const content::Referrer& referrer,
+ SessionStorageNamespace* session_storage_namespace,
+ const gfx::Size& size) {
+ return AddPrerender(ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR,
+ url,
+ referrer,
+ size,
session_storage_namespace);
}
@@ -575,8 +587,10 @@ void PrerenderManager::RecordPerceivedPageLoadTime(
double fraction_plt_elapsed_at_swap_in,
const GURL& url) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (GetPredictionStatus() != NetworkPredictionStatus::ENABLED)
+ if (GetPredictionStatusForOrigin(origin)
+ != NetworkPredictionStatus::ENABLED) {
return;
+ }
histograms_->RecordPerceivedPageLoadTime(
origin, perceived_page_load_time, navigation_type, url);
@@ -789,6 +803,12 @@ base::DictionaryValue* PrerenderManager::GetAsValue() const {
dict_value->Set("active", GetActivePrerendersAsValue());
dict_value->SetBoolean("enabled",
GetPredictionStatus() == NetworkPredictionStatus::ENABLED);
+ std::string disabled_note;
+ if (GetPredictionStatus() == NetworkPredictionStatus::DISABLED_ALWAYS)
+ disabled_note = "Disabled by user setting";
+ if (GetPredictionStatus() == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK)
+ disabled_note = "Disabled on cellular connection by default";
+ dict_value->SetString("disabled_note", disabled_note);
dict_value->SetBoolean("omnibox_enabled", IsOmniboxEnabled(profile_));
// If prerender is disabled via a flag this method is not even called.
std::string enabled_note;
@@ -934,7 +954,8 @@ PrerenderHandle* PrerenderManager::AddPrerender(
// histogram tracking.
histograms_->RecordPrerender(origin, url_arg);
- NetworkPredictionStatus prerendering_status = GetPredictionStatus();
+ NetworkPredictionStatus prerendering_status =
+ GetPredictionStatusForOrigin(origin);
if (prerendering_status != NetworkPredictionStatus::ENABLED) {
FinalStatus final_status =
prerendering_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK
@@ -1285,6 +1306,18 @@ NetworkPredictionStatus PrerenderManager::GetPredictionStatus() const {
return CanPrefetchAndPrerenderUI(profile_->GetPrefs());
}
+NetworkPredictionStatus PrerenderManager::GetPredictionStatusForOrigin(
+ Origin origin) const {
+ DCHECK(CalledOnValidThread());
+ NetworkPredictionStatus prediction_status =
+ CanPrefetchAndPrerenderUI(profile_->GetPrefs());
+ if (prediction_status == NetworkPredictionStatus::DISABLED_DUE_TO_NETWORK
+ && origin == ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR) {
+ prediction_status = NetworkPredictionStatus::ENABLED;
+ }
+ return prediction_status;
+}
+
void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64_t bytes) {
DCHECK_GE(bytes, 0);
if (GetPredictionStatus() == NetworkPredictionStatus::ENABLED &&
diff --git a/chrome/browser/prerender/prerender_manager.h b/chrome/browser/prerender/prerender_manager.h
index fdf874e..c33c540 100644
--- a/chrome/browser/prerender/prerender_manager.h
+++ b/chrome/browser/prerender/prerender_manager.h
@@ -134,6 +134,14 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
content::SessionStorageNamespace* session_storage_namespace,
const gfx::Size& size);
+ // Adds a prerender from an external request that will prerender even on
+ // cellular networks as long as the user setting for prerendering is ON.
+ PrerenderHandle* AddPrerenderOnCellularFromExternalRequest(
+ const GURL& url,
+ const content::Referrer& referrer,
+ content::SessionStorageNamespace* session_storage_namespace,
+ const gfx::Size& size);
+
// Adds a prerender for Instant Search |url| if valid. The
// |session_storage_namespace| matches the namespace of the active tab at the
// time the prerender is generated. Returns a caller-owned PrerenderHandle* or
@@ -395,6 +403,11 @@ class PrerenderManager : public base::SupportsWeakPtr<PrerenderManager>,
// disabled.
chrome_browser_net::NetworkPredictionStatus GetPredictionStatus() const;
+ // Returns whether prerendering is currently enabled or the reason why it is
+ // disabled after taking into account the origin of the request.
+ chrome_browser_net::NetworkPredictionStatus GetPredictionStatusForOrigin(
+ Origin origin) const;
+
// Adds a prerender for |url| from |referrer|. The |origin| specifies how the
// prerender was added. If |size| is empty, then
// PrerenderContents::StartPrerendering will instead use a default from
diff --git a/chrome/browser/prerender/prerender_origin.cc b/chrome/browser/prerender/prerender_origin.cc
index c5470ce..3c9b7b6 100644
--- a/chrome/browser/prerender/prerender_origin.cc
+++ b/chrome/browser/prerender/prerender_origin.cc
@@ -26,6 +26,7 @@ const char* kOriginNames[] = {
"External Request",
"Instant",
"Link Rel Next",
+ "External Request Forced Cellular",
"Max",
};
static_assert(arraysize(kOriginNames) == ORIGIN_MAX + 1,
diff --git a/chrome/browser/prerender/prerender_origin.h b/chrome/browser/prerender/prerender_origin.h
index e13ecf4..60e3e0b 100644
--- a/chrome/browser/prerender/prerender_origin.h
+++ b/chrome/browser/prerender/prerender_origin.h
@@ -23,6 +23,7 @@ enum Origin {
ORIGIN_EXTERNAL_REQUEST = 10,
ORIGIN_INSTANT = 11,
ORIGIN_LINK_REL_NEXT = 12,
+ ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR = 13,
ORIGIN_MAX,
};
diff --git a/chrome/browser/prerender/prerender_unittest.cc b/chrome/browser/prerender/prerender_unittest.cc
index c28014b..74ebdcf 100644
--- a/chrome/browser/prerender/prerender_unittest.cc
+++ b/chrome/browser/prerender/prerender_unittest.cc
@@ -31,6 +31,7 @@
#include "components/prefs/pref_service.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/test/test_browser_thread.h"
+#include "net/base/network_change_notifier.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
@@ -266,6 +267,13 @@ class RestorePrerenderMode {
PrerenderManager::PrerenderManagerMode prev_mode_;
};
+class MockNetworkChangeNotifier4G : public net::NetworkChangeNotifier {
+ public:
+ ConnectionType GetCurrentConnectionType() const override {
+ return NetworkChangeNotifier::CONNECTION_4G;
+ }
+};
+
DummyPrerenderContents::DummyPrerenderContents(
UnitTestPrerenderManager* test_prerender_manager,
const GURL& url,
@@ -379,6 +387,12 @@ class PrerenderTest : public testing::Test {
chrome_browser_net::NETWORK_PREDICTION_NEVER);
}
+ void EnablePrerender() {
+ profile_.GetPrefs()->SetInteger(
+ prefs::kNetworkPredictionOptions,
+ chrome_browser_net::NETWORK_PREDICTION_ALWAYS);
+ }
+
private:
// Needed to pass PrerenderManager's DCHECKs.
base::MessageLoop message_loop_;
@@ -1046,6 +1060,58 @@ TEST_F(PrerenderTest, LinkRelNotAllowedWhenDisabled) {
GURL("http://www.example.com")));
}
+TEST_F(PrerenderTest, PrerenderNotAllowedOnCellular) {
+ EnablePrerender();
+ scoped_ptr<net::NetworkChangeNotifier> mock(
+ new MockNetworkChangeNotifier4G);
+ EXPECT_TRUE(net::NetworkChangeNotifier::IsConnectionCellular(
+ net::NetworkChangeNotifier::GetConnectionType()));
+ EXPECT_FALSE(AddSimplePrerender(GURL("http://www.example.com")));
+}
+
+TEST_F(PrerenderTest, PrerenderNotAllowedOnCellularWithExternalOrigin) {
+ EnablePrerender();
+ scoped_ptr<net::NetworkChangeNotifier> mock(
+ new MockNetworkChangeNotifier4G);
+ EXPECT_TRUE(net::NetworkChangeNotifier::IsConnectionCellular(
+ net::NetworkChangeNotifier::GetConnectionType()));
+ GURL url("http://www.google.com/");
+ DummyPrerenderContents* prerender_contents =
+ prerender_manager()->CreateNextPrerenderContents(
+ url,
+ ORIGIN_EXTERNAL_REQUEST,
+ FINAL_STATUS_MANAGER_SHUTDOWN);
+ scoped_ptr<PrerenderHandle> prerender_handle(
+ prerender_manager()->AddPrerenderFromExternalRequest(
+ url, content::Referrer(), nullptr, kSize));
+ EXPECT_FALSE(prerender_handle);
+ EXPECT_FALSE(prerender_contents->prerendering_has_started());
+}
+
+TEST_F(PrerenderTest,PrerenderAllowedOnCellularWithForcedOrigin) {
+ EnablePrerender();
+ scoped_ptr<net::NetworkChangeNotifier> mock(
+ new MockNetworkChangeNotifier4G);
+ EXPECT_TRUE(net::NetworkChangeNotifier::IsConnectionCellular(
+ net::NetworkChangeNotifier::GetConnectionType()));
+ GURL url("http://www.google.com/");
+ DummyPrerenderContents* prerender_contents =
+ prerender_manager()->CreateNextPrerenderContents(
+ url,
+ ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR,
+ FINAL_STATUS_USED);
+ scoped_ptr<PrerenderHandle> prerender_handle(
+ prerender_manager()->AddPrerenderOnCellularFromExternalRequest(
+ url, content::Referrer(), nullptr, kSize));
+ EXPECT_TRUE(prerender_handle);
+ EXPECT_TRUE(prerender_handle->IsPrerendering());
+ EXPECT_TRUE(prerender_contents->prerendering_has_started());
+ EXPECT_EQ(prerender_contents, prerender_handle->contents());
+ EXPECT_EQ(ORIGIN_EXTERNAL_REQUEST_FORCED_CELLULAR,
+ prerender_handle->contents()->origin());
+ ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+}
+
TEST_F(PrerenderTest, LinkManagerCancel) {
EXPECT_TRUE(IsEmptyPrerenderLinkManager());
GURL url("http://www.myexample.com");
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java
index 2a7a8ecc..0c67fd1 100644
--- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java
+++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/PrerenderTestHelper.java
@@ -97,7 +97,8 @@ public class PrerenderTestHelper {
currentTab.getContentViewCore().getRenderCoordinates()
.getContentWidthPixInt(),
currentTab.getContentViewCore().getRenderCoordinates()
- .getContentHeightPixInt());
+ .getContentHeightPixInt(),
+ false);
Assert.assertTrue("Failed to prerender test url: " + testUrl, didPrerender);
return prerenderHandler;
}
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 37aad5a..deb3b16 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -87739,6 +87739,8 @@ To add a new entry, add it with any value and run test to compute valid value.
</suffix>
<suffix name="gws" label="GWS triggered prerender."/>
<suffix name="externalrequest" label="Externally triggered prerender."/>
+ <suffix name="externalrequestforced"
+ label="Forced prerender regardless of network."/>
<suffix name="Instant" label="Instant search prerender."/>
<suffix name="localpredictor" label="Local predictor triggered prerender.">
<obsolete>