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 "content/renderer/media/audio_renderer_mixer_manager.h" | 5 #include "content/renderer/media/audio_renderer_mixer_manager.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
| 9 #include "base/bind.h" |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
10 #include "base/macros.h" | 11 #include "base/macros.h" |
11 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
12 #include "content/renderer/media/audio_device_factory.h" | 13 #include "content/renderer/media/audio_renderer_sink_cache.h" |
13 #include "media/audio/audio_device_description.h" | 14 #include "media/audio/audio_device_description.h" |
14 #include "media/base/audio_capturer_source.h" | |
15 #include "media/base/audio_parameters.h" | 15 #include "media/base/audio_parameters.h" |
16 #include "media/base/audio_renderer_mixer.h" | 16 #include "media/base/audio_renderer_mixer.h" |
17 #include "media/base/audio_renderer_mixer_input.h" | 17 #include "media/base/audio_renderer_mixer_input.h" |
18 #include "media/base/fake_audio_render_callback.h" | 18 #include "media/base/fake_audio_render_callback.h" |
19 #include "media/base/mock_audio_renderer_sink.h" | 19 #include "media/base/mock_audio_renderer_sink.h" |
20 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
22 #include "url/gurl.h" | 22 #include "url/gurl.h" |
23 | 23 |
24 namespace content { | 24 namespace content { |
25 | 25 |
| 26 namespace { |
26 static const int kBitsPerChannel = 16; | 27 static const int kBitsPerChannel = 16; |
27 static const int kSampleRate = 48000; | 28 static const int kSampleRate = 48000; |
28 static const int kBufferSize = 8192; | 29 static const int kBufferSize = 8192; |
29 static const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO; | 30 static const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO; |
30 static const media::ChannelLayout kAnotherChannelLayout = | 31 static const media::ChannelLayout kAnotherChannelLayout = |
31 media::CHANNEL_LAYOUT_2_1; | 32 media::CHANNEL_LAYOUT_2_1; |
32 static const char* const kDefaultDeviceId = | 33 static const char* const kDefaultDeviceId = |
33 media::AudioDeviceDescription::kDefaultDeviceId; | 34 media::AudioDeviceDescription::kDefaultDeviceId; |
34 static const char kAnotherDeviceId[] = "another-device-id"; | 35 static const char kAnotherDeviceId[] = "another-device-id"; |
35 static const char kMatchedDeviceId[] = "matched-device-id"; | 36 static const char kMatchedDeviceId[] = "matched-device-id"; |
36 static const char kNonexistentDeviceId[] = "nonexistent-device-id"; | 37 static const char kNonexistentDeviceId[] = "nonexistent-device-id"; |
37 | 38 |
38 static const int kRenderFrameId = 124; | 39 static const int kRenderFrameId = 124; |
39 static const int kAnotherRenderFrameId = 678; | 40 static const int kAnotherRenderFrameId = 678; |
| 41 } // namespace; |
40 | 42 |
41 using media::AudioParameters; | 43 using media::AudioParameters; |
42 | 44 |
43 class AudioRendererMixerManagerTest : public testing::Test, | 45 class FakeAudioRendererSinkCache : public AudioRendererSinkCache { |
44 public AudioDeviceFactory { | 46 public: |
| 47 using GetSinkCallback = |
| 48 base::Callback<scoped_refptr<media::AudioRendererSink>( |
| 49 int render_frame_id, |
| 50 int session_id, |
| 51 const std::string& device_id, |
| 52 const url::Origin& security_origin)>; |
| 53 |
| 54 using ReleaseSinkCallback = |
| 55 base::Callback<void(const media::AudioRendererSink*)>; |
| 56 |
| 57 FakeAudioRendererSinkCache(const GetSinkCallback& get_sink_cb, |
| 58 const ReleaseSinkCallback& release_sink_cb) |
| 59 : get_sink_cb_(get_sink_cb), release_sink_cb_(release_sink_cb) {} |
| 60 |
| 61 media::OutputDeviceInfo GetSinkInfo( |
| 62 int source_render_frame_id, |
| 63 int session_id, |
| 64 const std::string& device_id, |
| 65 const url::Origin& security_origin) final { |
| 66 return get_sink_cb_ |
| 67 .Run(source_render_frame_id, session_id, device_id, security_origin) |
| 68 ->GetOutputDeviceInfo(); |
| 69 } |
| 70 |
| 71 scoped_refptr<media::AudioRendererSink> GetSink( |
| 72 int source_render_frame_id, |
| 73 const std::string& device_id, |
| 74 const url::Origin& security_origin) final { |
| 75 return get_sink_cb_.Run(source_render_frame_id, 0, device_id, |
| 76 security_origin); |
| 77 } |
| 78 |
| 79 void ReleaseSink(int source_render_frame_id, |
| 80 const std::string& device_id, |
| 81 const url::Origin& security_origin, |
| 82 const media::AudioRendererSink* sink) final { |
| 83 release_sink_cb_.Run(sink); |
| 84 } |
| 85 |
| 86 private: |
| 87 GetSinkCallback get_sink_cb_; |
| 88 ReleaseSinkCallback release_sink_cb_; |
| 89 }; |
| 90 |
| 91 class AudioRendererMixerManagerTest : public testing::Test { |
45 public: | 92 public: |
46 AudioRendererMixerManagerTest() | 93 AudioRendererMixerManagerTest() |
47 : manager_(new AudioRendererMixerManager()), | 94 : manager_(new AudioRendererMixerManager( |
| 95 std::unique_ptr<AudioRendererSinkCache>( |
| 96 new FakeAudioRendererSinkCache( |
| 97 base::Bind(&AudioRendererMixerManagerTest::GetSinkPtr, |
| 98 base::Unretained(this)), |
| 99 base::Bind(&AudioRendererMixerManagerTest::ReleaseSinkPtr, |
| 100 base::Unretained(this)))))), |
48 mock_sink_(new media::MockAudioRendererSink()), | 101 mock_sink_(new media::MockAudioRendererSink()), |
49 mock_sink_no_device_(new media::MockAudioRendererSink( | 102 mock_sink_no_device_(new media::MockAudioRendererSink( |
50 kNonexistentDeviceId, | 103 kNonexistentDeviceId, |
51 media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND)), | 104 media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND)), |
52 mock_sink_matched_device_( | 105 mock_sink_matched_device_( |
53 new media::MockAudioRendererSink(kMatchedDeviceId, | 106 new media::MockAudioRendererSink(kMatchedDeviceId, |
54 media::OUTPUT_DEVICE_STATUS_OK)), | 107 media::OUTPUT_DEVICE_STATUS_OK)), |
55 mock_sink_for_session_id_( | |
56 new media::MockAudioRendererSink(kMatchedDeviceId, | |
57 media::OUTPUT_DEVICE_STATUS_OK)), | |
58 kSecurityOrigin2(GURL("http://localhost")) {} | 108 kSecurityOrigin2(GURL("http://localhost")) {} |
59 | 109 |
60 media::AudioRendererMixer* GetMixer( | 110 media::AudioRendererMixer* GetMixer( |
61 int source_render_frame_id, | 111 int source_render_frame_id, |
62 const media::AudioParameters& params, | 112 const media::AudioParameters& params, |
63 const std::string& device_id, | 113 const std::string& device_id, |
64 const url::Origin& security_origin, | 114 const url::Origin& security_origin, |
65 media::OutputDeviceStatus* device_status) { | 115 media::OutputDeviceStatus* device_status) { |
66 return manager_->GetMixer(source_render_frame_id, params, device_id, | 116 return manager_->GetMixer(source_render_frame_id, params, device_id, |
67 security_origin, device_status); | 117 security_origin, device_status); |
68 } | 118 } |
69 | 119 |
70 void RemoveMixer(int source_render_frame_id, | 120 void ReturnMixer(int source_render_frame_id, |
71 const media::AudioParameters& params, | 121 const media::AudioParameters& params, |
72 const std::string& device_id, | 122 const std::string& device_id, |
73 const url::Origin& security_origin) { | 123 const url::Origin& security_origin) { |
74 return manager_->RemoveMixer(source_render_frame_id, params, device_id, | 124 return manager_->ReturnMixer(source_render_frame_id, params, device_id, |
75 security_origin); | 125 security_origin); |
76 } | 126 } |
77 | 127 |
78 // Number of instantiated mixers. | 128 // Number of instantiated mixers. |
79 int mixer_count() { | 129 int mixer_count() { |
80 return manager_->mixers_.size(); | 130 return manager_->mixers_.size(); |
81 } | 131 } |
82 | 132 |
83 protected: | 133 protected: |
84 MOCK_METHOD1(CreateAudioCapturerSource, | 134 scoped_refptr<media::AudioRendererSink> GetSinkPtr( |
85 scoped_refptr<media::AudioCapturerSource>(int)); | 135 int source_render_frame_id, |
86 MOCK_METHOD5( | |
87 CreateSwitchableAudioRendererSink, | |
88 scoped_refptr<media::SwitchableAudioRendererSink>(SourceType, | |
89 int, | |
90 int, | |
91 const std::string&, | |
92 const url::Origin&)); | |
93 MOCK_METHOD5(CreateAudioRendererSink, | |
94 scoped_refptr<media::AudioRendererSink>(SourceType, | |
95 int, | |
96 int, | |
97 const std::string&, | |
98 const url::Origin&)); | |
99 | |
100 scoped_refptr<media::AudioRendererSink> CreateFinalAudioRendererSink( | |
101 int render_frame_id, | |
102 int session_id, | 136 int session_id, |
103 const std::string& device_id, | 137 const std::string& device_id, |
104 const url::Origin& security_origin) { | 138 const url::Origin& security_origin) { |
105 if ((device_id == kDefaultDeviceId) || (device_id == kAnotherDeviceId)) { | 139 if ((device_id == kDefaultDeviceId) || (device_id == kAnotherDeviceId)) { |
106 // We don't care about separate sinks for these devices. | 140 // We don't care about separate sinks for these devices. |
107 return mock_sink_; | 141 return mock_sink_; |
108 } | 142 } |
109 if (device_id == kNonexistentDeviceId) | 143 if (device_id == kNonexistentDeviceId) |
110 return mock_sink_no_device_; | 144 return mock_sink_no_device_; |
111 if (device_id.empty()) { | 145 if (device_id.empty()) { |
112 // The sink used to get device ID from session ID if it's not empty | 146 // The sink used to get device ID from session ID if it's not empty |
113 return session_id ? mock_sink_for_session_id_ : mock_sink_; | 147 return session_id ? mock_sink_matched_device_ : mock_sink_; |
114 } | 148 } |
115 if (device_id == kMatchedDeviceId) | 149 if (device_id == kMatchedDeviceId) |
116 return mock_sink_matched_device_; | 150 return mock_sink_matched_device_; |
117 | 151 |
118 NOTREACHED(); | 152 NOTREACHED(); |
119 return nullptr; | 153 return nullptr; |
120 } | 154 } |
121 | 155 |
| 156 MOCK_METHOD1(ReleaseSinkPtr, void(const media::AudioRendererSink*)); |
| 157 |
122 std::unique_ptr<AudioRendererMixerManager> manager_; | 158 std::unique_ptr<AudioRendererMixerManager> manager_; |
| 159 |
123 scoped_refptr<media::MockAudioRendererSink> mock_sink_; | 160 scoped_refptr<media::MockAudioRendererSink> mock_sink_; |
124 scoped_refptr<media::MockAudioRendererSink> mock_sink_no_device_; | 161 scoped_refptr<media::MockAudioRendererSink> mock_sink_no_device_; |
125 scoped_refptr<media::MockAudioRendererSink> mock_sink_matched_device_; | 162 scoped_refptr<media::MockAudioRendererSink> mock_sink_matched_device_; |
126 scoped_refptr<media::MockAudioRendererSink> mock_sink_for_session_id_; | |
127 | 163 |
128 // To avoid global/static non-POD constants. | 164 // To avoid global/static non-POD constants. |
129 const url::Origin kSecurityOrigin; | 165 const url::Origin kSecurityOrigin; |
130 const url::Origin kSecurityOrigin2; | 166 const url::Origin kSecurityOrigin2; |
131 | 167 |
132 private: | 168 private: |
133 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManagerTest); | 169 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManagerTest); |
134 }; | 170 }; |
135 | 171 |
136 // Verify GetMixer() and RemoveMixer() both work as expected; particularly with | 172 // Verify GetMixer() and ReturnMixer() both work as expected; particularly with |
137 // respect to the explicit ref counting done. | 173 // respect to the explicit ref counting done. |
138 TEST_F(AudioRendererMixerManagerTest, GetRemoveMixer) { | 174 TEST_F(AudioRendererMixerManagerTest, GetReturnMixer) { |
139 // Since we're testing two different sets of parameters, we expect | 175 // Since we're testing two different sets of parameters, we expect |
140 // AudioRendererMixerManager to call Start and Stop on our mock twice. | 176 // AudioRendererMixerManager to call Start and Stop on our mock twice. |
141 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); | 177 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); |
142 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); | 178 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); |
143 | 179 |
| 180 // We expect 2 mixers to be created; each of them should release the sink. |
| 181 EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2); |
| 182 |
144 // There should be no mixers outstanding to start with. | 183 // There should be no mixers outstanding to start with. |
145 EXPECT_EQ(0, mixer_count()); | 184 EXPECT_EQ(0, mixer_count()); |
146 | 185 |
147 media::AudioParameters params1( | 186 media::AudioParameters params1( |
148 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, | 187 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, |
149 kBitsPerChannel, kBufferSize); | 188 kBitsPerChannel, kBufferSize); |
150 | 189 |
151 media::AudioRendererMixer* mixer1 = GetMixer( | 190 media::AudioRendererMixer* mixer1 = GetMixer( |
152 kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin, nullptr); | 191 kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin, nullptr); |
153 ASSERT_TRUE(mixer1); | 192 ASSERT_TRUE(mixer1); |
154 EXPECT_EQ(1, mixer_count()); | 193 EXPECT_EQ(1, mixer_count()); |
155 | 194 |
156 // The same parameters should return the same mixer1. | 195 // The same parameters should return the same mixer1. |
157 EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params1, kDefaultDeviceId, | 196 EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params1, kDefaultDeviceId, |
158 kSecurityOrigin, nullptr)); | 197 kSecurityOrigin, nullptr)); |
159 EXPECT_EQ(1, mixer_count()); | 198 EXPECT_EQ(1, mixer_count()); |
160 | 199 |
161 // Remove the extra mixer we just acquired. | 200 // Return the extra mixer we just acquired. |
162 RemoveMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin); | 201 ReturnMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin); |
163 EXPECT_EQ(1, mixer_count()); | 202 EXPECT_EQ(1, mixer_count()); |
164 | 203 |
165 media::AudioParameters params2( | 204 media::AudioParameters params2( |
166 AudioParameters::AUDIO_PCM_LINEAR, kAnotherChannelLayout, kSampleRate * 2, | 205 AudioParameters::AUDIO_PCM_LINEAR, kAnotherChannelLayout, kSampleRate * 2, |
167 kBitsPerChannel, kBufferSize * 2); | 206 kBitsPerChannel, kBufferSize * 2); |
168 media::AudioRendererMixer* mixer2 = GetMixer( | 207 media::AudioRendererMixer* mixer2 = GetMixer( |
169 kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin, nullptr); | 208 kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin, nullptr); |
170 ASSERT_TRUE(mixer2); | 209 ASSERT_TRUE(mixer2); |
171 EXPECT_EQ(2, mixer_count()); | 210 EXPECT_EQ(2, mixer_count()); |
172 | 211 |
173 // Different parameters should result in a different mixer1. | 212 // Different parameters should result in a different mixer1. |
174 EXPECT_NE(mixer1, mixer2); | 213 EXPECT_NE(mixer1, mixer2); |
175 | 214 |
176 // Remove both outstanding mixers. | 215 // Return both outstanding mixers. |
177 RemoveMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin); | 216 ReturnMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin); |
178 EXPECT_EQ(1, mixer_count()); | 217 EXPECT_EQ(1, mixer_count()); |
179 RemoveMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin); | 218 ReturnMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin); |
180 EXPECT_EQ(0, mixer_count()); | 219 EXPECT_EQ(0, mixer_count()); |
181 } | 220 } |
182 | 221 |
183 // Verify GetMixer() correctly deduplicates mixer with irrelevant AudioParameter | 222 // Verify GetMixer() correctly deduplicates mixer with irrelevant AudioParameter |
184 // differences. | 223 // differences. |
185 TEST_F(AudioRendererMixerManagerTest, MixerReuse) { | 224 TEST_F(AudioRendererMixerManagerTest, MixerReuse) { |
186 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); | 225 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); |
187 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); | 226 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); |
188 EXPECT_EQ(mixer_count(), 0); | 227 EXPECT_EQ(mixer_count(), 0); |
189 | 228 |
| 229 // We expect 2 mixers to be created; each of them should release the sink. |
| 230 EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2); |
| 231 |
190 media::AudioParameters params1(AudioParameters::AUDIO_PCM_LINEAR, | 232 media::AudioParameters params1(AudioParameters::AUDIO_PCM_LINEAR, |
191 kChannelLayout, | 233 kChannelLayout, |
192 kSampleRate, | 234 kSampleRate, |
193 kBitsPerChannel, | 235 kBitsPerChannel, |
194 kBufferSize); | 236 kBufferSize); |
195 media::AudioRendererMixer* mixer1 = GetMixer( | 237 media::AudioRendererMixer* mixer1 = GetMixer( |
196 kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin, nullptr); | 238 kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin, nullptr); |
197 ASSERT_TRUE(mixer1); | 239 ASSERT_TRUE(mixer1); |
198 EXPECT_EQ(1, mixer_count()); | 240 EXPECT_EQ(1, mixer_count()); |
199 | 241 |
200 // Different sample rates, formats, bit depths, and buffer sizes should not | 242 // Different sample rates, formats, bit depths, and buffer sizes should not |
201 // result in a different mixer. | 243 // result in a different mixer. |
202 media::AudioParameters params2(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 244 media::AudioParameters params2(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
203 kChannelLayout, | 245 kChannelLayout, |
204 kSampleRate * 2, | 246 kSampleRate * 2, |
205 kBitsPerChannel * 2, | 247 kBitsPerChannel * 2, |
206 kBufferSize * 2); | 248 kBufferSize * 2); |
207 EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params2, kDefaultDeviceId, | 249 EXPECT_EQ(mixer1, GetMixer(kRenderFrameId, params2, kDefaultDeviceId, |
208 kSecurityOrigin, nullptr)); | 250 kSecurityOrigin, nullptr)); |
209 EXPECT_EQ(1, mixer_count()); | 251 EXPECT_EQ(1, mixer_count()); |
210 RemoveMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin); | 252 ReturnMixer(kRenderFrameId, params2, kDefaultDeviceId, kSecurityOrigin); |
211 EXPECT_EQ(1, mixer_count()); | 253 EXPECT_EQ(1, mixer_count()); |
212 | 254 |
213 // Modify some parameters that do matter: channel layout | 255 // Modify some parameters that do matter: channel layout |
214 media::AudioParameters params3(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 256 media::AudioParameters params3(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
215 kAnotherChannelLayout, | 257 kAnotherChannelLayout, |
216 kSampleRate, | 258 kSampleRate, |
217 kBitsPerChannel, | 259 kBitsPerChannel, |
218 kBufferSize); | 260 kBufferSize); |
219 ASSERT_NE(params3.channel_layout(), params1.channel_layout()); | 261 ASSERT_NE(params3.channel_layout(), params1.channel_layout()); |
220 | 262 |
221 EXPECT_NE(mixer1, GetMixer(kRenderFrameId, params3, kDefaultDeviceId, | 263 EXPECT_NE(mixer1, GetMixer(kRenderFrameId, params3, kDefaultDeviceId, |
222 kSecurityOrigin, nullptr)); | 264 kSecurityOrigin, nullptr)); |
223 EXPECT_EQ(2, mixer_count()); | 265 EXPECT_EQ(2, mixer_count()); |
224 RemoveMixer(kRenderFrameId, params3, kDefaultDeviceId, kSecurityOrigin); | 266 ReturnMixer(kRenderFrameId, params3, kDefaultDeviceId, kSecurityOrigin); |
225 EXPECT_EQ(1, mixer_count()); | 267 EXPECT_EQ(1, mixer_count()); |
226 | 268 |
227 // Remove final mixer. | 269 // Return final mixer. |
228 RemoveMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin); | 270 ReturnMixer(kRenderFrameId, params1, kDefaultDeviceId, kSecurityOrigin); |
229 EXPECT_EQ(0, mixer_count()); | 271 EXPECT_EQ(0, mixer_count()); |
230 } | 272 } |
231 | 273 |
232 // Verify CreateInput() provides AudioRendererMixerInput with the appropriate | 274 // Verify CreateInput() provides AudioRendererMixerInput with the appropriate |
233 // callbacks and they are working as expected. Also, verify that separate | 275 // callbacks and they are working as expected. Also, verify that separate |
234 // mixers are created for separate render views, even though the AudioParameters | 276 // mixers are created for separate render views, even though the AudioParameters |
235 // are the same. | 277 // are the same. |
236 TEST_F(AudioRendererMixerManagerTest, CreateInput) { | 278 TEST_F(AudioRendererMixerManagerTest, CreateInput) { |
237 // Expect AudioRendererMixerManager to call Start and Stop on our mock twice | 279 // Expect AudioRendererMixerManager to call Start and Stop on our mock twice |
238 // each. Note: Under normal conditions, each mixer would get its own sink! | 280 // each. Note: Under normal conditions, each mixer would get its own sink! |
239 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); | 281 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); |
240 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); | 282 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); |
241 | 283 |
| 284 // We expect 2 mixers to be created; each of them should release the sink. |
| 285 EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2); |
| 286 |
242 media::AudioParameters params( | 287 media::AudioParameters params( |
243 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, | 288 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, |
244 kBitsPerChannel, kBufferSize); | 289 kBitsPerChannel, kBufferSize); |
245 | 290 |
246 // Create two mixer inputs and ensure this doesn't instantiate any mixers yet. | 291 // Create two mixer inputs and ensure this doesn't instantiate any mixers yet. |
247 EXPECT_EQ(0, mixer_count()); | 292 EXPECT_EQ(0, mixer_count()); |
248 media::FakeAudioRenderCallback callback(0); | 293 media::FakeAudioRenderCallback callback(0); |
249 scoped_refptr<media::AudioRendererMixerInput> input(manager_->CreateInput( | 294 scoped_refptr<media::AudioRendererMixerInput> input(manager_->CreateInput( |
250 kRenderFrameId, 0, kDefaultDeviceId, kSecurityOrigin)); | 295 kRenderFrameId, 0, kDefaultDeviceId, kSecurityOrigin)); |
251 input->Initialize(params, &callback); | 296 input->Initialize(params, &callback); |
252 EXPECT_EQ(0, mixer_count()); | 297 EXPECT_EQ(0, mixer_count()); |
253 media::FakeAudioRenderCallback another_callback(1); | 298 media::FakeAudioRenderCallback another_callback(1); |
254 scoped_refptr<media::AudioRendererMixerInput> another_input( | 299 scoped_refptr<media::AudioRendererMixerInput> another_input( |
255 manager_->CreateInput(kAnotherRenderFrameId, 0, kDefaultDeviceId, | 300 manager_->CreateInput(kAnotherRenderFrameId, 0, kDefaultDeviceId, |
256 kSecurityOrigin)); | 301 kSecurityOrigin)); |
257 another_input->Initialize(params, &another_callback); | 302 another_input->Initialize(params, &another_callback); |
258 EXPECT_EQ(0, mixer_count()); | 303 EXPECT_EQ(0, mixer_count()); |
259 | 304 |
260 // Implicitly test that AudioRendererMixerInput was provided with the expected | 305 // Implicitly test that AudioRendererMixerInput was provided with the expected |
261 // callbacks needed to acquire an AudioRendererMixer and remove it. | 306 // callbacks needed to acquire an AudioRendererMixer and return it. |
262 input->Start(); | 307 input->Start(); |
263 EXPECT_EQ(1, mixer_count()); | 308 EXPECT_EQ(1, mixer_count()); |
264 another_input->Start(); | 309 another_input->Start(); |
265 EXPECT_EQ(2, mixer_count()); | 310 EXPECT_EQ(2, mixer_count()); |
266 | 311 |
267 // Destroying the inputs should destroy the mixers. | 312 // Destroying the inputs should destroy the mixers. |
268 input->Stop(); | 313 input->Stop(); |
269 input = nullptr; | 314 input = nullptr; |
270 EXPECT_EQ(1, mixer_count()); | 315 EXPECT_EQ(1, mixer_count()); |
271 another_input->Stop(); | 316 another_input->Stop(); |
272 another_input = nullptr; | 317 another_input = nullptr; |
273 EXPECT_EQ(0, mixer_count()); | 318 EXPECT_EQ(0, mixer_count()); |
274 } | 319 } |
275 | 320 |
276 // Verify CreateInput() provided with session id creates AudioRendererMixerInput | 321 // Verify CreateInput() provided with session id creates AudioRendererMixerInput |
277 // with the appropriate callbacks and they are working as expected. | 322 // with the appropriate callbacks and they are working as expected. |
278 TEST_F(AudioRendererMixerManagerTest, CreateInputWithSessionId) { | 323 TEST_F(AudioRendererMixerManagerTest, CreateInputWithSessionId) { |
279 // Expect AudioRendererMixerManager to call Start and Stop on our mock twice | 324 // Expect AudioRendererMixerManager to call Start and Stop on our mock twice |
280 // each: for kDefaultDeviceId and for kAnotherDeviceId. Note: Under normal | 325 // each: for kDefaultDeviceId and for kAnotherDeviceId. Note: Under normal |
281 // conditions, each mixer would get its own sink! | 326 // conditions, each mixer would get its own sink! |
282 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); | 327 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); |
283 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); | 328 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); |
284 | 329 |
285 // Expect AudioRendererMixerManager to call Start and Stop on the matched sink | 330 // Expect AudioRendererMixerManager to call Start and Stop on the matched sink |
286 // once. | 331 // once. |
287 EXPECT_CALL(*mock_sink_matched_device_.get(), Start()).Times(1); | 332 EXPECT_CALL(*mock_sink_matched_device_.get(), Start()).Times(1); |
288 EXPECT_CALL(*mock_sink_matched_device_.get(), Stop()).Times(1); | 333 EXPECT_CALL(*mock_sink_matched_device_.get(), Stop()).Times(1); |
289 | 334 |
| 335 // We expect 3 mixers to be created; each of them should release a sink. |
| 336 EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(2); |
| 337 EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_matched_device_.get())).Times(1); |
| 338 |
290 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | 339 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
291 kChannelLayout, kSampleRate, kBitsPerChannel, | 340 kChannelLayout, kSampleRate, kBitsPerChannel, |
292 kBufferSize); | 341 kBufferSize); |
293 media::FakeAudioRenderCallback callback(0); | 342 media::FakeAudioRenderCallback callback(0); |
294 EXPECT_EQ(0, mixer_count()); | 343 EXPECT_EQ(0, mixer_count()); |
295 | 344 |
296 // Empty device id, zero session id; | 345 // Empty device id, zero session id; |
297 scoped_refptr<media::AudioRendererMixerInput> input_to_default_device( | 346 scoped_refptr<media::AudioRendererMixerInput> input_to_default_device( |
298 manager_->CreateInput(kRenderFrameId, 0, // session_id | 347 manager_->CreateInput(kRenderFrameId, 0, // session_id |
299 std::string(), kSecurityOrigin)); | 348 std::string(), kSecurityOrigin)); |
(...skipping 16 matching lines...) Expand all Loading... |
316 | 365 |
317 // Empty device id, non-zero session id; | 366 // Empty device id, non-zero session id; |
318 scoped_refptr<media::AudioRendererMixerInput> | 367 scoped_refptr<media::AudioRendererMixerInput> |
319 input_to_matched_device_with_session_id( | 368 input_to_matched_device_with_session_id( |
320 manager_->CreateInput(kRenderFrameId, 2, // session id | 369 manager_->CreateInput(kRenderFrameId, 2, // session id |
321 std::string(), kSecurityOrigin)); | 370 std::string(), kSecurityOrigin)); |
322 input_to_matched_device_with_session_id->Initialize(params, &callback); | 371 input_to_matched_device_with_session_id->Initialize(params, &callback); |
323 EXPECT_EQ(0, mixer_count()); | 372 EXPECT_EQ(0, mixer_count()); |
324 | 373 |
325 // Implicitly test that AudioRendererMixerInput was provided with the expected | 374 // Implicitly test that AudioRendererMixerInput was provided with the expected |
326 // callbacks needed to acquire an AudioRendererMixer and remove it. | 375 // callbacks needed to acquire an AudioRendererMixer and return it. |
327 input_to_default_device->Start(); | 376 input_to_default_device->Start(); |
328 EXPECT_EQ(1, mixer_count()); | 377 EXPECT_EQ(1, mixer_count()); |
329 | 378 |
330 input_to_another_device->Start(); | 379 input_to_another_device->Start(); |
331 EXPECT_EQ(2, mixer_count()); | 380 EXPECT_EQ(2, mixer_count()); |
332 | 381 |
333 input_to_matched_device->Start(); | 382 input_to_matched_device->Start(); |
334 EXPECT_EQ(3, mixer_count()); | 383 EXPECT_EQ(3, mixer_count()); |
335 | 384 |
336 // Should go to the same device as the input above. | 385 // Should go to the same device as the input above. |
(...skipping 15 matching lines...) Expand all Loading... |
352 EXPECT_EQ(0, mixer_count()); | 401 EXPECT_EQ(0, mixer_count()); |
353 } | 402 } |
354 | 403 |
355 // Verify GetMixer() correctly creates different mixers with the same | 404 // Verify GetMixer() correctly creates different mixers with the same |
356 // parameters, but different device ID and/or security origin | 405 // parameters, but different device ID and/or security origin |
357 TEST_F(AudioRendererMixerManagerTest, MixerDevices) { | 406 TEST_F(AudioRendererMixerManagerTest, MixerDevices) { |
358 EXPECT_CALL(*mock_sink_.get(), Start()).Times(3); | 407 EXPECT_CALL(*mock_sink_.get(), Start()).Times(3); |
359 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3); | 408 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3); |
360 EXPECT_EQ(0, mixer_count()); | 409 EXPECT_EQ(0, mixer_count()); |
361 | 410 |
| 411 // We expect 3 mixers to be created; each of them should release a sink. |
| 412 EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(3); |
| 413 |
362 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | 414 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
363 kChannelLayout, kSampleRate, kBitsPerChannel, | 415 kChannelLayout, kSampleRate, kBitsPerChannel, |
364 kBufferSize); | 416 kBufferSize); |
365 media::AudioRendererMixer* mixer1 = GetMixer( | 417 media::AudioRendererMixer* mixer1 = GetMixer( |
366 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr); | 418 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr); |
367 ASSERT_TRUE(mixer1); | 419 ASSERT_TRUE(mixer1); |
368 EXPECT_EQ(1, mixer_count()); | 420 EXPECT_EQ(1, mixer_count()); |
369 | 421 |
370 media::AudioRendererMixer* mixer2 = GetMixer( | 422 media::AudioRendererMixer* mixer2 = GetMixer( |
371 kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin, nullptr); | 423 kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin, nullptr); |
372 ASSERT_TRUE(mixer2); | 424 ASSERT_TRUE(mixer2); |
373 EXPECT_EQ(2, mixer_count()); | 425 EXPECT_EQ(2, mixer_count()); |
374 EXPECT_NE(mixer1, mixer2); | 426 EXPECT_NE(mixer1, mixer2); |
375 | 427 |
376 media::AudioRendererMixer* mixer3 = GetMixer( | 428 media::AudioRendererMixer* mixer3 = GetMixer( |
377 kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2, nullptr); | 429 kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2, nullptr); |
378 ASSERT_TRUE(mixer3); | 430 ASSERT_TRUE(mixer3); |
379 EXPECT_EQ(3, mixer_count()); | 431 EXPECT_EQ(3, mixer_count()); |
380 EXPECT_NE(mixer1, mixer3); | 432 EXPECT_NE(mixer1, mixer3); |
381 EXPECT_NE(mixer2, mixer3); | 433 EXPECT_NE(mixer2, mixer3); |
382 | 434 |
383 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); | 435 ReturnMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); |
384 EXPECT_EQ(2, mixer_count()); | 436 EXPECT_EQ(2, mixer_count()); |
385 RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin); | 437 ReturnMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin); |
386 EXPECT_EQ(1, mixer_count()); | 438 EXPECT_EQ(1, mixer_count()); |
387 RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2); | 439 ReturnMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2); |
388 EXPECT_EQ(0, mixer_count()); | 440 EXPECT_EQ(0, mixer_count()); |
389 } | 441 } |
390 | 442 |
391 // Verify GetMixer() correctly deduplicate mixers with the same | 443 // Verify GetMixer() correctly deduplicate mixers with the same |
392 // parameters, different security origins but default device ID | 444 // parameters, different security origins but default device ID |
393 TEST_F(AudioRendererMixerManagerTest, OneMixerDifferentOriginsDefaultDevice) { | 445 TEST_F(AudioRendererMixerManagerTest, OneMixerDifferentOriginsDefaultDevice) { |
394 EXPECT_CALL(*mock_sink_.get(), Start()).Times(1); | 446 EXPECT_CALL(*mock_sink_.get(), Start()).Times(1); |
395 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1); | 447 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1); |
396 EXPECT_EQ(0, mixer_count()); | 448 EXPECT_EQ(0, mixer_count()); |
397 | 449 |
| 450 // We expect 1 mixers to be created; it should release its sink. |
| 451 EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(1); |
| 452 |
398 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | 453 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
399 kChannelLayout, kSampleRate, kBitsPerChannel, | 454 kChannelLayout, kSampleRate, kBitsPerChannel, |
400 kBufferSize); | 455 kBufferSize); |
401 media::AudioRendererMixer* mixer1 = GetMixer( | 456 media::AudioRendererMixer* mixer1 = GetMixer( |
402 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr); | 457 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr); |
403 ASSERT_TRUE(mixer1); | 458 ASSERT_TRUE(mixer1); |
404 EXPECT_EQ(1, mixer_count()); | 459 EXPECT_EQ(1, mixer_count()); |
405 | 460 |
406 media::AudioRendererMixer* mixer2 = | 461 media::AudioRendererMixer* mixer2 = |
407 GetMixer(kRenderFrameId, params, std::string(), kSecurityOrigin, nullptr); | 462 GetMixer(kRenderFrameId, params, std::string(), kSecurityOrigin, nullptr); |
408 ASSERT_TRUE(mixer2); | 463 ASSERT_TRUE(mixer2); |
409 EXPECT_EQ(1, mixer_count()); | 464 EXPECT_EQ(1, mixer_count()); |
410 EXPECT_EQ(mixer1, mixer2); | 465 EXPECT_EQ(mixer1, mixer2); |
411 | 466 |
412 media::AudioRendererMixer* mixer3 = GetMixer( | 467 media::AudioRendererMixer* mixer3 = GetMixer( |
413 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2, nullptr); | 468 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2, nullptr); |
414 ASSERT_TRUE(mixer3); | 469 ASSERT_TRUE(mixer3); |
415 EXPECT_EQ(1, mixer_count()); | 470 EXPECT_EQ(1, mixer_count()); |
416 EXPECT_EQ(mixer1, mixer3); | 471 EXPECT_EQ(mixer1, mixer3); |
417 | 472 |
418 media::AudioRendererMixer* mixer4 = GetMixer( | 473 media::AudioRendererMixer* mixer4 = GetMixer( |
419 kRenderFrameId, params, std::string(), kSecurityOrigin2, nullptr); | 474 kRenderFrameId, params, std::string(), kSecurityOrigin2, nullptr); |
420 ASSERT_TRUE(mixer4); | 475 ASSERT_TRUE(mixer4); |
421 EXPECT_EQ(1, mixer_count()); | 476 EXPECT_EQ(1, mixer_count()); |
422 EXPECT_EQ(mixer1, mixer4); | 477 EXPECT_EQ(mixer1, mixer4); |
423 | 478 |
424 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); | 479 ReturnMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); |
425 EXPECT_EQ(1, mixer_count()); | 480 EXPECT_EQ(1, mixer_count()); |
426 RemoveMixer(kRenderFrameId, params, std::string(), kSecurityOrigin); | 481 ReturnMixer(kRenderFrameId, params, std::string(), kSecurityOrigin); |
427 EXPECT_EQ(1, mixer_count()); | 482 EXPECT_EQ(1, mixer_count()); |
428 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2); | 483 ReturnMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2); |
429 EXPECT_EQ(1, mixer_count()); | 484 EXPECT_EQ(1, mixer_count()); |
430 RemoveMixer(kRenderFrameId, params, std::string(), kSecurityOrigin2); | 485 ReturnMixer(kRenderFrameId, params, std::string(), kSecurityOrigin2); |
431 EXPECT_EQ(0, mixer_count()); | 486 EXPECT_EQ(0, mixer_count()); |
432 } | 487 } |
433 | 488 |
434 // Verify that GetMixer() correctly returns a null mixer and an appropriate | 489 // Verify that GetMixer() correctly returns a null mixer and an appropriate |
435 // status code when a nonexistent device is requested. | 490 // status code when a nonexistent device is requested. |
436 TEST_F(AudioRendererMixerManagerTest, NonexistentDevice) { | 491 TEST_F(AudioRendererMixerManagerTest, NonexistentDevice) { |
437 EXPECT_EQ(0, mixer_count()); | 492 EXPECT_EQ(0, mixer_count()); |
| 493 |
| 494 // Mixer manager should release a not-ok sink when failing to create a mixer. |
| 495 EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_no_device_.get())).Times(1); |
| 496 |
438 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | 497 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
439 kChannelLayout, kSampleRate, kBitsPerChannel, | 498 kChannelLayout, kSampleRate, kBitsPerChannel, |
440 kBufferSize); | 499 kBufferSize); |
441 media::OutputDeviceStatus device_status = media::OUTPUT_DEVICE_STATUS_OK; | 500 media::OutputDeviceStatus device_status = media::OUTPUT_DEVICE_STATUS_OK; |
442 EXPECT_CALL(*mock_sink_no_device_.get(), Stop()); | 501 |
443 media::AudioRendererMixer* mixer = | 502 media::AudioRendererMixer* mixer = |
444 GetMixer(kRenderFrameId, params, kNonexistentDeviceId, kSecurityOrigin, | 503 GetMixer(kRenderFrameId, params, kNonexistentDeviceId, kSecurityOrigin, |
445 &device_status); | 504 &device_status); |
| 505 |
446 EXPECT_FALSE(mixer); | 506 EXPECT_FALSE(mixer); |
447 EXPECT_EQ(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, device_status); | 507 EXPECT_EQ(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, device_status); |
448 EXPECT_EQ(0, mixer_count()); | 508 EXPECT_EQ(0, mixer_count()); |
449 } | 509 } |
450 | 510 |
451 } // namespace content | 511 } // namespace content |
OLD | NEW |