| 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" |
| 21 #include "base/threading/thread.h" |
| 20 #include "base/threading/thread_task_runner_handle.h" | 22 #include "base/threading/thread_task_runner_handle.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; |
| (...skipping 56 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(const AudioParameters& params); |
| 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_; |
| 120 std::unique_ptr<CancelableSyncSocket> browser_socket_; |
| 121 std::unique_ptr<CancelableSyncSocket> renderer_socket_; |
| 114 | 122 |
| 115 private: | 123 private: |
| 116 int CalculateMemorySize(); | 124 int CalculateMemorySize(); |
| 117 | 125 |
| 118 SharedMemory shared_memory_; | 126 std::unique_ptr<SharedMemory> shared_memory_; |
| 119 CancelableSyncSocket browser_socket_; | |
| 120 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), |
| 139 browser_socket_(new base::CancelableSyncSocket()), |
| 140 renderer_socket_(new base::CancelableSyncSocket()) { |
| 133 default_audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LINEAR, | 141 default_audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LINEAR, |
| 134 CHANNEL_LAYOUT_STEREO, 48000, 16, 1024); | 142 CHANNEL_LAYOUT_STEREO, 48000, 16, 1024); |
| 135 SetDevice(kDefaultDeviceId); | 143 SetDeviceInfoToGarbage(); |
| 136 } | 144 } |
| 137 | 145 |
| 138 AudioOutputDeviceTest::~AudioOutputDeviceTest() { | 146 AudioOutputDeviceTest::~AudioOutputDeviceTest() { |
| 139 audio_device_ = NULL; | 147 audio_device_ = NULL; |
| 140 } | 148 } |
| 141 | 149 |
| 142 void AudioOutputDeviceTest::SetDevice(const std::string& device_id) { | 150 void AudioOutputDeviceTest::SetDevice(const std::string& device_id) { |
| 143 audio_output_ipc_ = new MockAudioOutputIPC(); | 151 audio_output_ipc_ = new MockAudioOutputIPC(); |
| 144 audio_device_ = new AudioOutputDevice(base::WrapUnique(audio_output_ipc_), | 152 audio_device_ = new AudioOutputDevice(base::WrapUnique(audio_output_ipc_), |
| 145 io_loop_.task_runner(), 0, device_id, | 153 io_loop_.task_runner(), 0, device_id, |
| 146 url::Origin()); | 154 url::Origin()); |
| 147 EXPECT_CALL(*audio_output_ipc_, | 155 EXPECT_CALL(*audio_output_ipc_, |
| 148 RequestDeviceAuthorization(audio_device_.get(), 0, device_id, _)); | 156 RequestDeviceAuthorization(audio_device_.get(), 0, device_id, _)); |
| 149 audio_device_->RequestDeviceAuthorization(); | 157 audio_device_->RequestDeviceAuthorization(); |
| 150 io_loop_.RunUntilIdle(); | 158 io_loop_.RunUntilIdle(); |
| 151 | 159 |
| 152 // Simulate response from browser | 160 // Simulate response from browser |
| 153 OutputDeviceStatus device_status = | 161 OutputDeviceStatus device_status = |
| 154 (device_id == kUnauthorizedDeviceId) | 162 (device_id == kUnauthorizedDeviceId) |
| 155 ? OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED | 163 ? OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED |
| 156 : OUTPUT_DEVICE_STATUS_OK; | 164 : OUTPUT_DEVICE_STATUS_OK; |
| 157 ReceiveAuthorization(device_status); | 165 ReceiveAuthorization(device_status); |
| 158 | 166 |
| 159 audio_device_->Initialize(default_audio_parameters_, | 167 InitializeAudioDevice(default_audio_parameters_); |
| 160 &callback_); | |
| 161 } | 168 } |
| 162 | 169 |
| 163 void AudioOutputDeviceTest::ReceiveAuthorization(OutputDeviceStatus status) { | 170 void AudioOutputDeviceTest::ReceiveAuthorization(OutputDeviceStatus status) { |
| 164 device_status_ = status; | 171 device_status_ = status; |
| 165 if (device_status_ != OUTPUT_DEVICE_STATUS_OK) | 172 if (device_status_ != OUTPUT_DEVICE_STATUS_OK) |
| 166 EXPECT_CALL(*audio_output_ipc_, CloseStream()); | 173 EXPECT_CALL(*audio_output_ipc_, CloseStream()); |
| 167 | 174 |
| 168 audio_device_->OnDeviceAuthorized(device_status_, default_audio_parameters_, | 175 audio_device_->OnDeviceAuthorized(device_status_, default_audio_parameters_, |
| 169 kDefaultDeviceId); | 176 kDefaultDeviceId); |
| 170 io_loop_.RunUntilIdle(); | 177 io_loop_.RunUntilIdle(); |
| 171 } | 178 } |
| 172 | 179 |
| 173 void AudioOutputDeviceTest::StartAudioDevice() { | 180 void AudioOutputDeviceTest::StartAudioDevice() { |
| 174 if (device_status_ == OUTPUT_DEVICE_STATUS_OK) | 181 if (device_status_ == OUTPUT_DEVICE_STATUS_OK) |
| 175 EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _)); | 182 EXPECT_CALL(*audio_output_ipc_, CreateStream(audio_device_.get(), _)); |
| 176 else | 183 else |
| 177 EXPECT_CALL(callback_, OnRenderError()); | 184 EXPECT_CALL(callback_, OnRenderError()); |
| 178 | 185 |
| 179 audio_device_->Start(); | 186 audio_device_->Start(); |
| 180 io_loop_.RunUntilIdle(); | 187 io_loop_.RunUntilIdle(); |
| 181 } | 188 } |
| 182 | 189 |
| 190 void AudioOutputDeviceTest::InitializeAudioDevice( |
| 191 const AudioParameters& params) { |
| 192 audio_device_->Initialize(params, &callback_); |
| 193 } |
| 194 |
| 183 void AudioOutputDeviceTest::CreateStream() { | 195 void AudioOutputDeviceTest::CreateStream() { |
| 184 const int kMemorySize = CalculateMemorySize(); | 196 const int kMemorySize = CalculateMemorySize(); |
| 185 | 197 |
| 186 ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize)); | 198 shared_memory_.reset(new SharedMemory()); |
| 187 memset(shared_memory_.memory(), 0xff, kMemorySize); | |
| 188 | 199 |
| 189 ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket_, | 200 ASSERT_TRUE(shared_memory_->CreateAndMapAnonymous(kMemorySize)); |
| 190 &renderer_socket_)); | 201 memset(shared_memory_->memory(), 0xff, kMemorySize); |
| 202 |
| 203 ASSERT_TRUE(CancelableSyncSocket::CreatePair(browser_socket_.get(), |
| 204 renderer_socket_.get())); |
| 191 | 205 |
| 192 // Create duplicates of the handles we pass to AudioOutputDevice since | 206 // Create duplicates of the handles we pass to AudioOutputDevice since |
| 193 // ownership will be transferred and AudioOutputDevice is responsible for | 207 // ownership will be transferred and AudioOutputDevice is responsible for |
| 194 // freeing. | 208 // freeing. |
| 195 SyncSocket::TransitDescriptor audio_device_socket_descriptor; | 209 SyncSocket::TransitDescriptor audio_device_socket_descriptor; |
| 196 ASSERT_TRUE(renderer_socket_.PrepareTransitDescriptor( | 210 ASSERT_TRUE(renderer_socket_->PrepareTransitDescriptor( |
| 197 base::GetCurrentProcessHandle(), &audio_device_socket_descriptor)); | 211 base::GetCurrentProcessHandle(), &audio_device_socket_descriptor)); |
| 198 base::SharedMemoryHandle duplicated_memory_handle; | 212 base::SharedMemoryHandle duplicated_memory_handle; |
| 199 ASSERT_TRUE(shared_memory_.ShareToProcess(base::GetCurrentProcessHandle(), | 213 ASSERT_TRUE(shared_memory_->ShareToProcess(base::GetCurrentProcessHandle(), |
| 200 &duplicated_memory_handle)); | 214 &duplicated_memory_handle)); |
| 201 | 215 |
| 202 audio_device_->OnStreamCreated( | 216 audio_device_->OnStreamCreated( |
| 203 duplicated_memory_handle, | 217 duplicated_memory_handle, |
| 204 SyncSocket::UnwrapHandle(audio_device_socket_descriptor), kMemorySize); | 218 SyncSocket::UnwrapHandle(audio_device_socket_descriptor), kMemorySize); |
| 205 io_loop_.RunUntilIdle(); | 219 io_loop_.RunUntilIdle(); |
| 206 } | 220 } |
| 207 | 221 |
| 208 void AudioOutputDeviceTest::ExpectRenderCallback() { | 222 void AudioOutputDeviceTest::ExpectRenderCallback() { |
| 209 // We should get a 'play' notification when we call OnStreamCreated(). | 223 // We should get a 'play' notification when we call OnStreamCreated(). |
| 210 // Respond by asking for some audio data. This should ask our callback | 224 // Respond by asking for some audio data. This should ask our callback |
| 211 // to provide some audio data that AudioOutputDevice then writes into the | 225 // to provide some audio data that AudioOutputDevice then writes into the |
| 212 // shared memory section. | 226 // shared memory section. |
| 213 const int kMemorySize = CalculateMemorySize(); | 227 const int kMemorySize = CalculateMemorySize(); |
| 214 | 228 |
| 229 ASSERT_TRUE(browser_socket_.get()); |
| 215 EXPECT_CALL(*audio_output_ipc_, PlayStream()) | 230 EXPECT_CALL(*audio_output_ipc_, PlayStream()) |
| 216 .WillOnce(SendPendingBytes(&browser_socket_, kMemorySize)); | 231 .WillOnce(SendPendingBytes(browser_socket_.get(), kMemorySize)); |
| 217 | 232 |
| 218 // We expect calls to our audio renderer callback, which returns the number | 233 // We expect calls to our audio renderer callback, which returns the number |
| 219 // of frames written to the memory section. | 234 // of frames written to the memory section. |
| 220 // Here's the second place where it gets hacky: There's no way for us to | 235 // Here's the second place where it gets hacky: There's no way for us to |
| 221 // know (without using a sleep loop!) when the AudioOutputDevice has finished | 236 // know (without using a sleep loop!) when the AudioOutputDevice has finished |
| 222 // writing the interleaved audio data into the shared memory section. | 237 // writing the interleaved audio data into the shared memory section. |
| 223 // So, for the sake of this test, we consider the call to Render a sign | 238 // So, for the sake of this test, we consider the call to Render a sign |
| 224 // of success and quit the loop. | 239 // of success and quit the loop. |
| 225 const int kNumberOfFramesToProcess = 0; | 240 const int kNumberOfFramesToProcess = 0; |
| 226 EXPECT_CALL(callback_, Render(_, _, _)) | 241 EXPECT_CALL(callback_, Render(_, _, _)) |
| 227 .WillOnce(DoAll(QuitLoop(io_loop_.task_runner()), | 242 .WillOnce(DoAll(QuitLoop(io_loop_.task_runner()), |
| 228 Return(kNumberOfFramesToProcess))); | 243 Return(kNumberOfFramesToProcess))); |
| 229 } | 244 } |
| 230 | 245 |
| 231 void AudioOutputDeviceTest::WaitUntilRenderCallback() { | 246 void AudioOutputDeviceTest::WaitUntilRenderCallback() { |
| 232 // Don't hang the test if we never get the Render() callback. | 247 // Don't hang the test if we never get the Render() callback. |
| 233 io_loop_.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), | 248 io_loop_.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), |
| 234 TestTimeouts::action_timeout()); | 249 TestTimeouts::action_timeout()); |
| 235 io_loop_.Run(); | 250 io_loop_.Run(); |
| 236 } | 251 } |
| 237 | 252 |
| 238 void AudioOutputDeviceTest::StopAudioDevice() { | 253 void AudioOutputDeviceTest::StopAudioDevice() { |
| 239 if (device_status_ == OUTPUT_DEVICE_STATUS_OK) | 254 if (device_status_ == OUTPUT_DEVICE_STATUS_OK) |
| 240 EXPECT_CALL(*audio_output_ipc_, CloseStream()); | 255 EXPECT_CALL(*audio_output_ipc_, CloseStream()); |
| 241 | 256 |
| 242 audio_device_->Stop(); | 257 audio_device_->Stop(); |
| 243 io_loop_.RunUntilIdle(); | 258 io_loop_.RunUntilIdle(); |
| 244 } | 259 } |
| 245 | 260 |
| 261 void AudioOutputDeviceTest::GetOutputDeviceInfo(base::WaitableEvent* event) { |
| 262 device_info_ = audio_device_->GetOutputDeviceInfo(); |
| 263 event->Signal(); |
| 264 } |
| 265 |
| 266 void AudioOutputDeviceTest::SetDeviceInfoToGarbage() { |
| 267 device_info_ = |
| 268 OutputDeviceInfo("qwertyuiop", OUTPUT_DEVICE_STATUS_ERROR_INTERNAL, |
| 269 AudioParameters(AudioParameters::AUDIO_FAKE, |
| 270 CHANNEL_LAYOUT_NONE, 1, 2, 3)); |
| 271 } |
| 272 |
| 246 TEST_P(AudioOutputDeviceTest, Initialize) { | 273 TEST_P(AudioOutputDeviceTest, Initialize) { |
| 247 // Tests that the object can be constructed, initialized and destructed | 274 // Tests that the object can be constructed, initialized and destructed |
| 248 // without having ever been started. | 275 // without having ever been started. |
| 276 SetDevice(kDefaultDeviceId); |
| 249 StopAudioDevice(); | 277 StopAudioDevice(); |
| 250 } | 278 } |
| 251 | 279 |
| 252 // Calls Start() followed by an immediate Stop() and check for the basic message | 280 // Calls Start() followed by an immediate Stop() and check for the basic message |
| 253 // filter messages being sent in that case. | 281 // filter messages being sent in that case. |
| 254 TEST_P(AudioOutputDeviceTest, StartStop) { | 282 TEST_P(AudioOutputDeviceTest, StartStop) { |
| 283 SetDevice(kDefaultDeviceId); |
| 255 StartAudioDevice(); | 284 StartAudioDevice(); |
| 256 StopAudioDevice(); | 285 StopAudioDevice(); |
| 257 } | 286 } |
| 258 | 287 |
| 259 // AudioOutputDevice supports multiple start/stop sequences. | 288 TEST_P(AudioOutputDeviceTest, StartStopStop) { |
| 260 TEST_P(AudioOutputDeviceTest, StartStopStartStop) { | 289 SetDevice(kDefaultDeviceId); |
| 261 StartAudioDevice(); | 290 StartAudioDevice(); |
| 262 StopAudioDevice(); | 291 StopAudioDevice(); |
| 292 |
| 293 // Stop again, but don't expect a CloseStream() IPC call as StopAudioDevice() |
| 294 // does. |
| 295 audio_device_->Stop(); |
| 296 io_loop_.RunUntilIdle(); |
| 297 } |
| 298 |
| 299 // AudioOutputDevice supports multiple intialize/start/stop sequences. |
| 300 TEST_P(AudioOutputDeviceTest, StartStopStartStop) { |
| 301 SetDevice(kDefaultDeviceId); |
| 263 StartAudioDevice(); | 302 StartAudioDevice(); |
| 264 StopAudioDevice(); | 303 StopAudioDevice(); |
| 304 InitializeAudioDevice(default_audio_parameters_); |
| 305 EXPECT_CALL(*audio_output_ipc_, |
| 306 RequestDeviceAuthorization(audio_device_.get(), 0, _, _)); |
| 307 StartAudioDevice(); |
| 308 // Simulate reply from browser |
| 309 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK); |
| 310 StopAudioDevice(); |
| 265 } | 311 } |
| 266 | 312 |
| 267 // Simulate receiving OnStreamCreated() prior to processing ShutDownOnIOThread() | 313 // Simulate receiving OnStreamCreated() prior to processing ShutDownOnIOThread() |
| 268 // on the IO loop. | 314 // on the IO loop. |
| 269 TEST_P(AudioOutputDeviceTest, StopBeforeRender) { | 315 TEST_P(AudioOutputDeviceTest, StopBeforeRender) { |
| 316 SetDevice(kDefaultDeviceId); |
| 270 StartAudioDevice(); | 317 StartAudioDevice(); |
| 271 | 318 |
| 272 // Call Stop() but don't run the IO loop yet. | 319 // Call Stop() but don't run the IO loop yet. |
| 273 audio_device_->Stop(); | 320 audio_device_->Stop(); |
| 274 | 321 |
| 275 // Expect us to shutdown IPC but not to render anything despite the stream | 322 // Expect to play the stream and to shutdown IPC but not to render anything |
| 276 // getting created. | 323 // despite the stream getting created. |
| 324 EXPECT_CALL(*audio_output_ipc_, PlayStream()); |
| 277 EXPECT_CALL(*audio_output_ipc_, CloseStream()); | 325 EXPECT_CALL(*audio_output_ipc_, CloseStream()); |
| 278 CreateStream(); | 326 CreateStream(); |
| 279 } | 327 } |
| 280 | 328 |
| 281 // Full test with output only. | 329 // Full test with output only. |
| 282 TEST_P(AudioOutputDeviceTest, CreateStream) { | 330 TEST_P(AudioOutputDeviceTest, CreateStream) { |
| 331 SetDevice(kDefaultDeviceId); |
| 283 StartAudioDevice(); | 332 StartAudioDevice(); |
| 284 ExpectRenderCallback(); | 333 ExpectRenderCallback(); |
| 285 CreateStream(); | 334 CreateStream(); |
| 286 WaitUntilRenderCallback(); | 335 WaitUntilRenderCallback(); |
| 287 StopAudioDevice(); | 336 StopAudioDevice(); |
| 288 } | 337 } |
| 289 | 338 |
| 339 // Full test with output only. |
| 340 TEST_P(AudioOutputDeviceTest, CreateStreamMultipleStop) { |
| 341 SetDevice(kDefaultDeviceId); |
| 342 StartAudioDevice(); |
| 343 ExpectRenderCallback(); |
| 344 CreateStream(); |
| 345 WaitUntilRenderCallback(); |
| 346 StopAudioDevice(); |
| 347 |
| 348 // Stop again, but don't expect a CloseStream() IPC call as StopAudioDevice() |
| 349 // does. |
| 350 audio_device_->Stop(); |
| 351 io_loop_.RunUntilIdle(); |
| 352 } |
| 353 |
| 290 // Full test with output only with nondefault device. | 354 // Full test with output only with nondefault device. |
| 291 TEST_P(AudioOutputDeviceTest, NonDefaultCreateStream) { | 355 TEST_P(AudioOutputDeviceTest, NonDefaultCreateStream) { |
| 292 SetDevice(kNonDefaultDeviceId); | 356 SetDevice(kNonDefaultDeviceId); |
| 293 StartAudioDevice(); | 357 StartAudioDevice(); |
| 294 ExpectRenderCallback(); | 358 ExpectRenderCallback(); |
| 295 CreateStream(); | 359 CreateStream(); |
| 296 WaitUntilRenderCallback(); | 360 WaitUntilRenderCallback(); |
| 297 StopAudioDevice(); | 361 StopAudioDevice(); |
| 298 } | 362 } |
| 299 | 363 |
| 364 TEST_P(AudioOutputDeviceTest, MultipleCreateStream) { |
| 365 SetDevice(kDefaultDeviceId); |
| 366 StartAudioDevice(); |
| 367 ExpectRenderCallback(); |
| 368 CreateStream(); |
| 369 WaitUntilRenderCallback(); |
| 370 StopAudioDevice(); |
| 371 |
| 372 // Create a new pair of sockets and keep the old ones so that new handles |
| 373 // are used, otherwise AudioDeviceThread will keep an old socket with the same |
| 374 // handle as the new one, ending up closing the new socket instead of the old. |
| 375 std::unique_ptr<base::CancelableSyncSocket> new_browser_socket( |
| 376 new base::CancelableSyncSocket()); |
| 377 std::unique_ptr<base::CancelableSyncSocket> new_renderer_socket( |
| 378 new base::CancelableSyncSocket()); |
| 379 browser_socket_.swap(new_browser_socket); |
| 380 renderer_socket_.swap(new_renderer_socket); |
| 381 |
| 382 InitializeAudioDevice(default_audio_parameters_); |
| 383 EXPECT_CALL(*audio_output_ipc_, |
| 384 RequestDeviceAuthorization(audio_device_.get(), 0, _, _)); |
| 385 StartAudioDevice(); |
| 386 // Simulate reply from browser |
| 387 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK); |
| 388 |
| 389 ExpectRenderCallback(); |
| 390 CreateStream(); |
| 391 WaitUntilRenderCallback(); |
| 392 StopAudioDevice(); |
| 393 } |
| 394 |
| 300 // Multiple start/stop with nondefault device | 395 // Multiple start/stop with nondefault device |
| 301 TEST_P(AudioOutputDeviceTest, NonDefaultStartStopStartStop) { | 396 TEST_P(AudioOutputDeviceTest, NonDefaultStartStopStartStop) { |
| 302 SetDevice(kNonDefaultDeviceId); | 397 SetDevice(kNonDefaultDeviceId); |
| 303 StartAudioDevice(); | 398 StartAudioDevice(); |
| 304 StopAudioDevice(); | 399 StopAudioDevice(); |
| 305 | 400 InitializeAudioDevice(default_audio_parameters_); |
| 306 EXPECT_CALL(*audio_output_ipc_, | 401 EXPECT_CALL(*audio_output_ipc_, |
| 307 RequestDeviceAuthorization(audio_device_.get(), 0, _, _)); | 402 RequestDeviceAuthorization(audio_device_.get(), 0, _, _)); |
| 308 StartAudioDevice(); | 403 StartAudioDevice(); |
| 309 // Simulate reply from browser | 404 // Simulate reply from browser |
| 310 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK); | 405 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK); |
| 311 | |
| 312 StopAudioDevice(); | 406 StopAudioDevice(); |
| 313 } | 407 } |
| 314 | 408 |
| 315 TEST_P(AudioOutputDeviceTest, UnauthorizedDevice) { | 409 TEST_P(AudioOutputDeviceTest, UnauthorizedDevice) { |
| 316 SetDevice(kUnauthorizedDeviceId); | 410 SetDevice(kUnauthorizedDeviceId); |
| 317 StartAudioDevice(); | 411 StartAudioDevice(); |
| 318 StopAudioDevice(); | 412 StopAudioDevice(); |
| 319 } | 413 } |
| 320 | 414 |
| 415 TEST_P(AudioOutputDeviceTest, MultipleStartStopDifferentParameters) { |
| 416 SetDevice(kDefaultDeviceId); |
| 417 StartAudioDevice(); |
| 418 StopAudioDevice(); |
| 419 |
| 420 // Initialize with different parameters. |
| 421 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, |
| 422 16000, 16, 512); |
| 423 InitializeAudioDevice(params); |
| 424 EXPECT_CALL(*audio_output_ipc_, |
| 425 RequestDeviceAuthorization(audio_device_.get(), 0, _, _)); |
| 426 StartAudioDevice(); |
| 427 // Simulate reply from browser |
| 428 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK); |
| 429 StopAudioDevice(); |
| 430 |
| 431 // Back to default parameters. |
| 432 InitializeAudioDevice(default_audio_parameters_); |
| 433 EXPECT_CALL(*audio_output_ipc_, |
| 434 RequestDeviceAuthorization(audio_device_.get(), 0, _, _)); |
| 435 StartAudioDevice(); |
| 436 // Simulate reply from browser |
| 437 ReceiveAuthorization(OUTPUT_DEVICE_STATUS_OK); |
| 438 StopAudioDevice(); |
| 439 } |
| 440 |
| 441 TEST_P(AudioOutputDeviceTest, MultipleStartStopDifferentDevices) { |
| 442 SetDevice(kDefaultDeviceId); |
| 443 StartAudioDevice(); |
| 444 StopAudioDevice(); |
| 445 |
| 446 SetDevice(kNonDefaultDeviceId); |
| 447 StartAudioDevice(); |
| 448 StopAudioDevice(); |
| 449 |
| 450 SetDevice(kUnauthorizedDeviceId); |
| 451 StartAudioDevice(); |
| 452 StopAudioDevice(); |
| 453 |
| 454 SetDevice(kDefaultDeviceId); |
| 455 StartAudioDevice(); |
| 456 StopAudioDevice(); |
| 457 } |
| 458 |
| 459 // Test getting output device info. |
| 460 // GetOutputDeviceInfo() must be called on a different thread than the IO task |
| 461 // runner we hand to the AudioOutputDevice. Since we use the task runner for the |
| 462 // thread the test runs on as the IO task runner, we must spin up a new thread |
| 463 // and call GetOutputDeviceInfo() on that. |
| 464 TEST_P(AudioOutputDeviceTest, GetOutputDeviceInfo) { |
| 465 SetDevice(kDefaultDeviceId); |
| 466 |
| 467 base::WaitableEvent event(true, false); |
| 468 base::Thread thread("get_output_device_info"); |
| 469 thread.Start(); |
| 470 |
| 471 // Get device info on the other thread and wait until finished. |
| 472 thread.task_runner()->PostTask( |
| 473 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo, |
| 474 base::Unretained(this), &event)); |
| 475 event.Wait(); |
| 476 |
| 477 EXPECT_EQ(kDefaultDeviceId, device_info_.device_id()); |
| 478 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status()); |
| 479 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_)); |
| 480 |
| 481 StopAudioDevice(); |
| 482 } |
| 483 |
| 484 TEST_P(AudioOutputDeviceTest, NonDefaultGetOutputDeviceInfo) { |
| 485 SetDevice(kNonDefaultDeviceId); |
| 486 |
| 487 // AudioOutputDevice::GetOutputDeviceInfo must be called on a different thread |
| 488 // than the task runner given to it. |
| 489 base::WaitableEvent event(true, false); |
| 490 base::Thread thread("get_output_device_info"); |
| 491 thread.Start(); |
| 492 |
| 493 // Get device info on the other thread and wait until finished. |
| 494 thread.task_runner()->PostTask( |
| 495 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo, |
| 496 base::Unretained(this), &event)); |
| 497 event.Wait(); |
| 498 |
| 499 EXPECT_EQ(kNonDefaultDeviceId, device_info_.device_id()); |
| 500 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status()); |
| 501 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_)); |
| 502 |
| 503 StopAudioDevice(); |
| 504 } |
| 505 |
| 506 TEST_P(AudioOutputDeviceTest, MultipleNonDefaultGetOutputDeviceInfo) { |
| 507 SetDevice(kNonDefaultDeviceId); |
| 508 |
| 509 // AudioOutputDevice::GetOutputDeviceInfo must be called on a different thread |
| 510 // than the task runner given to it. |
| 511 base::WaitableEvent event(true, false); |
| 512 base::Thread thread("get_output_device_info"); |
| 513 thread.Start(); |
| 514 |
| 515 // Get device info on the other thread and wait until finished. |
| 516 thread.task_runner()->PostTask( |
| 517 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo, |
| 518 base::Unretained(this), &event)); |
| 519 event.Wait(); |
| 520 |
| 521 EXPECT_EQ(kNonDefaultDeviceId, device_info_.device_id()); |
| 522 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status()); |
| 523 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_)); |
| 524 |
| 525 SetDeviceInfoToGarbage(); |
| 526 event.Reset(); |
| 527 |
| 528 // Get device info on the other thread and wait until finished. |
| 529 thread.task_runner()->PostTask( |
| 530 FROM_HERE, base::Bind(&AudioOutputDeviceTest::GetOutputDeviceInfo, |
| 531 base::Unretained(this), &event)); |
| 532 event.Wait(); |
| 533 |
| 534 EXPECT_EQ(kNonDefaultDeviceId, device_info_.device_id()); |
| 535 EXPECT_EQ(OUTPUT_DEVICE_STATUS_OK, device_info_.device_status()); |
| 536 EXPECT_TRUE(device_info_.output_params().Equals(default_audio_parameters_)); |
| 537 |
| 538 StopAudioDevice(); |
| 539 } |
| 540 |
| 321 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false)); | 541 INSTANTIATE_TEST_CASE_P(Render, AudioOutputDeviceTest, Values(false)); |
| 322 | 542 |
| 323 } // namespace media. | 543 } // namespace media. |
| OLD | NEW |