Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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. |
| OLD | NEW |