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/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
12 #include "base/thread_task_runner_handle.h" | 12 #include "base/thread_task_runner_handle.h" |
13 #include "base/values.h" | 13 #include "base/values.h" |
14 #include "chromeos/audio/audio_devices_pref_handler_stub.h" | 14 #include "chromeos/audio/audio_devices_pref_handler_stub.h" |
15 #include "chromeos/dbus/audio_node.h" | 15 #include "chromeos/dbus/audio_node.h" |
16 #include "chromeos/dbus/dbus_thread_manager.h" | 16 #include "chromeos/dbus/dbus_thread_manager.h" |
17 #include "chromeos/dbus/fake_cras_audio_client.h" | 17 #include "chromeos/dbus/fake_cras_audio_client.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 |
| 21 using testing::NiceMock; |
| 22 using testing::StrictMock; |
| 23 |
20 namespace chromeos { | 24 namespace chromeos { |
21 | 25 |
22 const uint64 kInternalSpeakerId = 10001; | 26 const uint64 kInternalSpeakerId = 10001; |
23 const uint64 kHeadphoneId = 10002; | 27 const uint64 kHeadphoneId = 10002; |
24 const uint64 kInternalMicId = 10003; | 28 const uint64 kInternalMicId = 10003; |
25 const uint64 kUSBMicId = 10004; | 29 const uint64 kUSBMicId = 10004; |
26 const uint64 kBluetoothHeadsetId = 10005; | 30 const uint64 kBluetoothHeadsetId = 10005; |
27 const uint64 kHDMIOutputId = 10006; | 31 const uint64 kBluetoothHeadsetMicId = 10006; |
28 const uint64 kUSBHeadphoneId1 = 10007; | 32 const uint64 kHDMIOutputId = 10007; |
29 const uint64 kUSBHeadphoneId2 = 10008; | 33 const uint64 kUSBHeadphoneId1 = 10008; |
30 const uint64 kMicJackId = 10009; | 34 const uint64 kUSBHeadphoneId2 = 10009; |
31 const uint64 kKeyboardMicId = 10010; | 35 const uint64 kMicJackId = 10010; |
| 36 const uint64 kKeyboardMicId = 10011; |
| 37 const uint64 kPostMixLoopbackId = 10012; |
| 38 const uint64 kPostDSPLoopbackId = 10013; |
| 39 const uint64 kAOKRId = 10014; |
32 const uint64 kOtherTypeOutputId = 90001; | 40 const uint64 kOtherTypeOutputId = 90001; |
33 const uint64 kOtherTypeInputId = 90002; | 41 const uint64 kOtherTypeInputId = 90002; |
34 const uint64 kUSBJabraSpeakerOutputId1 = 90003; | 42 const uint64 kUSBJabraSpeakerOutputId1 = 90003; |
35 const uint64 kUSBJabraSpeakerOutputId2 = 90004; | 43 const uint64 kUSBJabraSpeakerOutputId2 = 90004; |
36 const uint64 kUSBJabraSpeakerInputId1 = 90005; | 44 const uint64 kUSBJabraSpeakerInputId1 = 90005; |
37 const uint64 kUSBJabraSpeakerInputId2 = 90006; | 45 const uint64 kUSBJabraSpeakerInputId2 = 90006; |
38 const uint64 kUSBCameraInputId = 90007; | 46 const uint64 kUSBCameraInputId = 90007; |
39 | 47 |
40 const AudioNode kInternalSpeaker( | 48 const AudioNode kInternalSpeaker( |
41 false, | 49 false, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 const AudioNode kOtherTypeInput( | 118 const AudioNode kOtherTypeInput( |
111 true, | 119 true, |
112 kOtherTypeInputId, | 120 kOtherTypeInputId, |
113 "Input Device", | 121 "Input Device", |
114 "SOME_OTHER_TYPE", | 122 "SOME_OTHER_TYPE", |
115 "Other Type Input Device", | 123 "Other Type Input Device", |
116 false, | 124 false, |
117 0 | 125 0 |
118 ); | 126 ); |
119 | 127 |
| 128 const AudioNode kPostMixLoopback(false, |
| 129 kPostMixLoopbackId, |
| 130 "Fake Post Mix Loopback", |
| 131 "POST_MIX_LOOPBACK", |
| 132 "Post Mix Loopback", |
| 133 false, |
| 134 0); |
| 135 |
| 136 const AudioNode kPostDSPLoopback(false, |
| 137 kPostDSPLoopbackId, |
| 138 "Fake Post DSP Loopback", |
| 139 "POST_DSP_LOOPBACK", |
| 140 "Post DSP Loopback", |
| 141 false, |
| 142 0); |
| 143 |
| 144 const AudioNode kAOKR(true, |
| 145 kAOKRId, |
| 146 "Fake AOKR Mic", |
| 147 "AOKR", |
| 148 "AOKR Mic", |
| 149 false, |
| 150 0); |
| 151 |
120 const AudioNode kBluetoothHeadset(false, | 152 const AudioNode kBluetoothHeadset(false, |
121 kBluetoothHeadsetId, | 153 kBluetoothHeadsetId, |
122 "Bluetooth Headset", | 154 "Bluetooth Headset", |
123 "BLUETOOTH", | 155 "BLUETOOTH", |
124 "Bluetooth Headset 1", | 156 "Bluetooth Headset 1", |
125 false, | 157 false, |
126 0); | 158 0); |
127 | 159 |
| 160 const AudioNode kBluetoothHeadsetMic(true, |
| 161 kBluetoothHeadsetMicId, |
| 162 "Bluetooth Headset", |
| 163 "BLUETOOTH", |
| 164 "Bluetooth Headset 1", |
| 165 false, |
| 166 0); |
| 167 |
128 const AudioNode kHDMIOutput(false, | 168 const AudioNode kHDMIOutput(false, |
129 kHDMIOutputId, | 169 kHDMIOutputId, |
130 "HDMI output", | 170 "HDMI output", |
131 "HDMI", | 171 "HDMI", |
132 "HDMI output", | 172 "HDMI output", |
133 false, | 173 false, |
134 0); | 174 0); |
135 | 175 |
136 const AudioNode kUSBHeadphone1(false, | 176 const AudioNode kUSBHeadphone1(false, |
137 kUSBHeadphoneId1, | 177 kUSBHeadphoneId1, |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 int active_input_node_changed_count_; | 312 int active_input_node_changed_count_; |
273 int audio_nodes_changed_count_; | 313 int audio_nodes_changed_count_; |
274 int output_mute_changed_count_; | 314 int output_mute_changed_count_; |
275 int input_mute_changed_count_; | 315 int input_mute_changed_count_; |
276 int output_volume_changed_count_; | 316 int output_volume_changed_count_; |
277 int input_gain_changed_count_; | 317 int input_gain_changed_count_; |
278 | 318 |
279 DISALLOW_COPY_AND_ASSIGN(TestObserver); | 319 DISALLOW_COPY_AND_ASSIGN(TestObserver); |
280 }; | 320 }; |
281 | 321 |
| 322 // AudioManagerWrapper is mocked in unittest because unittest is run in an |
| 323 // environment without AudioManagerCras. |
| 324 class MockAudioManagerWrapper : public CrasAudioHandler::AudioManagerWrapper { |
| 325 public: |
| 326 MockAudioManagerWrapper() {} |
| 327 ~MockAudioManagerWrapper() override {} |
| 328 MOCK_METHOD1(SetHasInputDevices, void(bool has_input_devices)); |
| 329 }; |
| 330 |
282 class CrasAudioHandlerTest : public testing::Test { | 331 class CrasAudioHandlerTest : public testing::Test { |
283 public: | 332 public: |
284 CrasAudioHandlerTest() : cras_audio_handler_(NULL), | 333 CrasAudioHandlerTest() |
285 fake_cras_audio_client_(NULL) { | 334 : cras_audio_handler_(NULL), |
286 } | 335 fake_cras_audio_client_(NULL), |
| 336 use_nice_mock_audio_manager_(true) {} |
287 ~CrasAudioHandlerTest() override {} | 337 ~CrasAudioHandlerTest() override {} |
288 | 338 |
289 void SetUp() override {} | 339 void SetUp() override {} |
290 | 340 |
291 void TearDown() override { | 341 void TearDown() override { |
292 cras_audio_handler_->RemoveAudioObserver(test_observer_.get()); | 342 cras_audio_handler_->RemoveAudioObserver(test_observer_.get()); |
293 test_observer_.reset(); | 343 test_observer_.reset(); |
294 CrasAudioHandler::Shutdown(); | 344 CrasAudioHandler::Shutdown(); |
295 audio_pref_handler_ = NULL; | 345 audio_pref_handler_ = NULL; |
296 DBusThreadManager::Shutdown(); | 346 DBusThreadManager::Shutdown(); |
297 } | 347 } |
298 | 348 |
| 349 // This is for the cases where the test does not care |
| 350 // audio manager behavior. |
| 351 void SetUpDefaultNiceMockAudioManagerIfNeeded() { |
| 352 if (use_nice_mock_audio_manager_) |
| 353 mock_audio_manager_ = new NiceMock<MockAudioManagerWrapper>(); |
| 354 } |
| 355 |
| 356 // Set the expected method and arguments on mock_audio_manager_ to |
| 357 // check that SetHasInputDevices is called with correct argument when a |
| 358 // list of audio nodes present in CrasAudioHandler. |
| 359 void CheckSetHasInputDevices(AudioNodeList audio_nodes, |
| 360 bool has_input_devices) { |
| 361 use_nice_mock_audio_manager_ = false; |
| 362 mock_audio_manager_ = new StrictMock<MockAudioManagerWrapper>(); |
| 363 EXPECT_CALL(*mock_audio_manager_, SetHasInputDevices(has_input_devices)); |
| 364 SetUpCrasAudioHandler(audio_nodes); |
| 365 } |
| 366 |
299 void SetUpCrasAudioHandler(const AudioNodeList& audio_nodes) { | 367 void SetUpCrasAudioHandler(const AudioNodeList& audio_nodes) { |
300 DBusThreadManager::Initialize(); | 368 DBusThreadManager::Initialize(); |
301 fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>( | 369 fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>( |
302 DBusThreadManager::Get()->GetCrasAudioClient()); | 370 DBusThreadManager::Get()->GetCrasAudioClient()); |
303 fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes); | 371 fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes); |
304 audio_pref_handler_ = new AudioDevicesPrefHandlerStub(); | 372 audio_pref_handler_ = new AudioDevicesPrefHandlerStub(); |
305 CrasAudioHandler::Initialize(audio_pref_handler_); | 373 SetUpDefaultNiceMockAudioManagerIfNeeded(); |
| 374 CrasAudioHandler::Initialize(audio_pref_handler_, |
| 375 make_scoped_ptr(mock_audio_manager_)); |
306 cras_audio_handler_ = CrasAudioHandler::Get(); | 376 cras_audio_handler_ = CrasAudioHandler::Get(); |
307 test_observer_.reset(new TestObserver); | 377 test_observer_.reset(new TestObserver); |
308 cras_audio_handler_->AddAudioObserver(test_observer_.get()); | 378 cras_audio_handler_->AddAudioObserver(test_observer_.get()); |
309 message_loop_.RunUntilIdle(); | 379 message_loop_.RunUntilIdle(); |
310 } | 380 } |
311 | 381 |
312 void SetUpCrasAudioHandlerWithPrimaryActiveNode( | 382 void SetUpCrasAudioHandlerWithPrimaryActiveNode( |
313 const AudioNodeList& audio_nodes, | 383 const AudioNodeList& audio_nodes, |
314 const AudioNode& primary_active_node) { | 384 const AudioNode& primary_active_node) { |
315 DBusThreadManager::Initialize(); | 385 DBusThreadManager::Initialize(); |
316 fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>( | 386 fake_cras_audio_client_ = static_cast<FakeCrasAudioClient*>( |
317 DBusThreadManager::Get()->GetCrasAudioClient()); | 387 DBusThreadManager::Get()->GetCrasAudioClient()); |
318 fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes); | 388 fake_cras_audio_client_->SetAudioNodesForTesting(audio_nodes); |
319 fake_cras_audio_client_->SetActiveOutputNode(primary_active_node.id), | 389 fake_cras_audio_client_->SetActiveOutputNode(primary_active_node.id), |
320 audio_pref_handler_ = new AudioDevicesPrefHandlerStub(); | 390 audio_pref_handler_ = new AudioDevicesPrefHandlerStub(); |
321 CrasAudioHandler::Initialize(audio_pref_handler_); | 391 SetUpDefaultNiceMockAudioManagerIfNeeded(); |
| 392 CrasAudioHandler::Initialize(audio_pref_handler_, |
| 393 make_scoped_ptr(mock_audio_manager_)); |
322 cras_audio_handler_ = CrasAudioHandler::Get(); | 394 cras_audio_handler_ = CrasAudioHandler::Get(); |
323 test_observer_.reset(new TestObserver); | 395 test_observer_.reset(new TestObserver); |
324 cras_audio_handler_->AddAudioObserver(test_observer_.get()); | 396 cras_audio_handler_->AddAudioObserver(test_observer_.get()); |
325 message_loop_.RunUntilIdle(); | 397 message_loop_.RunUntilIdle(); |
326 } | 398 } |
327 | 399 |
328 void ChangeAudioNodes(const AudioNodeList& audio_nodes) { | 400 void ChangeAudioNodes(const AudioNodeList& audio_nodes) { |
329 fake_cras_audio_client_->SetAudioNodesAndNotifyObserversForTesting( | 401 fake_cras_audio_client_->SetAudioNodesAndNotifyObserversForTesting( |
330 audio_nodes); | 402 audio_nodes); |
331 message_loop_.RunUntilIdle(); | 403 message_loop_.RunUntilIdle(); |
(...skipping 25 matching lines...) Expand all Loading... |
357 bool IsDuringHDMIRediscoverGracePeriod() { | 429 bool IsDuringHDMIRediscoverGracePeriod() { |
358 return cras_audio_handler_->hdmi_rediscovering(); | 430 return cras_audio_handler_->hdmi_rediscovering(); |
359 } | 431 } |
360 | 432 |
361 protected: | 433 protected: |
362 base::MessageLoopForUI message_loop_; | 434 base::MessageLoopForUI message_loop_; |
363 CrasAudioHandler* cras_audio_handler_; // Not owned. | 435 CrasAudioHandler* cras_audio_handler_; // Not owned. |
364 FakeCrasAudioClient* fake_cras_audio_client_; // Not owned. | 436 FakeCrasAudioClient* fake_cras_audio_client_; // Not owned. |
365 scoped_ptr<TestObserver> test_observer_; | 437 scoped_ptr<TestObserver> test_observer_; |
366 scoped_refptr<AudioDevicesPrefHandlerStub> audio_pref_handler_; | 438 scoped_refptr<AudioDevicesPrefHandlerStub> audio_pref_handler_; |
| 439 MockAudioManagerWrapper* mock_audio_manager_; |
| 440 bool use_nice_mock_audio_manager_; |
367 | 441 |
368 private: | 442 private: |
369 DISALLOW_COPY_AND_ASSIGN(CrasAudioHandlerTest); | 443 DISALLOW_COPY_AND_ASSIGN(CrasAudioHandlerTest); |
370 }; | 444 }; |
371 | 445 |
372 class HDMIRediscoverWaiter { | 446 class HDMIRediscoverWaiter { |
373 public: | 447 public: |
374 HDMIRediscoverWaiter(CrasAudioHandlerTest* cras_audio_handler_test, | 448 HDMIRediscoverWaiter(CrasAudioHandlerTest* cras_audio_handler_test, |
375 int grace_period_duration_in_ms) | 449 int grace_period_duration_in_ms) |
376 : cras_audio_handler_test_(cras_audio_handler_test), | 450 : cras_audio_handler_test_(cras_audio_handler_test), |
(...skipping 2213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2590 // After HDMI re-discover grace period, verify HDMI output is selected as the | 2664 // After HDMI re-discover grace period, verify HDMI output is selected as the |
2591 // active device and not muted. | 2665 // active device and not muted. |
2592 waiter.WaitUntilHDMIRediscoverGracePeriodEnd(); | 2666 waiter.WaitUntilHDMIRediscoverGracePeriodEnd(); |
2593 EXPECT_TRUE( | 2667 EXPECT_TRUE( |
2594 cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output)); | 2668 cras_audio_handler_->GetPrimaryActiveOutputDevice(&active_output)); |
2595 EXPECT_EQ(kHDMIOutput.id, active_output.id); | 2669 EXPECT_EQ(kHDMIOutput.id, active_output.id); |
2596 EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode()); | 2670 EXPECT_EQ(kHDMIOutput.id, cras_audio_handler_->GetPrimaryActiveOutputNode()); |
2597 EXPECT_FALSE(cras_audio_handler_->IsOutputMuted()); | 2671 EXPECT_FALSE(cras_audio_handler_->IsOutputMuted()); |
2598 } | 2672 } |
2599 | 2673 |
| 2674 // Test the case where there is no input device in the beginning. |
| 2675 // SetHasInputDevices on AudioManagerWrapper is called with argument false. |
| 2676 // After a mic jack is plugged, CrasAudioHandler calls SetHasInputDevices on |
| 2677 // AudioManagerWrapper with argument true. |
| 2678 TEST_F(CrasAudioHandlerTest, PlugMicJackAndUpdateAudioManager) { |
| 2679 use_nice_mock_audio_manager_ = false; |
| 2680 mock_audio_manager_ = new StrictMock<MockAudioManagerWrapper>(); |
| 2681 |
| 2682 // Set up audio handler with output nodes and input nodes for loopback. |
| 2683 // SetHasInputAudioDevices should be called with argument false. |
| 2684 AudioNodeList audio_nodes; |
| 2685 audio_nodes.push_back(kInternalSpeaker); |
| 2686 audio_nodes.push_back(kPostMixLoopback); |
| 2687 audio_nodes.push_back(kPostDSPLoopback); |
| 2688 EXPECT_CALL(*mock_audio_manager_, SetHasInputDevices(false)); |
| 2689 SetUpCrasAudioHandler(audio_nodes); |
| 2690 |
| 2691 // Plug the Mic Jack. SetHasInputAudioDevices should get called with argument |
| 2692 // true. |
| 2693 audio_nodes.push_back(kMicJack); |
| 2694 EXPECT_CALL(*mock_audio_manager_, SetHasInputDevices(true)); |
| 2695 ChangeAudioNodes(audio_nodes); |
| 2696 } |
| 2697 |
| 2698 // Test the case where there is no input device for simple usage. |
| 2699 // SetHasInputDevices on AudioManagerWrapper is called with argument false. |
| 2700 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToFalse) { |
| 2701 AudioNodeList audio_nodes; |
| 2702 audio_nodes.push_back(kHeadphone); |
| 2703 audio_nodes.push_back(kUSBHeadphone1); |
| 2704 audio_nodes.push_back(kBluetoothHeadset); |
| 2705 audio_nodes.push_back(kHDMIOutput); |
| 2706 audio_nodes.push_back(kInternalSpeaker); |
| 2707 audio_nodes.push_back(kKeyboardMic); |
| 2708 audio_nodes.push_back(kAOKR); |
| 2709 audio_nodes.push_back(kPostMixLoopback); |
| 2710 audio_nodes.push_back(kPostDSPLoopback); |
| 2711 audio_nodes.push_back(kOtherTypeOutput); |
| 2712 audio_nodes.push_back(kOtherTypeInput); |
| 2713 CheckSetHasInputDevices(audio_nodes, false); |
| 2714 } |
| 2715 |
| 2716 // Test the case where there is an internal mic. |
| 2717 // SetHasInputDevices on AudioManagerWrapper is called with argument true. |
| 2718 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToTrueForInternalMic) { |
| 2719 AudioNodeList audio_nodes; |
| 2720 audio_nodes.push_back(kInternalMic); |
| 2721 CheckSetHasInputDevices(audio_nodes, true); |
| 2722 } |
| 2723 |
| 2724 // Test the case where there is an external mic. |
| 2725 // SetHasInputDevices on AudioManagerWrapper is called with argument true. |
| 2726 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToTrueForMicJack) { |
| 2727 AudioNodeList audio_nodes; |
| 2728 audio_nodes.push_back(kMicJack); |
| 2729 CheckSetHasInputDevices(audio_nodes, true); |
| 2730 } |
| 2731 |
| 2732 // Test the case where there is a USB mic. |
| 2733 // SetHasInputDevices on AudioManagerWrapper is called with argument true. |
| 2734 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToTrueForUSBMic) { |
| 2735 AudioNodeList audio_nodes; |
| 2736 audio_nodes.push_back(kUSBMic); |
| 2737 CheckSetHasInputDevices(audio_nodes, true); |
| 2738 } |
| 2739 |
| 2740 // Test the case where there is a bluetooth mic. |
| 2741 // SetHasInputDevices on AudioManagerWrapper is called with argument true. |
| 2742 TEST_F(CrasAudioHandlerTest, SetHasInputDeviceToTrueForBluetoothMic) { |
| 2743 AudioNodeList audio_nodes; |
| 2744 audio_nodes.push_back(kBluetoothHeadsetMic); |
| 2745 CheckSetHasInputDevices(audio_nodes, true); |
| 2746 } |
| 2747 |
2600 } // namespace chromeos | 2748 } // namespace chromeos |
OLD | NEW |