Chromium Code Reviews| Index: content/renderer/media/audio_renderer_mixer_manager_unittest.cc |
| diff --git a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc |
| index e3eb3b3718fd765a7fe53b509066cf3432764467..8e6ccc9d17cdae98ae094386304621c23f304dc9 100644 |
| --- a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc |
| +++ b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc |
| @@ -6,12 +6,12 @@ |
| #include <memory> |
| +#include "base/bind.h" |
| #include "base/logging.h" |
| #include "base/macros.h" |
| #include "base/memory/ref_counted.h" |
| -#include "content/renderer/media/audio_device_factory.h" |
| +#include "content/renderer/media/audio_renderer_sink_cache.h" |
| #include "media/audio/audio_device_description.h" |
| -#include "media/base/audio_capturer_source.h" |
| #include "media/base/audio_parameters.h" |
| #include "media/base/audio_renderer_mixer.h" |
| #include "media/base/audio_renderer_mixer_input.h" |
| @@ -40,11 +40,57 @@ static const int kAnotherRenderFrameId = 678; |
| using media::AudioParameters; |
| -class AudioRendererMixerManagerTest : public testing::Test, |
| - public AudioDeviceFactory { |
| +class FakeAudioRendererSinkCache : public AudioRendererSinkCache { |
| + public: |
| + typedef base::Callback<media::AudioRendererSink*( |
|
miu
2016/05/12 21:53:06
nit: Consider using the more-readable C++11 "using
o1ka
2016/05/17 17:17:23
Done.
|
| + int render_frame_id, |
| + int session_id, |
| + const std::string& device_id, |
| + const url::Origin& security_origin)> |
| + GetSinkCallback; |
| + |
| + typedef base::Callback<void(media::AudioRendererSink*)> ReleaseSinkCallback; |
| + |
| + FakeAudioRendererSinkCache(const GetSinkCallback& get_sink_cb, |
| + const ReleaseSinkCallback& release_sink_cb) |
| + : get_sink_cb_(get_sink_cb), release_sink_cb_(release_sink_cb) {} |
| + |
| + media::OutputDeviceInfo GetSinkInfo( |
| + int source_render_frame_id, |
| + int session_id, |
| + const std::string& device_id, |
| + const url::Origin& security_origin) final { |
| + return get_sink_cb_ |
| + .Run(source_render_frame_id, session_id, device_id, security_origin) |
| + ->GetOutputDeviceInfo(); |
| + } |
| + |
| + media::AudioRendererSink* GetSink(int source_render_frame_id, |
| + const std::string& device_id, |
| + const url::Origin& security_origin) final { |
| + return get_sink_cb_.Run(source_render_frame_id, 0, device_id, |
| + security_origin); |
| + } |
| + |
| + void ReleaseSink(media::AudioRendererSink* sink) final { |
| + release_sink_cb_.Run(sink); |
| + } |
| + |
| + private: |
| + GetSinkCallback get_sink_cb_; |
| + ReleaseSinkCallback release_sink_cb_; |
| +}; |
| + |
| +class AudioRendererMixerManagerTest : public testing::Test { |
| public: |
| AudioRendererMixerManagerTest() |
| - : manager_(new AudioRendererMixerManager()), |
| + : manager_(new AudioRendererMixerManager( |
| + std::unique_ptr<AudioRendererSinkCache>( |
| + new FakeAudioRendererSinkCache( |
| + base::Bind(&AudioRendererMixerManagerTest::GetSinkPtr, |
| + base::Unretained(this)), |
| + base::Bind(&AudioRendererMixerManagerTest::ReleaseSinkPtr, |
| + base::Unretained(this)))))), |
| mock_sink_(new media::MockAudioRendererSink()), |
| mock_sink_no_device_(new media::MockAudioRendererSink( |
| kNonexistentDeviceId, |
| @@ -52,9 +98,6 @@ class AudioRendererMixerManagerTest : public testing::Test, |
| mock_sink_matched_device_( |
| new media::MockAudioRendererSink(kMatchedDeviceId, |
| media::OUTPUT_DEVICE_STATUS_OK)), |
| - mock_sink_for_session_id_( |
| - new media::MockAudioRendererSink(kMatchedDeviceId, |
| - media::OUTPUT_DEVICE_STATUS_OK)), |
| kSecurityOrigin2(GURL("http://localhost")) {} |
| media::AudioRendererMixer* GetMixer( |
| @@ -81,49 +124,34 @@ class AudioRendererMixerManagerTest : public testing::Test, |
| } |
| protected: |
| - MOCK_METHOD1(CreateAudioCapturerSource, |
| - scoped_refptr<media::AudioCapturerSource>(int)); |
| - MOCK_METHOD5( |
| - CreateSwitchableAudioRendererSink, |
| - scoped_refptr<media::SwitchableAudioRendererSink>(SourceType, |
| - int, |
| - int, |
| - const std::string&, |
| - const url::Origin&)); |
| - MOCK_METHOD5(CreateAudioRendererSink, |
| - scoped_refptr<media::AudioRendererSink>(SourceType, |
| - int, |
| - int, |
| - const std::string&, |
| - const url::Origin&)); |
| - |
| - scoped_refptr<media::AudioRendererSink> CreateFinalAudioRendererSink( |
| - int render_frame_id, |
| - int session_id, |
| - const std::string& device_id, |
| - const url::Origin& security_origin) { |
| + media::AudioRendererSink* GetSinkPtr(int source_render_frame_id, |
| + int session_id, |
| + const std::string& device_id, |
| + const url::Origin& security_origin) { |
| if ((device_id == kDefaultDeviceId) || (device_id == kAnotherDeviceId)) { |
| // We don't care about separate sinks for these devices. |
| - return mock_sink_; |
| + return mock_sink_.get(); |
| } |
| if (device_id == kNonexistentDeviceId) |
| - return mock_sink_no_device_; |
| + return mock_sink_no_device_.get(); |
| if (device_id.empty()) { |
| // The sink used to get device ID from session ID if it's not empty |
| - return session_id ? mock_sink_for_session_id_ : mock_sink_; |
| + return session_id ? mock_sink_matched_device_.get() : mock_sink_.get(); |
| } |
| if (device_id == kMatchedDeviceId) |
| - return mock_sink_matched_device_; |
| + return mock_sink_matched_device_.get(); |
| NOTREACHED(); |
| return nullptr; |
| } |
| + MOCK_METHOD1(ReleaseSinkPtr, void(media::AudioRendererSink*)); |
| + |
| std::unique_ptr<AudioRendererMixerManager> manager_; |
| + |
| scoped_refptr<media::MockAudioRendererSink> mock_sink_; |
| scoped_refptr<media::MockAudioRendererSink> mock_sink_no_device_; |
| scoped_refptr<media::MockAudioRendererSink> mock_sink_matched_device_; |
| - scoped_refptr<media::MockAudioRendererSink> mock_sink_for_session_id_; |
| // To avoid global/static non-POD constants. |
| const url::Origin kSecurityOrigin; |
| @@ -141,6 +169,9 @@ TEST_F(AudioRendererMixerManagerTest, GetRemoveMixer) { |
| EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); |
| EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); |
| + // We expect 2 mixers to be created; each of them should release the sink. |
| + EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2); |
| + |
| // There should be no mixers outstanding to start with. |
| EXPECT_EQ(0, mixer_count()); |
| @@ -187,6 +218,9 @@ TEST_F(AudioRendererMixerManagerTest, MixerReuse) { |
| EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); |
| EXPECT_EQ(mixer_count(), 0); |
| + // We expect 2 mixers to be created; each of them should release the sink. |
| + EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2); |
| + |
| media::AudioParameters params1(AudioParameters::AUDIO_PCM_LINEAR, |
| kChannelLayout, |
| kSampleRate, |
| @@ -239,6 +273,9 @@ TEST_F(AudioRendererMixerManagerTest, CreateInput) { |
| EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); |
| EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); |
| + // We expect 2 mixers to be created; each of them should release the sink. |
| + EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2); |
| + |
| media::AudioParameters params( |
| AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, |
| kBitsPerChannel, kBufferSize); |
| @@ -287,6 +324,10 @@ TEST_F(AudioRendererMixerManagerTest, CreateInputWithSessionId) { |
| EXPECT_CALL(*mock_sink_matched_device_.get(), Start()).Times(1); |
| EXPECT_CALL(*mock_sink_matched_device_.get(), Stop()).Times(1); |
| + // We expect 3 mixers to be created; each of them should release a sink. |
| + EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2); |
| + EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_matched_device_.get())).Times(1); |
| + |
| media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
| kChannelLayout, kSampleRate, kBitsPerChannel, |
| kBufferSize); |
| @@ -359,6 +400,9 @@ TEST_F(AudioRendererMixerManagerTest, MixerDevices) { |
| EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3); |
| EXPECT_EQ(0, mixer_count()); |
| + // We expect 3 mixers to be created; each of them should release a sink. |
| + EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(3); |
| + |
| media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
| kChannelLayout, kSampleRate, kBitsPerChannel, |
| kBufferSize); |
| @@ -395,6 +439,9 @@ TEST_F(AudioRendererMixerManagerTest, OneMixerDifferentOriginsDefaultDevice) { |
| EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1); |
| EXPECT_EQ(0, mixer_count()); |
| + // We expect 1 mixers to be created; it should release its sink. |
| + EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(1); |
| + |
| media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
| kChannelLayout, kSampleRate, kBitsPerChannel, |
| kBufferSize); |
| @@ -435,14 +482,19 @@ TEST_F(AudioRendererMixerManagerTest, OneMixerDifferentOriginsDefaultDevice) { |
| // status code when a nonexistent device is requested. |
| TEST_F(AudioRendererMixerManagerTest, NonexistentDevice) { |
| EXPECT_EQ(0, mixer_count()); |
| + |
| + // Mixer manager should release a not-ok sink when failing to create a mixer. |
| + EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_no_device_.get())).Times(1); |
| + |
| media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
| kChannelLayout, kSampleRate, kBitsPerChannel, |
| kBufferSize); |
| media::OutputDeviceStatus device_status = media::OUTPUT_DEVICE_STATUS_OK; |
| - EXPECT_CALL(*mock_sink_no_device_.get(), Stop()); |
| + |
| media::AudioRendererMixer* mixer = |
| GetMixer(kRenderFrameId, params, kNonexistentDeviceId, kSecurityOrigin, |
| &device_status); |
| + |
| EXPECT_FALSE(mixer); |
| EXPECT_EQ(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, device_status); |
| EXPECT_EQ(0, mixer_count()); |