Commit 9fd73cca authored by Rakina Zata Amni's avatar Rakina Zata Amni Committed by Commit Bot

bfcache: Check for blocklisted features in CanStoreRenderFrameHostLater

This CL make us check for blocklisted features in
CanStoreRenderFrameHostLater, which is called when determining whether
we should do a proactive BrowsingInstance swap or not.

We don't currently have support for knowing that a blocklisted API is no
longer used after pagehide. This means if a blocklisted feature before
navigation, it will always be ineligible for bfcache. We should not try
to do a BrowsingInstance swap, etc. in this case.

In the future, as we add support for blocklisted APIs to be deemed
as no longer used after it was torn down in pagehide, we can move the
check for the newly supported APIs one by one to
CanStoreRenderFrameHostNow.

More context: https://groups.google.com/a/google.com/g/chrome-bfcache/c/L-ZreZDY4n0/m/8cBbBGB5CQAJ

Bug: 1129331
Change-Id: Ic1756d8c8460036dc97603b38b4251fb7894f9fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2442397
Commit-Queue: Rakina Zata Amni <rakina@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarYuzu Saijo <yuzus@chromium.org>
Cr-Commit-Position: refs/heads/master@{#813505}
parent 0a8fae01
......@@ -110,7 +110,10 @@ bool ShouldIgnoreBlocklists() {
return should_ignore_blocklists.Get();
}
uint64_t GetDisallowedFeatures(RenderFrameHostImpl* rfh) {
enum RequestedFeatures { kAll, kOnlySticky };
uint64_t GetDisallowedFeatures(RenderFrameHostImpl* rfh,
RequestedFeatures requested_features) {
// TODO(https://crbug.com/1015784): Finalize disallowed feature list, and test
// for each disallowed feature.
constexpr uint64_t kAlwaysDisallowedFeatures =
......@@ -170,6 +173,11 @@ uint64_t GetDisallowedFeatures(RenderFrameHostImpl* rfh) {
FeatureToBit(WebSchedulerTrackedFeature::kOutstandingNetworkRequestXHR);
}
if (requested_features == RequestedFeatures::kOnlySticky) {
// Remove all non-sticky features from |result|.
result &= blink::scheduler::StickyFeaturesBitmask();
}
return result;
}
......@@ -435,6 +443,18 @@ void BackForwardCacheImpl::CanStoreRenderFrameHostLater(
if (rfh->IsOuterDelegateFrame())
result->No(BackForwardCacheMetrics::NotRestoredReason::kHaveInnerContents);
// When it's not the final decision for putting a page in the back-forward
// cache, we should only consider "sticky" features here - features that
// will always result in a page becoming ineligible for back-forward cache
// since the first time it's used.
if (uint64_t banned_features =
GetDisallowedFeatures(rfh, RequestedFeatures::kOnlySticky) &
rfh->scheduler_tracked_features()) {
if (!ShouldIgnoreBlocklists()) {
result->NoDueToFeatures(banned_features);
}
}
for (size_t i = 0; i < rfh->child_count(); i++)
CanStoreRenderFrameHostLater(result,
rfh->child_at(i)->current_frame_host());
......@@ -448,11 +468,14 @@ void BackForwardCacheImpl::CheckDynamicStatesOnSubtree(
if (!rfh->IsDOMContentLoaded())
result->No(BackForwardCacheMetrics::NotRestoredReason::kLoading);
// TODO(altimin): At the moment only the first detected failure is reported.
// For reporting purposes it's a good idea to also collect this information
// from children.
// Check for banned features currently being used. Note that unlike the check
// in CanStoreRenderFrameHostLater, we are checking all banned features here
// (not only the "sticky" features), because this time we're making a final
// decision on whether we should store a page in the back-forward cache or
// not.
if (uint64_t banned_features =
GetDisallowedFeatures(rfh) & rfh->scheduler_tracked_features()) {
GetDisallowedFeatures(rfh, RequestedFeatures::kAll) &
rfh->scheduler_tracked_features()) {
if (!ShouldIgnoreBlocklists()) {
result->NoDueToFeatures(banned_features);
}
......
......@@ -114,5 +114,53 @@ const char* FeatureToString(WebSchedulerTrackedFeature feature) {
}
}
bool IsFeatureSticky(WebSchedulerTrackedFeature feature) {
return (FeatureToBit(feature) & StickyFeaturesBitmask()) > 0;
}
uint64_t StickyFeaturesBitmask() {
return FeatureToBit(
WebSchedulerTrackedFeature::kMainResourceHasCacheControlNoStore) |
FeatureToBit(
WebSchedulerTrackedFeature::kMainResourceHasCacheControlNoCache) |
FeatureToBit(
WebSchedulerTrackedFeature::kSubresourceHasCacheControlNoStore) |
FeatureToBit(
WebSchedulerTrackedFeature::kSubresourceHasCacheControlNoCache) |
FeatureToBit(WebSchedulerTrackedFeature::kPageShowEventListener) |
FeatureToBit(WebSchedulerTrackedFeature::kPageHideEventListener) |
FeatureToBit(WebSchedulerTrackedFeature::kBeforeUnloadEventListener) |
FeatureToBit(WebSchedulerTrackedFeature::kUnloadEventListener) |
FeatureToBit(WebSchedulerTrackedFeature::kFreezeEventListener) |
FeatureToBit(WebSchedulerTrackedFeature::kResumeEventListener) |
FeatureToBit(WebSchedulerTrackedFeature::kContainsPlugins) |
FeatureToBit(WebSchedulerTrackedFeature::kDocumentLoaded) |
FeatureToBit(
WebSchedulerTrackedFeature::kRequestedGeolocationPermission) |
FeatureToBit(
WebSchedulerTrackedFeature::kRequestedNotificationsPermission) |
FeatureToBit(WebSchedulerTrackedFeature::kRequestedMIDIPermission) |
FeatureToBit(
WebSchedulerTrackedFeature::kRequestedAudioCapturePermission) |
FeatureToBit(
WebSchedulerTrackedFeature::kRequestedVideoCapturePermission) |
FeatureToBit(WebSchedulerTrackedFeature::
kRequestedBackForwardCacheBlockedSensors) |
FeatureToBit(
WebSchedulerTrackedFeature::kRequestedBackgroundWorkPermission) |
FeatureToBit(WebSchedulerTrackedFeature::kWebLocks) |
FeatureToBit(
WebSchedulerTrackedFeature::kRequestedStorageAccessGrant) |
FeatureToBit(WebSchedulerTrackedFeature::kWebNfc) |
FeatureToBit(WebSchedulerTrackedFeature::kWebFileSystem) |
FeatureToBit(WebSchedulerTrackedFeature::kAppBanner) |
FeatureToBit(WebSchedulerTrackedFeature::kPrinting) |
FeatureToBit(WebSchedulerTrackedFeature::kPictureInPicture) |
FeatureToBit(WebSchedulerTrackedFeature::kIdleManager) |
FeatureToBit(WebSchedulerTrackedFeature::kPaymentManager) |
FeatureToBit(WebSchedulerTrackedFeature::kKeyboardLock) |
FeatureToBit(WebSchedulerTrackedFeature::kSmsService);
}
} // namespace scheduler
} // namespace blink
......@@ -115,6 +115,13 @@ BLINK_COMMON_EXPORT constexpr uint64_t FeatureToBit(
return 1ull << static_cast<uint32_t>(feature);
}
// Sticky features can't be unregistered and remain active for the rest of the
// lifetime of the page.
BLINK_COMMON_EXPORT bool IsFeatureSticky(WebSchedulerTrackedFeature feature);
// All the sticky features in bitmask form.
BLINK_COMMON_EXPORT uint64_t StickyFeaturesBitmask();
} // namespace scheduler
} // namespace blink
......
......@@ -28,7 +28,6 @@ blink_platform_sources("scheduler") {
"common/scheduler_helper.cc",
"common/scheduler_helper.h",
"common/scheduling_lifecycle_state.cc",
"common/scheduling_policy.cc",
"common/simple_thread_scheduler.cc",
"common/simple_thread_scheduler.h",
"common/single_thread_idle_task_runner.cc",
......
......@@ -52,7 +52,7 @@ FrameOrWorkerScheduler::~FrameOrWorkerScheduler() {
FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle
FrameOrWorkerScheduler::RegisterFeature(SchedulingPolicy::Feature feature,
SchedulingPolicy policy) {
DCHECK(!SchedulingPolicy::IsFeatureSticky(feature));
DCHECK(!scheduler::IsFeatureSticky(feature));
// We reset feature sets upon frame navigation, so having a document-bound
// weak pointer ensures that the feature handle associated with previous
// document can't influence the new one.
......@@ -63,7 +63,7 @@ FrameOrWorkerScheduler::RegisterFeature(SchedulingPolicy::Feature feature,
void FrameOrWorkerScheduler::RegisterStickyFeature(
SchedulingPolicy::Feature feature,
SchedulingPolicy policy) {
DCHECK(SchedulingPolicy::IsFeatureSticky(feature));
DCHECK(scheduler::IsFeatureSticky(feature));
OnStartedUsingFeature(feature, policy);
}
......
// Copyright 2019 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/renderer/platform/scheduler/public/scheduling_policy.h"
namespace blink {
bool SchedulingPolicy::IsFeatureSticky(SchedulingPolicy::Feature feature) {
switch (feature) {
case Feature::kWebSocket:
case Feature::kWebRTC:
case Feature::kDedicatedWorkerOrWorklet:
case Feature::kOutstandingIndexedDBTransaction:
case Feature::kOutstandingNetworkRequestDirectSocket:
case Feature::kOutstandingNetworkRequestFetch:
case Feature::kOutstandingNetworkRequestOthers:
case Feature::kOutstandingNetworkRequestXHR:
case Feature::kBroadcastChannel:
case Feature::kIndexedDBConnection:
case Feature::kWebGL:
case Feature::kWebVR:
case Feature::kWebXR:
case Feature::kSharedWorker:
case Feature::kWebHID:
case Feature::kWebShare:
case Feature::kWebDatabase:
case Feature::kPortal:
case Feature::kSpeechRecognizer:
case Feature::kSpeechSynthesis:
case Feature::kWakeLock:
return false;
case Feature::kMainResourceHasCacheControlNoStore:
case Feature::kMainResourceHasCacheControlNoCache:
case Feature::kSubresourceHasCacheControlNoStore:
case Feature::kSubresourceHasCacheControlNoCache:
case Feature::kPageShowEventListener:
case Feature::kPageHideEventListener:
case Feature::kBeforeUnloadEventListener:
case Feature::kUnloadEventListener:
case Feature::kFreezeEventListener:
case Feature::kResumeEventListener:
case Feature::kContainsPlugins:
case Feature::kDocumentLoaded:
case Feature::kRequestedGeolocationPermission:
case Feature::kRequestedNotificationsPermission:
case Feature::kRequestedMIDIPermission:
case Feature::kRequestedAudioCapturePermission:
case Feature::kRequestedVideoCapturePermission:
case Feature::kRequestedBackForwardCacheBlockedSensors:
case Feature::kRequestedBackgroundWorkPermission:
case Feature::kWebLocks:
case Feature::kRequestedStorageAccessGrant:
case Feature::kWebNfc:
case Feature::kWebFileSystem:
case Feature::kAppBanner:
case Feature::kPrinting:
case Feature::kPictureInPicture:
case Feature::kIdleManager:
case Feature::kPaymentManager:
case Feature::kKeyboardLock:
case Feature::kSmsService:
return true;
}
}
} // namespace blink
......@@ -17,10 +17,6 @@ namespace blink {
struct PLATFORM_EXPORT SchedulingPolicy {
using Feature = scheduler::WebSchedulerTrackedFeature;
// Sticky features can't be unregistered and remain active for the rest
// of the lifetime of the page.
static bool IsFeatureSticky(Feature feature);
// List of opt-outs which form a policy.
struct DisableAllThrottling {};
struct DisableAggressiveThrottling {};
......
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