diff options
-rw-r--r-- | chromeos/audio/cras_audio_handler.cc | 2 | ||||
-rw-r--r-- | chromeos/audio/cras_audio_handler_unittest.cc | 174 |
2 files changed, 175 insertions, 1 deletions
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc index de6313f..0045f84 100644 --- a/chromeos/audio/cras_audio_handler.cc +++ b/chromeos/audio/cras_audio_handler.cc @@ -529,7 +529,7 @@ bool CrasAudioHandler::NonActiveDeviceUnplugged( size_t old_devices_size, size_t new_devices_size, uint64 current_active_node) { - return (new_devices_size <= old_devices_size && + return (new_devices_size < old_devices_size && GetDeviceFromId(current_active_node)); } diff --git a/chromeos/audio/cras_audio_handler_unittest.cc b/chromeos/audio/cras_audio_handler_unittest.cc index 573daea..f4c3c99 100644 --- a/chromeos/audio/cras_audio_handler_unittest.cc +++ b/chromeos/audio/cras_audio_handler_unittest.cc @@ -24,6 +24,7 @@ const uint64 kBluetoothHeadsetId = 10005; const uint64 kHDMIOutputId = 10006; const uint64 kUSBHeadphoneId1 = 10007; const uint64 kUSBHeadphoneId2 = 10008; +const uint64 kMicJackId = 10009; const uint64 kOtherTypeOutputId = 90001; const uint64 kOtherTypeInputId = 90002; @@ -57,6 +58,16 @@ const AudioNode kInternalMic( 0 ); +const AudioNode kMicJack( + true, + kMicJackId, + "Fake Mic Jack", + "MIC", + "Mic Jack", + false, + 0 +); + const AudioNode kUSBMic( true, kUSBMicId, @@ -1131,6 +1142,169 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMicNotAffectActiveOutput) { EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode()); } +TEST_F(CrasAudioHandlerTest, PlugHeadphoneAutoUnplugSpeakerWithActiveUSB) { + // Set up initial audio devices. + AudioNodeList audio_nodes; + audio_nodes.push_back(kUSBHeadphone1); + audio_nodes.push_back(kInternalSpeaker); + audio_nodes.push_back(kInternalMic); + SetUpCrasAudioHandler(audio_nodes); + const size_t init_nodes_size = audio_nodes.size(); + + // Verify the audio devices size. + EXPECT_EQ(0, test_observer_->audio_nodes_changed_count()); + AudioDeviceList audio_devices; + cras_audio_handler_->GetAudioDevices(&audio_devices); + EXPECT_EQ(init_nodes_size, audio_devices.size()); + + // Verify the internal mic is selected as the active input. + EXPECT_EQ(0, test_observer_->active_input_node_changed_count()); + EXPECT_EQ(kInternalMicId, cras_audio_handler_->GetActiveInputNode()); + EXPECT_FALSE(cras_audio_handler_->has_alternative_input()); + + // Verify the USB headphone is selected as the active output. + EXPECT_EQ(0, test_observer_->active_output_node_changed_count()); + EXPECT_EQ(kUSBHeadphoneId1, cras_audio_handler_->GetActiveOutputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_output()); + + // Plug the headphone and auto-unplug internal speaker. + audio_nodes.clear(); + AudioNode usb_headphone_node(kUSBHeadphone1); + usb_headphone_node.active = true; + audio_nodes.push_back(usb_headphone_node); + AudioNode headphone_node(kHeadphone); + headphone_node.plugged_time = 1000; + audio_nodes.push_back(headphone_node); + AudioNode internal_mic(kInternalMic); + internal_mic.active = true; + audio_nodes.push_back(internal_mic); + ChangeAudioNodes(audio_nodes); + + // Verify the AudioNodesChanged event is fired, with nodes count unchanged. + EXPECT_EQ(1, test_observer_->audio_nodes_changed_count()); + cras_audio_handler_->GetAudioDevices(&audio_devices); + EXPECT_EQ(init_nodes_size, audio_devices.size()); + + // Verify the active output device is switched to headphone, and + // an ActiveOutputChanged event is fired. + EXPECT_EQ(1, test_observer_->active_output_node_changed_count()); + EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_output()); + + // Unplug the headphone and internal speaker auto-plugs back. + audio_nodes.clear(); + audio_nodes.push_back(kUSBHeadphone1); + AudioNode internal_speaker_node(kInternalSpeaker); + internal_speaker_node.plugged_time = 2000; + audio_nodes.push_back(internal_speaker_node); + audio_nodes.push_back(internal_mic); + ChangeAudioNodes(audio_nodes); + + // Verify the AudioNodesChanged event is fired, with nodes count unchanged. + EXPECT_EQ(2, test_observer_->audio_nodes_changed_count()); + cras_audio_handler_->GetAudioDevices(&audio_devices); + EXPECT_EQ(init_nodes_size, audio_devices.size()); + + // Verify the active output device is switched back to USB, and + // an ActiveOutputChanged event is fired. + EXPECT_EQ(2, test_observer_->active_output_node_changed_count()); + EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_output()); + + // Verify the active input device is not changed. + EXPECT_EQ(0, test_observer_->active_input_node_changed_count()); + EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode()); +} + +TEST_F(CrasAudioHandlerTest, PlugMicAutoUnplugInternalMicWithActiveUSB) { + // Set up initial audio devices. + AudioNodeList audio_nodes; + audio_nodes.push_back(kUSBHeadphone1); + audio_nodes.push_back(kInternalSpeaker); + audio_nodes.push_back(kUSBMic); + audio_nodes.push_back(kInternalMic); + SetUpCrasAudioHandler(audio_nodes); + const size_t init_nodes_size = audio_nodes.size(); + + // Verify the audio devices size. + EXPECT_EQ(0, test_observer_->audio_nodes_changed_count()); + AudioDeviceList audio_devices; + cras_audio_handler_->GetAudioDevices(&audio_devices); + EXPECT_EQ(init_nodes_size, audio_devices.size()); + + // Verify the internal mic is selected as the active input. + EXPECT_EQ(0, test_observer_->active_input_node_changed_count()); + EXPECT_EQ(kUSBMicId, cras_audio_handler_->GetActiveInputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_input()); + + // Verify the internal speaker is selected as the active output. + EXPECT_EQ(0, test_observer_->active_output_node_changed_count()); + EXPECT_EQ(kUSBHeadphoneId1, cras_audio_handler_->GetActiveOutputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_output()); + + // Plug the headphone and mic, auto-unplug internal mic and speaker. + audio_nodes.clear(); + AudioNode usb_headphone_node(kUSBHeadphone1); + usb_headphone_node.active = true; + audio_nodes.push_back(usb_headphone_node); + AudioNode headphone_node(kHeadphone); + headphone_node.plugged_time = 1000; + audio_nodes.push_back(headphone_node); + AudioNode usb_mic(kUSBMic); + usb_mic.active = true; + audio_nodes.push_back(usb_mic); + AudioNode mic_jack(kMicJack); + mic_jack.plugged_time = 1000; + audio_nodes.push_back(mic_jack); + ChangeAudioNodes(audio_nodes); + + // Verify the AudioNodesChanged event is fired, with nodes count unchanged. + EXPECT_EQ(1, test_observer_->audio_nodes_changed_count()); + cras_audio_handler_->GetAudioDevices(&audio_devices); + EXPECT_EQ(init_nodes_size, audio_devices.size()); + + // Verify the active output device is switched to headphone, and + // an ActiveOutputChanged event is fired. + EXPECT_EQ(1, test_observer_->active_output_node_changed_count()); + EXPECT_EQ(kHeadphone.id, cras_audio_handler_->GetActiveOutputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_output()); + + // Verify the active input device is switched to mic jack, and + // an ActiveInputChanged event is fired. + EXPECT_EQ(1, test_observer_->active_input_node_changed_count()); + EXPECT_EQ(kMicJack.id, cras_audio_handler_->GetActiveInputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_input()); + + // Unplug the headphone and internal speaker auto-plugs back. + audio_nodes.clear(); + audio_nodes.push_back(kUSBHeadphone1); + AudioNode internal_speaker_node(kInternalSpeaker); + internal_speaker_node.plugged_time = 2000; + audio_nodes.push_back(internal_speaker_node); + audio_nodes.push_back(kUSBMic); + AudioNode internal_mic(kInternalMic); + internal_mic.plugged_time = 2000; + audio_nodes.push_back(internal_mic); + ChangeAudioNodes(audio_nodes); + + // Verify the AudioNodesChanged event is fired, with nodes count unchanged. + EXPECT_EQ(2, test_observer_->audio_nodes_changed_count()); + cras_audio_handler_->GetAudioDevices(&audio_devices); + EXPECT_EQ(init_nodes_size, audio_devices.size()); + + // Verify the active output device is switched back to USB, and + // an ActiveOutputChanged event is fired. + EXPECT_EQ(2, test_observer_->active_output_node_changed_count()); + EXPECT_EQ(kUSBHeadphone1.id, cras_audio_handler_->GetActiveOutputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_output()); + + // Verify the active input device is switched back to USB mic, and + // an ActiveInputChanged event is fired. + EXPECT_EQ(2, test_observer_->active_input_node_changed_count()); + EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_input()); +} + TEST_F(CrasAudioHandlerTest, MultipleNodesChangedSignalsOnPlugInHeadphone) { // Set up initial audio devices. AudioNodeList audio_nodes; |