Commit 3df81bcb authored by Nate Chapin's avatar Nate Chapin Committed by Commit Bot

Make ScriptRunner a ContextLifecycleStateObserver

ScriptRunner has special cases in Document to allow it to
pause/unpause, but ContextLifecycleStateObserver is the standard way
to pause/unpause.

Bug: 1029822
Change-Id: Ie8b5e427e6a217ba6a1aad9af7a286ce22444918
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1949225Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Nate Chapin <japhet@chromium.org>
Auto-Submit: Nate Chapin <japhet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#722506}
parent a6919374
...@@ -7293,15 +7293,11 @@ void Document::AddConsoleMessageImpl(ConsoleMessage* console_message, ...@@ -7293,15 +7293,11 @@ void Document::AddConsoleMessageImpl(ConsoleMessage* console_message,
} }
void Document::TasksWerePaused() { void Document::TasksWerePaused() {
GetScriptRunner()->Suspend();
if (scripted_animation_controller_) if (scripted_animation_controller_)
scripted_animation_controller_->Pause(); scripted_animation_controller_->Pause();
} }
void Document::TasksWereUnpaused() { void Document::TasksWereUnpaused() {
GetScriptRunner()->Resume();
if (scripted_animation_controller_) if (scripted_animation_controller_)
scripted_animation_controller_->Unpause(); scripted_animation_controller_->Unpause();
} }
......
...@@ -35,13 +35,16 @@ ...@@ -35,13 +35,16 @@
#include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h" #include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
namespace blink { namespace blink {
ScriptRunner::ScriptRunner(Document* document) ScriptRunner::ScriptRunner(Document* document)
: document_(document), : ContextLifecycleStateObserver(document),
document_(document),
task_runner_(document->GetTaskRunner(TaskType::kNetworking)) { task_runner_(document->GetTaskRunner(TaskType::kNetworking)) {
DCHECK(document); DCHECK(document);
UpdateStateIfNeeded();
} }
void ScriptRunner::QueueScriptForExecution(PendingScript* pending_script) { void ScriptRunner::QueueScriptForExecution(PendingScript* pending_script) {
...@@ -70,18 +73,17 @@ void ScriptRunner::PostTask(const base::Location& web_trace_location) { ...@@ -70,18 +73,17 @@ void ScriptRunner::PostTask(const base::Location& web_trace_location) {
WTF::Bind(&ScriptRunner::ExecuteTask, WrapWeakPersistent(this))); WTF::Bind(&ScriptRunner::ExecuteTask, WrapWeakPersistent(this)));
} }
void ScriptRunner::Suspend() { void ScriptRunner::ContextLifecycleStateChanged(
is_suspended_ = true; mojom::FrameLifecycleState state) {
}
void ScriptRunner::Resume() {
DCHECK(is_suspended_);
is_suspended_ = false;
if (!IsExecutionSuspended()) if (!IsExecutionSuspended())
PostTasksForReadyScripts(FROM_HERE); PostTasksForReadyScripts(FROM_HERE);
} }
bool ScriptRunner::IsExecutionSuspended() {
return !GetExecutionContext() || GetExecutionContext()->IsContextPaused() ||
is_force_deferred_;
}
void ScriptRunner::SetForceDeferredExecution(bool force_deferred) { void ScriptRunner::SetForceDeferredExecution(bool force_deferred) {
DCHECK(force_deferred != is_force_deferred_); DCHECK(force_deferred != is_force_deferred_);
...@@ -260,6 +262,7 @@ void ScriptRunner::ExecuteTask() { ...@@ -260,6 +262,7 @@ void ScriptRunner::ExecuteTask() {
} }
void ScriptRunner::Trace(Visitor* visitor) { void ScriptRunner::Trace(Visitor* visitor) {
ContextLifecycleStateObserver::Trace(visitor);
visitor->Trace(document_); visitor->Trace(document_);
visitor->Trace(pending_in_order_scripts_); visitor->Trace(pending_in_order_scripts_);
visitor->Trace(pending_async_scripts_); visitor->Trace(pending_async_scripts_);
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/context_lifecycle_state_observer.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/deque.h" #include "third_party/blink/renderer/platform/wtf/deque.h"
...@@ -42,7 +43,10 @@ class PendingScript; ...@@ -42,7 +43,10 @@ class PendingScript;
class ScriptLoader; class ScriptLoader;
class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>, class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>,
public ContextLifecycleStateObserver,
public NameClient { public NameClient {
USING_GARBAGE_COLLECTED_MIXIN(ScriptRunner);
public: public:
explicit ScriptRunner(Document*); explicit ScriptRunner(Document*);
...@@ -51,14 +55,14 @@ class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>, ...@@ -51,14 +55,14 @@ class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>,
return !pending_in_order_scripts_.IsEmpty() || return !pending_in_order_scripts_.IsEmpty() ||
!pending_async_scripts_.IsEmpty(); !pending_async_scripts_.IsEmpty();
} }
void Suspend();
void Resume();
void SetForceDeferredExecution(bool force_deferred); void SetForceDeferredExecution(bool force_deferred);
void NotifyScriptReady(PendingScript*); void NotifyScriptReady(PendingScript*);
void ContextLifecycleStateChanged(mojom::FrameLifecycleState) final;
static void MovePendingScript(Document&, Document&, ScriptLoader*); static void MovePendingScript(Document&, Document&, ScriptLoader*);
void Trace(Visitor*); void Trace(Visitor*) override;
const char* NameInHeapSnapshot() const override { return "ScriptRunner"; } const char* NameInHeapSnapshot() const override { return "ScriptRunner"; }
private: private:
...@@ -81,7 +85,7 @@ class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>, ...@@ -81,7 +85,7 @@ class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>,
void ExecuteTask(); void ExecuteTask();
bool IsExecutionSuspended() { return is_suspended_ || is_force_deferred_; } bool IsExecutionSuspended();
Member<Document> document_; Member<Document> document_;
...@@ -96,8 +100,6 @@ class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>, ...@@ -96,8 +100,6 @@ class CORE_EXPORT ScriptRunner final : public GarbageCollected<ScriptRunner>,
int number_of_in_order_scripts_with_pending_notification_ = 0; int number_of_in_order_scripts_with_pending_notification_ = 0;
bool is_suspended_ = false;
// Whether script execution is suspended due to there being force deferred // Whether script execution is suspended due to there being force deferred
// scripts that have not yet been executed. This is expected to be in sync // scripts that have not yet been executed. This is expected to be in sync
// with HTMLParserScriptRunner::suspended_async_script_execution_. // with HTMLParserScriptRunner::suspended_async_script_execution_.
......
...@@ -327,8 +327,10 @@ TEST_F(ScriptRunnerTest, ResumeAndSuspend_InOrder) { ...@@ -327,8 +327,10 @@ TEST_F(ScriptRunnerTest, ResumeAndSuspend_InOrder) {
NotifyScriptReady(pending_script3); NotifyScriptReady(pending_script3);
platform_->RunSingleTask(); platform_->RunSingleTask();
script_runner_->Suspend(); script_runner_->ContextLifecycleStateChanged(
script_runner_->Resume(); mojom::FrameLifecycleState::kPaused);
script_runner_->ContextLifecycleStateChanged(
mojom::FrameLifecycleState::kRunning);
platform_->RunUntilIdle(); platform_->RunUntilIdle();
// Make sure elements are correct and in right order. // Make sure elements are correct and in right order.
...@@ -356,8 +358,10 @@ TEST_F(ScriptRunnerTest, ResumeAndSuspend_Async) { ...@@ -356,8 +358,10 @@ TEST_F(ScriptRunnerTest, ResumeAndSuspend_Async) {
.WillOnce(InvokeWithoutArgs([this] { order_.push_back(3); })); .WillOnce(InvokeWithoutArgs([this] { order_.push_back(3); }));
platform_->RunSingleTask(); platform_->RunSingleTask();
script_runner_->Suspend(); script_runner_->ContextLifecycleStateChanged(
script_runner_->Resume(); mojom::FrameLifecycleState::kPaused);
script_runner_->ContextLifecycleStateChanged(
mojom::FrameLifecycleState::kRunning);
platform_->RunUntilIdle(); platform_->RunUntilIdle();
// Make sure elements are correct. // Make sure elements are correct.
...@@ -400,12 +404,14 @@ TEST_F(ScriptRunnerTest, SetForceDeferredAndResumeAndSuspend) { ...@@ -400,12 +404,14 @@ TEST_F(ScriptRunnerTest, SetForceDeferredAndResumeAndSuspend) {
platform_->RunSingleTask(); platform_->RunSingleTask();
ASSERT_EQ(0u, order_.size()); ASSERT_EQ(0u, order_.size());
script_runner_->Suspend(); script_runner_->ContextLifecycleStateChanged(
mojom::FrameLifecycleState::kPaused);
platform_->RunSingleTask(); platform_->RunSingleTask();
ASSERT_EQ(0u, order_.size()); ASSERT_EQ(0u, order_.size());
// Resume will not execute script while still in ForceDeferred state. // Resuming will not execute script while still in ForceDeferred state.
script_runner_->Resume(); script_runner_->ContextLifecycleStateChanged(
mojom::FrameLifecycleState::kRunning);
platform_->RunUntilIdle(); platform_->RunUntilIdle();
ASSERT_EQ(0u, order_.size()); ASSERT_EQ(0u, order_.size());
......
Tests that reparenting media elements also reparents ActiveDOMObject. Tests that reparenting media elements also reparents ActiveDOMObject.
Before Reparenting Before Reparenting
PASS: internals.contextLifecycleStateObserverObjectCount(document) should be '1' and is. PASS: internals.contextLifecycleStateObserverObjectCount(document) should be '2' and is.
PASS: internals.contextLifecycleStateObserverObjectCount(iframe) should be '4' and is. PASS: internals.contextLifecycleStateObserverObjectCount(iframe) should be '5' and is.
After Reparenting After Reparenting
PASS: internals.contextLifecycleStateObserverObjectCount(document) should be '4' and is. PASS: internals.contextLifecycleStateObserverObjectCount(document) should be '5' and is.
PASS: internals.contextLifecycleStateObserverObjectCount(iframe) should be '2' and is. PASS: internals.contextLifecycleStateObserverObjectCount(iframe) should be '3' and is.
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
window.iframe = document.querySelector('iframe').contentDocument; window.iframe = document.querySelector('iframe').contentDocument;
log('Before Reparenting'); log('Before Reparenting');
shouldBe('internals.contextLifecycleStateObserverObjectCount(document)', 1); shouldBe('internals.contextLifecycleStateObserverObjectCount(document)', 2);
shouldBe('internals.contextLifecycleStateObserverObjectCount(iframe)', 4); shouldBe('internals.contextLifecycleStateObserverObjectCount(iframe)', 5);
document.body.appendChild(window.iframe.querySelector('video')); document.body.appendChild(window.iframe.querySelector('video'));
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
// but a new one will be created in |document|, so the count is expected // but a new one will be created in |document|, so the count is expected
// to differ by one. // to differ by one.
log('After Reparenting'); log('After Reparenting');
shouldBe('internals.contextLifecycleStateObserverObjectCount(document)', 4); shouldBe('internals.contextLifecycleStateObserverObjectCount(document)', 5);
shouldBe('internals.contextLifecycleStateObserverObjectCount(iframe)', 2); shouldBe('internals.contextLifecycleStateObserverObjectCount(iframe)', 3);
} }
</script> </script>
</body> </body>
......
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