Commit 110babd3 authored by jennyz@chromium.org's avatar jennyz@chromium.org

Fix the bluetooth audio device id changing on the fly issue and the active...

Fix the bluetooth audio device id changing on the fly issue and the active device inconsistent issue caused by multiple NodesChanged signal received for the same node change.


BUG=290485

Review URL: https://chromiumcodereview.appspot.com/23620055

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@223507 0039d316-1c4b-4281-b951-d872f2087c98
parent eebac8a0
...@@ -30,6 +30,11 @@ const int kMuteThresholdPercent = 1; ...@@ -30,6 +30,11 @@ const int kMuteThresholdPercent = 1;
static CrasAudioHandler* g_cras_audio_handler = NULL; static CrasAudioHandler* g_cras_audio_handler = NULL;
bool IsSameAudioDevice(const AudioDevice& a, const AudioDevice& b) {
return a.id == b.id && a.is_input == b.is_input && a.type == b.type
&& a.device_name == b.device_name;
}
} // namespace } // namespace
CrasAudioHandler::AudioObserver::AudioObserver() { CrasAudioHandler::AudioObserver::AudioObserver() {
...@@ -562,12 +567,31 @@ bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes, ...@@ -562,12 +567,31 @@ bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes,
for (AudioNodeList::const_iterator it = new_nodes.begin(); for (AudioNodeList::const_iterator it = new_nodes.begin();
it != new_nodes.end(); ++it) { it != new_nodes.end(); ++it) {
if (is_input == it->is_input) if (is_input == it->is_input) {
++num_new_devices; ++num_new_devices;
// Look to see if the new device not in the old device list.
AudioDevice device(*it);
if (FoundNewDevice(device))
return true;
}
} }
return num_old_devices != num_new_devices; return num_old_devices != num_new_devices;
} }
bool CrasAudioHandler::FoundNewDevice(const AudioDevice& device) {
const AudioDevice* device_found = GetDeviceFromId(device.id);
if (!device_found)
return true;
if (!IsSameAudioDevice(device, *device_found)) {
LOG(WARNING) << "Different Audio devices with same id:"
<< " new device: " << device.ToString()
<< " old device: " << device_found->ToString();
return true;
}
return false;
}
void CrasAudioHandler::UpdateDevicesAndSwitchActive( void CrasAudioHandler::UpdateDevicesAndSwitchActive(
const AudioNodeList& nodes) { const AudioNodeList& nodes) {
size_t old_audio_devices_size = audio_devices_.size(); size_t old_audio_devices_size = audio_devices_.size();
......
...@@ -238,6 +238,9 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, ...@@ -238,6 +238,9 @@ class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
void HandleGetNodesError(const std::string& error_name, void HandleGetNodesError(const std::string& error_name,
const std::string& error_msg); const std::string& error_msg);
// Returns true if |device| is not found in audio_devices_.
bool FoundNewDevice(const AudioDevice& device);
scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler_; scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler_;
base::WeakPtrFactory<CrasAudioHandler> weak_ptr_factory_; base::WeakPtrFactory<CrasAudioHandler> weak_ptr_factory_;
ObserverList<AudioObserver> observers_; ObserverList<AudioObserver> observers_;
......
...@@ -935,6 +935,55 @@ TEST_F(CrasAudioHandlerTest, OneActiveAudioOutputAfterLoginNewUserSession) { ...@@ -935,6 +935,55 @@ TEST_F(CrasAudioHandlerTest, OneActiveAudioOutputAfterLoginNewUserSession) {
} }
} }
TEST_F(CrasAudioHandlerTest, BluetoothSpeakerIdChangedOnFly) {
// Initialize with internal speaker and bluetooth headset.
AudioNodeList audio_nodes;
audio_nodes.push_back(kInternalSpeaker);
audio_nodes.push_back(kBluetoothHeadset);
SetUpCrasAudioHandler(audio_nodes);
const size_t init_nodes_size = audio_nodes.size();
// Verify the audio devices size.
AudioDeviceList audio_devices;
cras_audio_handler_->GetAudioDevices(&audio_devices);
EXPECT_EQ(init_nodes_size, audio_devices.size());
EXPECT_EQ(0, test_observer_->audio_nodes_changed_count());
// Verify the bluetooth headset is selected as the active output and all other
// audio devices are not active.
EXPECT_EQ(0, test_observer_->active_output_node_changed_count());
AudioDevice active_output;
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_EQ(kBluetoothHeadset.id, active_output.id);
EXPECT_EQ(kBluetoothHeadset.id, cras_audio_handler_->GetActiveOutputNode());
EXPECT_TRUE(cras_audio_handler_->has_alternative_output());
// Cras changes the bluetooth headset's id on the fly.
audio_nodes.clear();
AudioNode internal_speaker(kInternalSpeaker);
internal_speaker.active = false;
audio_nodes.push_back(internal_speaker);
AudioNode bluetooth_headphone(kBluetoothHeadset);
// Change bluetooth headphone id.
bluetooth_headphone.id = kBluetoothHeadsetId + 20000;
bluetooth_headphone.active = false;
audio_nodes.push_back(bluetooth_headphone);
ChangeAudioNodes(audio_nodes);
// Verify NodesChanged event is fired, and the audio devices size is not
// changed.
audio_devices.clear();
cras_audio_handler_->GetAudioDevices(&audio_devices);
EXPECT_EQ(init_nodes_size, audio_devices.size());
EXPECT_EQ(1, test_observer_->audio_nodes_changed_count());
// Verify ActiveOutputNodeChanged event is fired, and active device should be
// bluetooth headphone.
EXPECT_EQ(1, test_observer_->active_output_node_changed_count());
EXPECT_TRUE(cras_audio_handler_->GetActiveOutputDevice(&active_output));
EXPECT_EQ(bluetooth_headphone.id, active_output.id);
}
TEST_F(CrasAudioHandlerTest, PlugUSBMic) { TEST_F(CrasAudioHandlerTest, PlugUSBMic) {
// Set up initial audio devices, only with internal mic. // Set up initial audio devices, only with internal mic.
AudioNodeList audio_nodes; AudioNodeList audio_nodes;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment