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