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