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

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

Issue 2501863003: Support for AudioContextOptions latencyHint. (Closed)
Patch Set: Updates based on reviewer comments. Created 4 years 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
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/BaseAudioContext.h" 5 #include "modules/webaudio/BaseAudioContext.h"
6 6
7 #include "core/dom/Document.h" 7 #include "core/dom/Document.h"
8 #include "core/dom/DocumentUserGestureToken.h" 8 #include "core/dom/DocumentUserGestureToken.h"
9 #include "core/frame/FrameOwner.h" 9 #include "core/frame/FrameOwner.h"
10 #include "core/frame/FrameTypes.h" 10 #include "core/frame/FrameTypes.h"
11 #include "core/frame/FrameView.h" 11 #include "core/frame/FrameView.h"
12 #include "core/frame/Settings.h" 12 #include "core/frame/Settings.h"
13 #include "core/loader/DocumentLoader.h" 13 #include "core/loader/DocumentLoader.h"
14 #include "core/loader/EmptyClients.h" 14 #include "core/loader/EmptyClients.h"
15 #include "core/testing/DummyPageHolder.h" 15 #include "core/testing/DummyPageHolder.h"
16 #include "platform/UserGestureIndicator.h" 16 #include "platform/UserGestureIndicator.h"
17 #include "platform/testing/HistogramTester.h" 17 #include "platform/testing/HistogramTester.h"
18 #include "platform/testing/TestingPlatformSupport.h" 18 #include "platform/testing/TestingPlatformSupport.h"
19 #include "public/platform/WebAudioDevice.h" 19 #include "public/platform/WebAudioDevice.h"
20 #include "public/platform/WebAudioLatencyHint.h"
20 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
21 22
22 namespace blink { 23 namespace blink {
23 24
24 namespace { 25 namespace {
25 26
26 const char* const kCrossOriginMetric = "WebAudio.Autoplay.CrossOrigin"; 27 const char* const kCrossOriginMetric = "WebAudio.Autoplay.CrossOrigin";
28 const WebAudioLatencyHint kLatencyHintInteractive(
29 WebAudioLatencyHint::CategoryInteractive);
hongchan 2016/12/02 17:40:12 Can't this be a part of WebAudioLatencyHint?
Andrew MacPherson 2016/12/05 14:12:53 I have refactored this now to pass an AudioContext
27 30
28 class MockCrossOriginFrameLoaderClient final : public EmptyFrameLoaderClient { 31 class MockCrossOriginFrameLoaderClient final : public EmptyFrameLoaderClient {
29 public: 32 public:
30 static MockCrossOriginFrameLoaderClient* create(Frame* parent) { 33 static MockCrossOriginFrameLoaderClient* create(Frame* parent) {
31 return new MockCrossOriginFrameLoaderClient(parent); 34 return new MockCrossOriginFrameLoaderClient(parent);
32 } 35 }
33 36
34 DEFINE_INLINE_VIRTUAL_TRACE() { 37 DEFINE_INLINE_VIRTUAL_TRACE() {
35 visitor->trace(m_parent); 38 visitor->trace(m_parent);
36 EmptyFrameLoaderClient::trace(visitor); 39 EmptyFrameLoaderClient::trace(visitor);
37 } 40 }
38 41
39 Frame* parent() const override { return m_parent.get(); } 42 Frame* parent() const override { return m_parent.get(); }
40 Frame* top() const override { return m_parent.get(); } 43 Frame* top() const override { return m_parent.get(); }
41 44
42 private: 45 private:
43 explicit MockCrossOriginFrameLoaderClient(Frame* parent) : m_parent(parent) {} 46 explicit MockCrossOriginFrameLoaderClient(Frame* parent) : m_parent(parent) {}
44 47
45 Member<Frame> m_parent; 48 Member<Frame> m_parent;
46 }; 49 };
47 50
48 class MockWebAudioDevice : public WebAudioDevice { 51 class MockWebAudioDevice : public WebAudioDevice {
49 public: 52 public:
50 explicit MockWebAudioDevice(double sampleRate) : m_sampleRate(sampleRate) {} 53 explicit MockWebAudioDevice(double sampleRate, int framesPerBuffer)
54 : m_sampleRate(sampleRate), m_framesPerBuffer(framesPerBuffer) {}
51 ~MockWebAudioDevice() override = default; 55 ~MockWebAudioDevice() override = default;
52 56
53 void start() override {} 57 void start() override {}
54 void stop() override {} 58 void stop() override {}
55 double sampleRate() override { return m_sampleRate; } 59 double sampleRate() override { return m_sampleRate; }
60 int framesPerBuffer() override { return m_framesPerBuffer; }
56 61
57 private: 62 private:
58 double m_sampleRate; 63 double m_sampleRate;
64 int m_framesPerBuffer;
59 }; 65 };
60 66
61 class BaseAudioContextTestPlatform : public TestingPlatformSupport { 67 class BaseAudioContextTestPlatform : public TestingPlatformSupport {
62 public: 68 public:
63 WebAudioDevice* createAudioDevice(size_t bufferSize, 69 WebAudioDevice* createAudioDevice(unsigned numberOfInputChannels,
64 unsigned numberOfInputChannels,
65 unsigned numberOfChannels, 70 unsigned numberOfChannels,
66 double sampleRate, 71 const WebAudioLatencyHint& latencyHint,
67 WebAudioDevice::RenderCallback*, 72 WebAudioDevice::RenderCallback*,
68 const WebString& deviceId, 73 const WebString& deviceId,
69 const WebSecurityOrigin&) override { 74 const WebSecurityOrigin&) override {
70 return new MockWebAudioDevice(sampleRate); 75 return new MockWebAudioDevice(audioHardwareSampleRate(),
76 audioHardwareBufferSize());
71 } 77 }
72 78
73 double audioHardwareSampleRate() override { return 44100; } 79 double audioHardwareSampleRate() override { return 44100; }
80 size_t audioHardwareBufferSize() override { return 128; }
74 }; 81 };
75 82
76 } // anonymous namespace 83 } // anonymous namespace
77 84
78 class BaseAudioContextTest : public ::testing::Test { 85 class BaseAudioContextTest : public ::testing::Test {
79 protected: 86 protected:
80 using AutoplayStatus = BaseAudioContext::AutoplayStatus; 87 using AutoplayStatus = BaseAudioContext::AutoplayStatus;
81 88
82 void SetUp() override { 89 void SetUp() override {
83 m_dummyPageHolder = DummyPageHolder::create(); 90 m_dummyPageHolder = DummyPageHolder::create();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 137
131 Persistent<LocalFrame> m_childFrame; 138 Persistent<LocalFrame> m_childFrame;
132 Persistent<DocumentLoader> m_childDocumentLoader; 139 Persistent<DocumentLoader> m_childDocumentLoader;
133 140
134 BaseAudioContextTestPlatform m_testPlatform; 141 BaseAudioContextTestPlatform m_testPlatform;
135 }; 142 };
136 143
137 TEST_F(BaseAudioContextTest, AutoplayMetrics_NoRestriction) { 144 TEST_F(BaseAudioContextTest, AutoplayMetrics_NoRestriction) {
138 HistogramTester histogramTester; 145 HistogramTester histogramTester;
139 146
140 BaseAudioContext* audioContext = 147 BaseAudioContext* audioContext = BaseAudioContext::create(
141 BaseAudioContext::create(document(), ASSERT_NO_EXCEPTION); 148 document(), kLatencyHintInteractive, ASSERT_NO_EXCEPTION);
142 recordAutoplayStatus(audioContext); 149 recordAutoplayStatus(audioContext);
143 150
144 histogramTester.expectTotalCount(kCrossOriginMetric, 0); 151 histogramTester.expectTotalCount(kCrossOriginMetric, 0);
145 } 152 }
146 153
147 TEST_F(BaseAudioContextTest, AutoplayMetrics_CreateNoGesture) { 154 TEST_F(BaseAudioContextTest, AutoplayMetrics_CreateNoGesture) {
148 HistogramTester histogramTester; 155 HistogramTester histogramTester;
149 createChildFrame(); 156 createChildFrame();
150 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); 157 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true);
151 158
152 BaseAudioContext* audioContext = 159 BaseAudioContext* audioContext = BaseAudioContext::create(
153 BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); 160 childDocument(), kLatencyHintInteractive, ASSERT_NO_EXCEPTION);
154 recordAutoplayStatus(audioContext); 161 recordAutoplayStatus(audioContext);
155 162
156 histogramTester.expectBucketCount(kCrossOriginMetric, 163 histogramTester.expectBucketCount(kCrossOriginMetric,
157 AutoplayStatus::AutoplayStatusFailed, 1); 164 AutoplayStatus::AutoplayStatusFailed, 1);
158 histogramTester.expectTotalCount(kCrossOriginMetric, 1); 165 histogramTester.expectTotalCount(kCrossOriginMetric, 1);
159 } 166 }
160 167
161 TEST_F(BaseAudioContextTest, AutoplayMetrics_CallResumeNoGesture) { 168 TEST_F(BaseAudioContextTest, AutoplayMetrics_CallResumeNoGesture) {
162 HistogramTester histogramTester; 169 HistogramTester histogramTester;
163 createChildFrame(); 170 createChildFrame();
164 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); 171 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true);
165 172
166 ScriptState::Scope scope(getScriptStateFrom(childDocument())); 173 ScriptState::Scope scope(getScriptStateFrom(childDocument()));
167 174
168 BaseAudioContext* audioContext = 175 BaseAudioContext* audioContext = BaseAudioContext::create(
169 BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); 176 childDocument(), kLatencyHintInteractive, ASSERT_NO_EXCEPTION);
170 audioContext->resumeContext(getScriptStateFrom(childDocument())); 177 audioContext->resumeContext(getScriptStateFrom(childDocument()));
171 rejectPendingResolvers(audioContext); 178 rejectPendingResolvers(audioContext);
172 recordAutoplayStatus(audioContext); 179 recordAutoplayStatus(audioContext);
173 180
174 histogramTester.expectBucketCount(kCrossOriginMetric, 181 histogramTester.expectBucketCount(kCrossOriginMetric,
175 AutoplayStatus::AutoplayStatusFailed, 1); 182 AutoplayStatus::AutoplayStatusFailed, 1);
176 histogramTester.expectTotalCount(kCrossOriginMetric, 1); 183 histogramTester.expectTotalCount(kCrossOriginMetric, 1);
177 } 184 }
178 185
179 TEST_F(BaseAudioContextTest, AutoplayMetrics_CreateGesture) { 186 TEST_F(BaseAudioContextTest, AutoplayMetrics_CreateGesture) {
180 HistogramTester histogramTester; 187 HistogramTester histogramTester;
181 createChildFrame(); 188 createChildFrame();
182 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); 189 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true);
183 190
184 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create( 191 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create(
185 &childDocument(), UserGestureToken::NewGesture)); 192 &childDocument(), UserGestureToken::NewGesture));
186 193
187 BaseAudioContext* audioContext = 194 BaseAudioContext* audioContext = BaseAudioContext::create(
188 BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); 195 childDocument(), kLatencyHintInteractive, ASSERT_NO_EXCEPTION);
189 recordAutoplayStatus(audioContext); 196 recordAutoplayStatus(audioContext);
190 197
191 histogramTester.expectBucketCount(kCrossOriginMetric, 198 histogramTester.expectBucketCount(kCrossOriginMetric,
192 AutoplayStatus::AutoplayStatusSucceeded, 1); 199 AutoplayStatus::AutoplayStatusSucceeded, 1);
193 histogramTester.expectTotalCount(kCrossOriginMetric, 1); 200 histogramTester.expectTotalCount(kCrossOriginMetric, 1);
194 } 201 }
195 202
196 TEST_F(BaseAudioContextTest, AutoplayMetrics_CallResumeGesture) { 203 TEST_F(BaseAudioContextTest, AutoplayMetrics_CallResumeGesture) {
197 HistogramTester histogramTester; 204 HistogramTester histogramTester;
198 createChildFrame(); 205 createChildFrame();
199 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); 206 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true);
200 207
201 ScriptState::Scope scope(getScriptStateFrom(childDocument())); 208 ScriptState::Scope scope(getScriptStateFrom(childDocument()));
202 209
203 BaseAudioContext* audioContext = 210 BaseAudioContext* audioContext = BaseAudioContext::create(
204 BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); 211 childDocument(), kLatencyHintInteractive, ASSERT_NO_EXCEPTION);
205 212
206 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create( 213 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create(
207 &childDocument(), UserGestureToken::NewGesture)); 214 &childDocument(), UserGestureToken::NewGesture));
208 215
209 audioContext->resumeContext(getScriptStateFrom(childDocument())); 216 audioContext->resumeContext(getScriptStateFrom(childDocument()));
210 rejectPendingResolvers(audioContext); 217 rejectPendingResolvers(audioContext);
211 recordAutoplayStatus(audioContext); 218 recordAutoplayStatus(audioContext);
212 219
213 histogramTester.expectBucketCount(kCrossOriginMetric, 220 histogramTester.expectBucketCount(kCrossOriginMetric,
214 AutoplayStatus::AutoplayStatusSucceeded, 1); 221 AutoplayStatus::AutoplayStatusSucceeded, 1);
215 histogramTester.expectTotalCount(kCrossOriginMetric, 1); 222 histogramTester.expectTotalCount(kCrossOriginMetric, 1);
216 } 223 }
217 224
218 TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartNoGesture) { 225 TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartNoGesture) {
219 HistogramTester histogramTester; 226 HistogramTester histogramTester;
220 createChildFrame(); 227 createChildFrame();
221 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); 228 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true);
222 229
223 BaseAudioContext* audioContext = 230 BaseAudioContext* audioContext = BaseAudioContext::create(
224 BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); 231 childDocument(), kLatencyHintInteractive, ASSERT_NO_EXCEPTION);
225 audioContext->maybeRecordStartAttempt(); 232 audioContext->maybeRecordStartAttempt();
226 recordAutoplayStatus(audioContext); 233 recordAutoplayStatus(audioContext);
227 234
228 histogramTester.expectBucketCount(kCrossOriginMetric, 235 histogramTester.expectBucketCount(kCrossOriginMetric,
229 AutoplayStatus::AutoplayStatusFailed, 1); 236 AutoplayStatus::AutoplayStatusFailed, 1);
230 histogramTester.expectTotalCount(kCrossOriginMetric, 1); 237 histogramTester.expectTotalCount(kCrossOriginMetric, 1);
231 } 238 }
232 239
233 TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartGesture) { 240 TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartGesture) {
234 HistogramTester histogramTester; 241 HistogramTester histogramTester;
235 createChildFrame(); 242 createChildFrame();
236 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); 243 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true);
237 244
238 BaseAudioContext* audioContext = 245 BaseAudioContext* audioContext = BaseAudioContext::create(
239 BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); 246 childDocument(), kLatencyHintInteractive, ASSERT_NO_EXCEPTION);
240 247
241 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create( 248 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create(
242 &childDocument(), UserGestureToken::NewGesture)); 249 &childDocument(), UserGestureToken::NewGesture));
243 audioContext->maybeRecordStartAttempt(); 250 audioContext->maybeRecordStartAttempt();
244 recordAutoplayStatus(audioContext); 251 recordAutoplayStatus(audioContext);
245 252
246 histogramTester.expectBucketCount( 253 histogramTester.expectBucketCount(
247 kCrossOriginMetric, AutoplayStatus::AutoplayStatusFailedWithStart, 1); 254 kCrossOriginMetric, AutoplayStatus::AutoplayStatusFailedWithStart, 1);
248 histogramTester.expectTotalCount(kCrossOriginMetric, 1); 255 histogramTester.expectTotalCount(kCrossOriginMetric, 1);
249 } 256 }
250 257
251 TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartNoGestureThenSuccess) { 258 TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartNoGestureThenSuccess) {
252 HistogramTester histogramTester; 259 HistogramTester histogramTester;
253 createChildFrame(); 260 createChildFrame();
254 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); 261 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true);
255 262
256 ScriptState::Scope scope(getScriptStateFrom(childDocument())); 263 ScriptState::Scope scope(getScriptStateFrom(childDocument()));
257 264
258 BaseAudioContext* audioContext = 265 BaseAudioContext* audioContext = BaseAudioContext::create(
259 BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); 266 childDocument(), kLatencyHintInteractive, ASSERT_NO_EXCEPTION);
260 audioContext->maybeRecordStartAttempt(); 267 audioContext->maybeRecordStartAttempt();
261 268
262 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create( 269 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create(
263 &childDocument(), UserGestureToken::NewGesture)); 270 &childDocument(), UserGestureToken::NewGesture));
264 audioContext->resumeContext(getScriptStateFrom(childDocument())); 271 audioContext->resumeContext(getScriptStateFrom(childDocument()));
265 rejectPendingResolvers(audioContext); 272 rejectPendingResolvers(audioContext);
266 recordAutoplayStatus(audioContext); 273 recordAutoplayStatus(audioContext);
267 274
268 histogramTester.expectBucketCount(kCrossOriginMetric, 275 histogramTester.expectBucketCount(kCrossOriginMetric,
269 AutoplayStatus::AutoplayStatusSucceeded, 1); 276 AutoplayStatus::AutoplayStatusSucceeded, 1);
270 histogramTester.expectTotalCount(kCrossOriginMetric, 1); 277 histogramTester.expectTotalCount(kCrossOriginMetric, 1);
271 } 278 }
272 279
273 TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartGestureThenSucces) { 280 TEST_F(BaseAudioContextTest, AutoplayMetrics_NodeStartGestureThenSucces) {
274 HistogramTester histogramTester; 281 HistogramTester histogramTester;
275 createChildFrame(); 282 createChildFrame();
276 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true); 283 childDocument().settings()->setMediaPlaybackRequiresUserGesture(true);
277 284
278 ScriptState::Scope scope(getScriptStateFrom(childDocument())); 285 ScriptState::Scope scope(getScriptStateFrom(childDocument()));
279 286
280 BaseAudioContext* audioContext = 287 BaseAudioContext* audioContext = BaseAudioContext::create(
281 BaseAudioContext::create(childDocument(), ASSERT_NO_EXCEPTION); 288 childDocument(), kLatencyHintInteractive, ASSERT_NO_EXCEPTION);
282 289
283 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create( 290 UserGestureIndicator userGestureScope(DocumentUserGestureToken::create(
284 &childDocument(), UserGestureToken::NewGesture)); 291 &childDocument(), UserGestureToken::NewGesture));
285 audioContext->maybeRecordStartAttempt(); 292 audioContext->maybeRecordStartAttempt();
286 audioContext->resumeContext(getScriptStateFrom(childDocument())); 293 audioContext->resumeContext(getScriptStateFrom(childDocument()));
287 rejectPendingResolvers(audioContext); 294 rejectPendingResolvers(audioContext);
288 recordAutoplayStatus(audioContext); 295 recordAutoplayStatus(audioContext);
289 296
290 histogramTester.expectBucketCount(kCrossOriginMetric, 297 histogramTester.expectBucketCount(kCrossOriginMetric,
291 AutoplayStatus::AutoplayStatusSucceeded, 1); 298 AutoplayStatus::AutoplayStatusSucceeded, 1);
292 histogramTester.expectTotalCount(kCrossOriginMetric, 1); 299 histogramTester.expectTotalCount(kCrossOriginMetric, 1);
293 } 300 }
294 301
295 } // namespace blink 302 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698