Chromium Code Reviews| 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 "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "base/macros.h" | 6 #include "base/macros.h" |
| 7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "content/renderer/media/audio_device_factory.h" | |
| 9 #include "content/renderer/media/audio_renderer_mixer_manager.h" | 10 #include "content/renderer/media/audio_renderer_mixer_manager.h" |
| 10 #include "ipc/ipc_message.h" | 11 #include "ipc/ipc_message.h" |
| 11 #include "media/audio/audio_parameters.h" | 12 #include "media/audio/audio_parameters.h" |
| 12 #include "media/base/audio_hardware_config.h" | 13 #include "media/base/audio_hardware_config.h" |
| 13 #include "media/base/audio_renderer_mixer.h" | 14 #include "media/base/audio_renderer_mixer.h" |
| 14 #include "media/base/audio_renderer_mixer_input.h" | 15 #include "media/base/audio_renderer_mixer_input.h" |
| 15 #include "media/base/fake_audio_render_callback.h" | 16 #include "media/base/fake_audio_render_callback.h" |
| 16 #include "media/base/mock_audio_renderer_sink.h" | 17 #include "media/base/mock_audio_renderer_sink.h" |
| 17 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 20 |
| 20 namespace content { | 21 namespace content { |
| 21 | 22 |
| 22 static const int kBitsPerChannel = 16; | 23 static const int kBitsPerChannel = 16; |
| 23 static const int kSampleRate = 48000; | 24 static const int kSampleRate = 48000; |
| 24 static const int kBufferSize = 8192; | 25 static const int kBufferSize = 8192; |
| 25 static const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO; | 26 static const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO; |
| 26 static const media::ChannelLayout kAnotherChannelLayout = | 27 static const media::ChannelLayout kAnotherChannelLayout = |
| 27 media::CHANNEL_LAYOUT_2_1; | 28 media::CHANNEL_LAYOUT_2_1; |
| 28 static const std::string kDefaultDeviceId; | 29 static const char* const kDefaultDeviceId = |
|
Henrik Grunell
2016/03/08 21:09:57
Why not use media::AudioManagerBase::kDefaultDevic
o1ka
2016/04/05 15:13:38
Because this is shorter?
| |
| 29 static const url::Origin kSecurityOrigin; | 30 media::AudioManagerBase::kDefaultDeviceId; |
| 31 static const char kAnotherDeviceId[] = "another-device-id"; | |
| 32 static const char kMatchedDeviceId[] = "matched-device-id"; | |
| 33 static const char kNonexistentDeviceId[] = "nonexistent-device-id"; | |
| 30 | 34 |
| 31 static const int kRenderFrameId = 124; | 35 static const int kRenderFrameId = 124; |
| 32 static const int kAnotherRenderFrameId = 678; | 36 static const int kAnotherRenderFrameId = 678; |
| 33 | 37 |
| 34 using media::AudioParameters; | 38 using media::AudioParameters; |
| 35 | 39 |
| 36 class AudioRendererMixerManagerTest : public testing::Test { | 40 class AudioRendererMixerManagerTest : public testing::Test, |
| 41 public AudioDeviceFactory { | |
| 37 public: | 42 public: |
| 38 AudioRendererMixerManagerTest() { | 43 AudioRendererMixerManagerTest() |
| 39 manager_.reset(new AudioRendererMixerManager()); | 44 : manager_(new AudioRendererMixerManager()), |
| 40 | 45 mock_sink_(new media::MockAudioRendererMixerSink()), |
| 41 // We don't want to deal with instantiating a real AudioOutputDevice since | 46 mock_sink_no_device_(new media::MockAudioRendererMixerSink( |
| 42 // it's not important to our testing, so we inject a mock. | 47 kNonexistentDeviceId, |
| 43 mock_sink_ = new media::MockAudioRendererSink(); | 48 media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND)), |
| 44 manager_->SetAudioRendererSinkForTesting(mock_sink_.get()); | 49 mock_sink_matched_device_(new media::MockAudioRendererMixerSink( |
| 45 } | 50 kMatchedDeviceId, |
| 51 media::OUTPUT_DEVICE_STATUS_OK)), | |
| 52 mock_sink_for_session_id_(new media::MockAudioRendererMixerSink( | |
| 53 kMatchedDeviceId, | |
| 54 media::OUTPUT_DEVICE_STATUS_OK)), | |
| 55 kSecurityOrigin2(GURL("http://localhost")) {} | |
| 46 | 56 |
| 47 media::AudioRendererMixer* GetMixer( | 57 media::AudioRendererMixer* GetMixer( |
| 48 int source_render_frame_id, | 58 int source_render_frame_id, |
| 49 const media::AudioParameters& params, | 59 const media::AudioParameters& params, |
| 50 const std::string& device_id, | 60 const std::string& device_id, |
| 51 const url::Origin& security_origin, | 61 const url::Origin& security_origin, |
| 52 media::OutputDeviceStatus* device_status) { | 62 media::OutputDeviceStatus* device_status) { |
| 53 return manager_->GetMixer(source_render_frame_id, params, device_id, | 63 return manager_->GetMixer(source_render_frame_id, params, device_id, |
| 54 security_origin, device_status); | 64 security_origin, device_status); |
| 55 } | 65 } |
| 56 | 66 |
| 57 void RemoveMixer(int source_render_frame_id, | 67 void RemoveMixer(int source_render_frame_id, |
| 58 const media::AudioParameters& params, | 68 const media::AudioParameters& params, |
| 59 const std::string& device_id, | 69 const std::string& device_id, |
| 60 const url::Origin& security_origin) { | 70 const url::Origin& security_origin) { |
| 61 return manager_->RemoveMixer(source_render_frame_id, params, device_id, | 71 return manager_->RemoveMixer(source_render_frame_id, params, device_id, |
| 62 security_origin); | 72 security_origin); |
| 63 } | 73 } |
| 64 | 74 |
| 65 void UseNonexistentSink() { | |
| 66 mock_sink_ = new media::MockAudioRendererSink( | |
| 67 media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND); | |
| 68 manager_->SetAudioRendererSinkForTesting(mock_sink_.get()); | |
| 69 } | |
| 70 | |
| 71 // Number of instantiated mixers. | 75 // Number of instantiated mixers. |
| 72 int mixer_count() { | 76 int mixer_count() { |
| 73 return manager_->mixers_.size(); | 77 return manager_->mixers_.size(); |
| 74 } | 78 } |
| 75 | 79 |
| 76 protected: | 80 protected: |
| 81 MOCK_METHOD1(CreateInputDevice, media::AudioInputDevice*(int)); | |
| 82 MOCK_METHOD5(CreateRestartableAudioRendererSink, | |
| 83 media::RestartableAudioRendererSink*(SourceType, | |
| 84 int, | |
| 85 int, | |
| 86 const std::string&, | |
| 87 const url::Origin&)); | |
| 88 MOCK_METHOD5(CreateAudioRendererSink, | |
| 89 media::AudioRendererSink*(SourceType, | |
| 90 int, | |
| 91 int, | |
| 92 const std::string&, | |
| 93 const url::Origin&)); | |
| 94 | |
| 95 media::AudioRendererMixerSink* CreateAudioRendererMixerSink( | |
| 96 int render_frame_id, | |
| 97 int session_id, | |
| 98 const std::string& device_id, | |
| 99 const url::Origin& security_origin) { | |
| 100 if ((device_id == kDefaultDeviceId) || (device_id == kAnotherDeviceId)) { | |
| 101 // We don't care about separate sinks for this devices | |
| 102 return mock_sink_.get(); | |
| 103 } | |
| 104 if (device_id == kNonexistentDeviceId) { | |
| 105 // The think to return device errror | |
| 106 return mock_sink_no_device_.get(); | |
| 107 } | |
| 108 if (device_id.empty()) { | |
| 109 // The sink used to get device ID from session ID if it's not empty | |
| 110 return session_id ? mock_sink_for_session_id_.get() : mock_sink_.get(); | |
| 111 } | |
| 112 if (device_id == kMatchedDeviceId) { | |
| 113 return mock_sink_matched_device_.get(); | |
| 114 } | |
| 115 | |
| 116 NOTREACHED(); | |
| 117 return nullptr; | |
| 118 } | |
| 119 | |
| 77 scoped_ptr<AudioRendererMixerManager> manager_; | 120 scoped_ptr<AudioRendererMixerManager> manager_; |
| 78 scoped_refptr<media::MockAudioRendererSink> mock_sink_; | 121 scoped_refptr<media::MockAudioRendererMixerSink> mock_sink_; |
| 122 scoped_refptr<media::MockAudioRendererMixerSink> mock_sink_no_device_; | |
| 123 scoped_refptr<media::MockAudioRendererMixerSink> mock_sink_matched_device_; | |
| 124 scoped_refptr<media::MockAudioRendererMixerSink> mock_sink_for_session_id_; | |
| 125 | |
| 126 // To avoid global/static non-POD constants. | |
| 127 const url::Origin kSecurityOrigin; | |
| 128 const url::Origin kSecurityOrigin2; | |
| 79 | 129 |
| 80 private: | 130 private: |
| 81 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManagerTest); | 131 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManagerTest); |
| 82 }; | 132 }; |
| 83 | 133 |
| 84 // Verify GetMixer() and RemoveMixer() both work as expected; particularly with | 134 // Verify GetMixer() and RemoveMixer() both work as expected; particularly with |
| 85 // respect to the explicit ref counting done. | 135 // respect to the explicit ref counting done. |
| 86 TEST_F(AudioRendererMixerManagerTest, GetRemoveMixer) { | 136 TEST_F(AudioRendererMixerManagerTest, GetRemoveMixer) { |
| 87 // Since we're testing two different sets of parameters, we expect | 137 // Since we're testing two different sets of parameters, we expect |
| 88 // AudioRendererMixerManager to call Start and Stop on our mock twice. | 138 // AudioRendererMixerManager to call Start and Stop on our mock twice. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); | 237 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); |
| 188 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); | 238 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); |
| 189 | 239 |
| 190 media::AudioParameters params( | 240 media::AudioParameters params( |
| 191 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, | 241 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, |
| 192 kBitsPerChannel, kBufferSize); | 242 kBitsPerChannel, kBufferSize); |
| 193 | 243 |
| 194 // Create two mixer inputs and ensure this doesn't instantiate any mixers yet. | 244 // Create two mixer inputs and ensure this doesn't instantiate any mixers yet. |
| 195 EXPECT_EQ(mixer_count(), 0); | 245 EXPECT_EQ(mixer_count(), 0); |
| 196 media::FakeAudioRenderCallback callback(0); | 246 media::FakeAudioRenderCallback callback(0); |
| 197 scoped_refptr<media::AudioRendererMixerInput> input( | 247 scoped_refptr<media::AudioRendererMixerInput> input(manager_->CreateInput( |
| 198 manager_->CreateInput(kRenderFrameId, kDefaultDeviceId, kSecurityOrigin)); | 248 kRenderFrameId, 0, kDefaultDeviceId, kSecurityOrigin)); |
| 199 input->Initialize(params, &callback); | 249 input->Initialize(params, &callback); |
| 200 EXPECT_EQ(mixer_count(), 0); | 250 EXPECT_EQ(mixer_count(), 0); |
| 201 media::FakeAudioRenderCallback another_callback(1); | 251 media::FakeAudioRenderCallback another_callback(1); |
| 202 scoped_refptr<media::AudioRendererMixerInput> another_input( | 252 scoped_refptr<media::AudioRendererMixerInput> another_input( |
| 203 manager_->CreateInput(kAnotherRenderFrameId, kDefaultDeviceId, | 253 manager_->CreateInput(kAnotherRenderFrameId, 0, kDefaultDeviceId, |
| 204 kSecurityOrigin)); | 254 kSecurityOrigin)); |
| 205 another_input->Initialize(params, &another_callback); | 255 another_input->Initialize(params, &another_callback); |
| 206 EXPECT_EQ(mixer_count(), 0); | 256 EXPECT_EQ(mixer_count(), 0); |
| 207 | 257 |
| 208 // Implicitly test that AudioRendererMixerInput was provided with the expected | 258 // Implicitly test that AudioRendererMixerInput was provided with the expected |
| 209 // callbacks needed to acquire an AudioRendererMixer and remove it. | 259 // callbacks needed to acquire an AudioRendererMixer and remove it. |
| 210 input->Start(); | 260 input->Start(); |
| 211 EXPECT_EQ(mixer_count(), 1); | 261 EXPECT_EQ(mixer_count(), 1); |
| 212 another_input->Start(); | 262 another_input->Start(); |
| 213 EXPECT_EQ(mixer_count(), 2); | 263 EXPECT_EQ(mixer_count(), 2); |
| 214 | 264 |
| 215 // Destroying the inputs should destroy the mixers. | 265 // Destroying the inputs should destroy the mixers. |
| 216 input->Stop(); | 266 input->Stop(); |
| 217 input = NULL; | 267 input = nullptr; |
| 218 EXPECT_EQ(mixer_count(), 1); | 268 EXPECT_EQ(mixer_count(), 1); |
| 219 another_input->Stop(); | 269 another_input->Stop(); |
| 220 another_input = NULL; | 270 another_input = nullptr; |
| 221 EXPECT_EQ(mixer_count(), 0); | 271 EXPECT_EQ(mixer_count(), 0); |
| 222 } | 272 } |
| 223 | 273 |
| 274 // Verify CreateInput() provided with session id creates AudioRendererMixerInput | |
| 275 // with the appropriate callbacks and they are working as expected. | |
| 276 TEST_F(AudioRendererMixerManagerTest, CreateInputWithSessionId) { | |
| 277 // Expect AudioRendererMixerManager to call Start and Stop on our mock twice | |
| 278 // each: for kDefaultDeviceId and for kAnotherDeviceId. Note: Under normal | |
| 279 // conditions, each mixer would get its own sink! | |
| 280 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); | |
| 281 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); | |
| 282 | |
| 283 // Expect AudioRendererMixerManager to call Start and Stop on the matched sink | |
| 284 // once. | |
| 285 EXPECT_CALL(*mock_sink_matched_device_.get(), Start()).Times(1); | |
|
Henrik Grunell
2016/03/08 21:09:57
Nit/Optional: I don't think you need .Times(1).
o1ka
2016/04/05 15:13:38
Acknowledged.
| |
| 286 EXPECT_CALL(*mock_sink_matched_device_.get(), Stop()).Times(1); | |
| 287 | |
| 288 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | |
| 289 kChannelLayout, kSampleRate, kBitsPerChannel, | |
| 290 kBufferSize); | |
| 291 media::FakeAudioRenderCallback callback(0); | |
| 292 EXPECT_EQ(mixer_count(), 0); | |
|
Henrik Grunell
2016/03/08 21:09:57
The syntax is actually EXPECT_EQ(expected, actual)
o1ka
2016/04/05 15:13:38
Done.
| |
| 293 | |
| 294 // Empty device id, zero session id; | |
| 295 scoped_refptr<media::AudioRendererMixerInput> input_to_default_device( | |
| 296 manager_->CreateInput(kRenderFrameId, 0, // session_id | |
| 297 "", kSecurityOrigin)); | |
|
Henrik Grunell
2016/03/08 21:09:57
Nit: Does it take an std::string? Change "" -> std
o1ka
2016/04/05 15:13:38
Done.
| |
| 298 input_to_default_device->Initialize(params, &callback); | |
| 299 EXPECT_EQ(mixer_count(), 0); | |
| 300 | |
| 301 // Specific device id, zero session id; | |
| 302 scoped_refptr<media::AudioRendererMixerInput> input_to_matched_device( | |
| 303 manager_->CreateInput(kRenderFrameId, 0, // session_id | |
| 304 kMatchedDeviceId, kSecurityOrigin)); | |
| 305 input_to_matched_device->Initialize(params, &callback); | |
| 306 EXPECT_EQ(mixer_count(), 0); | |
| 307 | |
| 308 // Specific device id, non-zero session id (to be ignored); | |
| 309 scoped_refptr<media::AudioRendererMixerInput> input_to_another_device( | |
| 310 manager_->CreateInput(kRenderFrameId, 1, // session id | |
| 311 kAnotherDeviceId, kSecurityOrigin)); | |
| 312 input_to_another_device->Initialize(params, &callback); | |
| 313 EXPECT_EQ(mixer_count(), 0); | |
| 314 | |
| 315 // Empty device id, non-zero session id; | |
| 316 scoped_refptr<media::AudioRendererMixerInput> | |
| 317 input_to_matched_device_with_session_id( | |
| 318 manager_->CreateInput(kRenderFrameId, 2, // session id | |
| 319 "", kSecurityOrigin)); | |
| 320 input_to_matched_device_with_session_id->Initialize(params, &callback); | |
| 321 EXPECT_EQ(mixer_count(), 0); | |
| 322 | |
| 323 // Implicitly test that AudioRendererMixerInput was provided with the expected | |
| 324 // callbacks needed to acquire an AudioRendererMixer and remove it. | |
| 325 input_to_default_device->Start(); | |
| 326 EXPECT_EQ(mixer_count(), 1); | |
| 327 | |
| 328 input_to_another_device->Start(); | |
| 329 EXPECT_EQ(mixer_count(), 2); | |
| 330 | |
| 331 input_to_matched_device->Start(); | |
| 332 EXPECT_EQ(mixer_count(), 3); | |
| 333 | |
| 334 // Should go to the same device as the input above. | |
| 335 input_to_matched_device_with_session_id->Start(); | |
| 336 EXPECT_EQ(mixer_count(), 3); | |
| 337 | |
| 338 // Destroying the inputs should destroy the mixers. | |
| 339 input_to_default_device->Stop(); | |
| 340 input_to_default_device = nullptr; | |
| 341 EXPECT_EQ(mixer_count(), 2); | |
| 342 input_to_another_device->Stop(); | |
| 343 input_to_another_device = nullptr; | |
| 344 EXPECT_EQ(mixer_count(), 1); | |
| 345 input_to_matched_device->Stop(); | |
| 346 input_to_matched_device = nullptr; | |
| 347 EXPECT_EQ(mixer_count(), 1); | |
| 348 input_to_matched_device_with_session_id->Stop(); | |
| 349 input_to_matched_device_with_session_id = nullptr; | |
| 350 EXPECT_EQ(mixer_count(), 0); | |
| 351 } | |
| 352 | |
| 224 // Verify GetMixer() correctly creates different mixers with the same | 353 // Verify GetMixer() correctly creates different mixers with the same |
| 225 // parameters, but different device ID and/or security origin | 354 // parameters, but different device ID and/or security origin |
| 226 TEST_F(AudioRendererMixerManagerTest, MixerDevices) { | 355 TEST_F(AudioRendererMixerManagerTest, MixerDevices) { |
| 227 EXPECT_CALL(*mock_sink_.get(), Start()).Times(3); | 356 EXPECT_CALL(*mock_sink_.get(), Start()).Times(3); |
| 228 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3); | 357 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3); |
| 229 EXPECT_EQ(mixer_count(), 0); | 358 EXPECT_EQ(mixer_count(), 0); |
| 230 | 359 |
| 231 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | 360 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
| 232 kChannelLayout, kSampleRate, kBitsPerChannel, | 361 kChannelLayout, kSampleRate, kBitsPerChannel, |
| 233 kBufferSize); | 362 kBufferSize); |
| 234 media::AudioRendererMixer* mixer1 = GetMixer( | 363 media::AudioRendererMixer* mixer1 = GetMixer( |
| 235 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr); | 364 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr); |
| 236 ASSERT_TRUE(mixer1); | 365 ASSERT_TRUE(mixer1); |
| 237 EXPECT_EQ(mixer_count(), 1); | 366 EXPECT_EQ(mixer_count(), 1); |
| 238 | 367 |
| 239 std::string device_id2("fake-device-id"); | 368 media::AudioRendererMixer* mixer2 = GetMixer( |
| 240 media::AudioRendererMixer* mixer2 = | 369 kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin, nullptr); |
| 241 GetMixer(kRenderFrameId, params, device_id2, kSecurityOrigin, nullptr); | |
| 242 ASSERT_TRUE(mixer2); | 370 ASSERT_TRUE(mixer2); |
| 243 EXPECT_EQ(mixer_count(), 2); | 371 EXPECT_EQ(mixer_count(), 2); |
| 244 EXPECT_NE(mixer1, mixer2); | 372 EXPECT_NE(mixer1, mixer2); |
| 245 | 373 |
| 246 url::Origin security_origin2(GURL("http://localhost")); | |
| 247 media::AudioRendererMixer* mixer3 = GetMixer( | 374 media::AudioRendererMixer* mixer3 = GetMixer( |
| 248 kRenderFrameId, params, kDefaultDeviceId, security_origin2, nullptr); | 375 kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2, nullptr); |
| 249 ASSERT_TRUE(mixer3); | 376 ASSERT_TRUE(mixer3); |
| 250 EXPECT_EQ(mixer_count(), 3); | 377 EXPECT_EQ(mixer_count(), 3); |
| 251 EXPECT_NE(mixer1, mixer3); | 378 EXPECT_NE(mixer1, mixer3); |
| 252 EXPECT_NE(mixer2, mixer3); | 379 EXPECT_NE(mixer2, mixer3); |
| 253 | 380 |
| 254 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); | 381 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); |
| 255 EXPECT_EQ(mixer_count(), 2); | 382 EXPECT_EQ(mixer_count(), 2); |
| 256 RemoveMixer(kRenderFrameId, params, device_id2, kSecurityOrigin); | 383 RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin); |
| 257 EXPECT_EQ(mixer_count(), 1); | 384 EXPECT_EQ(mixer_count(), 1); |
| 258 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, security_origin2); | 385 RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2); |
| 259 EXPECT_EQ(mixer_count(), 0); | 386 EXPECT_EQ(mixer_count(), 0); |
| 260 } | 387 } |
| 261 | 388 |
| 389 // Verify GetMixer() correctly deduplicate mixers with the same | |
| 390 // parameters, different security origins but default device ID | |
| 391 TEST_F(AudioRendererMixerManagerTest, OneMixerDiffferenrOriginsDefaultDevice) { | |
| 392 EXPECT_CALL(*mock_sink_.get(), Start()).Times(1); | |
| 393 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1); | |
| 394 EXPECT_EQ(mixer_count(), 0); | |
| 395 | |
| 396 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | |
| 397 kChannelLayout, kSampleRate, kBitsPerChannel, | |
| 398 kBufferSize); | |
| 399 media::AudioRendererMixer* mixer1 = GetMixer( | |
| 400 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin, nullptr); | |
| 401 ASSERT_TRUE(mixer1); | |
| 402 EXPECT_EQ(mixer_count(), 1); | |
| 403 | |
| 404 media::AudioRendererMixer* mixer2 = | |
| 405 GetMixer(kRenderFrameId, params, "", kSecurityOrigin, nullptr); | |
| 406 ASSERT_TRUE(mixer2); | |
| 407 EXPECT_EQ(mixer_count(), 1); | |
| 408 EXPECT_EQ(mixer1, mixer2); | |
| 409 | |
| 410 media::AudioRendererMixer* mixer3 = GetMixer( | |
| 411 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2, nullptr); | |
| 412 ASSERT_TRUE(mixer3); | |
| 413 EXPECT_EQ(mixer_count(), 1); | |
| 414 EXPECT_EQ(mixer1, mixer3); | |
| 415 | |
| 416 media::AudioRendererMixer* mixer4 = | |
| 417 GetMixer(kRenderFrameId, params, "", kSecurityOrigin2, nullptr); | |
| 418 ASSERT_TRUE(mixer4); | |
| 419 EXPECT_EQ(mixer_count(), 1); | |
| 420 EXPECT_EQ(mixer1, mixer4); | |
| 421 | |
| 422 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); | |
| 423 EXPECT_EQ(mixer_count(), 1); | |
| 424 RemoveMixer(kRenderFrameId, params, "", kSecurityOrigin); | |
| 425 EXPECT_EQ(mixer_count(), 1); | |
| 426 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2); | |
| 427 EXPECT_EQ(mixer_count(), 1); | |
| 428 RemoveMixer(kRenderFrameId, params, "", kSecurityOrigin2); | |
| 429 EXPECT_EQ(mixer_count(), 0); | |
| 430 } | |
| 431 | |
| 262 // Verify that GetMixer() correctly returns a null mixer and an appropriate | 432 // Verify that GetMixer() correctly returns a null mixer and an appropriate |
| 263 // status code when a nonexistent device is requested. | 433 // status code when a nonexistent device is requested. |
| 264 TEST_F(AudioRendererMixerManagerTest, NonexistentDevice) { | 434 TEST_F(AudioRendererMixerManagerTest, NonexistentDevice) { |
| 265 EXPECT_EQ(mixer_count(), 0); | 435 EXPECT_EQ(mixer_count(), 0); |
| 266 UseNonexistentSink(); | |
| 267 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | 436 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
| 268 kChannelLayout, kSampleRate, kBitsPerChannel, | 437 kChannelLayout, kSampleRate, kBitsPerChannel, |
| 269 kBufferSize); | 438 kBufferSize); |
| 270 std::string nonexistent_device_id("nonexistent-device-id"); | |
| 271 media::OutputDeviceStatus device_status = media::OUTPUT_DEVICE_STATUS_OK; | 439 media::OutputDeviceStatus device_status = media::OUTPUT_DEVICE_STATUS_OK; |
| 272 EXPECT_CALL(*mock_sink_.get(), Stop()); | 440 EXPECT_CALL(*mock_sink_no_device_.get(), Stop()); |
| 273 media::AudioRendererMixer* mixer = | 441 media::AudioRendererMixer* mixer = |
| 274 GetMixer(kRenderFrameId, params, nonexistent_device_id, kSecurityOrigin, | 442 GetMixer(kRenderFrameId, params, kNonexistentDeviceId, kSecurityOrigin, |
| 275 &device_status); | 443 &device_status); |
| 276 EXPECT_FALSE(mixer); | 444 EXPECT_FALSE(mixer); |
| 277 EXPECT_EQ(device_status, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND); | 445 EXPECT_EQ(device_status, media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND); |
| 278 EXPECT_EQ(mixer_count(), 0); | 446 EXPECT_EQ(mixer_count(), 0); |
| 279 } | 447 } |
| 280 | 448 |
| 281 } // namespace content | 449 } // namespace content |
| OLD | NEW |