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