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_device_factory.h" |
| 10 #include "content/renderer/media/audio_renderer_mixer_manager.h" | 10 #include "content/renderer/media/audio_renderer_mixer_manager.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 | 23 |
| 24 static const int kBitsPerChannel = 16; | 24 static const int kBitsPerChannel = 16; |
| 25 static const int kSampleRate = 48000; | 25 static const int kSampleRate = 48000; |
| 26 static const int kBufferSize = 8192; | 26 static const int kBufferSize = 8192; |
| 27 static const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO; | 27 static const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO; |
| 28 static const media::ChannelLayout kAnotherChannelLayout = | 28 static const media::ChannelLayout kAnotherChannelLayout = |
| 29 media::CHANNEL_LAYOUT_2_1; | 29 media::CHANNEL_LAYOUT_2_1; |
| 30 static const char* const kDefaultDeviceId = | 30 static const char* const kDefaultDeviceId = |
| 31 media::AudioManagerBase::kDefaultDeviceId; | 31 media::AudioManagerBase::kDefaultDeviceId; |
| 32 static const char kAnotherDeviceId[] = "another-device-id"; | 32 static const char kAnotherDeviceId[] = "another-device-id"; |
| 33 static const char kMatchedDeviceId[] = "matched-device-id"; | |
| 33 static const char kNonexistentDeviceId[] = "nonexistent-device-id"; | 34 static const char kNonexistentDeviceId[] = "nonexistent-device-id"; |
| 34 | 35 |
| 35 static const int kRenderFrameId = 124; | 36 static const int kRenderFrameId = 124; |
| 36 static const int kAnotherRenderFrameId = 678; | 37 static const int kAnotherRenderFrameId = 678; |
| 37 | 38 |
| 38 using media::AudioParameters; | 39 using media::AudioParameters; |
| 39 | 40 |
| 40 class AudioRendererMixerManagerTest : public testing::Test, | 41 class AudioRendererMixerManagerTest : public testing::Test, |
| 41 public AudioDeviceFactory { | 42 public AudioDeviceFactory { |
| 42 public: | 43 public: |
| 43 AudioRendererMixerManagerTest() | 44 AudioRendererMixerManagerTest() |
| 44 : manager_(new AudioRendererMixerManager()), | 45 : manager_(new AudioRendererMixerManager()), |
| 45 mock_sink_(new media::MockAudioRendererSink()), | 46 mock_sink_(new media::MockAudioRendererSink()), |
| 46 mock_sink_no_device_(new media::MockAudioRendererSink( | 47 mock_sink_no_device_(new media::MockAudioRendererSink( |
| 47 kNonexistentDeviceId, | 48 kNonexistentDeviceId, |
| 48 media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND)), | 49 media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND)), |
| 50 mock_sink_matched_device_( | |
| 51 new media::MockAudioRendererSink(kMatchedDeviceId, | |
| 52 media::OUTPUT_DEVICE_STATUS_OK)), | |
| 53 mock_sink_for_session_id_( | |
| 54 new media::MockAudioRendererSink(kMatchedDeviceId, | |
| 55 media::OUTPUT_DEVICE_STATUS_OK)), | |
| 49 kSecurityOrigin2(GURL("http://localhost")) {} | 56 kSecurityOrigin2(GURL("http://localhost")) {} |
| 50 | 57 |
| 51 media::AudioRendererMixer* GetMixer( | 58 media::AudioRendererMixer* GetMixer( |
| 52 int source_render_frame_id, | 59 int source_render_frame_id, |
| 53 const media::AudioParameters& params, | 60 const media::AudioParameters& params, |
| 54 const std::string& device_id, | 61 const std::string& device_id, |
| 55 const url::Origin& security_origin, | 62 const url::Origin& security_origin, |
| 56 media::OutputDeviceStatus* device_status) { | 63 media::OutputDeviceStatus* device_status) { |
| 57 return manager_->GetMixer(source_render_frame_id, params, device_id, | 64 return manager_->GetMixer(source_render_frame_id, params, device_id, |
| 58 security_origin, device_status); | 65 security_origin, device_status); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 87 int, | 94 int, |
| 88 const std::string&, | 95 const std::string&, |
| 89 const url::Origin&)); | 96 const url::Origin&)); |
| 90 | 97 |
| 91 scoped_refptr<media::AudioRendererSink> CreateAudioRendererMixerSink( | 98 scoped_refptr<media::AudioRendererSink> CreateAudioRendererMixerSink( |
| 92 int render_frame_id, | 99 int render_frame_id, |
| 93 int session_id, | 100 int session_id, |
| 94 const std::string& device_id, | 101 const std::string& device_id, |
| 95 const url::Origin& security_origin) { | 102 const url::Origin& security_origin) { |
| 96 if ((device_id == kDefaultDeviceId) || (device_id == kAnotherDeviceId)) { | 103 if ((device_id == kDefaultDeviceId) || (device_id == kAnotherDeviceId)) { |
| 97 // We don't care about separate sinks for these devices | 104 // We don't care about separate sinks for these devices. |
| 98 return mock_sink_; | 105 return mock_sink_; |
| 99 } | 106 } |
| 100 if (device_id == kNonexistentDeviceId) { | 107 if (device_id == kNonexistentDeviceId) |
| 101 return mock_sink_no_device_; | 108 return mock_sink_no_device_; |
| 109 if (device_id.empty()) { | |
| 110 // The sink used to get device ID from session ID if it's not empty | |
| 111 return session_id ? mock_sink_for_session_id_ : mock_sink_; | |
| 102 } | 112 } |
| 103 if (device_id.empty()) { | 113 if (device_id == kMatchedDeviceId) |
| 104 return mock_sink_; | 114 return mock_sink_matched_device_; |
| 105 } | |
| 106 | 115 |
| 107 NOTREACHED(); | 116 NOTREACHED(); |
| 108 return nullptr; | 117 return nullptr; |
| 109 } | 118 } |
| 110 | 119 |
| 111 scoped_ptr<AudioRendererMixerManager> manager_; | 120 scoped_ptr<AudioRendererMixerManager> manager_; |
| 112 scoped_refptr<media::MockAudioRendererSink> mock_sink_; | 121 scoped_refptr<media::MockAudioRendererSink> mock_sink_; |
| 113 scoped_refptr<media::MockAudioRendererSink> mock_sink_no_device_; | 122 scoped_refptr<media::MockAudioRendererSink> mock_sink_no_device_; |
| 123 scoped_refptr<media::MockAudioRendererSink> mock_sink_matched_device_; | |
| 124 scoped_refptr<media::MockAudioRendererSink> mock_sink_for_session_id_; | |
| 114 | 125 |
| 115 // To avoid global/static non-POD constants. | 126 // To avoid global/static non-POD constants. |
| 116 const url::Origin kSecurityOrigin; | 127 const url::Origin kSecurityOrigin; |
| 117 const url::Origin kSecurityOrigin2; | 128 const url::Origin kSecurityOrigin2; |
| 118 | 129 |
| 119 private: | 130 private: |
| 120 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManagerTest); | 131 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManagerTest); |
| 121 }; | 132 }; |
| 122 | 133 |
| 123 // Verify GetMixer() and RemoveMixer() both work as expected; particularly with | 134 // Verify GetMixer() and RemoveMixer() both work as expected; particularly with |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); | 237 EXPECT_CALL(*mock_sink_.get(), Start()).Times(2); |
| 227 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); | 238 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(2); |
| 228 | 239 |
| 229 media::AudioParameters params( | 240 media::AudioParameters params( |
| 230 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, | 241 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, |
| 231 kBitsPerChannel, kBufferSize); | 242 kBitsPerChannel, kBufferSize); |
| 232 | 243 |
| 233 // 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. |
| 234 EXPECT_EQ(0, mixer_count()); | 245 EXPECT_EQ(0, mixer_count()); |
| 235 media::FakeAudioRenderCallback callback(0); | 246 media::FakeAudioRenderCallback callback(0); |
| 236 scoped_refptr<media::AudioRendererMixerInput> input( | 247 scoped_refptr<media::AudioRendererMixerInput> input(manager_->CreateInput( |
| 237 manager_->CreateInput(kRenderFrameId, kDefaultDeviceId, kSecurityOrigin)); | 248 kRenderFrameId, 0, kDefaultDeviceId, kSecurityOrigin)); |
| 238 input->Initialize(params, &callback); | 249 input->Initialize(params, &callback); |
| 239 EXPECT_EQ(0, mixer_count()); | 250 EXPECT_EQ(0, mixer_count()); |
| 240 media::FakeAudioRenderCallback another_callback(1); | 251 media::FakeAudioRenderCallback another_callback(1); |
| 241 scoped_refptr<media::AudioRendererMixerInput> another_input( | 252 scoped_refptr<media::AudioRendererMixerInput> another_input( |
| 242 manager_->CreateInput(kAnotherRenderFrameId, kDefaultDeviceId, | 253 manager_->CreateInput(kAnotherRenderFrameId, 0, kDefaultDeviceId, |
| 243 kSecurityOrigin)); | 254 kSecurityOrigin)); |
| 244 another_input->Initialize(params, &another_callback); | 255 another_input->Initialize(params, &another_callback); |
| 245 EXPECT_EQ(0, mixer_count()); | 256 EXPECT_EQ(0, mixer_count()); |
| 246 | 257 |
| 247 // Implicitly test that AudioRendererMixerInput was provided with the expected | 258 // Implicitly test that AudioRendererMixerInput was provided with the expected |
| 248 // callbacks needed to acquire an AudioRendererMixer and remove it. | 259 // callbacks needed to acquire an AudioRendererMixer and remove it. |
| 249 input->Start(); | 260 input->Start(); |
| 250 EXPECT_EQ(1, mixer_count()); | 261 EXPECT_EQ(1, mixer_count()); |
| 251 another_input->Start(); | 262 another_input->Start(); |
| 252 EXPECT_EQ(2, mixer_count()); | 263 EXPECT_EQ(2, mixer_count()); |
| 253 | 264 |
| 254 // Destroying the inputs should destroy the mixers. | 265 // Destroying the inputs should destroy the mixers. |
| 255 input->Stop(); | 266 input->Stop(); |
| 256 input = nullptr; | 267 input = nullptr; |
| 257 EXPECT_EQ(1, mixer_count()); | 268 EXPECT_EQ(1, mixer_count()); |
| 258 another_input->Stop(); | 269 another_input->Stop(); |
| 259 another_input = nullptr; | 270 another_input = nullptr; |
| 260 EXPECT_EQ(0, mixer_count()); | 271 EXPECT_EQ(0, mixer_count()); |
| 261 } | 272 } |
| 262 | 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); | |
| 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(0, mixer_count()); | |
| 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 std::string(), kSecurityOrigin)); | |
| 298 input_to_default_device->Initialize(params, &callback); | |
| 299 EXPECT_EQ(0, mixer_count()); | |
| 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(0, mixer_count()); | |
| 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(0, mixer_count()); | |
| 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 std::string(), kSecurityOrigin)); | |
| 320 input_to_matched_device_with_session_id->Initialize(params, &callback); | |
| 321 EXPECT_EQ(0, mixer_count()); | |
| 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(1, mixer_count()); | |
| 327 | |
| 328 input_to_another_device->Start(); | |
| 329 EXPECT_EQ(2, mixer_count()); | |
| 330 | |
| 331 input_to_matched_device->Start(); | |
| 332 EXPECT_EQ(3, mixer_count()); | |
| 333 | |
| 334 // Should go to the same device as the input above. | |
| 335 input_to_matched_device_with_session_id->Start(); | |
| 336 EXPECT_EQ(3, mixer_count()); | |
| 337 | |
| 338 // Destroying the inputs should destroy the mixers. | |
| 339 input_to_default_device->Stop(); | |
| 340 input_to_default_device = nullptr; | |
| 341 EXPECT_EQ(2, mixer_count()); | |
| 342 input_to_another_device->Stop(); | |
| 343 input_to_another_device = nullptr; | |
| 344 EXPECT_EQ(1, mixer_count()); | |
| 345 input_to_matched_device->Stop(); | |
| 346 input_to_matched_device = nullptr; | |
| 347 EXPECT_EQ(1, mixer_count()); | |
| 348 input_to_matched_device_with_session_id->Stop(); | |
| 349 input_to_matched_device_with_session_id = nullptr; | |
| 350 EXPECT_EQ(0, mixer_count()); | |
| 351 } | |
| 352 | |
| 263 // Verify GetMixer() correctly creates different mixers with the same | 353 // Verify GetMixer() correctly creates different mixers with the same |
| 264 // parameters, but different device ID and/or security origin | 354 // parameters, but different device ID and/or security origin |
| 265 TEST_F(AudioRendererMixerManagerTest, MixerDevices) { | 355 TEST_F(AudioRendererMixerManagerTest, MixerDevices) { |
| 266 EXPECT_CALL(*mock_sink_.get(), Start()).Times(3); | 356 EXPECT_CALL(*mock_sink_.get(), Start()).Times(3); |
| 267 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3); | 357 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3); |
| 268 EXPECT_EQ(0, mixer_count()); | 358 EXPECT_EQ(0, mixer_count()); |
| 269 | 359 |
| 270 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | 360 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
| 271 kChannelLayout, kSampleRate, kBitsPerChannel, | 361 kChannelLayout, kSampleRate, kBitsPerChannel, |
| 272 kBufferSize); | 362 kBufferSize); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 289 EXPECT_NE(mixer2, mixer3); | 379 EXPECT_NE(mixer2, mixer3); |
| 290 | 380 |
| 291 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); | 381 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); |
| 292 EXPECT_EQ(2, mixer_count()); | 382 EXPECT_EQ(2, mixer_count()); |
| 293 RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin); | 383 RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin); |
| 294 EXPECT_EQ(1, mixer_count()); | 384 EXPECT_EQ(1, mixer_count()); |
| 295 RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2); | 385 RemoveMixer(kRenderFrameId, params, kAnotherDeviceId, kSecurityOrigin2); |
| 296 EXPECT_EQ(0, mixer_count()); | 386 EXPECT_EQ(0, mixer_count()); |
| 297 } | 387 } |
| 298 | 388 |
| 389 // Verify GetMixer() correctly deduplicate mixers with the same | |
| 390 // parameters, different security origins but default device ID | |
| 391 TEST_F(AudioRendererMixerManagerTest, OneMixerDiffferenrOriginsDefaultDevice) { | |
|
Guido Urdaneta
2016/04/07 11:14:28
typo: s/Diffferenr/Different
o1ka
2016/04/07 12:40:49
Wow, what a typo!
Done.
| |
| 392 EXPECT_CALL(*mock_sink_.get(), Start()).Times(1); | |
| 393 EXPECT_CALL(*mock_sink_.get(), Stop()).Times(1); | |
| 394 EXPECT_EQ(0, mixer_count()); | |
| 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(1, mixer_count()); | |
| 403 | |
| 404 media::AudioRendererMixer* mixer2 = | |
| 405 GetMixer(kRenderFrameId, params, std::string(), kSecurityOrigin, nullptr); | |
| 406 ASSERT_TRUE(mixer2); | |
| 407 EXPECT_EQ(1, mixer_count()); | |
| 408 EXPECT_EQ(mixer1, mixer2); | |
| 409 | |
| 410 media::AudioRendererMixer* mixer3 = GetMixer( | |
| 411 kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2, nullptr); | |
| 412 ASSERT_TRUE(mixer3); | |
| 413 EXPECT_EQ(1, mixer_count()); | |
| 414 EXPECT_EQ(mixer1, mixer3); | |
| 415 | |
| 416 media::AudioRendererMixer* mixer4 = GetMixer( | |
| 417 kRenderFrameId, params, std::string(), kSecurityOrigin2, nullptr); | |
| 418 ASSERT_TRUE(mixer4); | |
| 419 EXPECT_EQ(1, mixer_count()); | |
| 420 EXPECT_EQ(mixer1, mixer4); | |
| 421 | |
| 422 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin); | |
| 423 EXPECT_EQ(1, mixer_count()); | |
| 424 RemoveMixer(kRenderFrameId, params, std::string(), kSecurityOrigin); | |
| 425 EXPECT_EQ(1, mixer_count()); | |
| 426 RemoveMixer(kRenderFrameId, params, kDefaultDeviceId, kSecurityOrigin2); | |
| 427 EXPECT_EQ(1, mixer_count()); | |
| 428 RemoveMixer(kRenderFrameId, params, std::string(), kSecurityOrigin2); | |
| 429 EXPECT_EQ(0, mixer_count()); | |
| 430 } | |
| 431 | |
| 299 // Verify that GetMixer() correctly returns a null mixer and an appropriate | 432 // Verify that GetMixer() correctly returns a null mixer and an appropriate |
| 300 // status code when a nonexistent device is requested. | 433 // status code when a nonexistent device is requested. |
| 301 TEST_F(AudioRendererMixerManagerTest, NonexistentDevice) { | 434 TEST_F(AudioRendererMixerManagerTest, NonexistentDevice) { |
| 302 EXPECT_EQ(0, mixer_count()); | 435 EXPECT_EQ(0, mixer_count()); |
| 303 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | 436 media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
| 304 kChannelLayout, kSampleRate, kBitsPerChannel, | 437 kChannelLayout, kSampleRate, kBitsPerChannel, |
| 305 kBufferSize); | 438 kBufferSize); |
| 306 media::OutputDeviceStatus device_status = media::OUTPUT_DEVICE_STATUS_OK; | 439 media::OutputDeviceStatus device_status = media::OUTPUT_DEVICE_STATUS_OK; |
| 307 EXPECT_CALL(*mock_sink_no_device_.get(), Stop()); | 440 EXPECT_CALL(*mock_sink_no_device_.get(), Stop()); |
| 308 media::AudioRendererMixer* mixer = | 441 media::AudioRendererMixer* mixer = |
| 309 GetMixer(kRenderFrameId, params, kNonexistentDeviceId, kSecurityOrigin, | 442 GetMixer(kRenderFrameId, params, kNonexistentDeviceId, kSecurityOrigin, |
| 310 &device_status); | 443 &device_status); |
| 311 EXPECT_FALSE(mixer); | 444 EXPECT_FALSE(mixer); |
| 312 EXPECT_EQ(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, device_status); | 445 EXPECT_EQ(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, device_status); |
| 313 EXPECT_EQ(0, mixer_count()); | 446 EXPECT_EQ(0, mixer_count()); |
| 314 } | 447 } |
| 315 | 448 |
| 316 } // namespace content | 449 } // namespace content |
| OLD | NEW |