Commit 32367909 authored by Dave Tapuska's avatar Dave Tapuska Committed by Commit Bot

Change Background freezing to freeze the execution context.

The execution context state was never adjusted when a page was frozen.

ContextStateChangedListeners fire when the state of execution context
changes.
This adds a number of things that are desirable for background tab
freezing:
- Workers being frozen as well
- Mojo channels are appropriately dropped for IPCs while in the frozen
state

Add PauseExecutionContextOnBackgroundFreeze feature to control this and
enable feature experimentally for now. Added a content feature kill
switch for this as well.

The desire is that bfcache, iframe freezing, sync event calls
(window.print()) and background tab freezing all will share the
same code paths for task scheduling adjustment.

Intent to Implement:
https://groups.google.com/a/chromium.org/d/msg/blink-dev/KwDF6Eavfek/Qb48J5ceAwAJ

BUG=957589

Change-Id: Ic5b94ed971f4fe0883c39039534efd64ffd290f1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1588158Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Reviewed-by: default avatarShubhie Panicker <panicker@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Cr-Commit-Position: refs/heads/master@{#663151}
parent 69b3b010
...@@ -518,6 +518,11 @@ void SetIndividualRuntimeFeatures( ...@@ -518,6 +518,11 @@ void SetIndividualRuntimeFeatures(
WebRuntimeFeatures::EnableFeatureFromString( WebRuntimeFeatures::EnableFeatureFromString(
"AudioWorkletRealtimeThread", true); "AudioWorkletRealtimeThread", true);
} }
if (!base::FeatureList::IsEnabled(
features::kPauseExecutionContextOnBackgroundFreeze)) {
WebRuntimeFeatures::EnablePauseExecutionContextOnBackgroundFreeze(false);
}
} }
} // namespace } // namespace
......
...@@ -315,6 +315,11 @@ const base::Feature kPassiveEventListenersDueToFling{ ...@@ -315,6 +315,11 @@ const base::Feature kPassiveEventListenersDueToFling{
const base::Feature kPaymentRequestHasEnrolledInstrument = { const base::Feature kPaymentRequestHasEnrolledInstrument = {
"PaymentRequestHasEnrolledInstrument", base::FEATURE_ENABLED_BY_DEFAULT}; "PaymentRequestHasEnrolledInstrument", base::FEATURE_ENABLED_BY_DEFAULT};
// Whether ExecutionContext is paused (and workers) on background freeze.
const base::Feature kPauseExecutionContextOnBackgroundFreeze = {
"PauseExecutionContextOnBackgroundFreeze",
base::FEATURE_ENABLED_BY_DEFAULT};
// Whether PDF files should be rendered in diffent processes based on origin. // Whether PDF files should be rendered in diffent processes based on origin.
const base::Feature kPdfIsolation = {"PdfIsolation", const base::Feature kPdfIsolation = {"PdfIsolation",
base::FEATURE_ENABLED_BY_DEFAULT}; base::FEATURE_ENABLED_BY_DEFAULT};
......
...@@ -77,6 +77,8 @@ CONTENT_EXPORT extern const base::Feature kOverscrollHistoryNavigation; ...@@ -77,6 +77,8 @@ CONTENT_EXPORT extern const base::Feature kOverscrollHistoryNavigation;
CONTENT_EXPORT extern const base::Feature kPassiveDocumentEventListeners; CONTENT_EXPORT extern const base::Feature kPassiveDocumentEventListeners;
CONTENT_EXPORT extern const base::Feature kPassiveDocumentWheelEventListeners; CONTENT_EXPORT extern const base::Feature kPassiveDocumentWheelEventListeners;
CONTENT_EXPORT extern const base::Feature kPassiveEventListenersDueToFling; CONTENT_EXPORT extern const base::Feature kPassiveEventListenersDueToFling;
CONTENT_EXPORT extern const base::Feature
kPauseExecutionContextOnBackgroundFreeze;
CONTENT_EXPORT extern const base::Feature kPaymentRequestHasEnrolledInstrument; CONTENT_EXPORT extern const base::Feature kPaymentRequestHasEnrolledInstrument;
CONTENT_EXPORT extern const base::Feature kPdfIsolation; CONTENT_EXPORT extern const base::Feature kPdfIsolation;
CONTENT_EXPORT extern const base::Feature kPeriodicBackgroundSync; CONTENT_EXPORT extern const base::Feature kPeriodicBackgroundSync;
......
...@@ -245,6 +245,8 @@ class WebRuntimeFeatures { ...@@ -245,6 +245,8 @@ class WebRuntimeFeatures {
BLINK_PLATFORM_EXPORT static void EnableStaleWhileRevalidate(bool); BLINK_PLATFORM_EXPORT static void EnableStaleWhileRevalidate(bool);
BLINK_PLATFORM_EXPORT static void EnableSmsReceiver(bool); BLINK_PLATFORM_EXPORT static void EnableSmsReceiver(bool);
BLINK_PLATFORM_EXPORT static void EnableDisplayLocking(bool); BLINK_PLATFORM_EXPORT static void EnableDisplayLocking(bool);
BLINK_PLATFORM_EXPORT static void
EnablePauseExecutionContextOnBackgroundFreeze(bool);
private: private:
WebRuntimeFeatures(); WebRuntimeFeatures();
......
...@@ -503,6 +503,36 @@ void Page::SetLifecycleState(PageLifecycleState state) { ...@@ -503,6 +503,36 @@ void Page::SetLifecycleState(PageLifecycleState state) {
return; return;
DCHECK_NE(state, PageLifecycleState::kUnknown); DCHECK_NE(state, PageLifecycleState::kUnknown);
// When background tab freezing was first shipped it didn't pause
// the execution context but froze the frame scheduler. This feature
// flag attempts to bring the two mechanisms to use the same path for
// all pausing and freezing.
// This allows for mojo channels, workers to also be frozen because
// they listen for the page execution context being paused/frozen.
if (RuntimeEnabledFeatures::
PauseExecutionContextOnBackgroundFreezeEnabled()) {
base::Optional<mojom::FrameLifecycleState> next_state;
if (state == PageLifecycleState::kFrozen) {
next_state = mojom::FrameLifecycleState::kFrozen;
} else if (page_lifecycle_state_ == PageLifecycleState::kFrozen) {
// TODO(fmeawad): Only resume the page that just became visible, blocked
// on task queues per frame.
DCHECK(state == PageLifecycleState::kActive ||
state == PageLifecycleState::kHiddenBackgrounded ||
state == PageLifecycleState::kHiddenForegrounded);
next_state = mojom::FrameLifecycleState::kRunning;
}
if (next_state) {
for (Frame* frame = main_frame_.Get(); frame;
frame = frame->Tree().TraverseNext()) {
if (auto* local_frame = DynamicTo<LocalFrame>(frame))
local_frame->SetLifecycleState(next_state.value());
}
}
} else {
// The following code will dispatch the freeze/resume events,
// freeze the frame scheduler but but not pause the execution context.
if (state == PageLifecycleState::kFrozen) { if (state == PageLifecycleState::kFrozen) {
for (Frame* frame = main_frame_.Get(); frame; for (Frame* frame = main_frame_.Get(); frame;
frame = frame->Tree().TraverseNext()) { frame = frame->Tree().TraverseNext()) {
...@@ -519,6 +549,7 @@ void Page::SetLifecycleState(PageLifecycleState state) { ...@@ -519,6 +549,7 @@ void Page::SetLifecycleState(PageLifecycleState state) {
frame->DidResume(); frame->DidResume();
} }
} }
}
page_lifecycle_state_ = state; page_lifecycle_state_ = state;
} }
......
...@@ -693,4 +693,10 @@ void WebRuntimeFeatures::EnableDisplayLocking(bool enable) { ...@@ -693,4 +693,10 @@ void WebRuntimeFeatures::EnableDisplayLocking(bool enable) {
RuntimeEnabledFeatures::SetDisplayLockingEnabled(enable); RuntimeEnabledFeatures::SetDisplayLockingEnabled(enable);
} }
void WebRuntimeFeatures::EnablePauseExecutionContextOnBackgroundFreeze(
bool enable) {
RuntimeEnabledFeatures::SetPauseExecutionContextOnBackgroundFreezeEnabled(
enable);
}
} // namespace blink } // namespace blink
...@@ -1073,6 +1073,10 @@ ...@@ -1073,6 +1073,10 @@
{ {
name: "PassPaintVisualRectToCompositor", name: "PassPaintVisualRectToCompositor",
}, },
{
name: "PauseExecutionContextOnBackgroundFreeze",
status: "experimental",
},
{ {
name: "PaymentApp", name: "PaymentApp",
status: "experimental", status: "experimental",
......
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