Skip to content

Commit

Permalink
Prerender: Disable prerendering when datasaver is on
Browse files Browse the repository at this point in the history
This CL stops prerendering if the Data Saver is enabled on Android
devices.

Bug: 1350825
Change-Id: I844dac1369acde7775c1b426f296ce36d09202c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3820184
Reviewed-by: Andrey Kosyakov <caseq@chromium.org>
Commit-Queue: Yoshiki Tanioka <tanioka@google.com>
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Reviewed-by: Lingqi Chi <lingqi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1034948}
  • Loading branch information
Yoshiki Tanioka authored and Chromium LUCI CQ committed Aug 15, 2022
1 parent 114bec7 commit 0a29bc7
Show file tree
Hide file tree
Showing 10 changed files with 33 additions and 16 deletions.
2 changes: 2 additions & 0 deletions content/browser/devtools/protocol/page_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,8 @@ Page::PrerenderFinalStatus PrerenderFinalStatusToProtocol(
return Page::PrerenderFinalStatusEnum::CrossOriginNavigation;
case PrerenderHost::FinalStatus::kCrossOriginRedirect:
return Page::PrerenderFinalStatusEnum::CrossOriginRedirect;
case PrerenderHost::FinalStatus::kDataSaverEnabled:
return Page::PrerenderFinalStatusEnum::DataSaverEnabled;
case PrerenderHost::FinalStatus::kDestroyed:
return Page::PrerenderFinalStatusEnum::Destroyed;
case PrerenderHost::FinalStatus::kDidFailLoad:
Expand Down
22 changes: 9 additions & 13 deletions content/browser/preloading/prerender/prerender_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4571,28 +4571,24 @@ class ScopedDataSaverTestContentBrowserClient
raw_ptr<ContentBrowserClient> old_client;
};

// Tests that the data saver doesn't prevent image load in a prerendered page.
// Tests that prerender doesn't run when Data Saver mode is enabled.
IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, DataSaver) {
const GURL kInitialUrl = GetUrl("/empty.html");
const GURL kPrerenderingUrl = GetUrl("/prerender/image.html");
const GURL kImageUrl = GetUrl("/blank.jpg");
const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");

// Enable data saver.
ScopedDataSaverTestContentBrowserClient scoped_content_browser_client;
shell()->web_contents()->OnWebPreferencesChanged();

// Navigate to an initial page.
test::PrerenderHostRegistryObserver observer(*web_contents_impl());
ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
ASSERT_EQ(shell()->web_contents()->GetLastCommittedURL(), kInitialUrl);

// Start prerendering `kPrerenderingUrl`.
ASSERT_EQ(GetRequestCount(kPrerenderingUrl), 0);
AddPrerender(kPrerenderingUrl);
EXPECT_EQ(GetRequestCount(kPrerenderingUrl), 1);
AddPrerenderAsync(kPrerenderingUrl);
observer.WaitForTrigger(kPrerenderingUrl);

// A request for the image in the prerendered page shouldn't be prevented by
// the data saver.
EXPECT_EQ(GetRequestCount(kImageUrl), 1);
// Prerendering should fail.
ExpectFinalStatusForSpeculationRule(
PrerenderHost::FinalStatus::kDataSaverEnabled);
EXPECT_FALSE(HasHostForUrl(kPrerenderingUrl));
}

// Tests that loading=lazy doesn't prevent image load in a prerendered page.
Expand Down
1 change: 1 addition & 0 deletions content/browser/preloading/prerender/prerender_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ void PrerenderHost::SetFailureReason(FinalStatus status) {
case FinalStatus::kEmbedderTriggeredAndCrossOriginRedirected:
case FinalStatus::kMemoryLimitExceeded:
case FinalStatus::kFailToGetMemoryUsage:
case FinalStatus::kDataSaverEnabled:
attempt_->SetFailureReason(ToPreloadingFailureReason(status));
return;
}
Expand Down
3 changes: 2 additions & 1 deletion content/browser/preloading/prerender/prerender_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ class CONTENT_EXPORT PrerenderHost : public WebContentsObserver {
kEmbedderTriggeredAndDestroyed = 35,
kMemoryLimitExceeded = 36,
kFailToGetMemoryUsage = 37,
kMaxValue = kFailToGetMemoryUsage,
kDataSaverEnabled = 38,
kMaxValue = kDataSaverEnabled,
};

PrerenderHost(const PrerenderAttributes& attributes,
Expand Down
12 changes: 12 additions & 0 deletions content/browser/preloading/prerender/prerender_host_registry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_client.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
#include "third_party/blink/public/common/features.h"

Expand Down Expand Up @@ -124,6 +125,17 @@ int PrerenderHostRegistry::CreateAndStartHost(
return RenderFrameHost::kNoFrameTreeNodeId;
}

// Don't prerender when the Data Saver setting is enabled.
if (GetContentClient()->browser()->IsDataSaverEnabled(
web_contents.GetBrowserContext())) {
RecordPrerenderHostFinalStatus(
PrerenderHost::FinalStatus::kDataSaverEnabled, attributes,
ukm::kInvalidSourceId);
if (attempt)
attempt->SetEligibility(PreloadingEligibility::kDataSaverEnabled);
return RenderFrameHost::kNoFrameTreeNodeId;
}

// TODO(crbug.com/1176054): Support cross-origin prerendering.
// The initiator origin is nullopt when prerendering is initiated by the
// browser (not by a renderer using Speculation Rules API). In that case,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ const char* FinalStatusToString(PrerenderHost::FinalStatus final_status) {
return "MemoryLimitExceeded";
case PrerenderHost::FinalStatus::kFailToGetMemoryUsage:
return "FailToGetMemoryUsage";
case PrerenderHost::FinalStatus::kDataSaverEnabled:
return "DataSaverEnabled";
}
NOTREACHED();
return "";
Expand Down
3 changes: 3 additions & 0 deletions content/public/browser/preloading.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ enum class PreloadingEligibility {
// Preloading was ineligible as running JavaScript was disabled for the URL.
kJavascriptDisabled = 6,

// Preloading was ineligible because the Data Saver setting was enabled.
kDataSaverEnabled = 7,

// TODO(crbug.com/1309934): Add more specific ineligibility reasons subject to
// each preloading operation
// This constant is used to define the value from which embedders can add more
Expand Down
2 changes: 0 additions & 2 deletions content/test/data/prerender/image.html

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8464,6 +8464,7 @@ domain Page
# Prerenders can be cancelled when Chrome uses excessive memory. This is
# recorded when it fails to get the memory usage.
FailToGetMemoryUsage
DataSaverEnabled

# Fired when a prerender attempt is completed.
experimental event prerenderAttemptCompleted
Expand Down
1 change: 1 addition & 0 deletions tools/metrics/histograms/enums.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78940,6 +78940,7 @@ Called by update_net_trust_anchors.py.-->
<int value="35" label="kEmbedderTriggeredAndDestroyed"/>
<int value="36" label="kMemoryLimitExceeded"/>
<int value="37" label="kFailToGetMemoryUsage"/>
<int value="38" label="kDataSaverEnabled"/>
</enum>

<enum name="PrerenderHoverEvent">
Expand Down

0 comments on commit 0a29bc7

Please sign in to comment.