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 "modules/webaudio/AudioWorkletMessagingProxy.h" | 5 #include "modules/webaudio/AudioWorkletMessagingProxy.h" |
6 | 6 |
7 #include "core/workers/ThreadedWorkletObjectProxy.h" | 7 #include "bindings/core/v8/ScriptSourceCode.h" |
8 #include "core/dom/Document.h" | |
9 #include "core/dom/SecurityContext.h" | |
10 #include "core/dom/TaskRunnerHelper.h" | |
11 #include "core/frame/csp/ContentSecurityPolicy.h" | |
12 #include "core/loader/WorkletScriptLoader.h" | |
13 #include "core/origin_trials/OriginTrialContext.h" | |
14 #include "core/workers/WorkerInspectorProxy.h" | |
15 #include "core/workers/WorkerThreadStartupData.h" | |
16 #include "core/workers/WorkletGlobalScope.h" | |
17 #include "core/workers/WorkletPendingTasks.h" | |
18 #include "modules/webaudio/AudioWorkletNode.h" | |
19 #include "modules/webaudio/AudioWorkletObjectProxy.h" | |
8 #include "modules/webaudio/AudioWorkletThread.h" | 20 #include "modules/webaudio/AudioWorkletThread.h" |
21 #include "platform/CrossThreadFunctional.h" | |
22 #include "platform/WaitableEvent.h" | |
23 #include "platform/WebTaskRunner.h" | |
9 | 24 |
10 namespace blink { | 25 namespace blink { |
11 | 26 |
27 class AudioWorkletMessagingProxy::LoaderClient final | |
nhiroki
2017/06/07 14:43:52
We could factor out this class to share this with
| |
28 : public GarbageCollectedFinalized< | |
29 AudioWorkletMessagingProxy::LoaderClient>, | |
30 public WorkletScriptLoader::Client { | |
31 USING_GARBAGE_COLLECTED_MIXIN(LoaderClient); | |
32 | |
33 public: | |
34 LoaderClient(RefPtr<WebTaskRunner> outside_settings_task_runner, | |
35 WorkletPendingTasks* pending_tasks, | |
36 AudioWorkletMessagingProxy* proxy) | |
37 : outside_settings_task_runner_(std::move(outside_settings_task_runner)), | |
38 pending_tasks_(pending_tasks), | |
39 proxy_(proxy) {} | |
40 | |
41 // Implementation of the second half of the "fetch and invoke a worklet | |
42 // script" algorithm: | |
43 // https://drafts.css-houdini.org/worklets/#fetch-and-invoke-a-worklet-script | |
44 void NotifyWorkletScriptLoadingFinished( | |
45 WorkletScriptLoader* loader, | |
46 const ScriptSourceCode& source_code) final { | |
47 DCHECK(IsMainThread()); | |
48 proxy_->NotifyLoadingFinished(loader); | |
49 | |
50 if (!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 AudioWorkletMessagingProxy* proxy_; | |
77 }; | |
78 | |
12 AudioWorkletMessagingProxy::AudioWorkletMessagingProxy( | 79 AudioWorkletMessagingProxy::AudioWorkletMessagingProxy( |
13 ExecutionContext* execution_context, | 80 ExecutionContext* execution_context, |
14 WorkerClients* worker_clients) | 81 WorkerClients* worker_clients) |
15 : ThreadedWorkletMessagingProxy(execution_context, worker_clients) {} | 82 : ThreadedMessagingProxyBase(execution_context, worker_clients), |
83 weak_ptr_factory_(this) { | |
84 worklet_object_proxy_ = AudioWorkletObjectProxy::Create( | |
85 weak_ptr_factory_.CreateWeakPtr(), GetParentFrameTaskRunners()); | |
86 } | |
16 | 87 |
17 AudioWorkletMessagingProxy::~AudioWorkletMessagingProxy() {} | 88 AudioWorkletMessagingProxy::~AudioWorkletMessagingProxy() {} |
18 | 89 |
90 void AudioWorkletMessagingProxy::Initialize() { | |
91 DCHECK(IsParentContextThread()); | |
92 if (AskedToTerminate()) | |
93 return; | |
94 | |
95 Document* document = ToDocument(GetExecutionContext()); | |
96 SecurityOrigin* starter_origin = document->GetSecurityOrigin(); | |
97 KURL script_url = document->Url(); | |
98 | |
99 ContentSecurityPolicy* csp = document->GetContentSecurityPolicy(); | |
100 DCHECK(csp); | |
101 | |
102 WorkerThreadStartMode start_mode = | |
103 GetWorkerInspectorProxy()->WorkerStartMode(document); | |
104 std::unique_ptr<WorkerSettings> worker_settings = | |
105 WTF::WrapUnique(new WorkerSettings(document->GetSettings())); | |
106 | |
107 // TODO(ikilpatrick): Decide on sensible a value for referrerPolicy. | |
108 std::unique_ptr<WorkerThreadStartupData> startup_data = | |
109 WorkerThreadStartupData::Create( | |
110 script_url, document->UserAgent(), String(), nullptr, start_mode, | |
111 csp->Headers().get(), /* referrerPolicy */ String(), starter_origin, | |
112 ReleaseWorkerClients(), document->AddressSpace(), | |
113 OriginTrialContext::GetTokens(document).get(), | |
114 std::move(worker_settings), WorkerV8Settings::Default()); | |
115 | |
116 InitializeWorkerThread(std::move(startup_data)); | |
117 GetWorkerInspectorProxy()->WorkerThreadCreated(document, GetWorkerThread(), | |
nhiroki
2017/06/07 14:43:52
By the recent change, WorkerInspectorProxy::Worker
| |
118 script_url); | |
119 } | |
120 | |
121 void AudioWorkletMessagingProxy::FetchAndInvokeScript( | |
122 const KURL& module_url_record, | |
123 WebURLRequest::FetchCredentialsMode credentials_mode, | |
124 RefPtr<WebTaskRunner> outside_settings_task_runner, | |
125 WorkletPendingTasks* pending_tasks) { | |
126 DCHECK(IsMainThread()); | |
127 LoaderClient* client = new LoaderClient( | |
128 std::move(outside_settings_task_runner), pending_tasks, this); | |
129 WorkletScriptLoader* loader = WorkletScriptLoader::Create( | |
130 ToDocument(GetExecutionContext())->Fetcher(), client); | |
131 loaders_.insert(loader); | |
132 loader->FetchScript(module_url_record); | |
133 } | |
134 | |
135 void AudioWorkletMessagingProxy::TerminateWorkletGlobalScope() { | |
136 DCHECK(IsMainThread()); | |
137 for (const auto& loader : loaders_) | |
138 loader->Cancel(); | |
139 loaders_.clear(); | |
140 TerminateGlobalScope(); | |
141 } | |
142 | |
143 void AudioWorkletMessagingProxy::NotifyLoadingFinished( | |
144 WorkletScriptLoader* loader) { | |
145 loaders_.erase(loader); | |
146 } | |
147 | |
148 void AudioWorkletMessagingProxy::EvaluateScript( | |
149 const ScriptSourceCode& script_source_code) { | |
150 DCHECK(IsMainThread()); | |
151 TaskRunnerHelper::Get(TaskType::kUnthrottled, GetWorkerThread()) | |
152 ->PostTask( | |
153 BLINK_FROM_HERE, | |
154 CrossThreadBind(&AudioWorkletObjectProxy::EvaluateScript, | |
155 CrossThreadUnretained(worklet_object_proxy_.get()), | |
156 script_source_code.Source(), script_source_code.Url(), | |
157 CrossThreadUnretained(GetWorkerThread()))); | |
158 } | |
159 | |
160 void AudioWorkletMessagingProxy::CreateProcessorInstance( | |
161 const String& name, AudioWorkletHandler* handler, WaitableEvent* done) { | |
162 TaskRunnerHelper::Get(TaskType::kUnthrottled, GetWorkerThread()) | |
163 ->PostTask( | |
164 BLINK_FROM_HERE, | |
165 CrossThreadBind(&AudioWorkletObjectProxy::CreateProcessorInstance, | |
166 CrossThreadUnretained(worklet_object_proxy_.get()), | |
167 name, | |
168 CrossThreadUnretained(handler), | |
169 CrossThreadUnretained(done), | |
170 CrossThreadUnretained(GetWorkerThread()))); | |
171 } | |
172 | |
19 std::unique_ptr<WorkerThread> AudioWorkletMessagingProxy::CreateWorkerThread( | 173 std::unique_ptr<WorkerThread> AudioWorkletMessagingProxy::CreateWorkerThread( |
20 double origin_time) { | 174 double origin_time) { |
21 return AudioWorkletThread::Create(GetThreadableLoadingContext(), | 175 return AudioWorkletThread::Create(GetThreadableLoadingContext(), |
22 WorkletObjectProxy()); | 176 WorkletObjectProxy()); |
23 } | 177 } |
24 | 178 |
179 WebThreadSupportingGC* AudioWorkletMessagingProxy::GetRenderingThread() { | |
180 return &(GetWorkerThread()->GetWorkerBackingThread().BackingThread()); | |
181 }; | |
182 | |
25 } // namespace blink | 183 } // namespace blink |
OLD | NEW |