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

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: git cl format 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);
103 107
104 protected: 108 protected:
105 // Used to clean up TLS pointers that the test(s) will initialize. 109 // Used to clean up TLS pointers that the test(s) will initialize.
106 // Must remain the first member of this class. 110 // Must remain the first member of this class.
107 base::ShadowingAtExitManager at_exit_manager_; 111 base::ShadowingAtExitManager at_exit_manager_;
108 base::MessageLoopForIO io_loop_; 112 base::MessageLoopForIO io_loop_;
109 AudioParameters default_audio_parameters_; 113 AudioParameters default_audio_parameters_;
110 StrictMock<MockRenderCallback> callback_; 114 StrictMock<MockRenderCallback> callback_;
111 MockAudioOutputIPC* audio_output_ipc_; // owned by audio_device_ 115 MockAudioOutputIPC* audio_output_ipc_; // owned by audio_device_
112 scoped_refptr<AudioOutputDevice> audio_device_; 116 scoped_refptr<AudioOutputDevice> audio_device_;
113 OutputDeviceStatus device_status_; 117 OutputDeviceStatus device_status_;
118 OutputDeviceInfo device_info_;
114 119
115 private: 120 private:
116 int CalculateMemorySize(); 121 int CalculateMemorySize();
117 122
118 SharedMemory shared_memory_; 123 SharedMemory shared_memory_;
119 CancelableSyncSocket browser_socket_; 124 CancelableSyncSocket browser_socket_;
120 CancelableSyncSocket renderer_socket_; 125 CancelableSyncSocket renderer_socket_;
121 126
122 DISALLOW_COPY_AND_ASSIGN(AudioOutputDeviceTest); 127 DISALLOW_COPY_AND_ASSIGN(AudioOutputDeviceTest);
123 }; 128 };
(...skipping 25 matching lines...) Expand all
149 audio_device_->RequestDeviceAuthorization(); 154 audio_device_->RequestDeviceAuthorization();
150 io_loop_.RunUntilIdle(); 155 io_loop_.RunUntilIdle();
151 156
152 // Simulate response from browser 157 // Simulate response from browser
153 OutputDeviceStatus device_status = 158 OutputDeviceStatus device_status =
154 (device_id == kUnauthorizedDeviceId) 159 (device_id == kUnauthorizedDeviceId)
155 ? OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED 160 ? OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED
156 : OUTPUT_DEVICE_STATUS_OK; 161 : OUTPUT_DEVICE_STATUS_OK;
157 ReceiveAuthorization(device_status); 162 ReceiveAuthorization(device_status);
158 163
159 audio_device_->Initialize(default_audio_parameters_, 164 InitializeAudioDevice();
160 &callback_);
161 } 165 }
162 166
163 void AudioOutputDeviceTest::ReceiveAuthorization(OutputDeviceStatus status) { 167 void AudioOutputDeviceTest::ReceiveAuthorization(OutputDeviceStatus status) {
164 device_status_ = status; 168 device_status_ = status;
165 if (device_status_ != OUTPUT_DEVICE_STATUS_OK) 169 if (device_status_ != OUTPUT_DEVICE_STATUS_OK)
166 EXPECT_CALL(*audio_output_ipc_, CloseStream()); 170 EXPECT_CALL(*audio_output_ipc_, CloseStream());
167 171
168 audio_device_->OnDeviceAuthorized(device_status_, default_audio_parameters_, 172 audio_device_->OnDeviceAuthorized(device_status_, default_audio_parameters_,
169 kDefaultDeviceId); 173 kDefaultDeviceId);
170 io_loop_.RunUntilIdle(); 174 io_loop_.RunUntilIdle();
171 } 175 }
172 176
173 void AudioOutputDeviceTest::StartAudioDevice() { 177 void AudioOutputDeviceTest::StartAudioDevice() {
174 if (device_status_ == OUTPUT_DEVICE_STATUS_OK) 178 if (device_status_ == OUTPUT_DEVICE_STATUS_OK)
175 EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _)); 179 EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _));
176 else 180 else
177 EXPECT_CALL(callback_, OnRenderError()); 181 EXPECT_CALL(callback_, OnRenderError());
178 182
179 audio_device_->Start(); 183 audio_device_->Start();
180 io_loop_.RunUntilIdle(); 184 io_loop_.RunUntilIdle();
181 } 185 }
182 186
187 void AudioOutputDeviceTest::InitializeAudioDevice() {
188 audio_device_->Initialize(default_audio_parameters_, &callback_);
189 }
190
183 void AudioOutputDeviceTest::CreateStream() { 191 void AudioOutputDeviceTest::CreateStream() {
184 const int kMemorySize = CalculateMemorySize(); 192 const int kMemorySize = CalculateMemorySize();
185 193
186 ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize)); 194 ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize));
187 memset(shared_memory_.memory(), 0xff, kMemorySize); 195 memset(shared_memory_.memory(), 0xff, kMemorySize);
188 196
189 ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket_, 197 ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket_,
190 &renderer_socket_)); 198 &renderer_socket_));
191 199
192 // Create duplicates of the handles we pass to AudioOutputDevice since 200 // Create duplicates of the handles we pass to AudioOutputDevice since
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 } 244 }
237 245
238 void AudioOutputDeviceTest::StopAudioDevice() { 246 void AudioOutputDeviceTest::StopAudioDevice() {
239 if (device_status_ == OUTPUT_DEVICE_STATUS_OK) 247 if (device_status_ == OUTPUT_DEVICE_STATUS_OK)
240 EXPECT_CALL(*audio_output_ipc_, CloseStream()); 248 EXPECT_CALL(*audio_output_ipc_, CloseStream());
241 249
242 audio_device_->Stop(); 250 audio_device_->Stop();
243 io_loop_.RunUntilIdle(); 251 io_loop_.RunUntilIdle();
244 } 252 }
245 253
254 void AudioOutputDeviceTest::GetOutputDeviceInfo(base::WaitableEvent* event) {
255 device_info_ = audio_device_->GetOutputDeviceInfo();
256 event->Signal();
257 }
258
246 TEST_P(AudioOutputDeviceTest, Initialize) { 259 TEST_P(AudioOutputDeviceTest, Initialize) {
247 // Tests that the object can be constructed, initialized and destructed 260 // Tests that the object can be constructed, initialized and destructed
248 // without having ever been started. 261 // without having ever been started.
249 StopAudioDevice(); 262 StopAudioDevice();
250 } 263 }
251 264
252 // Calls Start() followed by an immediate Stop() and check for the basic message 265 // Calls Start() followed by an immediate Stop() and check for the basic message
253 // filter messages being sent in that case. 266 // filter messages being sent in that case.
254 TEST_P(AudioOutputDeviceTest, StartStop) { 267 TEST_P(AudioOutputDeviceTest, StartStop) {
255 StartAudioDevice(); 268 StartAudioDevice();
256 StopAudioDevice(); 269 StopAudioDevice();
257 } 270 }
258 271
259 // AudioOutputDevice supports multiple start/stop sequences. 272 // AudioOutputDevice supports multiple start/stop sequences.
260 TEST_P(AudioOutputDeviceTest, StartStopStartStop) { 273 TEST_P(AudioOutputDeviceTest, StartStopStartStop) {
261 StartAudioDevice(); 274 StartAudioDevice();
262 StopAudioDevice(); 275 StopAudioDevice();
276 InitializeAudioDevice();
263 StartAudioDevice(); 277 StartAudioDevice();
264 StopAudioDevice(); 278 StopAudioDevice();
265 } 279 }
266 280
267 // Simulate receiving OnStreamCreated() prior to processing ShutDownOnIOThread() 281 // Simulate receiving OnStreamCreated() prior to processing ShutDownOnIOThread()
268 // on the IO loop. 282 // on the IO loop.
269 TEST_P(AudioOutputDeviceTest, StopBeforeRender) { 283 TEST_P(AudioOutputDeviceTest, StopBeforeRender) {
270 StartAudioDevice(); 284 StartAudioDevice();
271 285
272 // Call Stop() but don't run the IO loop yet. 286 // Call Stop() but don't run the IO loop yet.
273 audio_device_->Stop(); 287 audio_device_->Stop();
274 288
275 // Expect us to shutdown IPC but not to render anything despite the stream 289 // Expect to play the stream and to shutdown IPC but not to render anything
276 // getting created. 290 // despite the stream getting created.
291 EXPECT_CALL(*audio_output_ipc_, PlayStream());
277 EXPECT_CALL(*audio_output_ipc_, CloseStream()); 292 EXPECT_CALL(*audio_output_ipc_, CloseStream());
278 CreateStream(); 293 CreateStream();
279 } 294 }
280 295
281 // Full test with output only. 296 // Full test with output only.
282 TEST_P(AudioOutputDeviceTest, CreateStream) { 297 TEST_P(AudioOutputDeviceTest, CreateStream) {
283 StartAudioDevice(); 298 StartAudioDevice();
284 ExpectRenderCallback(); 299 ExpectRenderCallback();
285 CreateStream(); 300 CreateStream();
286 WaitUntilRenderCallback(); 301 WaitUntilRenderCallback();
287 StopAudioDevice(); 302 StopAudioDevice();
288 } 303 }
289 304
290 // Full test with output only with nondefault device. 305 // Full test with output only with nondefault device.
291 TEST_P(AudioOutputDeviceTest, NonDefaultCreateStream) { 306 TEST_P(AudioOutputDeviceTest, NonDefaultCreateStream) {
307 StopAudioDevice();
o1ka 2016/05/03 15:47:32 Here and below: this does not look like a natural
Henrik Grunell 2016/05/04 09:05:12 Agree. A general note on this file is that I wasn'
292 SetDevice(kNonDefaultDeviceId); 308 SetDevice(kNonDefaultDeviceId);
293 StartAudioDevice(); 309 StartAudioDevice();
294 ExpectRenderCallback(); 310 ExpectRenderCallback();
295 CreateStream(); 311 CreateStream();
296 WaitUntilRenderCallback(); 312 WaitUntilRenderCallback();
297 StopAudioDevice(); 313 StopAudioDevice();
298 } 314 }
299 315
300 // Multiple start/stop with nondefault device 316 // Multiple start/stop with nondefault device
301 TEST_P(AudioOutputDeviceTest, NonDefaultStartStopStartStop) { 317 TEST_P(AudioOutputDeviceTest, NonDefaultStartStopStartStop) {
318 StopAudioDevice();
302 SetDevice(kNonDefaultDeviceId); 319 SetDevice(kNonDefaultDeviceId);
303 StartAudioDevice(); 320 StartAudioDevice();
304 StopAudioDevice(); 321 StopAudioDevice();
322 InitializeAudioDevice();
305 323
306 EXPECT_CALL(*audio_output_ipc_, 324 EXPECT_CALL(*audio_output_ipc_,
307 RequestDeviceAuthorization(audio_device_.get(), 0, _, _)); 325 RequestDeviceAuthorization(audio_device_.get(), 0, _, _));
308 StartAudioDevice(); 326 StartAudioDevice();
309 // Simulate reply from browser 327 // Simulate reply from browser
310 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK); 328 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK);
311 329
312 StopAudioDevice(); 330 StopAudioDevice();
313 } 331 }
314 332
315 TEST_P(AudioOutputDeviceTest, UnauthorizedDevice) { 333 TEST_P(AudioOutputDeviceTest, UnauthorizedDevice) {
334 StopAudioDevice();
316 SetDevice(kUnauthorizedDeviceId); 335 SetDevice(kUnauthorizedDeviceId);
317 StartAudioDevice(); 336 StartAudioDevice();
318 StopAudioDevice(); 337 StopAudioDevice();
319 } 338 }
320 339
340 TEST_P(AudioOutputDeviceTest, GetOutputDeviceInfo) {
341 // AudioOutputDevice::GetOutputDeviceInfo must be called on a different thread
342 // than the task runner given to it.
o1ka 2016/05/03 15:47:32 Comment is a bit unclear. GetOutputDeviceInfo must
Henrik Grunell 2016/05/04 09:05:12 Done.
343 base::WaitableEvent event(true, false);
344 base::Thread thread("get_output_device_info");
345 thread.Start();
346
o1ka 2016/05/03 15:47:32 Probably you should initialize device_info_ with s
Henrik Grunell 2016/05/04 09:05:12 Good point. Done.
347 // Get device info on the other thread and wait until finished.
348 thread.task_runner()->PostTask(
349 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo,
350 base::Unretained(this), &event));
351 event.Wait();
352
353 EXPECT_EQ(kDefaultDeviceId, device_info_.device_id());
354 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status());
355 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_));
356
357 StopAudioDevice();
358 }
359
360 TEST_P(AudioOutputDeviceTest, NonDefaultGetOutputDeviceInfo) {
361 StopAudioDevice();
362 SetDevice(kNonDefaultDeviceId);
363
364 // AudioOutputDevice::GetOutputDeviceInfo must be called on a different thread
365 // than the task runner given to it.
366 base::WaitableEvent event(true, false);
367 base::Thread thread("get_output_device_info");
368 thread.Start();
369
370 // Get device info on the other thread and wait until finished.
371 thread.task_runner()->PostTask(
372 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo,
373 base::Unretained(this), &event));
374 event.Wait();
375
376 EXPECT_EQ(kNonDefaultDeviceId, device_info_.device_id());
377 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status());
378 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_));
379
380 StopAudioDevice();
381 }
382
383 TEST_P(AudioOutputDeviceTest, MultipleNonDefaultGetOutputDeviceInfo) {
384 StopAudioDevice();
385 SetDevice(kNonDefaultDeviceId);
386
387 // AudioOutputDevice::GetOutputDeviceInfo must be called on a different thread
388 // than the task runner given to it.
389 base::WaitableEvent event(true, false);
390 base::Thread thread("get_output_device_info");
391 thread.Start();
392
393 // Get device info on the other thread and wait until finished.
394 thread.task_runner()->PostTask(
395 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo,
396 base::Unretained(this), &event));
397 event.Wait();
398
399 EXPECT_EQ(kNonDefaultDeviceId, device_info_.device_id());
400 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status());
401 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_));
402
403 device_info_ = OutputDeviceInfo();
404 event.Reset();
405
406 // Get device info on the other thread and wait until finished.
407 thread.task_runner()->PostTask(
408 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo,
409 base::Unretained(this), &event));
410 event.Wait();
411
412 EXPECT_EQ(kNonDefaultDeviceId, device_info_.device_id());
413 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status());
414 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_));
415
416 StopAudioDevice();
417 }
418
321 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false)); 419 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false));
322 420
323 } // namespace media. 421 } // 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