| 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 <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/message_loop/message_loop_proxy.h" | 8 #include "base/message_loop/message_loop_proxy.h" |
| 9 #include "base/run_loop.h" | |
| 10 #include "media/audio/audio_manager.h" | 9 #include "media/audio/audio_manager.h" |
| 11 #include "media/audio/audio_manager_base.h" | 10 #include "media/audio/audio_manager_base.h" |
| 12 #include "media/audio/audio_output_dispatcher_impl.h" | 11 #include "media/audio/audio_output_dispatcher_impl.h" |
| 13 #include "media/audio/audio_output_proxy.h" | 12 #include "media/audio/audio_output_proxy.h" |
| 14 #include "media/audio/audio_output_resampler.h" | 13 #include "media/audio/audio_output_resampler.h" |
| 15 #include "media/audio/fake_audio_output_stream.h" | 14 #include "media/audio/fake_audio_output_stream.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 17 |
| 19 using ::testing::_; | 18 using ::testing::_; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 30 using media::AudioManager; | 29 using media::AudioManager; |
| 31 using media::AudioManagerBase; | 30 using media::AudioManagerBase; |
| 32 using media::AudioOutputDispatcher; | 31 using media::AudioOutputDispatcher; |
| 33 using media::AudioOutputProxy; | 32 using media::AudioOutputProxy; |
| 34 using media::AudioOutputStream; | 33 using media::AudioOutputStream; |
| 35 using media::AudioParameters; | 34 using media::AudioParameters; |
| 36 using media::FakeAudioOutputStream; | 35 using media::FakeAudioOutputStream; |
| 37 | 36 |
| 38 namespace { | 37 namespace { |
| 39 | 38 |
| 40 static const int kTestCloseDelayMs = 10; | 39 static const int kTestCloseDelayMs = 100; |
| 40 |
| 41 // Used in the test where we don't want a stream to be closed unexpectedly. |
| 42 static const int kTestBigCloseDelaySeconds = 1000; |
| 41 | 43 |
| 42 // Delay between callbacks to AudioSourceCallback::OnMoreData. | 44 // Delay between callbacks to AudioSourceCallback::OnMoreData. |
| 43 static const int kOnMoreDataCallbackDelayMs = 10; | 45 static const int kOnMoreDataCallbackDelayMs = 10; |
| 44 | 46 |
| 45 // Let start run long enough for many OnMoreData callbacks to occur. | 47 // Let start run long enough for many OnMoreData callbacks to occur. |
| 46 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10; | 48 static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10; |
| 47 | 49 |
| 48 class MockAudioOutputStream : public AudioOutputStream { | 50 class MockAudioOutputStream : public AudioOutputStream { |
| 49 public: | 51 public: |
| 50 MockAudioOutputStream(AudioManagerBase* manager, | 52 MockAudioOutputStream(AudioManagerBase* manager, |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 | 141 |
| 140 namespace media { | 142 namespace media { |
| 141 | 143 |
| 142 class AudioOutputProxyTest : public testing::Test { | 144 class AudioOutputProxyTest : public testing::Test { |
| 143 protected: | 145 protected: |
| 144 virtual void SetUp() { | 146 virtual void SetUp() { |
| 145 EXPECT_CALL(manager_, GetMessageLoop()) | 147 EXPECT_CALL(manager_, GetMessageLoop()) |
| 146 .WillRepeatedly(Return(message_loop_.message_loop_proxy())); | 148 .WillRepeatedly(Return(message_loop_.message_loop_proxy())); |
| 147 EXPECT_CALL(manager_, GetWorkerLoop()) | 149 EXPECT_CALL(manager_, GetWorkerLoop()) |
| 148 .WillRepeatedly(Return(message_loop_.message_loop_proxy())); | 150 .WillRepeatedly(Return(message_loop_.message_loop_proxy())); |
| 149 // Use a low sample rate and large buffer size when testing otherwise the | |
| 150 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e., | |
| 151 // RunUntilIdle() will never terminate. | |
| 152 params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, | |
| 153 CHANNEL_LAYOUT_STEREO, 8000, 16, 2048); | |
| 154 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs)); | 151 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs)); |
| 155 } | 152 } |
| 156 | 153 |
| 157 virtual void TearDown() { | 154 virtual void TearDown() { |
| 155 // All paused proxies should have been closed at this point. |
| 156 EXPECT_EQ(0u, dispatcher_impl_->paused_proxies_); |
| 157 |
| 158 // This is necessary to free all proxy objects that have been | 158 // This is necessary to free all proxy objects that have been |
| 159 // closed by the test. | 159 // closed by the test. |
| 160 message_loop_.RunUntilIdle(); | 160 message_loop_.RunUntilIdle(); |
| 161 } | 161 } |
| 162 | 162 |
| 163 virtual void InitDispatcher(base::TimeDelta close_delay) { | 163 virtual void InitDispatcher(base::TimeDelta close_delay) { |
| 164 // Use a low sample rate and large buffer size when testing otherwise the |
| 165 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e., |
| 166 // RunUntilIdle() will never terminate. |
| 167 params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, |
| 168 CHANNEL_LAYOUT_STEREO, 8000, 16, 2048); |
| 164 dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(), | 169 dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(), |
| 165 params_, | 170 params_, |
| 166 std::string(), | 171 std::string(), |
| 167 std::string(), | 172 std::string(), |
| 168 close_delay); | 173 close_delay); |
| 174 |
| 175 // Necessary to know how long the dispatcher will wait before posting |
| 176 // StopStreamTask. |
| 177 pause_delay_ = dispatcher_impl_->pause_delay_; |
| 169 } | 178 } |
| 170 | 179 |
| 171 virtual void OnStart() {} | 180 virtual void OnStart() {} |
| 172 | 181 |
| 173 MockAudioManager& manager() { | 182 MockAudioManager& manager() { |
| 174 return manager_; | 183 return manager_; |
| 175 } | 184 } |
| 176 | 185 |
| 177 void WaitForCloseTimer(MockAudioOutputStream* stream) { | 186 // Wait for the close timer to fire. |
| 178 base::RunLoop run_loop; | 187 void WaitForCloseTimer(const int timer_delay_ms) { |
| 179 EXPECT_CALL(*stream, Close()) | 188 message_loop_.RunUntilIdle(); // OpenTask() may reset the timer. |
| 180 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); | 189 base::PlatformThread::Sleep( |
| 181 run_loop.Run(); | 190 base::TimeDelta::FromMilliseconds(timer_delay_ms) * 2); |
| 191 message_loop_.RunUntilIdle(); |
| 182 } | 192 } |
| 183 | 193 |
| 184 void CloseAndWaitForCloseTimer(AudioOutputProxy* proxy, | 194 // Methods that do actual tests. |
| 185 MockAudioOutputStream* stream) { | |
| 186 // Close the stream and verify it doesn't happen immediately. | |
| 187 proxy->Close(); | |
| 188 Mock::VerifyAndClear(stream); | |
| 189 | |
| 190 // Wait for the actual close event to come from the close timer. | |
| 191 WaitForCloseTimer(stream); | |
| 192 } | |
| 193 | |
| 194 // Basic Open() and Close() test. | |
| 195 void OpenAndClose(AudioOutputDispatcher* dispatcher) { | 195 void OpenAndClose(AudioOutputDispatcher* dispatcher) { |
| 196 MockAudioOutputStream stream(&manager_, params_); | 196 MockAudioOutputStream stream(&manager_, params_); |
| 197 | 197 |
| 198 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 198 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 199 .WillOnce(Return(&stream)); | 199 .WillOnce(Return(&stream)); |
| 200 EXPECT_CALL(stream, Open()) | 200 EXPECT_CALL(stream, Open()) |
| 201 .WillOnce(Return(true)); | 201 .WillOnce(Return(true)); |
| 202 EXPECT_CALL(stream, Close()) |
| 203 .Times(1); |
| 202 | 204 |
| 203 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 205 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 204 EXPECT_TRUE(proxy->Open()); | 206 EXPECT_TRUE(proxy->Open()); |
| 205 CloseAndWaitForCloseTimer(proxy, &stream); | 207 proxy->Close(); |
| 208 WaitForCloseTimer(kTestCloseDelayMs); |
| 206 } | 209 } |
| 207 | 210 |
| 208 // Creates a stream, and then calls Start() and Stop(). | 211 // Create a stream, and then calls Start() and Stop(). |
| 209 void StartAndStop(AudioOutputDispatcher* dispatcher) { | 212 void StartAndStop(AudioOutputDispatcher* dispatcher) { |
| 210 MockAudioOutputStream stream(&manager_, params_); | 213 MockAudioOutputStream stream(&manager_, params_); |
| 211 | 214 |
| 212 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 215 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 213 .WillOnce(Return(&stream)); | 216 .WillOnce(Return(&stream)); |
| 214 EXPECT_CALL(stream, Open()) | 217 EXPECT_CALL(stream, Open()) |
| 215 .WillOnce(Return(true)); | 218 .WillOnce(Return(true)); |
| 216 EXPECT_CALL(stream, SetVolume(_)) | 219 EXPECT_CALL(stream, SetVolume(_)) |
| 217 .Times(1); | 220 .Times(1); |
| 221 EXPECT_CALL(stream, Close()) |
| 222 .Times(1); |
| 218 | 223 |
| 219 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 224 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 220 EXPECT_TRUE(proxy->Open()); | 225 EXPECT_TRUE(proxy->Open()); |
| 221 | 226 |
| 222 proxy->Start(&callback_); | 227 proxy->Start(&callback_); |
| 223 OnStart(); | 228 OnStart(); |
| 224 proxy->Stop(); | 229 proxy->Stop(); |
| 225 | 230 |
| 226 CloseAndWaitForCloseTimer(proxy, &stream); | 231 proxy->Close(); |
| 232 WaitForCloseTimer(kTestCloseDelayMs); |
| 227 EXPECT_TRUE(stream.stop_called()); | 233 EXPECT_TRUE(stream.stop_called()); |
| 228 EXPECT_TRUE(stream.start_called()); | 234 EXPECT_TRUE(stream.start_called()); |
| 229 } | 235 } |
| 230 | 236 |
| 231 // Verify that the stream is closed after Stop() is called. | 237 // Verify that the stream is closed after Stop is called. |
| 232 void CloseAfterStop(AudioOutputDispatcher* dispatcher) { | 238 void CloseAfterStop(AudioOutputDispatcher* dispatcher) { |
| 233 MockAudioOutputStream stream(&manager_, params_); | 239 MockAudioOutputStream stream(&manager_, params_); |
| 234 | 240 |
| 235 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 241 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 236 .WillOnce(Return(&stream)); | 242 .WillOnce(Return(&stream)); |
| 237 EXPECT_CALL(stream, Open()) | 243 EXPECT_CALL(stream, Open()) |
| 238 .WillOnce(Return(true)); | 244 .WillOnce(Return(true)); |
| 239 EXPECT_CALL(stream, SetVolume(_)) | 245 EXPECT_CALL(stream, SetVolume(_)) |
| 240 .Times(1); | 246 .Times(1); |
| 247 EXPECT_CALL(stream, Close()) |
| 248 .Times(1); |
| 241 | 249 |
| 242 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 250 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 243 EXPECT_TRUE(proxy->Open()); | 251 EXPECT_TRUE(proxy->Open()); |
| 244 | 252 |
| 245 proxy->Start(&callback_); | 253 proxy->Start(&callback_); |
| 246 OnStart(); | 254 OnStart(); |
| 247 proxy->Stop(); | 255 proxy->Stop(); |
| 248 | 256 |
| 249 // Wait for the close timer to fire after StopStream(). | 257 // Wait for StopStream() to post StopStreamTask(). |
| 250 WaitForCloseTimer(&stream); | 258 base::PlatformThread::Sleep(pause_delay_ * 2); |
| 259 WaitForCloseTimer(kTestCloseDelayMs); |
| 260 |
| 261 // Verify expectation before calling Close(). |
| 262 Mock::VerifyAndClear(&stream); |
| 263 |
| 251 proxy->Close(); | 264 proxy->Close(); |
| 252 EXPECT_TRUE(stream.stop_called()); | 265 EXPECT_TRUE(stream.stop_called()); |
| 253 EXPECT_TRUE(stream.start_called()); | 266 EXPECT_TRUE(stream.start_called()); |
| 254 } | 267 } |
| 255 | 268 |
| 256 // Create two streams, but don't start them. Only one device must be opened. | 269 // Create two streams, but don't start them. Only one device must be open. |
| 257 void TwoStreams(AudioOutputDispatcher* dispatcher) { | 270 void TwoStreams(AudioOutputDispatcher* dispatcher) { |
| 258 MockAudioOutputStream stream(&manager_, params_); | 271 MockAudioOutputStream stream(&manager_, params_); |
| 259 | 272 |
| 260 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 273 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 261 .WillOnce(Return(&stream)); | 274 .WillOnce(Return(&stream)); |
| 262 EXPECT_CALL(stream, Open()) | 275 EXPECT_CALL(stream, Open()) |
| 263 .WillOnce(Return(true)); | 276 .WillOnce(Return(true)); |
| 277 EXPECT_CALL(stream, Close()) |
| 278 .Times(1); |
| 264 | 279 |
| 265 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); | 280 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); |
| 266 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); | 281 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); |
| 267 EXPECT_TRUE(proxy1->Open()); | 282 EXPECT_TRUE(proxy1->Open()); |
| 268 EXPECT_TRUE(proxy2->Open()); | 283 EXPECT_TRUE(proxy2->Open()); |
| 269 proxy1->Close(); | 284 proxy1->Close(); |
| 270 CloseAndWaitForCloseTimer(proxy2, &stream); | 285 proxy2->Close(); |
| 286 WaitForCloseTimer(kTestCloseDelayMs); |
| 271 EXPECT_FALSE(stream.stop_called()); | 287 EXPECT_FALSE(stream.stop_called()); |
| 272 EXPECT_FALSE(stream.start_called()); | 288 EXPECT_FALSE(stream.start_called()); |
| 273 } | 289 } |
| 274 | 290 |
| 275 // Open() method failed. | 291 // Open() method failed. |
| 276 void OpenFailed(AudioOutputDispatcher* dispatcher) { | 292 void OpenFailed(AudioOutputDispatcher* dispatcher) { |
| 277 MockAudioOutputStream stream(&manager_, params_); | 293 MockAudioOutputStream stream(&manager_, params_); |
| 278 | 294 |
| 279 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 295 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 280 .WillOnce(Return(&stream)); | 296 .WillOnce(Return(&stream)); |
| 281 EXPECT_CALL(stream, Open()) | 297 EXPECT_CALL(stream, Open()) |
| 282 .WillOnce(Return(false)); | 298 .WillOnce(Return(false)); |
| 283 EXPECT_CALL(stream, Close()) | 299 EXPECT_CALL(stream, Close()) |
| 284 .Times(1); | 300 .Times(1); |
| 285 | 301 |
| 286 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 302 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 287 EXPECT_FALSE(proxy->Open()); | 303 EXPECT_FALSE(proxy->Open()); |
| 288 proxy->Close(); | 304 proxy->Close(); |
| 305 WaitForCloseTimer(kTestCloseDelayMs); |
| 289 EXPECT_FALSE(stream.stop_called()); | 306 EXPECT_FALSE(stream.stop_called()); |
| 290 EXPECT_FALSE(stream.start_called()); | 307 EXPECT_FALSE(stream.start_called()); |
| 291 } | 308 } |
| 292 | 309 |
| 293 void CreateAndWait(AudioOutputDispatcher* dispatcher) { | 310 void CreateAndWait(AudioOutputDispatcher* dispatcher) { |
| 294 MockAudioOutputStream stream(&manager_, params_); | 311 MockAudioOutputStream stream(&manager_, params_); |
| 295 | 312 |
| 296 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 313 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 297 .WillOnce(Return(&stream)); | 314 .WillOnce(Return(&stream)); |
| 298 EXPECT_CALL(stream, Open()) | 315 EXPECT_CALL(stream, Open()) |
| 299 .WillOnce(Return(true)); | 316 .WillOnce(Return(true)); |
| 317 EXPECT_CALL(stream, Close()) |
| 318 .Times(1); |
| 300 | 319 |
| 301 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 320 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 302 EXPECT_TRUE(proxy->Open()); | 321 EXPECT_TRUE(proxy->Open()); |
| 303 | 322 |
| 304 WaitForCloseTimer(&stream); | 323 // Simulate a delay. |
| 324 base::PlatformThread::Sleep( |
| 325 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2); |
| 326 message_loop_.RunUntilIdle(); |
| 327 |
| 328 // Verify expectation before calling Close(). |
| 329 Mock::VerifyAndClear(&stream); |
| 330 |
| 305 proxy->Close(); | 331 proxy->Close(); |
| 306 EXPECT_FALSE(stream.stop_called()); | 332 EXPECT_FALSE(stream.stop_called()); |
| 307 EXPECT_FALSE(stream.start_called()); | 333 EXPECT_FALSE(stream.start_called()); |
| 308 } | 334 } |
| 309 | 335 |
| 310 void OneStream_TwoPlays(AudioOutputDispatcher* dispatcher) { | 336 void TwoStreams_OnePlaying(AudioOutputDispatcher* dispatcher) { |
| 311 MockAudioOutputStream stream(&manager_, params_); | 337 MockAudioOutputStream stream1(&manager_, params_); |
| 338 MockAudioOutputStream stream2(&manager_, params_); |
| 312 | 339 |
| 313 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 340 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 314 .WillOnce(Return(&stream)); | 341 .WillOnce(Return(&stream1)) |
| 342 .WillOnce(Return(&stream2)); |
| 315 | 343 |
| 316 EXPECT_CALL(stream, Open()) | 344 EXPECT_CALL(stream1, Open()) |
| 317 .WillOnce(Return(true)); | 345 .WillOnce(Return(true)); |
| 318 EXPECT_CALL(stream, SetVolume(_)) | 346 EXPECT_CALL(stream1, SetVolume(_)) |
| 319 .Times(2); | 347 .Times(1); |
| 348 EXPECT_CALL(stream1, Close()) |
| 349 .Times(1); |
| 350 |
| 351 EXPECT_CALL(stream2, Open()) |
| 352 .WillOnce(Return(true)); |
| 353 EXPECT_CALL(stream2, Close()) |
| 354 .Times(1); |
| 320 | 355 |
| 321 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); | 356 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); |
| 357 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); |
| 322 EXPECT_TRUE(proxy1->Open()); | 358 EXPECT_TRUE(proxy1->Open()); |
| 359 EXPECT_TRUE(proxy2->Open()); |
| 323 | 360 |
| 324 proxy1->Start(&callback_); | 361 proxy1->Start(&callback_); |
| 362 message_loop_.RunUntilIdle(); |
| 325 OnStart(); | 363 OnStart(); |
| 326 proxy1->Stop(); | 364 proxy1->Stop(); |
| 327 | 365 |
| 328 // The stream should now be idle and get reused by |proxy2|. | |
| 329 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); | |
| 330 EXPECT_TRUE(proxy2->Open()); | |
| 331 proxy2->Start(&callback_); | |
| 332 OnStart(); | |
| 333 proxy2->Stop(); | |
| 334 | |
| 335 proxy1->Close(); | 366 proxy1->Close(); |
| 336 CloseAndWaitForCloseTimer(proxy2, &stream); | 367 proxy2->Close(); |
| 337 EXPECT_TRUE(stream.stop_called()); | 368 EXPECT_TRUE(stream1.stop_called()); |
| 338 EXPECT_TRUE(stream.start_called()); | 369 EXPECT_TRUE(stream1.start_called()); |
| 370 EXPECT_FALSE(stream2.stop_called()); |
| 371 EXPECT_FALSE(stream2.start_called()); |
| 339 } | 372 } |
| 340 | 373 |
| 341 void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) { | 374 void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) { |
| 342 MockAudioOutputStream stream1(&manager_, params_); | 375 MockAudioOutputStream stream1(&manager_, params_); |
| 343 MockAudioOutputStream stream2(&manager_, params_); | 376 MockAudioOutputStream stream2(&manager_, params_); |
| 344 | 377 |
| 345 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 378 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 346 .WillOnce(Return(&stream1)) | 379 .WillOnce(Return(&stream1)) |
| 347 .WillOnce(Return(&stream2)); | 380 .WillOnce(Return(&stream2)); |
| 348 | 381 |
| 349 EXPECT_CALL(stream1, Open()) | 382 EXPECT_CALL(stream1, Open()) |
| 350 .WillOnce(Return(true)); | 383 .WillOnce(Return(true)); |
| 351 EXPECT_CALL(stream1, SetVolume(_)) | 384 EXPECT_CALL(stream1, SetVolume(_)) |
| 352 .Times(1); | 385 .Times(1); |
| 386 EXPECT_CALL(stream1, Close()) |
| 387 .Times(1); |
| 353 | 388 |
| 354 EXPECT_CALL(stream2, Open()) | 389 EXPECT_CALL(stream2, Open()) |
| 355 .WillOnce(Return(true)); | 390 .WillOnce(Return(true)); |
| 356 EXPECT_CALL(stream2, SetVolume(_)) | 391 EXPECT_CALL(stream2, SetVolume(_)) |
| 357 .Times(1); | 392 .Times(1); |
| 393 EXPECT_CALL(stream2, Close()) |
| 394 .Times(1); |
| 358 | 395 |
| 359 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); | 396 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); |
| 360 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); | 397 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); |
| 361 EXPECT_TRUE(proxy1->Open()); | 398 EXPECT_TRUE(proxy1->Open()); |
| 362 EXPECT_TRUE(proxy2->Open()); | 399 EXPECT_TRUE(proxy2->Open()); |
| 363 | 400 |
| 364 proxy1->Start(&callback_); | 401 proxy1->Start(&callback_); |
| 365 proxy2->Start(&callback_); | 402 proxy2->Start(&callback_); |
| 366 OnStart(); | 403 OnStart(); |
| 367 proxy1->Stop(); | 404 proxy1->Stop(); |
| 368 CloseAndWaitForCloseTimer(proxy1, &stream1); | 405 proxy2->Stop(); |
| 369 | 406 |
| 370 proxy2->Stop(); | 407 proxy1->Close(); |
| 371 CloseAndWaitForCloseTimer(proxy2, &stream2); | 408 proxy2->Close(); |
| 372 | |
| 373 EXPECT_TRUE(stream1.stop_called()); | 409 EXPECT_TRUE(stream1.stop_called()); |
| 374 EXPECT_TRUE(stream1.start_called()); | 410 EXPECT_TRUE(stream1.start_called()); |
| 375 EXPECT_TRUE(stream2.stop_called()); | 411 EXPECT_TRUE(stream2.stop_called()); |
| 376 EXPECT_TRUE(stream2.start_called()); | 412 EXPECT_TRUE(stream2.start_called()); |
| 377 } | 413 } |
| 378 | 414 |
| 379 void StartFailed(AudioOutputDispatcher* dispatcher) { | 415 void StartFailed(AudioOutputDispatcher* dispatcher) { |
| 380 MockAudioOutputStream stream(&manager_, params_); | 416 MockAudioOutputStream stream(&manager_, params_); |
| 381 | 417 |
| 382 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 418 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 383 .WillOnce(Return(&stream)); | 419 .WillOnce(Return(&stream)); |
| 384 EXPECT_CALL(stream, Open()) | 420 EXPECT_CALL(stream, Open()) |
| 385 .WillOnce(Return(true)); | 421 .WillOnce(Return(true)); |
| 422 EXPECT_CALL(stream, Close()) |
| 423 .Times(1); |
| 386 | 424 |
| 387 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); | 425 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); |
| 388 EXPECT_TRUE(proxy->Open()); | 426 EXPECT_TRUE(proxy->Open()); |
| 389 | 427 |
| 390 WaitForCloseTimer(&stream); | 428 // Simulate a delay. |
| 429 base::PlatformThread::Sleep( |
| 430 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2); |
| 431 message_loop_.RunUntilIdle(); |
| 432 |
| 433 // Verify expectation before calling Close(). |
| 434 Mock::VerifyAndClear(&stream); |
| 391 | 435 |
| 392 // |stream| is closed at this point. Start() should reopen it again. | 436 // |stream| is closed at this point. Start() should reopen it again. |
| 393 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 437 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 394 .Times(2) | 438 .Times(2) |
| 395 .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL))); | 439 .WillRepeatedly(Return(reinterpret_cast<AudioOutputStream*>(NULL))); |
| 396 | 440 |
| 397 EXPECT_CALL(callback_, OnError(_)) | 441 EXPECT_CALL(callback_, OnError(_)) |
| 398 .Times(2); | 442 .Times(2); |
| 399 | 443 |
| 400 proxy->Start(&callback_); | 444 proxy->Start(&callback_); |
| 401 | 445 |
| 402 // Double Start() in the error case should be allowed since it's possible a | 446 // Double Start() in the error case should be allowed since it's possible a |
| 403 // callback may not have had time to process the OnError() in between. | 447 // callback may not have had time to process the OnError() in between. |
| 404 proxy->Stop(); | 448 proxy->Stop(); |
| 405 proxy->Start(&callback_); | 449 proxy->Start(&callback_); |
| 406 | 450 |
| 407 Mock::VerifyAndClear(&callback_); | 451 Mock::VerifyAndClear(&callback_); |
| 408 | 452 |
| 409 proxy->Close(); | 453 proxy->Close(); |
| 410 } | 454 } |
| 411 | 455 |
| 412 base::MessageLoop message_loop_; | 456 base::MessageLoop message_loop_; |
| 413 scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_; | 457 scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_; |
| 458 base::TimeDelta pause_delay_; |
| 414 MockAudioManager manager_; | 459 MockAudioManager manager_; |
| 415 MockAudioSourceCallback callback_; | 460 MockAudioSourceCallback callback_; |
| 416 AudioParameters params_; | 461 AudioParameters params_; |
| 417 }; | 462 }; |
| 418 | 463 |
| 419 class AudioOutputResamplerTest : public AudioOutputProxyTest { | 464 class AudioOutputResamplerTest : public AudioOutputProxyTest { |
| 420 public: | 465 public: |
| 421 virtual void TearDown() { | 466 virtual void TearDown() { |
| 422 AudioOutputProxyTest::TearDown(); | 467 AudioOutputProxyTest::TearDown(); |
| 423 } | 468 } |
| 424 | 469 |
| 425 virtual void InitDispatcher(base::TimeDelta close_delay) OVERRIDE { | 470 virtual void InitDispatcher(base::TimeDelta close_delay) OVERRIDE { |
| 471 AudioOutputProxyTest::InitDispatcher(close_delay); |
| 426 // Use a low sample rate and large buffer size when testing otherwise the | 472 // Use a low sample rate and large buffer size when testing otherwise the |
| 427 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e., | 473 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e., |
| 428 // RunUntilIdle() will never terminate. | 474 // RunUntilIdle() will never terminate. |
| 429 resampler_params_ = AudioParameters( | 475 resampler_params_ = AudioParameters( |
| 430 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, | 476 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, |
| 431 16000, 16, 1024); | 477 16000, 16, 1024); |
| 432 resampler_ = new AudioOutputResampler( | 478 resampler_ = new AudioOutputResampler( |
| 433 &manager(), params_, resampler_params_, std::string(), std::string(), | 479 &manager(), params_, resampler_params_, std::string(), std::string(), |
| 434 close_delay); | 480 close_delay); |
| 435 } | 481 } |
| 436 | 482 |
| 437 virtual void OnStart() OVERRIDE { | 483 virtual void OnStart() OVERRIDE { |
| 438 // Let Start() run for a bit. | 484 // Let start run for a bit. |
| 439 base::RunLoop run_loop; | 485 message_loop_.RunUntilIdle(); |
| 440 message_loop_.PostDelayedTask( | 486 base::PlatformThread::Sleep( |
| 441 FROM_HERE, | |
| 442 run_loop.QuitClosure(), | |
| 443 base::TimeDelta::FromMilliseconds(kStartRunTimeMs)); | 487 base::TimeDelta::FromMilliseconds(kStartRunTimeMs)); |
| 444 run_loop.Run(); | |
| 445 } | 488 } |
| 446 | 489 |
| 447 protected: | 490 protected: |
| 448 AudioParameters resampler_params_; | 491 AudioParameters resampler_params_; |
| 449 scoped_refptr<AudioOutputResampler> resampler_; | 492 scoped_refptr<AudioOutputResampler> resampler_; |
| 450 }; | 493 }; |
| 451 | 494 |
| 452 TEST_F(AudioOutputProxyTest, CreateAndClose) { | 495 TEST_F(AudioOutputProxyTest, CreateAndClose) { |
| 453 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_); | 496 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_.get()); |
| 454 proxy->Close(); | 497 proxy->Close(); |
| 455 } | 498 } |
| 456 | 499 |
| 457 TEST_F(AudioOutputResamplerTest, CreateAndClose) { | 500 TEST_F(AudioOutputResamplerTest, CreateAndClose) { |
| 458 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 501 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
| 459 proxy->Close(); | 502 proxy->Close(); |
| 460 } | 503 } |
| 461 | 504 |
| 462 TEST_F(AudioOutputProxyTest, OpenAndClose) { | 505 TEST_F(AudioOutputProxyTest, OpenAndClose) { |
| 463 OpenAndClose(dispatcher_impl_); | 506 OpenAndClose(dispatcher_impl_.get()); |
| 464 } | 507 } |
| 465 | 508 |
| 466 TEST_F(AudioOutputResamplerTest, OpenAndClose) { | 509 TEST_F(AudioOutputResamplerTest, OpenAndClose) { |
| 467 OpenAndClose(resampler_); | 510 OpenAndClose(resampler_.get()); |
| 468 } | 511 } |
| 469 | 512 |
| 470 // Create a stream, and verify that it is closed after kTestCloseDelayMs. | 513 // Create a stream, and verify that it is closed after kTestCloseDelayMs. |
| 471 // if it doesn't start playing. | 514 // if it doesn't start playing. |
| 472 TEST_F(AudioOutputProxyTest, CreateAndWait) { | 515 TEST_F(AudioOutputProxyTest, CreateAndWait) { |
| 473 CreateAndWait(dispatcher_impl_); | 516 CreateAndWait(dispatcher_impl_.get()); |
| 474 } | 517 } |
| 475 | 518 |
| 476 // Create a stream, and verify that it is closed after kTestCloseDelayMs. | 519 // Create a stream, and verify that it is closed after kTestCloseDelayMs. |
| 477 // if it doesn't start playing. | 520 // if it doesn't start playing. |
| 478 TEST_F(AudioOutputResamplerTest, CreateAndWait) { | 521 TEST_F(AudioOutputResamplerTest, CreateAndWait) { |
| 479 CreateAndWait(resampler_); | 522 CreateAndWait(resampler_.get()); |
| 480 } | 523 } |
| 481 | 524 |
| 482 TEST_F(AudioOutputProxyTest, StartAndStop) { | 525 TEST_F(AudioOutputProxyTest, StartAndStop) { |
| 483 StartAndStop(dispatcher_impl_); | 526 StartAndStop(dispatcher_impl_.get()); |
| 484 } | 527 } |
| 485 | 528 |
| 486 TEST_F(AudioOutputResamplerTest, StartAndStop) { | 529 TEST_F(AudioOutputResamplerTest, StartAndStop) { |
| 487 StartAndStop(resampler_); | 530 StartAndStop(resampler_.get()); |
| 488 } | 531 } |
| 489 | 532 |
| 490 TEST_F(AudioOutputProxyTest, CloseAfterStop) { | 533 TEST_F(AudioOutputProxyTest, CloseAfterStop) { |
| 491 CloseAfterStop(dispatcher_impl_); | 534 CloseAfterStop(dispatcher_impl_.get()); |
| 492 } | 535 } |
| 493 | 536 |
| 494 TEST_F(AudioOutputResamplerTest, CloseAfterStop) { | 537 TEST_F(AudioOutputResamplerTest, CloseAfterStop) { |
| 495 CloseAfterStop(resampler_); | 538 CloseAfterStop(resampler_.get()); |
| 496 } | 539 } |
| 497 | 540 |
| 498 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_); } | 541 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_.get()); } |
| 499 | 542 |
| 500 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_); } | 543 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_.get()); } |
| 501 | 544 |
| 502 // Two streams: verify that second stream is allocated when the first | 545 // Two streams: verify that second stream is allocated when the first |
| 503 // starts playing. | 546 // starts playing. |
| 504 TEST_F(AudioOutputProxyTest, OneStream_TwoPlays) { | 547 TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) { |
| 505 OneStream_TwoPlays(dispatcher_impl_); | 548 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); |
| 549 TwoStreams_OnePlaying(dispatcher_impl_.get()); |
| 506 } | 550 } |
| 507 | 551 |
| 508 TEST_F(AudioOutputResamplerTest, OneStream_TwoPlays) { | 552 TEST_F(AudioOutputResamplerTest, TwoStreams_OnePlaying) { |
| 509 OneStream_TwoPlays(resampler_); | 553 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); |
| 554 TwoStreams_OnePlaying(resampler_.get()); |
| 510 } | 555 } |
| 511 | 556 |
| 512 // Two streams, both are playing. Dispatcher should not open a third stream. | 557 // Two streams, both are playing. Dispatcher should not open a third stream. |
| 513 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { | 558 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { |
| 514 TwoStreams_BothPlaying(dispatcher_impl_); | 559 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); |
| 560 TwoStreams_BothPlaying(dispatcher_impl_.get()); |
| 515 } | 561 } |
| 516 | 562 |
| 517 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) { | 563 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) { |
| 518 TwoStreams_BothPlaying(resampler_); | 564 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); |
| 565 TwoStreams_BothPlaying(resampler_.get()); |
| 519 } | 566 } |
| 520 | 567 |
| 521 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_); } | 568 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_.get()); } |
| 522 | 569 |
| 523 // Start() method failed. | 570 // Start() method failed. |
| 524 TEST_F(AudioOutputProxyTest, StartFailed) { | 571 TEST_F(AudioOutputProxyTest, StartFailed) { |
| 525 StartFailed(dispatcher_impl_); | 572 StartFailed(dispatcher_impl_.get()); |
| 526 } | 573 } |
| 527 | 574 |
| 528 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_); } | 575 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_.get()); } |
| 529 | 576 |
| 530 // Simulate AudioOutputStream::Create() failure with a low latency stream and | 577 // Simulate AudioOutputStream::Create() failure with a low latency stream and |
| 531 // ensure AudioOutputResampler falls back to the high latency path. | 578 // ensure AudioOutputResampler falls back to the high latency path. |
| 532 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) { | 579 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) { |
| 533 MockAudioOutputStream stream(&manager_, params_); | 580 MockAudioOutputStream stream(&manager_, params_); |
| 534 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 581 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 535 .Times(2) | 582 .Times(2) |
| 536 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL))) | 583 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL))) |
| 537 .WillRepeatedly(Return(&stream)); | 584 .WillRepeatedly(Return(&stream)); |
| 538 EXPECT_CALL(stream, Open()) | 585 EXPECT_CALL(stream, Open()) |
| 539 .WillOnce(Return(true)); | 586 .WillOnce(Return(true)); |
| 587 EXPECT_CALL(stream, Close()) |
| 588 .Times(1); |
| 540 | 589 |
| 541 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 590 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
| 542 EXPECT_TRUE(proxy->Open()); | 591 EXPECT_TRUE(proxy->Open()); |
| 543 CloseAndWaitForCloseTimer(proxy, &stream); | 592 proxy->Close(); |
| 593 WaitForCloseTimer(kTestCloseDelayMs); |
| 544 } | 594 } |
| 545 | 595 |
| 546 // Simulate AudioOutputStream::Open() failure with a low latency stream and | 596 // Simulate AudioOutputStream::Open() failure with a low latency stream and |
| 547 // ensure AudioOutputResampler falls back to the high latency path. | 597 // ensure AudioOutputResampler falls back to the high latency path. |
| 548 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) { | 598 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) { |
| 549 MockAudioOutputStream failed_stream(&manager_, params_); | 599 MockAudioOutputStream failed_stream(&manager_, params_); |
| 550 MockAudioOutputStream okay_stream(&manager_, params_); | 600 MockAudioOutputStream okay_stream(&manager_, params_); |
| 551 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 601 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 552 .Times(2) | 602 .Times(2) |
| 553 .WillOnce(Return(&failed_stream)) | 603 .WillOnce(Return(&failed_stream)) |
| 554 .WillRepeatedly(Return(&okay_stream)); | 604 .WillRepeatedly(Return(&okay_stream)); |
| 555 EXPECT_CALL(failed_stream, Open()) | 605 EXPECT_CALL(failed_stream, Open()) |
| 556 .WillOnce(Return(false)); | 606 .WillOnce(Return(false)); |
| 557 EXPECT_CALL(failed_stream, Close()) | 607 EXPECT_CALL(failed_stream, Close()) |
| 558 .Times(1); | 608 .Times(1); |
| 559 EXPECT_CALL(okay_stream, Open()) | 609 EXPECT_CALL(okay_stream, Open()) |
| 560 .WillOnce(Return(true)); | 610 .WillOnce(Return(true)); |
| 611 EXPECT_CALL(okay_stream, Close()) |
| 612 .Times(1); |
| 561 | 613 |
| 562 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 614 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
| 563 EXPECT_TRUE(proxy->Open()); | 615 EXPECT_TRUE(proxy->Open()); |
| 564 CloseAndWaitForCloseTimer(proxy, &okay_stream); | 616 proxy->Close(); |
| 617 WaitForCloseTimer(kTestCloseDelayMs); |
| 565 } | 618 } |
| 566 | 619 |
| 567 // Simulate failures to open both the low latency and the fallback high latency | 620 // Simulate failures to open both the low latency and the fallback high latency |
| 568 // stream and ensure AudioOutputResampler falls back to a fake stream. | 621 // stream and ensure AudioOutputResampler falls back to a fake stream. |
| 569 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) { | 622 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) { |
| 570 MockAudioOutputStream okay_stream(&manager_, params_); | 623 MockAudioOutputStream okay_stream(&manager_, params_); |
| 571 | 624 |
| 572 // Only Windows has a high latency output driver that is not the same as the low | 625 // Only Windows has a high latency output driver that is not the same as the low |
| 573 // latency path. | 626 // latency path. |
| 574 #if defined(OS_WIN) | 627 #if defined(OS_WIN) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 585 EXPECT_CALL(manager(), MakeAudioOutputStream(AllOf( | 638 EXPECT_CALL(manager(), MakeAudioOutputStream(AllOf( |
| 586 testing::Property(&AudioParameters::format, AudioParameters::AUDIO_FAKE), | 639 testing::Property(&AudioParameters::format, AudioParameters::AUDIO_FAKE), |
| 587 testing::Property(&AudioParameters::sample_rate, params_.sample_rate()), | 640 testing::Property(&AudioParameters::sample_rate, params_.sample_rate()), |
| 588 testing::Property( | 641 testing::Property( |
| 589 &AudioParameters::frames_per_buffer, params_.frames_per_buffer())), | 642 &AudioParameters::frames_per_buffer, params_.frames_per_buffer())), |
| 590 _, _)) | 643 _, _)) |
| 591 .Times(1) | 644 .Times(1) |
| 592 .WillOnce(Return(&okay_stream)); | 645 .WillOnce(Return(&okay_stream)); |
| 593 EXPECT_CALL(okay_stream, Open()) | 646 EXPECT_CALL(okay_stream, Open()) |
| 594 .WillOnce(Return(true)); | 647 .WillOnce(Return(true)); |
| 648 EXPECT_CALL(okay_stream, Close()) |
| 649 .Times(1); |
| 595 | 650 |
| 596 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 651 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
| 597 EXPECT_TRUE(proxy->Open()); | 652 EXPECT_TRUE(proxy->Open()); |
| 598 CloseAndWaitForCloseTimer(proxy, &okay_stream); | 653 proxy->Close(); |
| 654 WaitForCloseTimer(kTestCloseDelayMs); |
| 599 } | 655 } |
| 600 | 656 |
| 601 // Simulate failures to open both the low latency, the fallback high latency | 657 // Simulate failures to open both the low latency, the fallback high latency |
| 602 // stream, and the fake audio output stream and ensure AudioOutputResampler | 658 // stream, and the fake audio output stream and ensure AudioOutputResampler |
| 603 // terminates normally. | 659 // terminates normally. |
| 604 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) { | 660 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) { |
| 605 // Only Windows has a high latency output driver that is not the same as the low | 661 // Only Windows has a high latency output driver that is not the same as the low |
| 606 // latency path. | 662 // latency path. |
| 607 #if defined(OS_WIN) | 663 #if defined(OS_WIN) |
| 608 static const int kFallbackCount = 3; | 664 static const int kFallbackCount = 3; |
| 609 #else | 665 #else |
| 610 static const int kFallbackCount = 2; | 666 static const int kFallbackCount = 2; |
| 611 #endif | 667 #endif |
| 612 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 668 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 613 .Times(kFallbackCount) | 669 .Times(kFallbackCount) |
| 614 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); | 670 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); |
| 615 | 671 |
| 616 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 672 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
| 617 EXPECT_FALSE(proxy->Open()); | 673 EXPECT_FALSE(proxy->Open()); |
| 618 proxy->Close(); | 674 proxy->Close(); |
| 675 WaitForCloseTimer(kTestCloseDelayMs); |
| 619 } | 676 } |
| 620 | 677 |
| 621 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls | 678 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls |
| 622 // eventually followed by one which fails; root cause of http://crbug.com/150619 | 679 // eventually followed by one which fails; root cause of http://crbug.com/150619 |
| 623 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) { | 680 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) { |
| 624 MockAudioOutputStream stream1(&manager_, params_); | 681 MockAudioOutputStream stream1(&manager_, params_); |
| 625 MockAudioOutputStream stream2(&manager_, params_); | 682 MockAudioOutputStream stream2(&manager_, params_); |
| 683 MockAudioOutputStream stream3(&manager_, params_); |
| 626 | 684 |
| 627 // Setup the mock such that all three streams are successfully created. | 685 // Setup the mock such that all three streams are successfully created. |
| 628 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) | 686 EXPECT_CALL(manager(), MakeAudioOutputStream(_, _, _)) |
| 629 .WillOnce(Return(&stream1)) | 687 .WillOnce(Return(&stream1)) |
| 630 .WillOnce(Return(&stream2)) | 688 .WillOnce(Return(&stream2)) |
| 689 .WillOnce(Return(&stream3)) |
| 631 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); | 690 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); |
| 632 | 691 |
| 633 // Stream1 should be able to successfully open and start. | 692 // Stream1 should be able to successfully open and start. |
| 634 EXPECT_CALL(stream1, Open()) | 693 EXPECT_CALL(stream1, Open()) |
| 635 .WillOnce(Return(true)); | 694 .WillOnce(Return(true)); |
| 695 EXPECT_CALL(stream1, Close()) |
| 696 .Times(1); |
| 636 EXPECT_CALL(stream1, SetVolume(_)) | 697 EXPECT_CALL(stream1, SetVolume(_)) |
| 637 .Times(1); | 698 .Times(1); |
| 638 | 699 |
| 639 // Stream2 should also be able to successfully open and start. | 700 // Stream2 should also be able to successfully open and start. |
| 640 EXPECT_CALL(stream2, Open()) | 701 EXPECT_CALL(stream2, Open()) |
| 641 .WillOnce(Return(true)); | 702 .WillOnce(Return(true)); |
| 703 EXPECT_CALL(stream2, Close()) |
| 704 .Times(1); |
| 642 EXPECT_CALL(stream2, SetVolume(_)) | 705 EXPECT_CALL(stream2, SetVolume(_)) |
| 643 .Times(1); | 706 .Times(1); |
| 644 | 707 |
| 708 // Stream3 should fail on Open() (yet still be closed since |
| 709 // MakeAudioOutputStream returned a valid AudioOutputStream object). |
| 710 EXPECT_CALL(stream3, Open()) |
| 711 .WillOnce(Return(false)); |
| 712 EXPECT_CALL(stream3, Close()) |
| 713 .Times(1); |
| 714 |
| 645 // Open and start the first proxy and stream. | 715 // Open and start the first proxy and stream. |
| 646 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_); | 716 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_.get()); |
| 647 EXPECT_TRUE(proxy1->Open()); | 717 EXPECT_TRUE(proxy1->Open()); |
| 648 proxy1->Start(&callback_); | 718 proxy1->Start(&callback_); |
| 649 OnStart(); | 719 OnStart(); |
| 650 | 720 |
| 651 // Open and start the second proxy and stream. | 721 // Open and start the second proxy and stream. |
| 652 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_); | 722 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_.get()); |
| 653 EXPECT_TRUE(proxy2->Open()); | 723 EXPECT_TRUE(proxy2->Open()); |
| 654 proxy2->Start(&callback_); | 724 proxy2->Start(&callback_); |
| 655 OnStart(); | 725 OnStart(); |
| 656 | 726 |
| 657 // Attempt to open the third stream which should fail. | 727 // Attempt to open the third stream which should fail. |
| 658 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_); | 728 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_.get()); |
| 659 EXPECT_FALSE(proxy3->Open()); | 729 EXPECT_FALSE(proxy3->Open()); |
| 660 proxy3->Close(); | |
| 661 | 730 |
| 662 // Perform the required Stop()/Close() shutdown dance for each proxy. Under | 731 // Perform the required Stop()/Close() shutdown dance for each proxy. Under |
| 663 // the hood each proxy should correctly call CloseStream() if OpenStream() | 732 // the hood each proxy should correctly call CloseStream() if OpenStream() |
| 664 // succeeded or not. | 733 // succeeded or not. |
| 734 proxy3->Stop(); |
| 735 proxy3->Close(); |
| 665 proxy2->Stop(); | 736 proxy2->Stop(); |
| 666 CloseAndWaitForCloseTimer(proxy2, &stream2); | 737 proxy2->Close(); |
| 738 proxy1->Stop(); |
| 739 proxy1->Close(); |
| 667 | 740 |
| 668 proxy1->Stop(); | 741 // Wait for all of the messages to fly and then verify stream behavior. |
| 669 CloseAndWaitForCloseTimer(proxy1, &stream1); | 742 WaitForCloseTimer(kTestCloseDelayMs); |
| 670 | |
| 671 EXPECT_TRUE(stream1.stop_called()); | 743 EXPECT_TRUE(stream1.stop_called()); |
| 672 EXPECT_TRUE(stream1.start_called()); | 744 EXPECT_TRUE(stream1.start_called()); |
| 673 EXPECT_TRUE(stream2.stop_called()); | 745 EXPECT_TRUE(stream2.stop_called()); |
| 674 EXPECT_TRUE(stream2.start_called()); | 746 EXPECT_TRUE(stream2.start_called()); |
| 747 EXPECT_FALSE(stream3.stop_called()); |
| 748 EXPECT_FALSE(stream3.start_called()); |
| 675 } | 749 } |
| 676 | 750 |
| 677 } // namespace media | 751 } // namespace media |
| OLD | NEW |