Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: third_party/WebKit/Source/modules/webaudio/AudioWorkletGlobalScopeTest.cpp

Issue 2727733002: Implement AudioWorkletProcessor interface (Closed)
Patch Set: Added AudioWorkletGlobalScopeTest.cpp Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "modules/webaudio/AudioWorkletGlobalScope.h"
6
7 #include "bindings/core/v8/ScriptSourceCode.h"
8 #include "bindings/core/v8/ScriptState.h"
9 #include "bindings/core/v8/ScriptValue.h"
10 #include "bindings/core/v8/SourceLocation.h"
11 #include "bindings/core/v8/ToV8.h"
12 #include "bindings/core/v8/V8Binding.h"
13 #include "bindings/core/v8/V8BindingForTesting.h"
14 #include "bindings/core/v8/V8BindingMacros.h"
15 #include "bindings/core/v8/V8GCController.h"
16 #include "bindings/core/v8/V8ObjectConstructor.h"
17 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
18 #include "core/workers/WorkerBackingThread.h"
19 #include "core/workers/WorkerReportingProxy.h"
20 #include "core/workers/WorkerThreadStartupData.h"
21 #include "modules/webaudio/AudioBuffer.h"
22 #include "modules/webaudio/AudioWorkletProcessor.h"
23 #include "modules/webaudio/AudioWorkletProcessorDefinition.h"
24 #include "modules/webaudio/AudioWorkletThread.h"
25 #include "platform/weborigin/SecurityOrigin.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace blink {
29
30 namespace {
31
32 // A null WorkerReportingProxy, supplied when creating AudioWorkletThreads.
33 class TestAudioWorkletReportingProxy : public WorkerReportingProxy {
34 public:
35 static std::unique_ptr<TestAudioWorkletReportingProxy> create() {
36 return WTF::wrapUnique(new TestAudioWorkletReportingProxy());
37 }
38
39 // (Empty) WorkerReportingProxy implementation:
40 void countFeature(UseCounter::Feature) override {}
41 void countDeprecation(UseCounter::Feature) override {}
42 void reportException(const String& errorMessage,
43 std::unique_ptr<SourceLocation>,
44 int exceptionId) override {}
45 void reportConsoleMessage(MessageSource,
46 MessageLevel,
47 const String& message,
48 SourceLocation*) override {}
49 void postMessageToPageInspector(const String&) override {}
50 void didEvaluateWorkerScript(bool success) override {}
51 void didCloseWorkerGlobalScope() override {}
52 void willDestroyWorkerGlobalScope() override {}
53 void didTerminateWorkerThread() override {}
54
55 private:
56 TestAudioWorkletReportingProxy() {}
57 };
58
59 } // namespace
60
61 class AudioWorkletGlobalScopeTest : public ::testing::Test {
62 public:
63 void SetUp() override {
64 AudioWorkletThread::createSharedBackingThreadForTest();
65 m_reportingProxy = TestAudioWorkletReportingProxy::create();
66 m_securityOrigin =
67 SecurityOrigin::create(KURL(ParsedURLString, "http://fake.url/"));
68 }
69
70 void TearDown() override { AudioWorkletThread::clearSharedBackingThread(); }
71
72 std::unique_ptr<AudioWorkletThread> createAudioWorkletThread() {
73 std::unique_ptr<AudioWorkletThread> thread =
74 AudioWorkletThread::create(nullptr, *m_reportingProxy);
75 thread->start(
76 WorkerThreadStartupData::create(
77 KURL(ParsedURLString, "http://fake.url/"), "fake user agent", "",
78 nullptr, DontPauseWorkerGlobalScopeOnStart, nullptr, "",
79 m_securityOrigin.get(), nullptr, WebAddressSpaceLocal, nullptr,
80 nullptr, WorkerV8Settings::Default()),
81 ParentFrameTaskRunners::create(nullptr));
82 return thread;
83 }
84
85 void runBasicTest(WorkerThread* thread) {
86 WaitableEvent waitableEvent;
87 thread->workerBackingThread().backingThread().postTask(
nhiroki 2017/03/16 00:21:35 Why don't we call thread->postTask()?
hongchan 2017/03/16 22:11:28 Done.
88 BLINK_FROM_HERE,
89 crossThreadBind(
90 &AudioWorkletGlobalScopeTest::runBasicTestOnWorkletThread,
91 crossThreadUnretained(this), crossThreadUnretained(thread),
92 crossThreadUnretained(&waitableEvent)));
93 waitableEvent.wait();
94 }
95
96 void runSimpleProcessTest(WorkerThread* thread) {
97 WaitableEvent waitableEvent;
98 thread->workerBackingThread().backingThread().postTask(
nhiroki 2017/03/16 00:21:35 ditto.
hongchan 2017/03/16 22:11:28 Done.
99 BLINK_FROM_HERE,
100 crossThreadBind(
101 &AudioWorkletGlobalScopeTest::runSimpleProcessTestOnWorkletThread,
102 crossThreadUnretained(this), crossThreadUnretained(thread),
103 crossThreadUnretained(&waitableEvent)));
104 waitableEvent.wait();
105 }
106
107 private:
108 void runBasicTestOnWorkletThread(WorkerThread* thread,
109 WaitableEvent* waitEvent) {
nhiroki 2017/03/16 00:21:35 EXPECT_TRUE(thread->isCurrentThread());
hongchan 2017/03/16 22:11:28 Done.
110 AudioWorkletGlobalScope* globalScope =
111 static_cast<AudioWorkletGlobalScope*>(thread->globalScope());
112 EXPECT_TRUE(globalScope);
113 EXPECT_TRUE(globalScope->isAudioWorkletGlobalScope());
114
115 ScriptState* scriptState =
116 globalScope->scriptController()->getScriptState();
117 EXPECT_TRUE(scriptState);
118
119 v8::Isolate* isolate = scriptState->isolate();
120 EXPECT_TRUE(isolate);
121
122 ScriptState::Scope scope(scriptState);
123
124 globalScope->scriptController()->evaluate(ScriptSourceCode(
125 R"JS(
126 registerProcessor('testProcessor', class {
127 constructor () {}
128 process () {}
129 });
130 )JS"));
131
132 AudioWorkletProcessorDefinition* definition =
133 globalScope->findDefinition("testProcessor");
134 EXPECT_TRUE(definition);
135 EXPECT_EQ(definition->name(), "testProcessor");
136 EXPECT_TRUE(definition->constructorLocal(isolate)->IsFunction());
137 EXPECT_TRUE(definition->processLocal(isolate)->IsFunction());
138
139 AudioWorkletProcessor* processor =
140 globalScope->createInstance("testProcessor");
141 EXPECT_TRUE(processor);
142 EXPECT_EQ(processor->name(), "testProcessor");
143 EXPECT_TRUE(processor->instanceLocal(isolate)->IsObject());
144
145 waitEvent->signal();
146 }
147
148 void runSimpleProcessTestOnWorkletThread(WorkerThread* thread,
149 WaitableEvent* waitEvent) {
nhiroki 2017/03/16 00:21:35 EXPECT_TRUE(thread->isCurrentThread());
hongchan 2017/03/16 22:11:28 Done.
150 AudioWorkletGlobalScope* globalScope =
151 static_cast<AudioWorkletGlobalScope*>(thread->globalScope());
152 ScriptState* scriptState =
153 globalScope->scriptController()->getScriptState();
154
155 ScriptState::Scope scope(scriptState);
156
157 globalScope->scriptController()->evaluate(ScriptSourceCode(
158 R"JS(
159 registerProcessor('foo', class {
160 constructor () {
161 this.constant = 1;
162 }
163 process (input, output) {
164 let inputChannelData = input.getChannelData(0);
165 let outputChannelData = output.getChannelData(0);
166 for (let i = 0; i < input.length; ++i) {
167 outputChannelData[i] = inputChannelData[i] + this.constant;
168 }
169 }
170 }
171 )
172 )JS"));
173
174 AudioWorkletProcessor* processor = globalScope->createInstance("foo");
175 EXPECT_TRUE(processor);
176
177 // Set the buffer length to 128. (= WebAudio's render quantum size)
nhiroki 2017/03/16 00:21:35 For readability and maintainability, how about def
hongchan 2017/03/16 22:11:28 Done.
178 AudioBuffer* inputBuffer = AudioBuffer::create(1, 128, 44100);
179 AudioBuffer* outputBuffer = AudioBuffer::create(1, 128, 44100);
180 DOMFloat32Array* inputChannelData = inputBuffer->getChannelData(0);
181 float* inputArrayData = inputChannelData->data();
182 EXPECT_TRUE(inputArrayData);
183 DOMFloat32Array* outputChannelData = outputBuffer->getChannelData(0);
184 float* outputArrayData = outputChannelData->data();
185 EXPECT_TRUE(outputArrayData);
186
187 // Fill |inputBuffer| with 1 and zero out |outputBuffer|.
188 std::fill(inputArrayData, inputArrayData + inputBuffer->length(), 1);
189 outputBuffer->zero();
190
191 // Then invoke the process() method to perform JS buffer manipulation. The
192 // output buffer should contain a constant value of 2.
193 processor->process(inputBuffer, outputBuffer);
194 for (unsigned i = 0; i < outputBuffer->length(); ++i) {
195 EXPECT_EQ(outputArrayData[i], 2);
196 }
197
198 waitEvent->signal();
199 }
200
201 RefPtr<SecurityOrigin> m_securityOrigin;
202 std::unique_ptr<WorkerReportingProxy> m_reportingProxy;
203 };
204
205 TEST_F(AudioWorkletGlobalScopeTest, Basic) {
206 std::unique_ptr<AudioWorkletThread> thread = createAudioWorkletThread();
207 runBasicTest(thread.get());
208 thread->terminateAndWait();
209 }
210
211 TEST_F(AudioWorkletGlobalScopeTest, BufferProcessing) {
212 std::unique_ptr<AudioWorkletThread> thread = createAudioWorkletThread();
213 runSimpleProcessTest(thread.get());
214 thread->terminateAndWait();
215 }
216
217 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698