Commit 7a964b4a authored by Hajime Hoshi's avatar Hajime Hoshi Committed by Chromium LUCI CQ

BackForwardCache: Reland: Add a flag parameter supported_features

This is a reland of crrev.com/c/2573850

This CL adds a new flag parameter supported_features to BackForwardCache
feature. This parameter can specify the set of the features to be
allowed with back-forward cache. This enables us to enable the feature
remotely.

Change-Id: Ib5adce784dc6f0b20d3225a6db5e50fb79167787
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2586643
Commit-Queue: Hajime Hoshi <hajimehoshi@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarFergal Daly <fergal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836993}
parent 0e528de2
......@@ -8891,4 +8891,123 @@ IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
EXPECT_FALSE(rfh_b->GetIsolationInfoForSubresources().IsEmpty());
}
class BackForwardCacheBrowserTestWithSupportedFeatures
: public BackForwardCacheBrowserTest {
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
EnableFeatureAndSetParams(features::kBackForwardCache, "supported_features",
"BroadcastChannel,KeyboardLock");
BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
}
};
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithSupportedFeatures,
CacheWithSpecifiedFeatures) {
ASSERT_TRUE(CreateHttpsServer()->Start());
GURL url_a(https_server()->GetURL("a.com", "/title1.html"));
GURL url_b(https_server()->GetURL("b.com", "/title1.html"));
// 1) Navigate to the page A with BroadcastChannel.
EXPECT_TRUE(NavigateToURL(shell(), url_a));
RenderFrameHostImpl* rfh_a = current_frame_host();
RenderFrameDeletedObserver deleted(rfh_a);
EXPECT_TRUE(ExecJs(rfh_a, "window.foo = new BroadcastChannel('foo');"));
// 2) Navigate away.
EXPECT_TRUE(NavigateToURL(shell(), url_b));
EXPECT_FALSE(deleted.deleted());
EXPECT_TRUE(rfh_a->IsInBackForwardCache());
// 3) Go back to the page A
web_contents()->GetController().GoBack();
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
EXPECT_EQ(rfh_a, current_frame_host());
ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kRestored,
FROM_HERE);
// 4) Use KeyboardLock
EXPECT_EQ("DONE", EvalJs(rfh_a, R"(
new Promise(resolve => {
navigator.keyboard.lock();
resolve('DONE');
});
)"));
// 5) Navigate away again.
EXPECT_TRUE(NavigateToURL(shell(), url_b));
EXPECT_FALSE(deleted.deleted());
EXPECT_TRUE(rfh_a->IsInBackForwardCache());
// 6) Go back to the page A again.
web_contents()->GetController().GoBack();
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
EXPECT_EQ(rfh_a, current_frame_host());
ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kRestored,
FROM_HERE);
}
class BackForwardCacheBrowserTestWithNoSupportedFeatures
: public BackForwardCacheBrowserTest {
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
// Specify empty supported features explicitly.
EnableFeatureAndSetParams(features::kBackForwardCache, "supported_features",
"");
BackForwardCacheBrowserTest::SetUpCommandLine(command_line);
}
};
IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTestWithNoSupportedFeatures,
DontCache) {
ASSERT_TRUE(CreateHttpsServer()->Start());
GURL url_a(https_server()->GetURL("a.com", "/title1.html"));
GURL url_b(https_server()->GetURL("b.com", "/title1.html"));
// 1) Navigate to the page A with BoradcastChannel.
EXPECT_TRUE(NavigateToURL(shell(), url_a));
RenderFrameHostImpl* rfh_a1 = current_frame_host();
RenderFrameDeletedObserver deleted_a1(rfh_a1);
EXPECT_TRUE(ExecJs(rfh_a1, "window.foo = new BroadcastChannel('foo');"));
// 2) Navigate away.
EXPECT_TRUE(NavigateToURL(shell(), url_b));
deleted_a1.WaitUntilDeleted();
// 3) Go back to the page A
web_contents()->GetController().GoBack();
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
ExpectNotRestored(
{BackForwardCacheMetrics::NotRestoredReason::kBlocklistedFeatures},
FROM_HERE);
ExpectBlocklistedFeature(
blink::scheduler::WebSchedulerTrackedFeature::kBroadcastChannel,
FROM_HERE);
RenderFrameHostImpl* rfh_a2 = current_frame_host();
RenderFrameDeletedObserver deleted_a2(rfh_a2);
// 4) Use KeyboardLock
EXPECT_EQ("DONE", EvalJs(rfh_a2, R"(
new Promise(resolve => {
navigator.keyboard.lock();
resolve('DONE');
});
)"));
// 5) Navigate away again.
EXPECT_TRUE(NavigateToURL(shell(), url_b));
deleted_a2.WaitUntilDeleted();
// 6) Go back to the page A again.
web_contents()->GetController().GoBack();
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
ExpectNotRestored(
{BackForwardCacheMetrics::NotRestoredReason::kBlocklistedFeatures},
FROM_HERE);
ExpectBlocklistedFeatures(
{blink::scheduler::WebSchedulerTrackedFeature::kKeyboardLock}, FROM_HERE);
}
} // namespace content
......@@ -18,7 +18,7 @@ std::string DescribeFeatures(uint64_t blocklisted_features) {
for (size_t i = 0;
i <= static_cast<size_t>(WebSchedulerTrackedFeature::kMaxValue); ++i) {
if (blocklisted_features & (1 << i)) {
features.push_back(blink::scheduler::FeatureToString(
features.push_back(blink::scheduler::FeatureToHumanReadableString(
static_cast<WebSchedulerTrackedFeature>(i)));
}
}
......
......@@ -96,6 +96,31 @@ bool IsFileSystemSupported() {
return file_system_api_supported.Get();
}
uint64_t SupportedFeaturesBitmaskImpl() {
if (!DeviceHasEnoughMemoryForBackForwardCache())
return 0;
static constexpr base::FeatureParam<std::string> supported_features(
&features::kBackForwardCache, "supported_features", "");
std::vector<std::string> tokens =
base::SplitString(supported_features.Get(), ",", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
uint64_t mask = 0;
for (const std::string& token : tokens) {
auto feature = blink::scheduler::StringToFeature(token);
DCHECK(feature.has_value()) << "invalid feature string: " << token;
if (feature.has_value()) {
mask |= blink::scheduler::FeatureToBit(feature.value());
}
}
return mask;
}
uint64_t SupportedFeaturesBitmask() {
static uint64_t mask = SupportedFeaturesBitmaskImpl();
return mask;
}
bool IgnoresOutstandingNetworkRequestForTesting() {
if (!DeviceHasEnoughMemoryForBackForwardCache())
return false;
......@@ -187,6 +212,8 @@ uint64_t GetDisallowedFeatures(RenderFrameHostImpl* rfh,
result &= blink::scheduler::StickyFeaturesBitmask();
}
result &= ~SupportedFeaturesBitmask();
return result;
}
......
......@@ -274,6 +274,7 @@ source_set("common_unittests_sources") {
"origin_trials/trial_token_validator_unittest.cc",
"page/content_to_visible_time_reporter_unittest.cc",
"page_state/page_state_serialization_unittest.cc",
"scheduler/web_scheduler_tracked_feature_unittest.cc",
"service_worker/service_worker_scope_match_unittest.cc",
"test/run_all_unittests.cc",
"tokens/multi_token_unittest.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
namespace scheduler {
TEST(WebSchedulerTrackedFeatureTest, StringToFeature) {
ASSERT_EQ(WebSchedulerTrackedFeature::kWebFileSystem,
StringToFeature("WebFileSystem"));
ASSERT_EQ(WebSchedulerTrackedFeature::kDocumentLoaded,
StringToFeature("DocumentLoaded"));
ASSERT_EQ(base::nullopt, StringToFeature("FeatureThatNeverExists"));
}
} // namespace scheduler
} // namespace blink
......@@ -6,7 +6,8 @@
#define THIRD_PARTY_BLINK_PUBLIC_COMMON_SCHEDULER_WEB_SCHEDULER_TRACKED_FEATURE_H_
#include <stdint.h>
#include <string>
#include "base/optional.h"
#include "third_party/blink/public/common/common_export.h"
namespace blink {
......@@ -106,9 +107,12 @@ static_assert(static_cast<uint32_t>(WebSchedulerTrackedFeature::kMaxValue) < 64,
"This enum is used in a bitmask, so the values should fit into a"
"64-bit integer");
BLINK_COMMON_EXPORT const char* FeatureToString(
BLINK_COMMON_EXPORT std::string FeatureToHumanReadableString(
WebSchedulerTrackedFeature feature);
BLINK_COMMON_EXPORT base::Optional<WebSchedulerTrackedFeature> StringToFeature(
const std::string& str);
// Converts a WebSchedulerTrackedFeature to a bit for use in a bitmask.
BLINK_COMMON_EXPORT constexpr uint64_t FeatureToBit(
WebSchedulerTrackedFeature feature) {
......
......@@ -668,7 +668,7 @@ void FrameSchedulerImpl::OnStartedUsingFeature(
"renderer.scheduler", "ActiveSchedulerTrackedFeature",
TRACE_ID_LOCAL(reinterpret_cast<intptr_t>(this) ^
static_cast<int>(feature)),
"feature", FeatureToString(feature));
"feature", FeatureToHumanReadableString(feature));
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment