diff options
author | jennyz@chromium.org <jennyz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-09 23:50:23 +0000 |
---|---|---|
committer | jennyz@chromium.org <jennyz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-09 23:50:23 +0000 |
commit | babc24b7a9e9ac8ac27252804506e88fa2fb80af (patch) | |
tree | b8d9a4f104ac4252e1c33d0495078b62fc410cad /chromeos/audio | |
parent | e11fceee0f158a9b51eabf593010ee6093f5ef5e (diff) | |
download | chromium_src-babc24b7a9e9ac8ac27252804506e88fa2fb80af.zip chromium_src-babc24b7a9e9ac8ac27252804506e88fa2fb80af.tar.gz chromium_src-babc24b7a9e9ac8ac27252804506e88fa2fb80af.tar.bz2 |
Fix the wrong output device switching caused by an input device being plugged in.
BUG=286029
Review URL: https://chromiumcodereview.appspot.com/23819034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222133 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos/audio')
-rw-r--r-- | chromeos/audio/cras_audio_handler.cc | 26 | ||||
-rw-r--r-- | chromeos/audio/cras_audio_handler.h | 4 | ||||
-rw-r--r-- | chromeos/audio/cras_audio_handler_unittest.cc | 61 |
3 files changed, 88 insertions, 3 deletions
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc index 9ed5253..94c032e 100644 --- a/chromeos/audio/cras_audio_handler.cc +++ b/chromeos/audio/cras_audio_handler.cc @@ -513,9 +513,29 @@ void CrasAudioHandler::SwitchToDevice(const AudioDevice& device) { } } +bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes, + bool is_input) { + size_t num_old_devices = 0; + size_t num_new_devices = 0; + for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); + it != audio_devices_.end(); ++it) { + if (is_input == it->second.is_input) + ++num_old_devices; + } + + for (AudioNodeList::const_iterator it = new_nodes.begin(); + it != new_nodes.end(); ++it) { + if (is_input == it->is_input) + ++num_new_devices; + } + return num_old_devices != num_new_devices; +} + void CrasAudioHandler::UpdateDevicesAndSwitchActive( const AudioNodeList& nodes) { size_t old_audio_devices_size = audio_devices_.size(); + bool output_devices_changed = HasDeviceChange(nodes, false); + bool input_devices_changed = HasDeviceChange(nodes, true); audio_devices_.clear(); has_alternative_input_ = false; has_alternative_output_ = false; @@ -548,12 +568,14 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive( // If audio nodes change is caused by unplugging some non-active audio // devices, the previously set active audio device will stay active. // Otherwise, switch to a new active audio device according to their priority. - if (!NonActiveDeviceUnplugged(old_audio_devices_size, + if (input_devices_changed && + !NonActiveDeviceUnplugged(old_audio_devices_size, audio_devices_.size(), active_input_node_id_) && !input_devices_pq_.empty()) SwitchToDevice(input_devices_pq_.top()); - if (!NonActiveDeviceUnplugged(old_audio_devices_size, + if (output_devices_changed && + !NonActiveDeviceUnplugged(old_audio_devices_size, audio_devices_.size(), active_output_node_id_) && !output_devices_pq_.empty()) { diff --git a/chromeos/audio/cras_audio_handler.h b/chromeos/audio/cras_audio_handler.h index 48e0376..cbd8612 100644 --- a/chromeos/audio/cras_audio_handler.h +++ b/chromeos/audio/cras_audio_handler.h @@ -219,6 +219,10 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, size_t new_device_size, uint64 current_active_node); + // Returns true if there is any device change for for input or output, + // specified by |is_input|. + bool HasDeviceChange(const AudioNodeList& new_nodes, bool is_input); + // Handles dbus callback for GetNodes. void HandleGetNodes(const chromeos::AudioNodeList& node_list, bool success); diff --git a/chromeos/audio/cras_audio_handler_unittest.cc b/chromeos/audio/cras_audio_handler_unittest.cc index 8d6468c..03dd4aa 100644 --- a/chromeos/audio/cras_audio_handler_unittest.cc +++ b/chromeos/audio/cras_audio_handler_unittest.cc @@ -948,7 +948,7 @@ TEST_F(CrasAudioHandlerTest, PlugUSBMic) { EXPECT_EQ(init_nodes_size, audio_devices.size()); EXPECT_EQ(0, test_observer_->audio_nodes_changed_count()); - // Verify the internal mic is selected as the active output. + // Verify the internal mic is selected as the active input. EXPECT_EQ(0, test_observer_->active_input_node_changed_count()); EXPECT_EQ(kInternalMic.id, cras_audio_handler_->GetActiveInputNode()); EXPECT_FALSE(cras_audio_handler_->has_alternative_input()); @@ -1006,6 +1006,65 @@ TEST_F(CrasAudioHandlerTest, UnplugUSBMic) { EXPECT_FALSE(cras_audio_handler_->has_alternative_input()); } +TEST_F(CrasAudioHandlerTest, PlugUSBMicNotAffectActiveOutput) { + // Set up initial audio devices. + AudioNodeList audio_nodes; + audio_nodes.push_back(kInternalSpeaker); + audio_nodes.push_back(kHeadphone); + 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 headphone is selected as the active output. + EXPECT_EQ(0, test_observer_->active_output_node_changed_count()); + EXPECT_EQ(kHeadphoneId, cras_audio_handler_->GetActiveOutputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_output()); + + // Switch the active output to internal speaker. + AudioDevice internal_speaker(kInternalSpeaker); + cras_audio_handler_->SwitchToDevice(internal_speaker); + + // Verify the active output is switched to internal speaker, and the + // ActiveOutputNodeChanged event is fired. + EXPECT_EQ(1, test_observer_->active_output_node_changed_count()); + AudioDevice active_output; + EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output)); + EXPECT_EQ(kInternalSpeaker.id, active_output.id); + EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode()); + + // Plug the USB Mic. + audio_nodes.push_back(kUSBMic); + ChangeAudioNodes(audio_nodes); + + // Verify the AudioNodesChanged event is fired, one new device is added. + EXPECT_EQ(1, test_observer_->audio_nodes_changed_count()); + cras_audio_handler_->GetAudioDevices(&audio_devices); + EXPECT_EQ(init_nodes_size + 1, audio_devices.size()); + + // Verify the active input device is switched to USB mic, and + // and ActiveInputChanged event is fired. + EXPECT_EQ(1, test_observer_->active_input_node_changed_count()); + EXPECT_EQ(kUSBMic.id, cras_audio_handler_->GetActiveInputNode()); + EXPECT_TRUE(cras_audio_handler_->has_alternative_input()); + + // Verify the active output device is not changed. + EXPECT_EQ(1, test_observer_->active_output_node_changed_count()); + EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output)); + EXPECT_EQ(kInternalSpeaker.id, active_output.id); + EXPECT_EQ(kInternalSpeaker.id, cras_audio_handler_->GetActiveOutputNode()); +} + TEST_F(CrasAudioHandlerTest, SetOutputMute) { AudioNodeList audio_nodes; audio_nodes.push_back(kInternalSpeaker); |