| Index: chromeos/audio/cras_audio_handler.cc
|
| diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc
|
| index ce25eabf11c758bb98014531a8f8ee9f71194869..c3e7c2dafe2ef876611420e4c671a3bb05be331c 100644
|
| --- a/chromeos/audio/cras_audio_handler.cc
|
| +++ b/chromeos/audio/cras_audio_handler.cc
|
| @@ -39,6 +39,14 @@ bool IsInNodeList(uint64 node_id, const CrasAudioHandler::NodeIdList& id_list) {
|
| return std::find(id_list.begin(), id_list.end(), node_id) != id_list.end();
|
| }
|
|
|
| +bool IsNodeInTheList(uint64 node_id, const AudioNodeList& node_list) {
|
| + for (size_t i = 0; i < node_list.size(); ++i) {
|
| + if (node_id == node_list[i].id)
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| } // namespace
|
|
|
| CrasAudioHandler::AudioObserver::AudioObserver() {
|
| @@ -728,7 +736,8 @@ void CrasAudioHandler::SwitchToDevice(const AudioDevice& device, bool notify) {
|
| }
|
|
|
| bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes,
|
| - bool is_input) {
|
| + bool is_input,
|
| + AudioNodeList* new_discovered) {
|
| size_t num_old_devices = 0;
|
| size_t num_new_devices = 0;
|
| for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
|
| @@ -737,34 +746,41 @@ bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes,
|
| ++num_old_devices;
|
| }
|
|
|
| + bool new_or_changed_device = false;
|
| + new_discovered->clear();
|
| for (AudioNodeList::const_iterator it = new_nodes.begin();
|
| it != new_nodes.end(); ++it) {
|
| if (is_input == it->is_input) {
|
| ++num_new_devices;
|
| // Look to see if the new device not in the old device list.
|
| AudioDevice device(*it);
|
| - if (FoundNewOrChangedDevice(device))
|
| - return true;
|
| + DeviceStatus status = CheckDeviceStatus(device);
|
| + if (status == NEW_DEVICE)
|
| + new_discovered->push_back(*it);
|
| + if (status == NEW_DEVICE || status == CHANGED_DEVICE) {
|
| + new_or_changed_device = true;
|
| + }
|
| }
|
| }
|
| - return num_old_devices != num_new_devices;
|
| + return new_or_changed_device || (num_old_devices != num_new_devices);
|
| }
|
|
|
| -bool CrasAudioHandler::FoundNewOrChangedDevice(const AudioDevice& device) {
|
| +CrasAudioHandler::DeviceStatus CrasAudioHandler::CheckDeviceStatus(
|
| + const AudioDevice& device) {
|
| const AudioDevice* device_found = GetDeviceFromId(device.id);
|
| if (!device_found)
|
| - return true;
|
| + return NEW_DEVICE;
|
|
|
| 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 CHANGED_DEVICE;
|
| } else if (device.active != device_found->active) {
|
| - return true;
|
| + return CHANGED_DEVICE;
|
| }
|
|
|
| - return false;
|
| + return OLD_DEVICE;
|
| }
|
|
|
| void CrasAudioHandler::NotifyActiveNodeChanged(bool is_input) {
|
| @@ -786,8 +802,12 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive(
|
| ++old_output_device_size;
|
| }
|
|
|
| - bool output_devices_changed = HasDeviceChange(nodes, false);
|
| - bool input_devices_changed = HasDeviceChange(nodes, true);
|
| + AudioNodeList hotplug_output_nodes;
|
| + AudioNodeList hotplug_input_nodes;
|
| + bool output_devices_changed =
|
| + HasDeviceChange(nodes, false, &hotplug_output_nodes);
|
| + bool input_devices_changed =
|
| + HasDeviceChange(nodes, true, &hotplug_input_nodes);
|
| audio_devices_.clear();
|
| has_alternative_input_ = false;
|
| has_alternative_output_ = false;
|
| @@ -823,6 +843,13 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive(
|
| }
|
| }
|
|
|
| + // If the previous active device is removed from the new node list,
|
| + // reset active_output_node_id_.
|
| + if (!GetDeviceFromId(active_output_node_id_))
|
| + active_output_node_id_ = 0;
|
| + if (!GetDeviceFromId(active_input_node_id_))
|
| + active_input_node_id_ = 0;
|
| +
|
| // 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.
|
| @@ -836,7 +863,14 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive(
|
| active_input_node_id_ = 0;
|
| NotifyActiveNodeChanged(true);
|
| } else {
|
| - SwitchToDevice(input_devices_pq_.top(), true);
|
| + // If user has hot plugged a new node, we should change to the active
|
| + // device to the new node if it has the highest priority; otherwise,
|
| + // we should keep the existing active node chosen by user.
|
| + // For all other cases, we will choose the node with highest priority.
|
| + if (!active_input_node_id_ || hotplug_input_nodes.empty() ||
|
| + IsNodeInTheList(input_devices_pq_.top().id, hotplug_input_nodes)) {
|
| + SwitchToDevice(input_devices_pq_.top(), true);
|
| + }
|
| }
|
| }
|
| if (output_devices_changed &&
|
| @@ -849,7 +883,11 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive(
|
| active_output_node_id_ = 0;
|
| NotifyActiveNodeChanged(false);
|
| } else {
|
| - SwitchToDevice(output_devices_pq_.top(), true);
|
| + // ditto input node case.
|
| + if (!active_output_node_id_ || hotplug_output_nodes.empty() ||
|
| + IsNodeInTheList(output_devices_pq_.top().id, hotplug_output_nodes)) {
|
| + SwitchToDevice(output_devices_pq_.top(), true);
|
| + }
|
| }
|
| }
|
| }
|
|
|