Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "chromeos/audio/cras_audio_handler.h" | 5 #include "chromeos/audio/cras_audio_handler.h" |
| 6 | 6 |
| 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 "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| 11 #include "chromeos/audio/audio_devices_pref_handler_stub.h" | 11 #include "chromeos/audio/audio_devices_pref_handler_stub.h" |
| 12 #include "chromeos/dbus/audio_node.h" | 12 #include "chromeos/dbus/audio_node.h" |
| 13 #include "chromeos/dbus/dbus_thread_manager.h" | 13 #include "chromeos/dbus/dbus_thread_manager.h" |
| 14 #include "chromeos/dbus/fake_cras_audio_client.h" | 14 #include "chromeos/dbus/fake_cras_audio_client.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 17 |
| 18 using testing::NiceMock; | |
| 19 using testing::StrictMock; | |
| 20 | |
| 17 namespace chromeos { | 21 namespace chromeos { |
| 18 | 22 |
| 19 const uint64 kInternalSpeakerId = 10001; | 23 const uint64 kInternalSpeakerId = 10001; |
| 20 const uint64 kHeadphoneId = 10002; | 24 const uint64 kHeadphoneId = 10002; |
| 21 const uint64 kInternalMicId = 10003; | 25 const uint64 kInternalMicId = 10003; |
| 22 const uint64 kUSBMicId = 10004; | 26 const uint64 kUSBMicId = 10004; |
| 23 const uint64 kBluetoothHeadsetId = 10005; | 27 const uint64 kBluetoothHeadsetId = 10005; |
| 24 const uint64 kHDMIOutputId = 10006; | 28 const uint64 kBluetoothHeadsetMicId = 10006; |
| 25 const uint64 kUSBHeadphoneId1 = 10007; | 29 const uint64 kHDMIOutputId = 10007; |
| 26 const uint64 kUSBHeadphoneId2 = 10008; | 30 const uint64 kUSBHeadphoneId1 = 10008; |
| 27 const uint64 kMicJackId = 10009; | 31 const uint64 kUSBHeadphoneId2 = 10009; |
| 28 const uint64 kKeyboardMicId = 10010; | 32 const uint64 kMicJackId = 10010; |
| 33 const uint64 kKeyboardMicId = 10011; | |
| 34 const uint64 kPostMixLoopbackId = 10012; | |
| 35 const uint64 kPostDSPLoopbackId = 10013; | |
| 36 const uint64 kAOKRId = 10014; | |
| 29 const uint64 kOtherTypeOutputId = 90001; | 37 const uint64 kOtherTypeOutputId = 90001; |
| 30 const uint64 kOtherTypeInputId = 90002; | 38 const uint64 kOtherTypeInputId = 90002; |
| 31 const uint64 kUSBJabraSpeakerOutputId1 = 90003; | 39 const uint64 kUSBJabraSpeakerOutputId1 = 90003; |
| 32 const uint64 kUSBJabraSpeakerOutputId2 = 90004; | 40 const uint64 kUSBJabraSpeakerOutputId2 = 90004; |
| 33 const uint64 kUSBJabraSpeakerInputId1 = 90005; | 41 const uint64 kUSBJabraSpeakerInputId1 = 90005; |
| 34 const uint64 kUSBJabraSpeakerInputId2 = 90006; | 42 const uint64 kUSBJabraSpeakerInputId2 = 90006; |
| 35 const uint64 kUSBCameraInputId = 90007; | 43 const uint64 kUSBCameraInputId = 90007; |
| 36 | 44 |
| 37 const AudioNode kInternalSpeaker( | 45 const AudioNode kInternalSpeaker( |
| 38 false, | 46 false, |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 const AudioNode kOtherTypeInput( | 115 const AudioNode kOtherTypeInput( |
| 108 true, | 116 true, |
| 109 kOtherTypeInputId, | 117 kOtherTypeInputId, |
| 110 "Input Device", | 118 "Input Device", |
| 111 "SOME_OTHER_TYPE", | 119 "SOME_OTHER_TYPE", |
| 112 "Other Type Input Device", | 120 "Other Type Input Device", |
| 113 false, | 121 false, |
| 114 0 | 122 0 |
| 115 ); | 123 ); |
| 116 | 124 |
| 125 const AudioNode kPostMixLoopback(false, | |
| 126 kPostMixLoopbackId, | |
| 127 "Fake Post Mix Loopback", | |
| 128 "POST_MIX_LOOPBACK", | |
| 129 "Post Mix Loopback", | |
| 130 false, | |
| 131 0); | |
| 132 | |
| 133 const AudioNode kPostDSPLoopback(false, | |
| 134 kPostDSPLoopbackId, | |
| 135 "Fake Post DSP Loopback", | |
| 136 "POST_DSP_LOOPBACK", | |
| 137 "Post DSP Loopback", | |
| 138 false, | |
| 139 0); | |
| 140 | |
| 141 const AudioNode kAOKR(true, | |
| 142 kAOKRId, | |
| 143 "Fake AOKR Mic", | |
| 144 "AOKR", | |
| 145 "AOKR Mic", | |
| 146 false, | |
| 147 0); | |
| 148 | |
| 117 const AudioNode kBluetoothHeadset(false, | 149 const AudioNode kBluetoothHeadset(false, |
| 118 kBluetoothHeadsetId, | 150 kBluetoothHeadsetId, |
| 119 "Bluetooth Headset", | 151 "Bluetooth Headset", |
| 120 "BLUETOOTH", | 152 "BLUETOOTH", |
| 121 "Bluetooth Headset 1", | 153 "Bluetooth Headset 1", |
| 122 false, | 154 false, |
| 123 0); | 155 0); |
| 124 | 156 |
| 157 const AudioNode kBluetoothHeadsetMic(true, | |
| 158 kBluetoothHeadsetMicId, | |
| 159 "Bluetooth Headset", | |
| 160 "BLUETOOTH", | |
| 161 "Bluetooth Headset 1", | |
| 162 false, | |
| 163 0); | |
| 164 | |
| 125 const AudioNode kHDMIOutput(false, | 165 const AudioNode kHDMIOutput(false, |
| 126 kHDMIOutputId, | 166 kHDMIOutputId, |
| 127 "HDMI output", | 167 "HDMI output", |
| 128 "HDMI", | 168 "HDMI", |
| 129 "HDMI output", | 169 "HDMI output", |
| 130 false, | 170 false, |
| 131 0); | 171 0); |
| 132 | 172 |
| 133 const AudioNode kUSBHeadphone1(false, | 173 const AudioNode kUSBHeadphone1(false, |
| 134 kUSBHeadphoneId1, | 174 kUSBHeadphoneId1, |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 int active_input_node_changed_count_; | 309 int active_input_node_changed_count_; |
| 270 int audio_nodes_changed_count_; | 310 int audio_nodes_changed_count_; |
| 271 int output_mute_changed_count_; | 311 int output_mute_changed_count_; |
| 272 int input_mute_changed_count_; | 312 int input_mute_changed_count_; |
| 273 int output_volume_changed_count_; | 313 int output_volume_changed_count_; |
| 274 int input_gain_changed_count_; | 314 int input_gain_changed_count_; |
| 275 | 315 |
| 276 DISALLOW_COPY_AND_ASSIGN(TestObserver); | 316 DISALLOW_COPY_AND_ASSIGN(TestObserver); |
| 277 }; | 317 }; |
| 278 | 318 |
| 319 // AudioManagerWrapper is mocked in unittest because unittest is run in an | |
| 320 // environment without AudioManagerCras. | |
| 321 class MockAudioManagerWrapper : public CrasAudioHandler::AudioManagerWrapper { | |
| 322 public: | |
| 323 MockAudioManagerWrapper() {} | |
| 324 ~MockAudioManagerWrapper() override {} | |
| 325 MOCK_METHOD1(SetHasInputDevices, void(bool has_input_devices)); | |
| 326 }; | |
| 327 | |
| 279 class CrasAudioHandlerTest : public testing::Test { | 328 class CrasAudioHandlerTest : public testing::Test { |
| 280 public: | 329 public: |
| 281 CrasAudioHandlerTest() : cras_audio_handler_(NULL), | 330 CrasAudioHandlerTest() |
| 282 fake_cras_audio_client_(NULL) { | 331 : cras_audio_handler_(NULL), |
| 283 } | 332 fake_cras_audio_client_(NULL), |
| 333 use_nice_mock_audio_manager_(true) {} | |
| 284 ~CrasAudioHandlerTest() override {} | 334 ~CrasAudioHandlerTest() override {} |
| 285 | 335 |
| 286 void SetUp() override {} | 336 void SetUp() override {} |
| 287 | 337 |
| 288 void TearDown() override { | 338 void TearDown() override { |
| 289 cras_audio_handler_->RemoveAudioObserver(test_observer_.get()); | 339 cras_audio_handler_->RemoveAudioObserver(test_observer_.get()); |
| 290 test_observer_.reset(); | 340 test_observer_.reset(); |
| 291 CrasAudioHandler::Shutdown(); | 341 CrasAudioHandler::Shutdown(); |
| 292 audio_pref_handler_ = NULL; | 342 audio_pref_handler_ = NULL; |
| 293 DBusThreadManager::Shutdown(); | 343 DBusThreadManager::Shutdown(); |
| 294 } | 344 } |
| 295 | 345 |
| 346 // This is for the cases where the test does not care | |
| 347 // audio manager behavior. | |
| 348 void SetUpDefaultNiceMockAudioManagerIfNeeded() { | |
| 349 if (use_nice_mock_audio_manager_) | |
| 350 SetUpNiceMockAudioManager(); | |
| 351 } | |
| 352 | |
| 353 void SetUpNiceMockAudioManager() { | |
| 354 nice_mock_audio_manager_ = new NiceMock<MockAudioManagerWrapper>(); | |
| 355 CrasAudioHandler::SetUpAudioManagerWrapperForTesting( | |
| 356 nice_mock_audio_manager_); | |
| 357 } | |
| 358 | |
| 359 // Set the expected method and arguments on strict_mock_audio_manager_ to | |
| 360 // check that SetHasInputDevices is called with correct argument when a | |
| 361 // list of audio nodes present in CrasAudioHandler. | |
| 362 void CheckSetHasInputDevices(AudioNodeList audio_nodes, | |
| 363 bool has_input_devices) { | |
| 364 use_nice_mock_audio_manager_ = false; | |
| 365 SetUpStrictMockAudioManager(); | |
| 366 EXPECT_CALL(*strict_mock_audio_manager_, | |
| 367 SetHasInputDevices(has_input_devices)); | |
| 368 SetUpCrasAudioHandler(audio_nodes); | |
| 369 } | |
| 370 | |
| 371 void SetUpStrictMockAudioManager() { | |
| 372 strict_mock_audio_manager_ = new StrictMock<MockAudioManagerWrapper>(); | |
| 373 CrasAudioHandler::SetUpAudioManagerWrapperForTesting( | |
| 374 strict_mock_audio_manager_); | |
| 375 } | |
| 376 | |
| 296 void SetUpCrasAudioHandler(const AudioNodeList& audio_nodes) { | 377 void SetUpCrasAudioHandler(const AudioNodeList& audio_nodes) { |
| 297 DBusThreadManager::Initialize(); | 378 DBusThreadManager::Initialize(); |
| 298 fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>( | 379 fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>( |
| 299 DBusThreadManager::Get()->GetCrasAudioClient()); | 380 DBusThreadManager::Get()->GetCrasAudioClient()); |
| 300 fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes); | 381 fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes); |
| 301 audio_pref_handler_ = new AudioDevicesPrefHandlerStub(); | 382 audio_pref_handler_ = new AudioDevicesPrefHandlerStub(); |
| 383 SetUpDefaultNiceMockAudioManagerIfNeeded(); | |
| 302 CrasAudioHandler::Initialize(audio_pref_handler_); | 384 CrasAudioHandler::Initialize(audio_pref_handler_); |
| 303 cras_audio_handler_ = CrasAudioHandler::Get(); | 385 cras_audio_handler_ = CrasAudioHandler::Get(); |
| 304 test_observer_.reset(new TestObserver); | 386 test_observer_.reset(new TestObserver); |
| 305 cras_audio_handler_->AddAudioObserver(test_observer_.get()); | 387 cras_audio_handler_->AddAudioObserver(test_observer_.get()); |
| 306 message_loop_.RunUntilIdle(); | 388 message_loop_.RunUntilIdle(); |
| 307 } | 389 } |
| 308 | 390 |
| 309 void SetUpCrasAudioHandlerWithPrimaryActiveNode( | 391 void SetUpCrasAudioHandlerWithPrimaryActiveNode( |
| 310 const AudioNodeList& audio_nodes, | 392 const AudioNodeList& audio_nodes, |
| 311 const AudioNode& primary_active_node) { | 393 const AudioNode& primary_active_node) { |
| 312 DBusThreadManager::Initialize(); | 394 DBusThreadManager::Initialize(); |
| 313 fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>( | 395 fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>( |
| 314 DBusThreadManager::Get()->GetCrasAudioClient()); | 396 DBusThreadManager::Get()->GetCrasAudioClient()); |
| 315 fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes); | 397 fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes); |
| 316 fake_cras_audio_client_->SetActiveOutputNode(primary_active_node.id), | 398 fake_cras_audio_client_->SetActiveOutputNode(primary_active_node.id), |
| 317 audio_pref_handler_ = new AudioDevicesPrefHandlerStub(); | 399 audio_pref_handler_ = new AudioDevicesPrefHandlerStub(); |
| 400 SetUpDefaultNiceMockAudioManagerIfNeeded(); | |
| 318 CrasAudioHandler::Initialize(audio_pref_handler_); | 401 CrasAudioHandler::Initialize(audio_pref_handler_); |
| 319 cras_audio_handler_ = CrasAudioHandler::Get(); | 402 cras_audio_handler_ = CrasAudioHandler::Get(); |
| 320 test_observer_.reset(new TestObserver); | 403 test_observer_.reset(new TestObserver); |
| 321 cras_audio_handler_->AddAudioObserver(test_observer_.get()); | 404 cras_audio_handler_->AddAudioObserver(test_observer_.get()); |
| 322 message_loop_.RunUntilIdle(); | 405 message_loop_.RunUntilIdle(); |
| 323 } | 406 } |
| 324 | 407 |
| 325 void ChangeAudioNodes(const AudioNodeList& audio_nodes) { | 408 void ChangeAudioNodes(const AudioNodeList& audio_nodes) { |
| 326 fake_cras_audio_client_->SetAudioNodesAndNotifyObserversForTesting( | 409 fake_cras_audio_client_->SetAudioNodesAndNotifyObserversForTesting( |
| 327 audio_nodes); | 410 audio_nodes); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 342 } | 425 } |
| 343 return num_active_nodes; | 426 return num_active_nodes; |
| 344 } | 427 } |
| 345 | 428 |
| 346 protected: | 429 protected: |
| 347 base::MessageLoopForUI message_loop_; | 430 base::MessageLoopForUI message_loop_; |
| 348 CrasAudioHandler* cras_audio_handler_; // Not owned. | 431 CrasAudioHandler* cras_audio_handler_; // Not owned. |
| 349 FakeCrasAudioClient* fake_cras_audio_client_; // Not owned. | 432 FakeCrasAudioClient* fake_cras_audio_client_; // Not owned. |
| 350 scoped_ptr<TestObserver> test_observer_; | 433 scoped_ptr<TestObserver> test_observer_; |
| 351 scoped_refptr<AudioDevicesPrefHandlerStub> audio_pref_handler_; | 434 scoped_refptr<AudioDevicesPrefHandlerStub> audio_pref_handler_; |
| 435 NiceMock<MockAudioManagerWrapper>* nice_mock_audio_manager_; | |
| 436 StrictMock<MockAudioManagerWrapper>* strict_mock_audio_manager_; | |
| 437 bool use_nice_mock_audio_manager_; | |
| 352 | 438 |
| 353 private: | 439 private: |
| 354 DISALLOW_COPY_AND_ASSIGN(CrasAudioHandlerTest); | 440 DISALLOW_COPY_AND_ASSIGN(CrasAudioHandlerTest); |
| 355 }; | 441 }; |
| 356 | 442 |
| 357 TEST_F(CrasAudioHandlerTest, InitializeWithOnlyDefaultAudioDevices) { | 443 TEST_F(CrasAudioHandlerTest, InitializeWithOnlyDefaultAudioDevices) { |
| 358 AudioNodeList audio_nodes; | 444 AudioNodeList audio_nodes; |
| 359 audio_nodes.push_back(kInternalSpeaker); | 445 audio_nodes.push_back(kInternalSpeaker); |
| 360 audio_nodes.push_back(kInternalMic); | 446 audio_nodes.push_back(kInternalMic); |
| 361 SetUpCrasAudioHandler(audio_nodes); | 447 SetUpCrasAudioHandler(audio_nodes); |
| (...skipping 2124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2486 audio_nodes.push_back(kHDMIOutput); | 2572 audio_nodes.push_back(kHDMIOutput); |
| 2487 ChangeAudioNodes(audio_nodes); | 2573 ChangeAudioNodes(audio_nodes); |
| 2488 | 2574 |
| 2489 // Verify the headphone is set to active again. | 2575 // Verify the headphone is set to active again. |
| 2490 EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode()); | 2576 EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetPrimaryActiveOutputNode()); |
| 2491 const AudioDevice* headphone_resumed = GetDeviceFromId(kHeadphone.id); | 2577 const AudioDevice* headphone_resumed = GetDeviceFromId(kHeadphone.id); |
| 2492 EXPECT_EQ(kHeadphone.id, headphone_resumed->id); | 2578 EXPECT_EQ(kHeadphone.id, headphone_resumed->id); |
| 2493 EXPECT_TRUE(headphone_resumed->active); | 2579 EXPECT_TRUE(headphone_resumed->active); |
| 2494 } | 2580 } |
| 2495 | 2581 |
| 2582 // Test the case where there is no input device in the beginning. | |
| 2583 // SetHasInputDevices on AudioManagerWrapper is called with argument false. | |
| 2584 // After a mic jack is plugged, CrasAudioHandler calls SetHasInputDevices on | |
| 2585 // AudioManagerWrapper with argument true. | |
| 2586 TEST_F(CrasAudioHandlerTest, PlugMicJackAndUpdateAudioManager) { | |
| 2587 // Set up audio handler with output nodes and input nodes for loopback. | |
| 2588 AudioNodeList audio_nodes; | |
| 2589 audio_nodes.push_back(kInternalSpeaker); | |
| 2590 audio_nodes.push_back(kPostMixLoopback); | |
| 2591 audio_nodes.push_back(kPostDSPLoopback); | |
| 2592 | |
| 2593 // SetHasInputAudioDevices should be called with argument false. | |
| 2594 use_nice_mock_audio_manager_ = false; | |
| 2595 SetUpStrictMockAudioManager(); | |
| 2596 EXPECT_CALL(*strict_mock_audio_manager_, SetHasInputDevices(false)); | |
| 2597 SetUpCrasAudioHandler(audio_nodes); | |
| 2598 | |
| 2599 // Plug the Mic Jack. SetHasInputAudioDevices should get called with argument | |
| 2600 // true. | |
| 2601 audio_nodes.push_back(kMicJack); | |
| 2602 EXPECT_CALL(*strict_mock_audio_manager_, SetHasInputDevices(true)); | |
| 2603 ChangeAudioNodes(audio_nodes); | |
| 2604 } | |
| 2605 | |
| 2606 // Test the case where there is no input device for simple usage. | |
| 2607 // SetHasInputDevices on AudioManagerWrapper is called with argument false. | |
| 2608 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToFalse) { | |
| 2609 AudioNodeList audio_nodes = {kHeadphone, | |
|
Daniel Erat
2015/06/23 14:15:49
i don't think that this initialization style is al
cychiang
2015/06/24 08:11:29
Done.
| |
| 2610 kUSBHeadphone1, | |
| 2611 kBluetoothHeadset, | |
| 2612 kHDMIOutput, | |
| 2613 kInternalSpeaker, | |
| 2614 kKeyboardMic, | |
| 2615 kAOKR, | |
| 2616 kPostMixLoopback, | |
| 2617 kPostDSPLoopback, | |
| 2618 kOtherTypeOutput, | |
| 2619 kOtherTypeInput}; | |
| 2620 CheckSetHasInputDevices(audio_nodes, false); | |
| 2621 } | |
| 2622 | |
| 2623 // Test the case where there is an internal mic. | |
| 2624 // SetHasInputDevices on AudioManagerWrapper is called with argument true. | |
| 2625 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToTrueForInternalMic) { | |
| 2626 AudioNodeList audio_nodes = {kInternalMic}; | |
| 2627 CheckSetHasInputDevices(audio_nodes, true); | |
| 2628 } | |
| 2629 | |
| 2630 // Test the case where there is an external mic. | |
| 2631 // SetHasInputDevices on AudioManagerWrapper is called with argument true. | |
| 2632 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToTrueForMicJack) { | |
| 2633 AudioNodeList audio_nodes = {kMicJack}; | |
| 2634 CheckSetHasInputDevices(audio_nodes, true); | |
| 2635 } | |
| 2636 | |
| 2637 // Test the case where there is a USB mic. | |
| 2638 // SetHasInputDevices on AudioManagerWrapper is called with argument true. | |
| 2639 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToTrueForUSBMic) { | |
| 2640 AudioNodeList audio_nodes = {kUSBMic}; | |
| 2641 CheckSetHasInputDevices(audio_nodes, true); | |
| 2642 } | |
| 2643 | |
| 2644 // Test the case where there is a bluetooth mic. | |
| 2645 // SetHasInputDevices on AudioManagerWrapper is called with argument true. | |
| 2646 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToTrueForBluetoothMic) { | |
| 2647 AudioNodeList audio_nodes = {kBluetoothHeadsetMic}; | |
| 2648 CheckSetHasInputDevices(audio_nodes, true); | |
| 2649 } | |
| 2650 | |
| 2496 } // namespace chromeos | 2651 } // namespace chromeos |
| OLD | NEW |