summaryrefslogtreecommitdiffstats
path: root/chromeos/audio
diff options
context:
space:
mode:
authorjennyz@chromium.org <jennyz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-09 23:50:23 +0000
committerjennyz@chromium.org <jennyz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-09 23:50:23 +0000
commitbabc24b7a9e9ac8ac27252804506e88fa2fb80af (patch)
treeb8d9a4f104ac4252e1c33d0495078b62fc410cad /chromeos/audio
parente11fceee0f158a9b51eabf593010ee6093f5ef5e (diff)
downloadchromium_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.cc26
-rw-r--r--chromeos/audio/cras_audio_handler.h4
-rw-r--r--chromeos/audio/cras_audio_handler_unittest.cc61
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);