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.h" | 7 #include "base/message_loop.h" |
8 #include "base/message_loop_proxy.h" | 8 #include "base/message_loop_proxy.h" |
9 #include "media/audio/audio_output_dispatcher_impl.h" | 9 #include "media/audio/audio_output_dispatcher_impl.h" |
10 #include "media/audio/audio_output_proxy.h" | 10 #include "media/audio/audio_output_proxy.h" |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 base::PlatformThread::Sleep( | 476 base::PlatformThread::Sleep( |
477 base::TimeDelta::FromMilliseconds(kStartRunTimeMs)); | 477 base::TimeDelta::FromMilliseconds(kStartRunTimeMs)); |
478 } | 478 } |
479 | 479 |
480 protected: | 480 protected: |
481 AudioParameters resampler_params_; | 481 AudioParameters resampler_params_; |
482 scoped_refptr<AudioOutputResampler> resampler_; | 482 scoped_refptr<AudioOutputResampler> resampler_; |
483 }; | 483 }; |
484 | 484 |
485 TEST_F(AudioOutputProxyTest, CreateAndClose) { | 485 TEST_F(AudioOutputProxyTest, CreateAndClose) { |
486 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_); | 486 AudioOutputProxy* proxy = new AudioOutputProxy(dispatcher_impl_.get()); |
487 proxy->Close(); | 487 proxy->Close(); |
488 } | 488 } |
489 | 489 |
490 TEST_F(AudioOutputResamplerTest, CreateAndClose) { | 490 TEST_F(AudioOutputResamplerTest, CreateAndClose) { |
491 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 491 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
492 proxy->Close(); | 492 proxy->Close(); |
493 } | 493 } |
494 | 494 |
495 TEST_F(AudioOutputProxyTest, OpenAndClose) { | 495 TEST_F(AudioOutputProxyTest, OpenAndClose) { |
496 OpenAndClose(dispatcher_impl_); | 496 OpenAndClose(dispatcher_impl_.get()); |
497 } | 497 } |
498 | 498 |
499 TEST_F(AudioOutputResamplerTest, OpenAndClose) { | 499 TEST_F(AudioOutputResamplerTest, OpenAndClose) { |
500 OpenAndClose(resampler_); | 500 OpenAndClose(resampler_.get()); |
501 } | 501 } |
502 | 502 |
503 // Create a stream, and verify that it is closed after kTestCloseDelayMs. | 503 // Create a stream, and verify that it is closed after kTestCloseDelayMs. |
504 // if it doesn't start playing. | 504 // if it doesn't start playing. |
505 TEST_F(AudioOutputProxyTest, CreateAndWait) { | 505 TEST_F(AudioOutputProxyTest, CreateAndWait) { |
506 CreateAndWait(dispatcher_impl_); | 506 CreateAndWait(dispatcher_impl_.get()); |
507 } | 507 } |
508 | 508 |
509 // Create a stream, and verify that it is closed after kTestCloseDelayMs. | 509 // Create a stream, and verify that it is closed after kTestCloseDelayMs. |
510 // if it doesn't start playing. | 510 // if it doesn't start playing. |
511 TEST_F(AudioOutputResamplerTest, CreateAndWait) { | 511 TEST_F(AudioOutputResamplerTest, CreateAndWait) { |
512 CreateAndWait(resampler_); | 512 CreateAndWait(resampler_.get()); |
513 } | 513 } |
514 | 514 |
515 TEST_F(AudioOutputProxyTest, StartAndStop) { | 515 TEST_F(AudioOutputProxyTest, StartAndStop) { |
516 StartAndStop(dispatcher_impl_); | 516 StartAndStop(dispatcher_impl_.get()); |
517 } | 517 } |
518 | 518 |
519 TEST_F(AudioOutputResamplerTest, StartAndStop) { | 519 TEST_F(AudioOutputResamplerTest, StartAndStop) { |
520 StartAndStop(resampler_); | 520 StartAndStop(resampler_.get()); |
521 } | 521 } |
522 | 522 |
523 TEST_F(AudioOutputProxyTest, CloseAfterStop) { | 523 TEST_F(AudioOutputProxyTest, CloseAfterStop) { |
524 CloseAfterStop(dispatcher_impl_); | 524 CloseAfterStop(dispatcher_impl_.get()); |
525 } | 525 } |
526 | 526 |
527 TEST_F(AudioOutputResamplerTest, CloseAfterStop) { | 527 TEST_F(AudioOutputResamplerTest, CloseAfterStop) { |
528 CloseAfterStop(resampler_); | 528 CloseAfterStop(resampler_.get()); |
529 } | 529 } |
530 | 530 |
531 TEST_F(AudioOutputProxyTest, TwoStreams) { | 531 TEST_F(AudioOutputProxyTest, TwoStreams) { TwoStreams(dispatcher_impl_.get()); } |
532 TwoStreams(dispatcher_impl_); | |
533 } | |
534 | 532 |
535 TEST_F(AudioOutputResamplerTest, TwoStreams) { | 533 TEST_F(AudioOutputResamplerTest, TwoStreams) { TwoStreams(resampler_.get()); } |
536 TwoStreams(resampler_); | |
537 } | |
538 | 534 |
539 // Two streams: verify that second stream is allocated when the first | 535 // Two streams: verify that second stream is allocated when the first |
540 // starts playing. | 536 // starts playing. |
541 TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) { | 537 TEST_F(AudioOutputProxyTest, TwoStreams_OnePlaying) { |
542 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); | 538 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); |
543 TwoStreams_OnePlaying(dispatcher_impl_); | 539 TwoStreams_OnePlaying(dispatcher_impl_.get()); |
544 } | 540 } |
545 | 541 |
546 TEST_F(AudioOutputResamplerTest, TwoStreams_OnePlaying) { | 542 TEST_F(AudioOutputResamplerTest, TwoStreams_OnePlaying) { |
547 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); | 543 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); |
548 TwoStreams_OnePlaying(resampler_); | 544 TwoStreams_OnePlaying(resampler_.get()); |
549 } | 545 } |
550 | 546 |
551 // Two streams, both are playing. Dispatcher should not open a third stream. | 547 // Two streams, both are playing. Dispatcher should not open a third stream. |
552 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { | 548 TEST_F(AudioOutputProxyTest, TwoStreams_BothPlaying) { |
553 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); | 549 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); |
554 TwoStreams_BothPlaying(dispatcher_impl_); | 550 TwoStreams_BothPlaying(dispatcher_impl_.get()); |
555 } | 551 } |
556 | 552 |
557 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) { | 553 TEST_F(AudioOutputResamplerTest, TwoStreams_BothPlaying) { |
558 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); | 554 InitDispatcher(base::TimeDelta::FromSeconds(kTestBigCloseDelaySeconds)); |
559 TwoStreams_BothPlaying(resampler_); | 555 TwoStreams_BothPlaying(resampler_.get()); |
560 } | 556 } |
561 | 557 |
562 TEST_F(AudioOutputProxyTest, OpenFailed) { | 558 TEST_F(AudioOutputProxyTest, OpenFailed) { OpenFailed(dispatcher_impl_.get()); } |
563 OpenFailed(dispatcher_impl_); | |
564 } | |
565 | 559 |
566 // Start() method failed. | 560 // Start() method failed. |
567 TEST_F(AudioOutputProxyTest, StartFailed) { | 561 TEST_F(AudioOutputProxyTest, StartFailed) { |
568 StartFailed(dispatcher_impl_); | 562 StartFailed(dispatcher_impl_.get()); |
569 } | 563 } |
570 | 564 |
571 TEST_F(AudioOutputResamplerTest, StartFailed) { | 565 TEST_F(AudioOutputResamplerTest, StartFailed) { StartFailed(resampler_.get()); } |
572 StartFailed(resampler_); | |
573 } | |
574 | 566 |
575 // Simulate AudioOutputStream::Create() failure with a low latency stream and | 567 // Simulate AudioOutputStream::Create() failure with a low latency stream and |
576 // ensure AudioOutputResampler falls back to the high latency path. | 568 // ensure AudioOutputResampler falls back to the high latency path. |
577 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) { | 569 TEST_F(AudioOutputResamplerTest, LowLatencyCreateFailedFallback) { |
578 MockAudioOutputStream stream(&manager_, params_); | 570 MockAudioOutputStream stream(&manager_, params_); |
579 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) | 571 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) |
580 .Times(2) | 572 .Times(2) |
581 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL))) | 573 .WillOnce(Return(static_cast<AudioOutputStream*>(NULL))) |
582 .WillRepeatedly(Return(&stream)); | 574 .WillRepeatedly(Return(&stream)); |
583 EXPECT_CALL(stream, Open()) | 575 EXPECT_CALL(stream, Open()) |
584 .WillOnce(Return(true)); | 576 .WillOnce(Return(true)); |
585 EXPECT_CALL(stream, Close()) | 577 EXPECT_CALL(stream, Close()) |
586 .Times(1); | 578 .Times(1); |
587 | 579 |
588 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 580 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
589 EXPECT_TRUE(proxy->Open()); | 581 EXPECT_TRUE(proxy->Open()); |
590 proxy->Close(); | 582 proxy->Close(); |
591 WaitForCloseTimer(kTestCloseDelayMs); | 583 WaitForCloseTimer(kTestCloseDelayMs); |
592 } | 584 } |
593 | 585 |
594 // Simulate AudioOutputStream::Open() failure with a low latency stream and | 586 // Simulate AudioOutputStream::Open() failure with a low latency stream and |
595 // ensure AudioOutputResampler falls back to the high latency path. | 587 // ensure AudioOutputResampler falls back to the high latency path. |
596 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) { | 588 TEST_F(AudioOutputResamplerTest, LowLatencyOpenFailedFallback) { |
597 MockAudioOutputStream failed_stream(&manager_, params_); | 589 MockAudioOutputStream failed_stream(&manager_, params_); |
598 MockAudioOutputStream okay_stream(&manager_, params_); | 590 MockAudioOutputStream okay_stream(&manager_, params_); |
599 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) | 591 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) |
600 .Times(2) | 592 .Times(2) |
601 .WillOnce(Return(&failed_stream)) | 593 .WillOnce(Return(&failed_stream)) |
602 .WillRepeatedly(Return(&okay_stream)); | 594 .WillRepeatedly(Return(&okay_stream)); |
603 EXPECT_CALL(failed_stream, Open()) | 595 EXPECT_CALL(failed_stream, Open()) |
604 .WillOnce(Return(false)); | 596 .WillOnce(Return(false)); |
605 EXPECT_CALL(failed_stream, Close()) | 597 EXPECT_CALL(failed_stream, Close()) |
606 .Times(1); | 598 .Times(1); |
607 EXPECT_CALL(okay_stream, Open()) | 599 EXPECT_CALL(okay_stream, Open()) |
608 .WillOnce(Return(true)); | 600 .WillOnce(Return(true)); |
609 EXPECT_CALL(okay_stream, Close()) | 601 EXPECT_CALL(okay_stream, Close()) |
610 .Times(1); | 602 .Times(1); |
611 | 603 |
612 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 604 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
613 EXPECT_TRUE(proxy->Open()); | 605 EXPECT_TRUE(proxy->Open()); |
614 proxy->Close(); | 606 proxy->Close(); |
615 WaitForCloseTimer(kTestCloseDelayMs); | 607 WaitForCloseTimer(kTestCloseDelayMs); |
616 } | 608 } |
617 | 609 |
618 // Simulate failures to open both the low latency and the fallback high latency | 610 // Simulate failures to open both the low latency and the fallback high latency |
619 // stream and ensure AudioOutputResampler falls back to a fake stream. | 611 // stream and ensure AudioOutputResampler falls back to a fake stream. |
620 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) { | 612 TEST_F(AudioOutputResamplerTest, HighLatencyFallbackFailed) { |
621 MockAudioOutputStream okay_stream(&manager_, params_); | 613 MockAudioOutputStream okay_stream(&manager_, params_); |
622 | 614 |
(...skipping 15 matching lines...) Expand all Loading... |
638 testing::Property(&AudioParameters::sample_rate, params_.sample_rate()), | 630 testing::Property(&AudioParameters::sample_rate, params_.sample_rate()), |
639 testing::Property( | 631 testing::Property( |
640 &AudioParameters::frames_per_buffer, params_.frames_per_buffer())))) | 632 &AudioParameters::frames_per_buffer, params_.frames_per_buffer())))) |
641 .Times(1) | 633 .Times(1) |
642 .WillOnce(Return(&okay_stream)); | 634 .WillOnce(Return(&okay_stream)); |
643 EXPECT_CALL(okay_stream, Open()) | 635 EXPECT_CALL(okay_stream, Open()) |
644 .WillOnce(Return(true)); | 636 .WillOnce(Return(true)); |
645 EXPECT_CALL(okay_stream, Close()) | 637 EXPECT_CALL(okay_stream, Close()) |
646 .Times(1); | 638 .Times(1); |
647 | 639 |
648 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 640 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
649 EXPECT_TRUE(proxy->Open()); | 641 EXPECT_TRUE(proxy->Open()); |
650 proxy->Close(); | 642 proxy->Close(); |
651 WaitForCloseTimer(kTestCloseDelayMs); | 643 WaitForCloseTimer(kTestCloseDelayMs); |
652 } | 644 } |
653 | 645 |
654 // Simulate failures to open both the low latency, the fallback high latency | 646 // Simulate failures to open both the low latency, the fallback high latency |
655 // stream, and the fake audio output stream and ensure AudioOutputResampler | 647 // stream, and the fake audio output stream and ensure AudioOutputResampler |
656 // terminates normally. | 648 // terminates normally. |
657 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) { | 649 TEST_F(AudioOutputResamplerTest, AllFallbackFailed) { |
658 // Only Windows has a high latency output driver that is not the same as the low | 650 // Only Windows has a high latency output driver that is not the same as the low |
659 // latency path. | 651 // latency path. |
660 #if defined(OS_WIN) | 652 #if defined(OS_WIN) |
661 static const int kFallbackCount = 3; | 653 static const int kFallbackCount = 3; |
662 #else | 654 #else |
663 static const int kFallbackCount = 2; | 655 static const int kFallbackCount = 2; |
664 #endif | 656 #endif |
665 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) | 657 EXPECT_CALL(manager(), MakeAudioOutputStream(_)) |
666 .Times(kFallbackCount) | 658 .Times(kFallbackCount) |
667 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); | 659 .WillRepeatedly(Return(static_cast<AudioOutputStream*>(NULL))); |
668 | 660 |
669 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_); | 661 AudioOutputProxy* proxy = new AudioOutputProxy(resampler_.get()); |
670 EXPECT_FALSE(proxy->Open()); | 662 EXPECT_FALSE(proxy->Open()); |
671 proxy->Close(); | 663 proxy->Close(); |
672 WaitForCloseTimer(kTestCloseDelayMs); | 664 WaitForCloseTimer(kTestCloseDelayMs); |
673 } | 665 } |
674 | 666 |
675 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls | 667 // Simulate an eventual OpenStream() failure; i.e. successful OpenStream() calls |
676 // eventually followed by one which fails; root cause of http://crbug.com/150619 | 668 // eventually followed by one which fails; root cause of http://crbug.com/150619 |
677 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) { | 669 TEST_F(AudioOutputResamplerTest, LowLatencyOpenEventuallyFails) { |
678 MockAudioOutputStream stream1(&manager_, params_); | 670 MockAudioOutputStream stream1(&manager_, params_); |
679 MockAudioOutputStream stream2(&manager_, params_); | 671 MockAudioOutputStream stream2(&manager_, params_); |
(...skipping 23 matching lines...) Expand all Loading... |
703 .Times(1); | 695 .Times(1); |
704 | 696 |
705 // Stream3 should fail on Open() (yet still be closed since | 697 // Stream3 should fail on Open() (yet still be closed since |
706 // MakeAudioOutputStream returned a valid AudioOutputStream object). | 698 // MakeAudioOutputStream returned a valid AudioOutputStream object). |
707 EXPECT_CALL(stream3, Open()) | 699 EXPECT_CALL(stream3, Open()) |
708 .WillOnce(Return(false)); | 700 .WillOnce(Return(false)); |
709 EXPECT_CALL(stream3, Close()) | 701 EXPECT_CALL(stream3, Close()) |
710 .Times(1); | 702 .Times(1); |
711 | 703 |
712 // Open and start the first proxy and stream. | 704 // Open and start the first proxy and stream. |
713 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_); | 705 AudioOutputProxy* proxy1 = new AudioOutputProxy(resampler_.get()); |
714 EXPECT_TRUE(proxy1->Open()); | 706 EXPECT_TRUE(proxy1->Open()); |
715 proxy1->Start(&callback_); | 707 proxy1->Start(&callback_); |
716 OnStart(); | 708 OnStart(); |
717 | 709 |
718 // Open and start the second proxy and stream. | 710 // Open and start the second proxy and stream. |
719 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_); | 711 AudioOutputProxy* proxy2 = new AudioOutputProxy(resampler_.get()); |
720 EXPECT_TRUE(proxy2->Open()); | 712 EXPECT_TRUE(proxy2->Open()); |
721 proxy2->Start(&callback_); | 713 proxy2->Start(&callback_); |
722 OnStart(); | 714 OnStart(); |
723 | 715 |
724 // Attempt to open the third stream which should fail. | 716 // Attempt to open the third stream which should fail. |
725 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_); | 717 AudioOutputProxy* proxy3 = new AudioOutputProxy(resampler_.get()); |
726 EXPECT_FALSE(proxy3->Open()); | 718 EXPECT_FALSE(proxy3->Open()); |
727 | 719 |
728 // Perform the required Stop()/Close() shutdown dance for each proxy. Under | 720 // Perform the required Stop()/Close() shutdown dance for each proxy. Under |
729 // the hood each proxy should correctly call CloseStream() if OpenStream() | 721 // the hood each proxy should correctly call CloseStream() if OpenStream() |
730 // succeeded or not. | 722 // succeeded or not. |
731 proxy3->Stop(); | 723 proxy3->Stop(); |
732 proxy3->Close(); | 724 proxy3->Close(); |
733 proxy2->Stop(); | 725 proxy2->Stop(); |
734 proxy2->Close(); | 726 proxy2->Close(); |
735 proxy1->Stop(); | 727 proxy1->Stop(); |
736 proxy1->Close(); | 728 proxy1->Close(); |
737 | 729 |
738 // Wait for all of the messages to fly and then verify stream behavior. | 730 // Wait for all of the messages to fly and then verify stream behavior. |
739 WaitForCloseTimer(kTestCloseDelayMs); | 731 WaitForCloseTimer(kTestCloseDelayMs); |
740 EXPECT_TRUE(stream1.stop_called()); | 732 EXPECT_TRUE(stream1.stop_called()); |
741 EXPECT_TRUE(stream1.start_called()); | 733 EXPECT_TRUE(stream1.start_called()); |
742 EXPECT_TRUE(stream2.stop_called()); | 734 EXPECT_TRUE(stream2.stop_called()); |
743 EXPECT_TRUE(stream2.start_called()); | 735 EXPECT_TRUE(stream2.start_called()); |
744 EXPECT_FALSE(stream3.stop_called()); | 736 EXPECT_FALSE(stream3.stop_called()); |
745 EXPECT_FALSE(stream3.start_called()); | 737 EXPECT_FALSE(stream3.start_called()); |
746 } | 738 } |
747 | 739 |
748 } // namespace media | 740 } // namespace media |
OLD | NEW |