| Index: media/blink/webaudiosourceprovider_impl_unittest.cc
|
| diff --git a/media/blink/webaudiosourceprovider_impl_unittest.cc b/media/blink/webaudiosourceprovider_impl_unittest.cc
|
| index 4a6d22ff31b1d39eb55ee7a959318e3f1d88d401..fdc51b1ebecbdbe846bb2581e07b06b79825e666 100644
|
| --- a/media/blink/webaudiosourceprovider_impl_unittest.cc
|
| +++ b/media/blink/webaudiosourceprovider_impl_unittest.cc
|
| @@ -10,6 +10,7 @@
|
| #include "base/run_loop.h"
|
| #include "media/base/audio_parameters.h"
|
| #include "media/base/fake_audio_render_callback.h"
|
| +#include "media/base/media_log.h"
|
| #include "media/base/mock_audio_renderer_sink.h"
|
| #include "media/blink/webaudiosourceprovider_impl.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| @@ -22,38 +23,75 @@ namespace media {
|
|
|
| namespace {
|
| const float kTestVolume = 0.25;
|
| +
|
| +class WebAudioSourceProviderImplUnderTest : public WebAudioSourceProviderImpl {
|
| + public:
|
| + WebAudioSourceProviderImplUnderTest(
|
| + scoped_refptr<SwitchableAudioRendererSink> sink)
|
| + : WebAudioSourceProviderImpl(std::move(sink), new MediaLog()),
|
| + fallback_sink_(new MockAudioRendererSink()) {}
|
| +
|
| + MockAudioRendererSink* fallback_sink() { return fallback_sink_.get(); }
|
| +
|
| + protected:
|
| + scoped_refptr<SwitchableAudioRendererSink> CreateFallbackSink() override {
|
| + return fallback_sink_;
|
| + }
|
| +
|
| + private:
|
| + ~WebAudioSourceProviderImplUnderTest() override = default;
|
| + scoped_refptr<MockAudioRendererSink> fallback_sink_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(WebAudioSourceProviderImplUnderTest);
|
| +};
|
| +
|
| +enum class WaspSinkStatus { WASP_SINK_OK, WASP_SINK_ERROR, WASP_SINK_NULL };
|
| +
|
| +scoped_refptr<MockAudioRendererSink> CreateWaspMockSink(WaspSinkStatus status) {
|
| + if (status == WaspSinkStatus::WASP_SINK_NULL)
|
| + return nullptr;
|
| + return new MockAudioRendererSink(status == WaspSinkStatus::WASP_SINK_OK
|
| + ? OUTPUT_DEVICE_STATUS_OK
|
| + : OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
|
| +}
|
| +
|
| } // namespace
|
|
|
| class WebAudioSourceProviderImplTest
|
| - : public testing::Test,
|
| + : public testing::TestWithParam<WaspSinkStatus>,
|
| public blink::WebAudioSourceProviderClient {
|
| public:
|
| WebAudioSourceProviderImplTest()
|
| : params_(AudioParameters::AUDIO_PCM_LINEAR,
|
| - CHANNEL_LAYOUT_STEREO, 48000, 16, 64),
|
| + CHANNEL_LAYOUT_STEREO,
|
| + 48000,
|
| + 16,
|
| + 64),
|
| fake_callback_(0.1),
|
| - mock_sink_(new MockAudioRendererSink()),
|
| - wasp_impl_(new WebAudioSourceProviderImpl(mock_sink_)) {
|
| - }
|
| + mock_sink_(CreateWaspMockSink(GetParam())),
|
| + wasp_impl_(new WebAudioSourceProviderImplUnderTest(mock_sink_)),
|
| + expected_sink_(GetParam() == WaspSinkStatus::WASP_SINK_OK
|
| + ? mock_sink_.get()
|
| + : wasp_impl_->fallback_sink()) {}
|
|
|
| virtual ~WebAudioSourceProviderImplTest() {}
|
|
|
| void CallAllSinkMethodsAndVerify(bool verify) {
|
| testing::InSequence s;
|
|
|
| - EXPECT_CALL(*mock_sink_.get(), Start()).Times(verify);
|
| + EXPECT_CALL(*expected_sink_, Start()).Times(verify);
|
| wasp_impl_->Start();
|
|
|
| - EXPECT_CALL(*mock_sink_.get(), Play()).Times(verify);
|
| + EXPECT_CALL(*expected_sink_, Play()).Times(verify);
|
| wasp_impl_->Play();
|
|
|
| - EXPECT_CALL(*mock_sink_.get(), Pause()).Times(verify);
|
| + EXPECT_CALL(*expected_sink_, Pause()).Times(verify);
|
| wasp_impl_->Pause();
|
|
|
| - EXPECT_CALL(*mock_sink_.get(), SetVolume(kTestVolume)).Times(verify);
|
| + EXPECT_CALL(*expected_sink_, SetVolume(kTestVolume)).Times(verify);
|
| wasp_impl_->SetVolume(kTestVolume);
|
|
|
| - EXPECT_CALL(*mock_sink_.get(), Stop()).Times(verify);
|
| + EXPECT_CALL(*expected_sink_, Stop()).Times(verify);
|
| wasp_impl_->Stop();
|
|
|
| testing::Mock::VerifyAndClear(mock_sink_.get());
|
| @@ -63,13 +101,14 @@ class WebAudioSourceProviderImplTest
|
| testing::InSequence s;
|
|
|
| if (client) {
|
| - EXPECT_CALL(*mock_sink_.get(), Stop());
|
| + EXPECT_CALL(*expected_sink_, Stop());
|
| EXPECT_CALL(*this, setFormat(params_.channels(), params_.sample_rate()));
|
| }
|
| wasp_impl_->setClient(client);
|
| base::RunLoop().RunUntilIdle();
|
|
|
| testing::Mock::VerifyAndClear(mock_sink_.get());
|
| + testing::Mock::VerifyAndClear(wasp_impl_->fallback_sink());
|
| testing::Mock::VerifyAndClear(this);
|
| }
|
|
|
| @@ -101,21 +140,41 @@ class WebAudioSourceProviderImplTest
|
| return wasp_impl_->RenderForTesting(audio_bus);
|
| }
|
|
|
| + void ExpectUnhealthySinkToStop() {
|
| + if (GetParam() == WaspSinkStatus::WASP_SINK_ERROR)
|
| + EXPECT_CALL(*mock_sink_.get(), Stop());
|
| + }
|
| +
|
| protected:
|
| AudioParameters params_;
|
| FakeAudioRenderCallback fake_callback_;
|
| scoped_refptr<MockAudioRendererSink> mock_sink_;
|
| - scoped_refptr<WebAudioSourceProviderImpl> wasp_impl_;
|
| + scoped_refptr<WebAudioSourceProviderImplUnderTest> wasp_impl_;
|
| + MockAudioRendererSink* expected_sink_;
|
| base::MessageLoop message_loop_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(WebAudioSourceProviderImplTest);
|
| };
|
|
|
| -TEST_F(WebAudioSourceProviderImplTest, SetClientBeforeInitialize) {
|
| +TEST_P(WebAudioSourceProviderImplTest, SetClientBeforeInitialize) {
|
| // setClient() with a NULL client should do nothing if no client is set.
|
| wasp_impl_->setClient(NULL);
|
|
|
| - EXPECT_CALL(*mock_sink_.get(), Stop());
|
| + // If |mock_sink_| is not null, it should be stopped during setClient(this).
|
| + // If it is unhealthy, it should also be stopped during fallback in
|
| + // Initialize().
|
| + if (mock_sink_)
|
| + EXPECT_CALL(*mock_sink_.get(), Stop())
|
| + .Times(2 + static_cast<int>(GetParam()));
|
| +
|
| + wasp_impl_->setClient(this);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + if (mock_sink_)
|
| + EXPECT_CALL(*mock_sink_.get(), SetVolume(1)).Times(1);
|
| + wasp_impl_->setClient(NULL);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| wasp_impl_->setClient(this);
|
| base::RunLoop().RunUntilIdle();
|
|
|
| @@ -131,7 +190,8 @@ TEST_F(WebAudioSourceProviderImplTest, SetClientBeforeInitialize) {
|
| }
|
|
|
| // Verify AudioRendererSink functionality w/ and w/o a client.
|
| -TEST_F(WebAudioSourceProviderImplTest, SinkMethods) {
|
| +TEST_P(WebAudioSourceProviderImplTest, SinkMethods) {
|
| + ExpectUnhealthySinkToStop();
|
| wasp_impl_->Initialize(params_, &fake_callback_);
|
|
|
| // Without a client all WASP calls should fall through to the underlying sink.
|
| @@ -143,22 +203,23 @@ TEST_F(WebAudioSourceProviderImplTest, SinkMethods) {
|
| CallAllSinkMethodsAndVerify(false);
|
|
|
| // Removing the client should cause WASP to revert to the underlying sink.
|
| - EXPECT_CALL(*mock_sink_.get(), SetVolume(kTestVolume));
|
| + EXPECT_CALL(*expected_sink_, SetVolume(kTestVolume));
|
| SetClient(NULL);
|
| CallAllSinkMethodsAndVerify(true);
|
| }
|
|
|
| // Verify underlying sink state is restored after client removal.
|
| -TEST_F(WebAudioSourceProviderImplTest, SinkStateRestored) {
|
| +TEST_P(WebAudioSourceProviderImplTest, SinkStateRestored) {
|
| + ExpectUnhealthySinkToStop();
|
| wasp_impl_->Initialize(params_, &fake_callback_);
|
|
|
| // Verify state set before the client is set propagates back afterward.
|
| - EXPECT_CALL(*mock_sink_.get(), Start());
|
| + EXPECT_CALL(*expected_sink_, Start());
|
| wasp_impl_->Start();
|
| SetClient(this);
|
|
|
| - EXPECT_CALL(*mock_sink_.get(), SetVolume(1.0));
|
| - EXPECT_CALL(*mock_sink_.get(), Start());
|
| + EXPECT_CALL(*expected_sink_, SetVolume(1.0));
|
| + EXPECT_CALL(*expected_sink_, Start());
|
| SetClient(NULL);
|
|
|
| // Verify state set while the client was attached propagates back afterward.
|
| @@ -166,14 +227,15 @@ TEST_F(WebAudioSourceProviderImplTest, SinkStateRestored) {
|
| wasp_impl_->Play();
|
| wasp_impl_->SetVolume(kTestVolume);
|
|
|
| - EXPECT_CALL(*mock_sink_.get(), SetVolume(kTestVolume));
|
| - EXPECT_CALL(*mock_sink_.get(), Start());
|
| - EXPECT_CALL(*mock_sink_.get(), Play());
|
| + EXPECT_CALL(*expected_sink_, SetVolume(kTestVolume));
|
| + EXPECT_CALL(*expected_sink_, Start());
|
| + EXPECT_CALL(*expected_sink_, Play());
|
| SetClient(NULL);
|
| }
|
|
|
| // Test the AudioRendererSink state machine and its effects on provideInput().
|
| -TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
|
| +TEST_P(WebAudioSourceProviderImplTest, ProvideInput) {
|
| + ExpectUnhealthySinkToStop();
|
| std::unique_ptr<AudioBus> bus1 = AudioBus::Create(params_);
|
| std::unique_ptr<AudioBus> bus2 = AudioBus::Create(params_);
|
|
|
| @@ -259,7 +321,9 @@ TEST_F(WebAudioSourceProviderImplTest, ProvideInput) {
|
| }
|
|
|
| // Verify CopyAudioCB is called if registered.
|
| -TEST_F(WebAudioSourceProviderImplTest, CopyAudioCB) {
|
| +TEST_P(WebAudioSourceProviderImplTest, CopyAudioCB) {
|
| + ExpectUnhealthySinkToStop();
|
| +
|
| testing::InSequence s;
|
| wasp_impl_->Initialize(params_, &fake_callback_);
|
| wasp_impl_->SetCopyAudioCallback(base::Bind(
|
| @@ -276,4 +340,11 @@ TEST_F(WebAudioSourceProviderImplTest, CopyAudioCB) {
|
| testing::Mock::VerifyAndClear(mock_sink_.get());
|
| }
|
|
|
| +INSTANTIATE_TEST_CASE_P(
|
| + /* prefix intentionally left blank due to only one parameterization */,
|
| + WebAudioSourceProviderImplTest,
|
| + testing::Values(WaspSinkStatus::WASP_SINK_OK,
|
| + WaspSinkStatus::WASP_SINK_ERROR,
|
| + WaspSinkStatus::WASP_SINK_NULL));
|
| +
|
| } // namespace media
|
|
|