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 |