OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/workers/ThreadedWorkletMessagingProxy.h" | 5 #include "core/workers/ThreadedWorkletMessagingProxy.h" |
6 | 6 |
7 #include "bindings/core/v8/ScriptSourceCode.h" | 7 #include "bindings/core/v8/ScriptSourceCode.h" |
8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
9 #include "core/dom/SecurityContext.h" | 9 #include "core/dom/SecurityContext.h" |
10 #include "core/dom/TaskRunnerHelper.h" | 10 #include "core/dom/TaskRunnerHelper.h" |
11 #include "core/frame/csp/ContentSecurityPolicy.h" | 11 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 12 #include "core/loader/WorkletScriptLoader.h" |
12 #include "core/origin_trials/OriginTrialContext.h" | 13 #include "core/origin_trials/OriginTrialContext.h" |
13 #include "core/workers/ThreadedWorkletObjectProxy.h" | 14 #include "core/workers/ThreadedWorkletObjectProxy.h" |
14 #include "core/workers/WorkerInspectorProxy.h" | 15 #include "core/workers/WorkerInspectorProxy.h" |
15 #include "core/workers/WorkerThreadStartupData.h" | 16 #include "core/workers/WorkerThreadStartupData.h" |
16 #include "core/workers/WorkletGlobalScope.h" | 17 #include "core/workers/WorkletGlobalScope.h" |
17 #include "platform/CrossThreadFunctional.h" | 18 #include "platform/CrossThreadFunctional.h" |
18 #include "platform/WebTaskRunner.h" | 19 #include "platform/WebTaskRunner.h" |
19 | 20 |
20 namespace blink { | 21 namespace blink { |
21 | 22 |
| 23 namespace { |
| 24 |
| 25 // Implementation of the second half of the "fetch and invoke a worklet script" |
| 26 // algorithm: |
| 27 // https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script |
| 28 // TODO(nhiroki): This should be in sync with WorkletModuleTreeClient as much as |
| 29 // possible because this will be replaced with that when module loading is ready |
| 30 // for threaded worklets (https://crbug.com/727194). |
| 31 class LoaderClient final : public GarbageCollectedFinalized<LoaderClient>, |
| 32 public WorkletScriptLoader::Client { |
| 33 USING_GARBAGE_COLLECTED_MIXIN(LoaderClient); |
| 34 |
| 35 public: |
| 36 LoaderClient(RefPtr<WebTaskRunner> outside_settings_task_runner, |
| 37 WorkletPendingTasks* pending_tasks, |
| 38 ThreadedWorkletMessagingProxy* proxy) |
| 39 : outside_settings_task_runner_(std::move(outside_settings_task_runner)), |
| 40 pending_tasks_(pending_tasks), |
| 41 proxy_(proxy) {} |
| 42 |
| 43 // Implementation of the second half of the "fetch and invoke a worklet |
| 44 // script" algorithm: |
| 45 // https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script |
| 46 void NotifyWorkletScriptLoadingFinished( |
| 47 WorkletScriptLoader* script_loader, |
| 48 const ScriptSourceCode& source_code) final { |
| 49 DCHECK(IsMainThread()); |
| 50 if (!script_loader->WasScriptLoadSuccessful()) { |
| 51 // Step 3: "If script is null, then queue a task on outsideSettings's |
| 52 // responsible event loop to run these steps:" |
| 53 // The steps are implemented in WorkletPendingTasks::Abort(). |
| 54 outside_settings_task_runner_->PostTask( |
| 55 BLINK_FROM_HERE, WTF::Bind(&WorkletPendingTasks::Abort, |
| 56 WrapPersistent(pending_tasks_.Get()))); |
| 57 return; |
| 58 } |
| 59 |
| 60 // Step 4: "Run a module script given script." |
| 61 proxy_->EvaluateScript(source_code); |
| 62 |
| 63 // Step 5: "Queue a task on outsideSettings's responsible event loop to run |
| 64 // these steps:" |
| 65 // The steps are implemented in WorkletPendingTasks::DecrementCounter(). |
| 66 outside_settings_task_runner_->PostTask( |
| 67 BLINK_FROM_HERE, WTF::Bind(&WorkletPendingTasks::DecrementCounter, |
| 68 WrapPersistent(pending_tasks_.Get()))); |
| 69 } |
| 70 |
| 71 DEFINE_INLINE_TRACE() { visitor->Trace(pending_tasks_); } |
| 72 |
| 73 private: |
| 74 RefPtr<WebTaskRunner> outside_settings_task_runner_; |
| 75 Member<WorkletPendingTasks> pending_tasks_; |
| 76 ThreadedWorkletMessagingProxy* proxy_; |
| 77 }; |
| 78 |
| 79 } // namespace |
| 80 |
22 ThreadedWorkletMessagingProxy::ThreadedWorkletMessagingProxy( | 81 ThreadedWorkletMessagingProxy::ThreadedWorkletMessagingProxy( |
23 ExecutionContext* execution_context) | 82 ExecutionContext* execution_context) |
24 : ThreadedMessagingProxyBase(execution_context), weak_ptr_factory_(this) { | 83 : ThreadedMessagingProxyBase(execution_context), weak_ptr_factory_(this) { |
25 worklet_object_proxy_ = ThreadedWorkletObjectProxy::Create( | 84 worklet_object_proxy_ = ThreadedWorkletObjectProxy::Create( |
26 weak_ptr_factory_.CreateWeakPtr(), GetParentFrameTaskRunners()); | 85 weak_ptr_factory_.CreateWeakPtr(), GetParentFrameTaskRunners()); |
27 } | 86 } |
28 | 87 |
29 void ThreadedWorkletMessagingProxy::Initialize() { | 88 void ThreadedWorkletMessagingProxy::Initialize() { |
30 DCHECK(IsParentContextThread()); | 89 DCHECK(IsMainThread()); |
31 if (AskedToTerminate()) | 90 if (AskedToTerminate()) |
32 return; | 91 return; |
33 | 92 |
34 Document* document = ToDocument(GetExecutionContext()); | 93 Document* document = ToDocument(GetExecutionContext()); |
35 SecurityOrigin* starter_origin = document->GetSecurityOrigin(); | 94 SecurityOrigin* starter_origin = document->GetSecurityOrigin(); |
36 KURL script_url = document->Url(); | 95 KURL script_url = document->Url(); |
37 | 96 |
38 ContentSecurityPolicy* csp = document->GetContentSecurityPolicy(); | 97 ContentSecurityPolicy* csp = document->GetContentSecurityPolicy(); |
39 DCHECK(csp); | 98 DCHECK(csp); |
40 | 99 |
41 WorkerThreadStartMode start_mode = | 100 WorkerThreadStartMode start_mode = |
42 GetWorkerInspectorProxy()->WorkerStartMode(document); | 101 GetWorkerInspectorProxy()->WorkerStartMode(document); |
43 std::unique_ptr<WorkerSettings> worker_settings = | 102 std::unique_ptr<WorkerSettings> worker_settings = |
44 WTF::WrapUnique(new WorkerSettings(document->GetSettings())); | 103 WTF::WrapUnique(new WorkerSettings(document->GetSettings())); |
45 | 104 |
46 // TODO(ikilpatrick): Decide on sensible a value for referrerPolicy. | 105 // TODO(ikilpatrick): Decide on sensible a value for referrerPolicy. |
47 std::unique_ptr<WorkerThreadStartupData> startup_data = | 106 std::unique_ptr<WorkerThreadStartupData> startup_data = |
48 WorkerThreadStartupData::Create( | 107 WorkerThreadStartupData::Create( |
49 script_url, document->UserAgent(), String(), nullptr, start_mode, | 108 script_url, document->UserAgent(), String(), nullptr, start_mode, |
50 csp->Headers().get(), /* referrerPolicy */ String(), starter_origin, | 109 csp->Headers().get(), /* referrerPolicy */ String(), starter_origin, |
51 nullptr, document->AddressSpace(), | 110 nullptr, document->AddressSpace(), |
52 OriginTrialContext::GetTokens(document).get(), | 111 OriginTrialContext::GetTokens(document).get(), |
53 std::move(worker_settings), WorkerV8Settings::Default()); | 112 std::move(worker_settings), WorkerV8Settings::Default()); |
54 | 113 |
55 InitializeWorkerThread(std::move(startup_data)); | 114 InitializeWorkerThread(std::move(startup_data)); |
56 GetWorkerInspectorProxy()->WorkerThreadCreated(document, GetWorkerThread(), | 115 GetWorkerInspectorProxy()->WorkerThreadCreated(document, GetWorkerThread(), |
57 script_url); | 116 script_url); |
58 } | 117 } |
59 | 118 |
| 119 void ThreadedWorkletMessagingProxy::FetchAndInvokeScript( |
| 120 const KURL& module_url_record, |
| 121 WebURLRequest::FetchCredentialsMode credentials_mode, |
| 122 RefPtr<WebTaskRunner> outside_settings_task_runner, |
| 123 WorkletPendingTasks* pending_tasks) { |
| 124 DCHECK(IsMainThread()); |
| 125 LoaderClient* client = new LoaderClient( |
| 126 std::move(outside_settings_task_runner), pending_tasks, this); |
| 127 WorkletScriptLoader* script_loader = WorkletScriptLoader::Create( |
| 128 ToDocument(GetExecutionContext())->Fetcher(), client); |
| 129 script_loader->FetchScript(module_url_record); |
| 130 } |
| 131 |
60 void ThreadedWorkletMessagingProxy::EvaluateScript( | 132 void ThreadedWorkletMessagingProxy::EvaluateScript( |
61 const ScriptSourceCode& script_source_code) { | 133 const ScriptSourceCode& script_source_code) { |
| 134 DCHECK(IsMainThread()); |
62 TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, GetWorkerThread()) | 135 TaskRunnerHelper::Get(TaskType::kMiscPlatformAPI, GetWorkerThread()) |
63 ->PostTask( | 136 ->PostTask( |
64 BLINK_FROM_HERE, | 137 BLINK_FROM_HERE, |
65 CrossThreadBind(&ThreadedWorkletObjectProxy::EvaluateScript, | 138 CrossThreadBind(&ThreadedWorkletObjectProxy::EvaluateScript, |
66 CrossThreadUnretained(worklet_object_proxy_.get()), | 139 CrossThreadUnretained(worklet_object_proxy_.get()), |
67 script_source_code.Source(), script_source_code.Url(), | 140 script_source_code.Source(), script_source_code.Url(), |
68 CrossThreadUnretained(GetWorkerThread()))); | 141 CrossThreadUnretained(GetWorkerThread()))); |
69 } | 142 } |
70 | 143 |
71 void ThreadedWorkletMessagingProxy::TerminateWorkletGlobalScope() { | 144 void ThreadedWorkletMessagingProxy::TerminateWorkletGlobalScope() { |
| 145 DCHECK(IsMainThread()); |
72 TerminateGlobalScope(); | 146 TerminateGlobalScope(); |
73 } | 147 } |
74 | 148 |
75 } // namespace blink | 149 } // namespace blink |
OLD | NEW |