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

Side by Side Diff: media/audio/audio_output_device_unittest.cc

Issue 1703473002: Make AudioOutputDevice restartable and reinitializable (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@new_mixing
Patch Set: Fixed comments in olka@'s CL. Updated some comments. Created 4 years, 7 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <stdint.h> 5 #include <stdint.h>
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/at_exit.h" 9 #include "base/at_exit.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/callback.h" 11 #include "base/callback.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/memory/shared_memory.h" 14 #include "base/memory/shared_memory.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/process/process_handle.h" 16 #include "base/process/process_handle.h"
17 #include "base/sync_socket.h" 17 #include "base/sync_socket.h"
18 #include "base/synchronization/waitable_event.h"
18 #include "base/task_runner.h" 19 #include "base/task_runner.h"
19 #include "base/test/test_timeouts.h" 20 #include "base/test/test_timeouts.h"
20 #include "base/thread_task_runner_handle.h" 21 #include "base/thread_task_runner_handle.h"
22 #include "base/threading/thread.h"
21 #include "media/audio/audio_output_device.h" 23 #include "media/audio/audio_output_device.h"
22 #include "media/audio/sample_rates.h" 24 #include "media/audio/sample_rates.h"
23 #include "testing/gmock/include/gmock/gmock.h" 25 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gmock_mutant.h" 26 #include "testing/gmock_mutant.h"
25 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
26 28
27 using base::CancelableSyncSocket; 29 using base::CancelableSyncSocket;
28 using base::SharedMemory; 30 using base::SharedMemory;
29 using base::SyncSocket; 31 using base::SyncSocket;
30 using testing::_; 32 using testing::_;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 88
87 } // namespace. 89 } // namespace.
88 90
89 class AudioOutputDeviceTest 91 class AudioOutputDeviceTest
90 : public testing::Test, 92 : public testing::Test,
91 public testing::WithParamInterface<bool> { 93 public testing::WithParamInterface<bool> {
92 public: 94 public:
93 AudioOutputDeviceTest(); 95 AudioOutputDeviceTest();
94 ~AudioOutputDeviceTest(); 96 ~AudioOutputDeviceTest();
95 97
98 void SetDevice(const std::string& device_id);
96 void ReceiveAuthorization(OutputDeviceStatus device_status); 99 void ReceiveAuthorization(OutputDeviceStatus device_status);
100 void InitializeAudioDevice();
97 void StartAudioDevice(); 101 void StartAudioDevice();
98 void CreateStream(); 102 void CreateStream();
99 void ExpectRenderCallback(); 103 void ExpectRenderCallback();
100 void WaitUntilRenderCallback(); 104 void WaitUntilRenderCallback();
101 void StopAudioDevice(); 105 void StopAudioDevice();
102 void SetDevice(const std::string& device_id); 106 void GetOutputDeviceInfo(base::WaitableEvent* event);
107 void SetDeviceInfoToGarbage();
103 108
104 protected: 109 protected:
105 // Used to clean up TLS pointers that the test(s) will initialize. 110 // Used to clean up TLS pointers that the test(s) will initialize.
106 // Must remain the first member of this class. 111 // Must remain the first member of this class.
107 base::ShadowingAtExitManager at_exit_manager_; 112 base::ShadowingAtExitManager at_exit_manager_;
108 base::MessageLoopForIO io_loop_; 113 base::MessageLoopForIO io_loop_;
109 AudioParameters default_audio_parameters_; 114 AudioParameters default_audio_parameters_;
110 StrictMock<MockRenderCallback> callback_; 115 StrictMock<MockRenderCallback> callback_;
111 MockAudioOutputIPC* audio_output_ipc_; // owned by audio_device_ 116 MockAudioOutputIPC* audio_output_ipc_; // owned by audio_device_
112 scoped_refptr<AudioOutputDevice> audio_device_; 117 scoped_refptr<AudioOutputDevice> audio_device_;
113 OutputDeviceStatus device_status_; 118 OutputDeviceStatus device_status_;
119 OutputDeviceInfo device_info_;
114 120
115 private: 121 private:
116 int CalculateMemorySize(); 122 int CalculateMemorySize();
117 123
118 SharedMemory shared_memory_; 124 SharedMemory shared_memory_;
119 CancelableSyncSocket browser_socket_; 125 CancelableSyncSocket browser_socket_;
120 CancelableSyncSocket renderer_socket_; 126 CancelableSyncSocket renderer_socket_;
121 127
122 DISALLOW_COPY_AND_ASSIGN(AudioOutputDeviceTest); 128 DISALLOW_COPY_AND_ASSIGN(AudioOutputDeviceTest);
123 }; 129 };
124 130
125 int AudioOutputDeviceTest::CalculateMemorySize() { 131 int AudioOutputDeviceTest::CalculateMemorySize() {
126 // Calculate output memory size. 132 // Calculate output memory size.
127 return sizeof(AudioOutputBufferParameters) + 133 return sizeof(AudioOutputBufferParameters) +
128 AudioBus::CalculateMemorySize(default_audio_parameters_); 134 AudioBus::CalculateMemorySize(default_audio_parameters_);
129 } 135 }
130 136
131 AudioOutputDeviceTest::AudioOutputDeviceTest() 137 AudioOutputDeviceTest::AudioOutputDeviceTest()
132 : device_status_(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL) { 138 : device_status_(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL) {
133 default_audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LINEAR, 139 default_audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LINEAR,
134 CHANNEL_LAYOUT_STEREO, 48000, 16, 1024); 140 CHANNEL_LAYOUT_STEREO, 48000, 16, 1024);
135 SetDevice(kDefaultDeviceId); 141 SetDeviceInfoToGarbage();
136 } 142 }
137 143
138 AudioOutputDeviceTest::~AudioOutputDeviceTest() { 144 AudioOutputDeviceTest::~AudioOutputDeviceTest() {
139 audio_device_ = NULL; 145 audio_device_ = NULL;
140 } 146 }
141 147
142 void AudioOutputDeviceTest::SetDevice(const std::string& device_id) { 148 void AudioOutputDeviceTest::SetDevice(const std::string& device_id) {
143 audio_output_ipc_ = new MockAudioOutputIPC(); 149 audio_output_ipc_ = new MockAudioOutputIPC();
144 audio_device_ = new AudioOutputDevice(base::WrapUnique(audio_output_ipc_), 150 audio_device_ = new AudioOutputDevice(base::WrapUnique(audio_output_ipc_),
145 io_loop_.task_runner(), 0, device_id, 151 io_loop_.task_runner(), 0, device_id,
146 url::Origin()); 152 url::Origin());
147 EXPECT_CALL(*audio_output_ipc_, 153 EXPECT_CALL(*audio_output_ipc_,
148 RequestDeviceAuthorization(audio_device_.get(), 0, device_id, _)); 154 RequestDeviceAuthorization(audio_device_.get(), 0, device_id, _));
149 audio_device_->RequestDeviceAuthorization(); 155 audio_device_->RequestDeviceAuthorization();
150 io_loop_.RunUntilIdle(); 156 io_loop_.RunUntilIdle();
151 157
152 // Simulate response from browser 158 // Simulate response from browser
153 OutputDeviceStatus device_status = 159 OutputDeviceStatus device_status =
154 (device_id == kUnauthorizedDeviceId) 160 (device_id == kUnauthorizedDeviceId)
155 ? OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED 161 ? OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED
156 : OUTPUT_DEVICE_STATUS_OK; 162 : OUTPUT_DEVICE_STATUS_OK;
157 ReceiveAuthorization(device_status); 163 ReceiveAuthorization(device_status);
158 164
159 audio_device_->Initialize(default_audio_parameters_, 165 InitializeAudioDevice();
160 &callback_);
161 } 166 }
162 167
163 void AudioOutputDeviceTest::ReceiveAuthorization(OutputDeviceStatus status) { 168 void AudioOutputDeviceTest::ReceiveAuthorization(OutputDeviceStatus status) {
164 device_status_ = status; 169 device_status_ = status;
165 if (device_status_ != OUTPUT_DEVICE_STATUS_OK) 170 if (device_status_ != OUTPUT_DEVICE_STATUS_OK)
166 EXPECT_CALL(*audio_output_ipc_, CloseStream()); 171 EXPECT_CALL(*audio_output_ipc_, CloseStream());
167 172
168 audio_device_->OnDeviceAuthorized(device_status_, default_audio_parameters_, 173 audio_device_->OnDeviceAuthorized(device_status_, default_audio_parameters_,
169 kDefaultDeviceId); 174 kDefaultDeviceId);
170 io_loop_.RunUntilIdle(); 175 io_loop_.RunUntilIdle();
171 } 176 }
172 177
173 void AudioOutputDeviceTest::StartAudioDevice() { 178 void AudioOutputDeviceTest::StartAudioDevice() {
174 if (device_status_ == OUTPUT_DEVICE_STATUS_OK) 179 if (device_status_ == OUTPUT_DEVICE_STATUS_OK)
175 EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _)); 180 EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _));
176 else 181 else
177 EXPECT_CALL(callback_, OnRenderError()); 182 EXPECT_CALL(callback_, OnRenderError());
178 183
179 audio_device_->Start(); 184 audio_device_->Start();
180 io_loop_.RunUntilIdle(); 185 io_loop_.RunUntilIdle();
181 } 186 }
182 187
188 void AudioOutputDeviceTest::InitializeAudioDevice() {
189 audio_device_->Initialize(default_audio_parameters_, &callback_);
190 }
191
183 void AudioOutputDeviceTest::CreateStream() { 192 void AudioOutputDeviceTest::CreateStream() {
184 const int kMemorySize = CalculateMemorySize(); 193 const int kMemorySize = CalculateMemorySize();
185 194
186 ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize)); 195 ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize));
187 memset(shared_memory_.memory(), 0xff, kMemorySize); 196 memset(shared_memory_.memory(), 0xff, kMemorySize);
188 197
189 ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket_, 198 ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket_,
190 &renderer_socket_)); 199 &renderer_socket_));
191 200
192 // Create duplicates of the handles we pass to AudioOutputDevice since 201 // Create duplicates of the handles we pass to AudioOutputDevice since
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 } 245 }
237 246
238 void AudioOutputDeviceTest::StopAudioDevice() { 247 void AudioOutputDeviceTest::StopAudioDevice() {
239 if (device_status_ == OUTPUT_DEVICE_STATUS_OK) 248 if (device_status_ == OUTPUT_DEVICE_STATUS_OK)
240 EXPECT_CALL(*audio_output_ipc_, CloseStream()); 249 EXPECT_CALL(*audio_output_ipc_, CloseStream());
241 250
242 audio_device_->Stop(); 251 audio_device_->Stop();
243 io_loop_.RunUntilIdle(); 252 io_loop_.RunUntilIdle();
244 } 253 }
245 254
255 void AudioOutputDeviceTest::GetOutputDeviceInfo(base::WaitableEvent* event) {
256 device_info_ = audio_device_->GetOutputDeviceInfo();
257 event->Signal();
258 }
259
260 void AudioOutputDeviceTest::SetDeviceInfoToGarbage() {
261 device_info_ =
262 OutputDeviceInfo("qwertyuiop", OUTPUT_DEVICE_STATUS_ERROR_INTERNAL,
263 AudioParameters(AudioParameters::AUDIO_FAKE,
264 CHANNEL_LAYOUT_NONE, 1, 2, 3));
265 }
266
246 TEST_P(AudioOutputDeviceTest, Initialize) { 267 TEST_P(AudioOutputDeviceTest, Initialize) {
247 // Tests that the object can be constructed, initialized and destructed 268 // Tests that the object can be constructed, initialized and destructed
248 // without having ever been started. 269 // without having ever been started.
270 SetDevice(kDefaultDeviceId);
249 StopAudioDevice(); 271 StopAudioDevice();
250 } 272 }
251 273
252 // Calls Start() followed by an immediate Stop() and check for the basic message 274 // Calls Start() followed by an immediate Stop() and check for the basic message
253 // filter messages being sent in that case. 275 // filter messages being sent in that case.
254 TEST_P(AudioOutputDeviceTest, StartStop) { 276 TEST_P(AudioOutputDeviceTest, StartStop) {
277 SetDevice(kDefaultDeviceId);
255 StartAudioDevice(); 278 StartAudioDevice();
256 StopAudioDevice(); 279 StopAudioDevice();
257 } 280 }
258 281
259 // AudioOutputDevice supports multiple start/stop sequences. 282 // AudioOutputDevice supports multiple intialize/start/stop sequences.
260 TEST_P(AudioOutputDeviceTest, StartStopStartStop) { 283 TEST_P(AudioOutputDeviceTest, StartStopStartStop) {
284 SetDevice(kDefaultDeviceId);
261 StartAudioDevice(); 285 StartAudioDevice();
262 StopAudioDevice(); 286 StopAudioDevice();
287 InitializeAudioDevice();
288 EXPECT_CALL(*audio_output_ipc_,
289 RequestDeviceAuthorization(audio_device_.get(), 0, _, _));
263 StartAudioDevice(); 290 StartAudioDevice();
291 // Simulate reply from browser
292 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK);
264 StopAudioDevice(); 293 StopAudioDevice();
265 } 294 }
266 295
267 // Simulate receiving OnStreamCreated() prior to processing ShutDownOnIOThread() 296 // Simulate receiving OnStreamCreated() prior to processing ShutDownOnIOThread()
268 // on the IO loop. 297 // on the IO loop.
269 TEST_P(AudioOutputDeviceTest, StopBeforeRender) { 298 TEST_P(AudioOutputDeviceTest, StopBeforeRender) {
299 SetDevice(kDefaultDeviceId);
270 StartAudioDevice(); 300 StartAudioDevice();
271 301
272 // Call Stop() but don't run the IO loop yet. 302 // Call Stop() but don't run the IO loop yet.
273 audio_device_->Stop(); 303 audio_device_->Stop();
274 304
275 // Expect us to shutdown IPC but not to render anything despite the stream 305 // Expect to play the stream and to shutdown IPC but not to render anything
276 // getting created. 306 // despite the stream getting created.
307 EXPECT_CALL(*audio_output_ipc_, PlayStream());
277 EXPECT_CALL(*audio_output_ipc_, CloseStream()); 308 EXPECT_CALL(*audio_output_ipc_, CloseStream());
278 CreateStream(); 309 CreateStream();
279 } 310 }
280 311
281 // Full test with output only. 312 // Full test with output only.
282 TEST_P(AudioOutputDeviceTest, CreateStream) { 313 TEST_P(AudioOutputDeviceTest, CreateStream) {
314 SetDevice(kDefaultDeviceId);
283 StartAudioDevice(); 315 StartAudioDevice();
284 ExpectRenderCallback(); 316 ExpectRenderCallback();
285 CreateStream(); 317 CreateStream();
286 WaitUntilRenderCallback(); 318 WaitUntilRenderCallback();
287 StopAudioDevice(); 319 StopAudioDevice();
288 } 320 }
289 321
290 // Full test with output only with nondefault device. 322 // Full test with output only with nondefault device.
291 TEST_P(AudioOutputDeviceTest, NonDefaultCreateStream) { 323 TEST_P(AudioOutputDeviceTest, NonDefaultCreateStream) {
292 SetDevice(kNonDefaultDeviceId); 324 SetDevice(kNonDefaultDeviceId);
293 StartAudioDevice(); 325 StartAudioDevice();
294 ExpectRenderCallback(); 326 ExpectRenderCallback();
295 CreateStream(); 327 CreateStream();
296 WaitUntilRenderCallback(); 328 WaitUntilRenderCallback();
297 StopAudioDevice(); 329 StopAudioDevice();
298 } 330 }
299 331
300 // Multiple start/stop with nondefault device 332 // Multiple start/stop with nondefault device
301 TEST_P(AudioOutputDeviceTest, NonDefaultStartStopStartStop) { 333 TEST_P(AudioOutputDeviceTest, NonDefaultStartStopStartStop) {
302 SetDevice(kNonDefaultDeviceId); 334 SetDevice(kNonDefaultDeviceId);
303 StartAudioDevice(); 335 StartAudioDevice();
304 StopAudioDevice(); 336 StopAudioDevice();
305 337 InitializeAudioDevice();
306 EXPECT_CALL(*audio_output_ipc_, 338 EXPECT_CALL(*audio_output_ipc_,
307 RequestDeviceAuthorization(audio_device_.get(), 0, _, _)); 339 RequestDeviceAuthorization(audio_device_.get(), 0, _, _));
308 StartAudioDevice(); 340 StartAudioDevice();
309 // Simulate reply from browser 341 // Simulate reply from browser
310 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK); 342 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK);
311
312 StopAudioDevice(); 343 StopAudioDevice();
313 } 344 }
314 345
315 TEST_P(AudioOutputDeviceTest, UnauthorizedDevice) { 346 TEST_P(AudioOutputDeviceTest, UnauthorizedDevice) {
316 SetDevice(kUnauthorizedDeviceId); 347 SetDevice(kUnauthorizedDeviceId);
317 StartAudioDevice(); 348 StartAudioDevice();
318 StopAudioDevice(); 349 StopAudioDevice();
319 } 350 }
320 351
352 TEST_P(AudioOutputDeviceTest, MultipleStartStopDifferentDevices) {
353 SetDevice(kDefaultDeviceId);
354 StartAudioDevice();
355 StopAudioDevice();
356
357 SetDevice(kNonDefaultDeviceId);
358 StartAudioDevice();
359 StopAudioDevice();
360
361 SetDevice(kUnauthorizedDeviceId);
362 StartAudioDevice();
363 StopAudioDevice();
364
365 SetDevice(kDefaultDeviceId);
366 StartAudioDevice();
367 StopAudioDevice();
368 }
369
370 // Test getting output device info.
371 // GetOutputDeviceInfo() must be called on a different thread than the IO task
372 // runner we hand to the AudioOutputDevice. Since we use the task runner for the
373 // thread the test runs on as the IO task runner, we must spin up a new thread
374 // and call GetOutputDeviceInfo() on that.
375 TEST_P(AudioOutputDeviceTest, GetOutputDeviceInfo) {
376 SetDevice(kDefaultDeviceId);
377
378 base::WaitableEvent event(true, false);
379 base::Thread thread("get_output_device_info");
380 thread.Start();
381
382 // Get device info on the other thread and wait until finished.
383 thread.task_runner()->PostTask(
384 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo,
385 base::Unretained(this), &event));
386 event.Wait();
387
388 EXPECT_EQ(kDefaultDeviceId, device_info_.device_id());
389 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status());
390 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_));
391
392 StopAudioDevice();
393 }
394
395 TEST_P(AudioOutputDeviceTest, NonDefaultGetOutputDeviceInfo) {
396 SetDevice(kNonDefaultDeviceId);
397
398 // AudioOutputDevice::GetOutputDeviceInfo must be called on a different thread
399 // than the task runner given to it.
400 base::WaitableEvent event(true, false);
401 base::Thread thread("get_output_device_info");
402 thread.Start();
403
404 // Get device info on the other thread and wait until finished.
405 thread.task_runner()->PostTask(
406 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo,
407 base::Unretained(this), &event));
408 event.Wait();
409
410 EXPECT_EQ(kNonDefaultDeviceId, device_info_.device_id());
411 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status());
412 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_));
413
414 StopAudioDevice();
415 }
416
417 TEST_P(AudioOutputDeviceTest, MultipleNonDefaultGetOutputDeviceInfo) {
418 SetDevice(kNonDefaultDeviceId);
419
420 // AudioOutputDevice::GetOutputDeviceInfo must be called on a different thread
421 // than the task runner given to it.
422 base::WaitableEvent event(true, false);
423 base::Thread thread("get_output_device_info");
424 thread.Start();
425
426 // Get device info on the other thread and wait until finished.
427 thread.task_runner()->PostTask(
428 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo,
429 base::Unretained(this), &event));
430 event.Wait();
431
432 EXPECT_EQ(kNonDefaultDeviceId, device_info_.device_id());
433 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status());
434 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_));
435
436 SetDeviceInfoToGarbage();
437 event.Reset();
438
439 // Get device info on the other thread and wait until finished.
440 thread.task_runner()->PostTask(
441 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo,
442 base::Unretained(this), &event));
443 event.Wait();
444
445 EXPECT_EQ(kNonDefaultDeviceId, device_info_.device_id());
446 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status());
447 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_));
448
449 StopAudioDevice();
450 }
451
321 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false)); 452 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false));
322 453
323 } // namespace media. 454 } // namespace media.
OLDNEW
« media/audio/audio_output_device.cc ('K') | « media/audio/audio_output_device.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698