audio_output_proxy_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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/command_line.h" 8#include "base/message_loop.h" 9#include "base/message_loop_proxy.h" 10#include "media/audio/audio_output_dispatcher_impl.h" 11#include "media/audio/audio_output_proxy.h" 12#include "media/audio/audio_output_resampler.h" 13#include "media/audio/audio_manager.h" 14#include "media/audio/audio_manager_base.h" 15#include "media/audio/fake_audio_output_stream.h" 16#include "media/base/media_switches.h" 17#include "testing/gmock/include/gmock/gmock.h" 18#include "testing/gtest/include/gtest/gtest.h" 19 20// TODO(dalecurtis): Temporarily disabled while switching pipeline to use float, 21// http://crbug.com/114700 22#if defined(ENABLE_AUDIO_MIXER) 23#include "media/audio/audio_output_mixer.h" 24#endif 25 26using ::testing::_; 27using ::testing::AllOf; 28using ::testing::DoAll; 29using ::testing::Field; 30using ::testing::Mock; 31using ::testing::NotNull; 32using ::testing::Return; 33using ::testing::SetArrayArgument; 34using media::AudioBus; 35using media::AudioBuffersState; 36using media::AudioInputStream; 37using media::AudioManager; 38using media::AudioManagerBase; 39using media::AudioOutputDispatcher; 40using media::AudioOutputProxy; 41using media::AudioOutputStream; 42using media::AudioParameters; 43using media::FakeAudioOutputStream; 44 45namespace { 46 47static const int kTestCloseDelayMs = 100; 48 49// Used in the test where we don't want a stream to be closed unexpectedly. 50static const int kTestBigCloseDelaySeconds = 1000; 51 52// Delay between callbacks to AudioSourceCallback::OnMoreData. 53static const int kOnMoreDataCallbackDelayMs = 10; 54 55// Let start run long enough for many OnMoreData callbacks to occur. 56static const int kStartRunTimeMs = kOnMoreDataCallbackDelayMs * 10; 57 58class MockAudioOutputStream : public AudioOutputStream { 59 public: 60 MockAudioOutputStream(AudioManagerBase* manager, 61 const AudioParameters& params) 62 : start_called_(false), 63 stop_called_(false), 64 params_(params), 65 fake_output_stream_( 66 FakeAudioOutputStream::MakeFakeStream(manager, params_)) { 67 } 68 69 void Start(AudioSourceCallback* callback) { 70 start_called_ = true; 71 fake_output_stream_->Start(callback); 72 } 73 74 void Stop() { 75 stop_called_ = true; 76 fake_output_stream_->Stop(); 77 } 78 79 ~MockAudioOutputStream() {} 80 81 bool start_called() { return start_called_; } 82 bool stop_called() { return stop_called_; } 83 84 MOCK_METHOD0(Open, bool()); 85 MOCK_METHOD1(SetVolume, void(double volume)); 86 MOCK_METHOD1(GetVolume, void(double* volume)); 87 MOCK_METHOD0(Close, void()); 88 89 private: 90 bool start_called_; 91 bool stop_called_; 92 AudioParameters params_; 93 scoped_ptr<AudioOutputStream> fake_output_stream_; 94}; 95 96class MockAudioManager : public AudioManagerBase { 97 public: 98 MockAudioManager() {} 99 virtual ~MockAudioManager() { 100 Shutdown(); 101 } 102 103 MOCK_METHOD0(HasAudioOutputDevices, bool()); 104 MOCK_METHOD0(HasAudioInputDevices, bool()); 105 MOCK_METHOD0(GetAudioInputDeviceModel, string16()); 106 MOCK_METHOD1(MakeAudioOutputStream, AudioOutputStream*( 107 const AudioParameters& params)); 108 MOCK_METHOD1(MakeAudioOutputStreamProxy, AudioOutputStream*( 109 const AudioParameters& params)); 110 MOCK_METHOD2(MakeAudioInputStream, AudioInputStream*( 111 const AudioParameters& params, const std::string& device_id)); 112 MOCK_METHOD0(CanShowAudioInputSettings, bool()); 113 MOCK_METHOD0(ShowAudioInputSettings, void()); 114 MOCK_METHOD0(GetMessageLoop, scoped_refptr<base::MessageLoopProxy>()); 115 MOCK_METHOD1(GetAudioInputDeviceNames, void( 116 media::AudioDeviceNames* device_name)); 117 MOCK_METHOD0(IsRecordingInProcess, bool()); 118 119 MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*( 120 const AudioParameters& params)); 121 MOCK_METHOD1(MakeLowLatencyOutputStream, AudioOutputStream*( 122 const AudioParameters& params)); 123 MOCK_METHOD2(MakeLinearInputStream, AudioInputStream*( 124 const AudioParameters& params, const std::string& device_id)); 125 MOCK_METHOD2(MakeLowLatencyInputStream, AudioInputStream*( 126 const AudioParameters& params, const std::string& device_id)); 127}; 128 129class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { 130 public: 131 int OnMoreData(AudioBus* audio_bus, AudioBuffersState buffers_state) { 132 audio_bus->Zero(); 133 return audio_bus->frames(); 134 } 135 int OnMoreIOData(AudioBus* source, AudioBus* dest, 136 AudioBuffersState buffers_state) { 137 return OnMoreData(dest, buffers_state); 138 } 139 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); 140}; 141 142} // namespace 143 144namespace media { 145 146class AudioOutputProxyTest : public testing::Test { 147 protected: 148 virtual void SetUp() { 149 EXPECT_CALL(manager_, GetMessageLoop()) 150 .WillRepeatedly(Return(message_loop_.message_loop_proxy())); 151 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs)); 152 } 153 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 159 // closed by the test. 160 message_loop_.RunAllPending(); 161 } 162 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 // RunAllPending() will never terminate. 167 params_ = AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 168 CHANNEL_LAYOUT_STEREO, 8000, 16, 2048); 169 dispatcher_impl_ = new AudioOutputDispatcherImpl(&manager(), 170 params_, 171 close_delay); 172#if defined(ENABLE_AUDIO_MIXER) 173 mixer_ = new AudioOutputMixer(&manager(), params_, close_delay); 174#endif 175 176 // Necessary to know how long the dispatcher will wait before posting 177 // StopStreamTask. 178 pause_delay_ = dispatcher_impl_->pause_delay_; 179 } 180 181 virtual void OnStart() {} 182 183 MockAudioManager& manager() { 184 return manager_; 185 } 186 187 // Wait for the close timer to fire. 188 void WaitForCloseTimer(const int timer_delay_ms) { 189 message_loop_.RunAllPending(); // OpenTask() may reset the timer. 190 base::PlatformThread::Sleep( 191 base::TimeDelta::FromMilliseconds(timer_delay_ms) * 2); 192 message_loop_.RunAllPending(); 193 } 194 195 // Methods that do actual tests. 196 void OpenAndClose(AudioOutputDispatcher* dispatcher) { 197 MockAudioOutputStream stream(&manager_, params_); 198 199 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 200 .WillOnce(Return(&stream)); 201 EXPECT_CALL(stream, Open()) 202 .WillOnce(Return(true)); 203 EXPECT_CALL(stream, Close()) 204 .Times(1); 205 206 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); 207 EXPECT_TRUE(proxy->Open()); 208 proxy->Close(); 209 WaitForCloseTimer(kTestCloseDelayMs); 210 } 211 212 // Create a stream, and then calls Start() and Stop(). 213 void StartAndStop(AudioOutputDispatcher* dispatcher) { 214 MockAudioOutputStream stream(&manager_, params_); 215 216 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 217 .WillOnce(Return(&stream)); 218 EXPECT_CALL(stream, Open()) 219 .WillOnce(Return(true)); 220 EXPECT_CALL(stream, SetVolume(_)) 221 .Times(1); 222 EXPECT_CALL(stream, Close()) 223 .Times(1); 224 225 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); 226 EXPECT_TRUE(proxy->Open()); 227 228 proxy->Start(&callback_); 229 OnStart(); 230 proxy->Stop(); 231 232 proxy->Close(); 233 WaitForCloseTimer(kTestCloseDelayMs); 234 EXPECT_TRUE(stream.stop_called()); 235 EXPECT_TRUE(stream.start_called()); 236 } 237 238 // Verify that the stream is closed after Stop is called. 239 void CloseAfterStop(AudioOutputDispatcher* dispatcher) { 240 MockAudioOutputStream stream(&manager_, params_); 241 242 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 243 .WillOnce(Return(&stream)); 244 EXPECT_CALL(stream, Open()) 245 .WillOnce(Return(true)); 246 EXPECT_CALL(stream, SetVolume(_)) 247 .Times(1); 248 EXPECT_CALL(stream, Close()) 249 .Times(1); 250 251 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); 252 EXPECT_TRUE(proxy->Open()); 253 254 proxy->Start(&callback_); 255 OnStart(); 256 proxy->Stop(); 257 258 // Wait for StopStream() to post StopStreamTask(). 259 base::PlatformThread::Sleep(pause_delay_ * 2); 260 WaitForCloseTimer(kTestCloseDelayMs); 261 262 // Verify expectation before calling Close(). 263 Mock::VerifyAndClear(&stream); 264 265 proxy->Close(); 266 EXPECT_TRUE(stream.stop_called()); 267 EXPECT_TRUE(stream.start_called()); 268 } 269 270 // Create two streams, but don't start them. Only one device must be open. 271 void TwoStreams(AudioOutputDispatcher* dispatcher) { 272 MockAudioOutputStream stream(&manager_, params_); 273 274 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 275 .WillOnce(Return(&stream)); 276 EXPECT_CALL(stream, Open()) 277 .WillOnce(Return(true)); 278 EXPECT_CALL(stream, Close()) 279 .Times(1); 280 281 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); 282 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); 283 EXPECT_TRUE(proxy1->Open()); 284 EXPECT_TRUE(proxy2->Open()); 285 proxy1->Close(); 286 proxy2->Close(); 287 WaitForCloseTimer(kTestCloseDelayMs); 288 EXPECT_FALSE(stream.stop_called()); 289 EXPECT_FALSE(stream.start_called()); 290 } 291 292 // Open() method failed. 293 void OpenFailed(AudioOutputDispatcher* dispatcher) { 294 MockAudioOutputStream stream(&manager_, params_); 295 296 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 297 .WillOnce(Return(&stream)); 298 EXPECT_CALL(stream, Open()) 299 .WillOnce(Return(false)); 300 EXPECT_CALL(stream, Close()) 301 .Times(1); 302 303 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); 304 EXPECT_FALSE(proxy->Open()); 305 proxy->Close(); 306 WaitForCloseTimer(kTestCloseDelayMs); 307 EXPECT_FALSE(stream.stop_called()); 308 EXPECT_FALSE(stream.start_called()); 309 } 310 311 void CreateAndWait(AudioOutputDispatcher* dispatcher) { 312 MockAudioOutputStream stream(&manager_, params_); 313 314 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 315 .WillOnce(Return(&stream)); 316 EXPECT_CALL(stream, Open()) 317 .WillOnce(Return(true)); 318 EXPECT_CALL(stream, Close()) 319 .Times(1); 320 321 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher); 322 EXPECT_TRUE(proxy->Open()); 323 324 // Simulate a delay. 325 base::PlatformThread::Sleep( 326 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2); 327 message_loop_.RunAllPending(); 328 329 // Verify expectation before calling Close(). 330 Mock::VerifyAndClear(&stream); 331 332 proxy->Close(); 333 EXPECT_FALSE(stream.stop_called()); 334 EXPECT_FALSE(stream.start_called()); 335 } 336 337 void TwoStreams_OnePlaying(AudioOutputDispatcher* dispatcher) { 338 MockAudioOutputStream stream1(&manager_, params_); 339 MockAudioOutputStream stream2(&manager_, params_); 340 341 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 342 .WillOnce(Return(&stream1)) 343 .WillOnce(Return(&stream2)); 344 345 EXPECT_CALL(stream1, Open()) 346 .WillOnce(Return(true)); 347 EXPECT_CALL(stream1, SetVolume(_)) 348 .Times(1); 349 EXPECT_CALL(stream1, Close()) 350 .Times(1); 351 352 EXPECT_CALL(stream2, Open()) 353 .WillOnce(Return(true)); 354 EXPECT_CALL(stream2, Close()) 355 .Times(1); 356 357 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); 358 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); 359 EXPECT_TRUE(proxy1->Open()); 360 EXPECT_TRUE(proxy2->Open()); 361 362 proxy1->Start(&callback_); 363 message_loop_.RunAllPending(); 364 OnStart(); 365 proxy1->Stop(); 366 367 proxy1->Close(); 368 proxy2->Close(); 369 EXPECT_TRUE(stream1.stop_called()); 370 EXPECT_TRUE(stream1.start_called()); 371 EXPECT_FALSE(stream2.stop_called()); 372 EXPECT_FALSE(stream2.start_called()); 373 } 374 375 void TwoStreams_BothPlaying(AudioOutputDispatcher* dispatcher) { 376 MockAudioOutputStream stream1(&manager_, params_); 377 MockAudioOutputStream stream2(&manager_, params_); 378 379 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 380 .WillOnce(Return(&stream1)) 381 .WillOnce(Return(&stream2)); 382 383 EXPECT_CALL(stream1, Open()) 384 .WillOnce(Return(true)); 385 EXPECT_CALL(stream1, SetVolume(_)) 386 .Times(1); 387 EXPECT_CALL(stream1, Close()) 388 .Times(1); 389 390 EXPECT_CALL(stream2, Open()) 391 .WillOnce(Return(true)); 392 EXPECT_CALL(stream2, SetVolume(_)) 393 .Times(1); 394 EXPECT_CALL(stream2, Close()) 395 .Times(1); 396 397 AudioOutputProxy* proxy1 = new AudioOutputProxy(dispatcher); 398 AudioOutputProxy* proxy2 = new AudioOutputProxy(dispatcher); 399 EXPECT_TRUE(proxy1->Open()); 400 EXPECT_TRUE(proxy2->Open()); 401 402 proxy1->Start(&callback_); 403 proxy2->Start(&callback_); 404 OnStart(); 405 proxy1->Stop(); 406 proxy2->Stop(); 407 408 proxy1->Close(); 409 proxy2->Close(); 410 EXPECT_TRUE(stream1.stop_called()); 411 EXPECT_TRUE(stream1.start_called()); 412 EXPECT_TRUE(stream2.stop_called()); 413 EXPECT_TRUE(stream2.start_called()); 414 } 415 416 void StartFailed(AudioOutputDispatcher* dispatcher) { 417 MockAudioOutputStream stream(&manager_, params_); 418 419 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 420 .WillOnce(Return(&stream)); 421 EXPECT_CALL(stream, Open()) 422 .WillOnce(Return(true)); 423 EXPECT_CALL(stream, Close()) 424 .Times(1); 425 426 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_); 427 EXPECT_TRUE(proxy->Open()); 428 429 // Simulate a delay. 430 base::PlatformThread::Sleep( 431 base::TimeDelta::FromMilliseconds(kTestCloseDelayMs) * 2); 432 message_loop_.RunAllPending(); 433 434 // Verify expectation before calling Close(). 435 Mock::VerifyAndClear(&stream); 436 437 // |stream| is closed at this point. Start() should reopen it again. 438 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 439 .WillOnce(Return(reinterpret_cast<AudioOutputStream*>(NULL))); 440 441 EXPECT_CALL(callback_, OnError(_, _)) 442 .Times(1); 443 444 proxy->Start(&callback_); 445 446 Mock::VerifyAndClear(&callback_); 447 448 proxy->Close(); 449 } 450 451 MessageLoop message_loop_; 452 scoped_refptr<AudioOutputDispatcherImpl> dispatcher_impl_; 453#if defined(ENABLE_AUDIO_MIXER) 454 scoped_refptr<AudioOutputMixer> mixer_; 455#endif 456 base::TimeDelta pause_delay_; 457 MockAudioManager manager_; 458 MockAudioSourceCallback callback_; 459 AudioParameters params_; 460}; 461 462class AudioOutputResamplerTest : public AudioOutputProxyTest { 463 public: 464 virtual void TearDown() { 465 AudioOutputProxyTest::TearDown(); 466 } 467 468 virtual void InitDispatcher(base::TimeDelta close_delay) { 469 AudioOutputProxyTest::InitDispatcher(close_delay); 470 // Use a low sample rate and large buffer size when testing otherwise the 471 // FakeAudioOutputStream will keep the message loop busy indefinitely; i.e., 472 // RunAllPending() will never terminate. 473 resampler_params_ = AudioParameters( 474 AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO, 475 16000, 16, 1024); 476 resampler_ = new AudioOutputResampler( 477 &manager(), params_, resampler_params_, close_delay); 478 } 479 480 virtual void OnStart() { 481 // Let start run for a bit. 482 message_loop_.RunAllPending(); 483 base::PlatformThread::Sleep( 484 base::TimeDelta::FromMilliseconds(kStartRunTimeMs)); 485 } 486 487 protected: 488 AudioParameters resampler_params_; 489 scoped_refptr<AudioOutputResampler> resampler_; 490}; 491 492TEST_F(AudioOutputProxyTest, CreateAndClose) { 493 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_); 494 proxy->Close(); 495} 496 497#if defined(ENABLE_AUDIO_MIXER) 498TEST_F(AudioOutputProxyTest, CreateAndClose_Mixer) { 499 AudioOutputProxy* proxy = new AudioOutputProxy(mixer_); 500 proxy->Close(); 501} 502#endif 503 504TEST_F(AudioOutputResamplerTest, CreateAndClose) { 505 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); 506 proxy->Close(); 507} 508 509TEST_F(AudioOutputProxyTest, OpenAndClose) { 510 OpenAndClose(dispatcher_impl_); 511} 512 513#if defined(ENABLE_AUDIO_MIXER) 514TEST_F(AudioOutputProxyTest, OpenAndClose_Mixer) { 515 OpenAndClose(mixer_); 516} 517#endif 518 519TEST_F(AudioOutputResamplerTest, OpenAndClose) { 520 OpenAndClose(resampler_); 521} 522 523// Create a stream, and verify that it is closed after kTestCloseDelayMs. 524// if it doesn't start playing. 525TEST_F(AudioOutputProxyTest, CreateAndWait) { 526 CreateAndWait(dispatcher_impl_); 527} 528 529// Create a stream, and verify that it is closed after kTestCloseDelayMs. 530// if it doesn't start playing. 531TEST_F(AudioOutputResamplerTest, CreateAndWait) { 532 CreateAndWait(resampler_); 533} 534 535TEST_F(AudioOutputProxyTest, StartAndStop) { 536 StartAndStop(dispatcher_impl_); 537} 538 539#if defined(ENABLE_AUDIO_MIXER) 540TEST_F(AudioOutputProxyTest, StartAndStop_Mixer) { 541 StartAndStop(mixer_); 542} 543#endif 544 545TEST_F(AudioOutputResamplerTest, StartAndStop) { 546 StartAndStop(resampler_); 547} 548 549TEST_F(AudioOutputProxyTest, CloseAfterStop) { 550 CloseAfterStop(dispatcher_impl_); 551} 552 553#if defined(ENABLE_AUDIO_MIXER) 554TEST_F(AudioOutputProxyTest, CloseAfterStop_Mixer) { 555 CloseAfterStop(mixer_); 556} 557#endif 558 559TEST_F(AudioOutputResamplerTest, CloseAfterStop) { 560 CloseAfterStop(resampler_); 561} 562 563TEST_F(AudioOutputProxyTest, TwoStreams) { 564 TwoStreams(dispatcher_impl_); 565} 566 567#if defined(ENABLE_AUDIO_MIXER) 568TEST_F(AudioOutputProxyTest, TwoStreams_Mixer) { 569 TwoStreams(mixer_); 570} 571#endif 572 573TEST_F(AudioOutputResamplerTest, TwoStreams) { 574 TwoStreams(resampler_); 575} 576 577// Two streams: verify that second stream is allocated when the first 578// starts playing. 579TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) { 580 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); 581 TwoStreams_OnePlaying(dispatcher_impl_); 582} 583 584#if defined(ENABLE_AUDIO_MIXER) 585// Two streams: verify that only one device will be created. 586TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying_Mixer) { 587 MockAudioOutputStream stream(&manager_, params_); 588 589 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs)); 590 591 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 592 .WillOnce(Return(&stream)); 593 594 EXPECT_CALL(stream, Open()) 595 .WillOnce(Return(true)); 596 EXPECT_CALL(stream, Start(_)) 597 .Times(1); 598 EXPECT_CALL(stream, SetVolume(_)) 599 .Times(1); 600 EXPECT_CALL(stream, Stop()) 601 .Times(1); 602 EXPECT_CALL(stream, Close()) 603 .Times(1); 604 605 AudioOutputProxy* proxy1 = new AudioOutputProxy(mixer_); 606 AudioOutputProxy* proxy2 = new AudioOutputProxy(mixer_); 607 EXPECT_TRUE(proxy1->Open()); 608 EXPECT_TRUE(proxy2->Open()); 609 610 proxy1->Start(&callback_); 611 proxy1->Stop(); 612 613 proxy1->Close(); 614 proxy2->Close(); 615 WaitForCloseTimer(kTestCloseDelayMs); 616} 617#endif 618 619TEST_F(AudioOutputResamplerTest, TwoStreams_OnePlaying) { 620 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); 621 TwoStreams_OnePlaying(resampler_); 622} 623 624// Two streams, both are playing. Dispatcher should not open a third stream. 625TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { 626 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); 627 TwoStreams_BothPlaying(dispatcher_impl_); 628} 629 630#if defined(ENABLE_AUDIO_MIXER) 631// Two streams, both are playing. Still have to use single device. 632// Also verifies that every proxy stream gets its own pending_bytes. 633TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying_Mixer) { 634 MockAudioOutputStream stream(&manager_, params_); 635 636 InitDispatcher(base::TimeDelta::FromMilliseconds(kTestCloseDelayMs)); 637 638 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 639 .WillOnce(Return(&stream)); 640 641 EXPECT_CALL(stream, Open()) 642 .WillOnce(Return(true)); 643 EXPECT_CALL(stream, Start(_)) 644 .Times(1); 645 EXPECT_CALL(stream, SetVolume(_)) 646 .Times(1); 647 EXPECT_CALL(stream, Stop()) 648 .Times(1); 649 EXPECT_CALL(stream, Close()) 650 .Times(1); 651 652 AudioOutputProxy* proxy1 = new AudioOutputProxy(mixer_); 653 AudioOutputProxy* proxy2 = new AudioOutputProxy(mixer_); 654 EXPECT_TRUE(proxy1->Open()); 655 EXPECT_TRUE(proxy2->Open()); 656 657 proxy1->Start(&callback_); 658 659 // Mute the proxy. Resulting stream should still have correct length. 660 proxy1->SetVolume(0.0); 661 662 uint8 zeroes[4] = {0, 0, 0, 0}; 663 uint8 buf1[4] = {0}; 664 EXPECT_CALL(callback_, 665 OnMoreData(NotNull(), 4, 666 AllOf(Field(&AudioBuffersState::pending_bytes, 0), 667 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) 668 .WillOnce(DoAll(SetArrayArgument<0>(zeroes, zeroes + sizeof(zeroes)), 669 Return(4))); 670 mixer_->OnMoreData(buf1, sizeof(buf1), AudioBuffersState(0, 0)); 671 proxy2->Start(&callback_); 672 uint8 buf2[4] = {0}; 673 EXPECT_CALL(callback_, 674 OnMoreData(NotNull(), 4, 675 AllOf(Field(&AudioBuffersState::pending_bytes, 4), 676 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) 677 .WillOnce(DoAll(SetArrayArgument<0>(zeroes, zeroes + sizeof(zeroes)), 678 Return(4))); 679 EXPECT_CALL(callback_, 680 OnMoreData(NotNull(), 4, 681 AllOf(Field(&AudioBuffersState::pending_bytes, 0), 682 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) 683 .WillOnce(DoAll(SetArrayArgument<0>(zeroes, zeroes + sizeof(zeroes)), 684 Return(4))); 685 mixer_->OnMoreData(buf2, sizeof(buf2), AudioBuffersState(4, 0)); 686 proxy1->Stop(); 687 proxy2->Stop(); 688 689 proxy1->Close(); 690 proxy2->Close(); 691 WaitForCloseTimer(kTestCloseDelayMs); 692} 693#endif 694 695TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) { 696 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); 697 TwoStreams_BothPlaying(resampler_); 698} 699 700TEST_F(AudioOutputProxyTest, OpenFailed) { 701 OpenFailed(dispatcher_impl_); 702} 703 704#if defined(ENABLE_AUDIO_MIXER) 705TEST_F(AudioOutputProxyTest, OpenFailed_Mixer) { 706 OpenFailed(mixer_); 707} 708#endif 709 710TEST_F(AudioOutputResamplerTest, OpenFailed) { 711 CommandLine::ForCurrentProcess()->AppendSwitch( 712 switches::kDisableAudioFallback); 713 OpenFailed(resampler_); 714} 715 716// Start() method failed. 717TEST_F(AudioOutputProxyTest, StartFailed) { 718 StartFailed(dispatcher_impl_); 719} 720 721#if defined(ENABLE_AUDIO_MIXER) 722// Start() method failed. 723TEST_F(AudioOutputProxyTest, StartFailed_Mixer) { 724 MockAudioOutputStream stream(&manager_, params_); 725 726 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 727 .WillOnce(Return(&stream)); 728 EXPECT_CALL(stream, Open()) 729 .WillOnce(Return(true)); 730 EXPECT_CALL(stream, Close()) 731 .Times(1); 732 EXPECT_CALL(stream, Start(_)) 733 .Times(1); 734 EXPECT_CALL(stream, SetVolume(_)) 735 .Times(1); 736 EXPECT_CALL(stream, Stop()) 737 .Times(1); 738 739 AudioOutputProxy* proxy1 = new AudioOutputProxy(mixer_); 740 AudioOutputProxy* proxy2 = new AudioOutputProxy(mixer_); 741 EXPECT_TRUE(proxy1->Open()); 742 EXPECT_TRUE(proxy2->Open()); 743 proxy1->Start(&callback_); 744 proxy1->Stop(); 745 proxy1->Close(); 746 WaitForCloseTimer(kTestCloseDelayMs); 747 748 // Verify expectation before continueing. 749 Mock::VerifyAndClear(&stream); 750 751 // |stream| is closed at this point. Start() should reopen it again. 752 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 753 .WillOnce(Return(reinterpret_cast<AudioOutputStream*>(NULL))); 754 755 EXPECT_CALL(callback_, OnError(_, _)) 756 .Times(1); 757 758 proxy2->Start(&callback_); 759 760 Mock::VerifyAndClear(&callback_); 761 762 proxy2->Close(); 763 WaitForCloseTimer(kTestCloseDelayMs); 764} 765#endif 766 767TEST_F(AudioOutputResamplerTest, StartFailed) { 768 StartFailed(resampler_); 769} 770 771// Simulate AudioOutputStream::Create() failure with a low latency stream and 772// ensure AudioOutputResampler falls back to the high latency path. 773TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) { 774 MockAudioOutputStream stream(&manager_, params_); 775 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 776 .Times(2) 777 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL))) 778 .WillRepeatedly(Return(&stream)); 779 EXPECT_CALL(stream, Open()) 780 .WillOnce(Return(true)); 781 EXPECT_CALL(stream, Close()) 782 .Times(1); 783 784 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); 785 EXPECT_TRUE(proxy->Open()); 786 proxy->Close(); 787 WaitForCloseTimer(kTestCloseDelayMs); 788} 789 790// Simulate AudioOutputStream::Open() failure with a low latency stream and 791// ensure AudioOutputResampler falls back to the high latency path. 792TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) { 793 MockAudioOutputStream failed_stream(&manager_, params_); 794 MockAudioOutputStream okay_stream(&manager_, params_); 795 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 796 .Times(2) 797 .WillOnce(Return(&failed_stream)) 798 .WillRepeatedly(Return(&okay_stream)); 799 EXPECT_CALL(failed_stream, Open()) 800 .WillOnce(Return(false)); 801 EXPECT_CALL(failed_stream, Close()) 802 .Times(1); 803 EXPECT_CALL(okay_stream, Open()) 804 .WillOnce(Return(true)); 805 EXPECT_CALL(okay_stream, Close()) 806 .Times(1); 807 808 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); 809 EXPECT_TRUE(proxy->Open()); 810 proxy->Close(); 811 WaitForCloseTimer(kTestCloseDelayMs); 812} 813 814// Simulate failures to open both the low latency and the fallback high latency 815// stream and ensure AudioOutputResampler terminates normally. 816TEST_F(AudioOutputResamplerTest, LowLatencyFallbackFailed) { 817 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 818 .Times(2) 819 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); 820 821 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); 822 EXPECT_FALSE(proxy->Open()); 823 proxy->Close(); 824 WaitForCloseTimer(kTestCloseDelayMs); 825} 826 827// Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls 828// eventually followed by one which fails; root cause of http://crbug.com/150619 829TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) { 830 MockAudioOutputStream stream1(&manager_, params_); 831 MockAudioOutputStream stream2(&manager_, params_); 832 MockAudioOutputStream stream3(&manager_, params_); 833 834 // Setup the mock such that all three streams are successfully created. 835 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) 836 .WillOnce(Return(&stream1)) 837 .WillOnce(Return(&stream2)) 838 .WillOnce(Return(&stream3)) 839 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); 840 841 // Stream1 should be able to successfully open and start. 842 EXPECT_CALL(stream1, Open()) 843 .WillOnce(Return(true)); 844 EXPECT_CALL(stream1, Close()) 845 .Times(1); 846 EXPECT_CALL(stream1, SetVolume(_)) 847 .Times(1); 848 849 // Stream2 should also be able to successfully open and start. 850 EXPECT_CALL(stream2, Open()) 851 .WillOnce(Return(true)); 852 EXPECT_CALL(stream2, Close()) 853 .Times(1); 854 EXPECT_CALL(stream2, SetVolume(_)) 855 .Times(1); 856 857 // Stream3 should fail on Open() (yet still be closed since 858 // MakeAudioOutputStream returned a valid AudioOutputStream object). 859 EXPECT_CALL(stream3, Open()) 860 .WillOnce(Return(false)); 861 EXPECT_CALL(stream3, Close()) 862 .Times(1); 863 864 // Open and start the first proxy and stream. 865 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_); 866 EXPECT_TRUE(proxy1->Open()); 867 proxy1->Start(&callback_); 868 OnStart(); 869 870 // Open and start the second proxy and stream. 871 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_); 872 EXPECT_TRUE(proxy2->Open()); 873 proxy2->Start(&callback_); 874 OnStart(); 875 876 // Attempt to open the third stream which should fail. 877 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_); 878 EXPECT_FALSE(proxy3->Open()); 879 880 // Perform the required Stop()/Close() shutdown dance for each proxy. Under 881 // the hood each proxy should correctly call CloseStream() if OpenStream() 882 // succeeded or not. 883 proxy3->Stop(); 884 proxy3->Close(); 885 proxy2->Stop(); 886 proxy2->Close(); 887 proxy1->Stop(); 888 proxy1->Close(); 889 890 // Wait for all of the messages to fly and then verify stream behavior. 891 WaitForCloseTimer(kTestCloseDelayMs); 892 EXPECT_TRUE(stream1.stop_called()); 893 EXPECT_TRUE(stream1.start_called()); 894 EXPECT_TRUE(stream2.stop_called()); 895 EXPECT_TRUE(stream2.start_called()); 896 EXPECT_FALSE(stream3.stop_called()); 897 EXPECT_FALSE(stream3.start_called()); 898} 899 900} // namespace media 901