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 |