Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Unified Diff: content/renderer/media/audio_renderer_mixer_manager_unittest.cc

Issue 1942803002: Caching AudioOutputDevice instances in mixer manager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: First round of comments addressed Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..85a634169cf55db03b3236a8eff82aec4475db90 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"
@@ -23,6 +23,7 @@
namespace content {
+namespace {
static const int kBitsPerChannel = 16;
static const int kSampleRate = 48000;
static const int kBufferSize = 8192;
@@ -37,14 +38,66 @@ static const char kNonexistentDeviceId[] = "nonexistent-device-id";
static const int kRenderFrameId = 124;
static const int kAnotherRenderFrameId = 678;
+} // namespace;
using media::AudioParameters;
-class AudioRendererMixerManagerTest : public testing::Test,
- public AudioDeviceFactory {
+class FakeAudioRendererSinkCache : public AudioRendererSinkCache {
+ public:
+ using GetSinkCallback =
+ base::Callback<scoped_refptr<media::AudioRendererSink>(
+ int render_frame_id,
+ int session_id,
+ const std::string& device_id,
+ const url::Origin& security_origin)>;
+
+ using ReleaseSinkCallback =
+ base::Callback<void(const media::AudioRendererSink*)>;
+
+ 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();
+ }
+
+ scoped_refptr<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(int source_render_frame_id,
+ const std::string& device_id,
+ const url::Origin& security_origin,
+ const 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 +105,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(
@@ -67,11 +117,11 @@ class AudioRendererMixerManagerTest : public testing::Test,
security_origin, device_status);
}
- void RemoveMixer(int source_render_frame_id,
+ void ReturnMixer(int source_render_frame_id,
const media::AudioParameters& params,
const std::string& device_id,
const url::Origin& security_origin) {
- return manager_->RemoveMixer(source_render_frame_id, params, device_id,
+ return manager_->ReturnMixer(source_render_frame_id, params, device_id,
security_origin);
}
@@ -81,24 +131,8 @@ 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,
+ scoped_refptr<media::AudioRendererSink> GetSinkPtr(
+ int source_render_frame_id,
int session_id,
const std::string& device_id,
const url::Origin& security_origin) {
@@ -110,7 +144,7 @@ class AudioRendererMixerManagerTest : public testing::Test,
return mock_sink_no_device_;
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_ : mock_sink_;
}
if (device_id == kMatchedDeviceId)
return mock_sink_matched_device_;
@@ -119,11 +153,13 @@ class AudioRendererMixerManagerTest : public testing::Test,
return nullptr;
}
+ MOCK_METHOD1(ReleaseSinkPtr, void(const 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;
@@ -133,14 +169,17 @@ class AudioRendererMixerManagerTest : public testing::Test,
DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManagerTest);
};
-// Verify GetMixer() and RemoveMixer() both work as expected; particularly with
+// Verify GetMixer() and ReturnMixer() both work as expected; particularly with
// respect to the explicit ref counting done.
-TEST_F(AudioRendererMixerManagerTest, GetRemoveMixer) {
+TEST_F(AudioRendererMixerManagerTest, GetReturnMixer) {
// Since we're testing two different sets of parameters, we expect
// AudioRendererMixerManager to call Start and Stop on our mock twice.
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());
@@ -158,8 +197,8 @@ TEST_F(AudioRendererMixerManagerTest, GetRemoveMixer) {
kSecurityOrigin, nullptr));
EXPECT_EQ(1, mixer_count());
- // Remove the extra mixer we just acquired.
- RemoveMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin);
+ // Return the extra mixer we just acquired.
+ ReturnMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin);
EXPECT_EQ(1, mixer_count());
media::AudioParameters params2(
@@ -173,10 +212,10 @@ TEST_F(AudioRendererMixerManagerTest, GetRemoveMixer) {
// Different parameters should result in a different mixer1.
EXPECT_NE(mixer1, mixer2);
- // Remove both outstanding mixers.
- RemoveMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin);
+ // Return both outstanding mixers.
+ ReturnMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin);
EXPECT_EQ(0, mixer_count());
}
@@ -187,6 +226,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,
@@ -207,7 +249,7 @@ TEST_F(AudioRendererMixerManagerTest, MixerReuse) {
EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params2, kDefaultDeviceId,
kSecurityOrigin, nullptr));
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin);
EXPECT_EQ(1, mixer_count());
// Modify some parameters that do matter: channel layout
@@ -221,11 +263,11 @@ TEST_F(AudioRendererMixerManagerTest, MixerReuse) {
EXPECT_NE(mixer1, GetMixer(kRenderFrameId, params3, kDefaultDeviceId,
kSecurityOrigin, nullptr));
EXPECT_EQ(2, mixer_count());
- RemoveMixer(kRenderFrameId, params3, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(kRenderFrameId, params3, kDefaultDeviceId, kSecurityOrigin);
EXPECT_EQ(1, mixer_count());
- // Remove final mixer.
- RemoveMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin);
+ // Return final mixer.
+ ReturnMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin);
EXPECT_EQ(0, mixer_count());
}
@@ -239,6 +281,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);
@@ -258,7 +303,7 @@ TEST_F(AudioRendererMixerManagerTest, CreateInput) {
EXPECT_EQ(0, mixer_count());
// Implicitly test that AudioRendererMixerInput was provided with the expected
- // callbacks needed to acquire an AudioRendererMixer and remove it.
+ // callbacks needed to acquire an AudioRendererMixer and return it.
input->Start();
EXPECT_EQ(1, mixer_count());
another_input->Start();
@@ -287,6 +332,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);
@@ -323,7 +372,7 @@ TEST_F(AudioRendererMixerManagerTest, CreateInputWithSessionId) {
EXPECT_EQ(0, mixer_count());
// Implicitly test that AudioRendererMixerInput was provided with the expected
- // callbacks needed to acquire an AudioRendererMixer and remove it.
+ // callbacks needed to acquire an AudioRendererMixer and return it.
input_to_default_device->Start();
EXPECT_EQ(1, mixer_count());
@@ -359,6 +408,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);
@@ -380,11 +432,11 @@ TEST_F(AudioRendererMixerManagerTest, MixerDevices) {
EXPECT_NE(mixer1, mixer3);
EXPECT_NE(mixer2, mixer3);
- RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin);
EXPECT_EQ(2, mixer_count());
- RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin);
+ ReturnMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2);
+ ReturnMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2);
EXPECT_EQ(0, mixer_count());
}
@@ -395,6 +447,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);
@@ -421,13 +476,13 @@ TEST_F(AudioRendererMixerManagerTest, OneMixerDifferentOriginsDefaultDevice) {
EXPECT_EQ(1, mixer_count());
EXPECT_EQ(mixer1, mixer4);
- RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin);
+ ReturnMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params, std::string(), kSecurityOrigin);
+ ReturnMixer(kRenderFrameId, params, std::string(), kSecurityOrigin);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2);
+ ReturnMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2);
EXPECT_EQ(1, mixer_count());
- RemoveMixer(kRenderFrameId, params, std::string(), kSecurityOrigin2);
+ ReturnMixer(kRenderFrameId, params, std::string(), kSecurityOrigin2);
EXPECT_EQ(0, mixer_count());
}
@@ -435,14 +490,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());

Powered by Google App Engine
This is Rietveld 408576698