Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Unified Diff: chromeos/audio/cras_audio_handler.cc

Issue 1746843002: Persist the user's active audio device choice across chromeos session and reboots. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix nits. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chromeos/audio/cras_audio_handler.h ('k') | chromeos/audio/cras_audio_handler_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromeos/audio/cras_audio_handler.cc
diff --git a/chromeos/audio/cras_audio_handler.cc b/chromeos/audio/cras_audio_handler.cc
index 531f82e02a92f957724d0561df3de90a569a679e..64114c9071ebffacd4b16f45f9f469bf2ac72d7d 100644
--- a/chromeos/audio/cras_audio_handler.cc
+++ b/chromeos/audio/cras_audio_handler.cc
@@ -13,7 +13,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
-#include "chromeos/audio/audio_devices_pref_handler.h"
+#include "base/sys_info.h"
#include "chromeos/audio/audio_devices_pref_handler_stub.h"
#include "chromeos/dbus/dbus_thread_manager.h"
@@ -37,8 +37,8 @@ const int kHDMIRediscoverGracePeriodDurationInMs = 2000;
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;
+ return a.stable_device_id == b.stable_device_id && a.is_input == b.is_input &&
+ a.type == b.type && a.device_name == b.device_name;
}
bool IsInNodeList(uint64_t node_id,
@@ -46,6 +46,14 @@ bool IsInNodeList(uint64_t node_id,
return std::find(id_list.begin(), id_list.end(), node_id) != id_list.end();
}
+bool IsDeviceInList(const AudioDevice& device, const AudioNodeList& node_list) {
+ for (const AudioNode& node : node_list) {
+ if (device.stable_device_id == node.stable_device_id)
+ return true;
+ }
+ return false;
+}
+
} // namespace
CrasAudioHandler::AudioObserver::AudioObserver() {
@@ -233,7 +241,7 @@ void CrasAudioHandler::AddActiveNode(uint64_t node_id, bool notify) {
// If there is no primary active device, set |node_id| to primary active node.
if ((device->is_input && !active_input_node_id_) ||
(!device->is_input && !active_output_node_id_)) {
- SwitchToDevice(*device, notify);
+ SwitchToDevice(*device, notify, ACTIVATE_BY_USER);
return;
}
@@ -388,37 +396,50 @@ void CrasAudioHandler::SetInputMute(bool mute_on) {
OnInputMuteChanged(input_mute_on_));
}
-void CrasAudioHandler::SetActiveOutputNode(uint64_t node_id, bool notify) {
- chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->
- SetActiveOutputNode(node_id);
+void CrasAudioHandler::SetActiveDevice(const AudioDevice& active_device,
+ bool notify,
+ DeviceActivateType activate_by) {
+ if (active_device.is_input) {
+ chromeos::DBusThreadManager::Get()
+ ->GetCrasAudioClient()
+ ->SetActiveInputNode(active_device.id);
+ } else {
+ chromeos::DBusThreadManager::Get()
+ ->GetCrasAudioClient()
+ ->SetActiveOutputNode(active_device.id);
+ }
+
if (notify)
- NotifyActiveNodeChanged(false);
+ NotifyActiveNodeChanged(active_device.is_input);
- // Save state for all output nodes.
+ // Save active state for the nodes.
for (AudioDeviceMap::iterator it = audio_devices_.begin();
it != audio_devices_.end(); ++it) {
- if (it->second.is_input)
+ const AudioDevice& device = it->second;
+ if (device.is_input != active_device.is_input)
continue;
- audio_pref_handler_->SetDeviceState(it->second, it->second.active
- ? AUDIO_STATE_ACTIVE
- : AUDIO_STATE_INACTIVE);
+ SaveDeviceState(device, device.active, activate_by);
}
}
-void CrasAudioHandler::SetActiveInputNode(uint64_t node_id, bool notify) {
- chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->
- SetActiveInputNode(node_id);
- if (notify)
- NotifyActiveNodeChanged(true);
-
- // Save state for all input nodes.
- for (AudioDeviceMap::iterator it = audio_devices_.begin();
- it != audio_devices_.end(); ++it) {
- if (!it->second.is_input)
- continue;
- audio_pref_handler_->SetDeviceState(it->second, it->second.active
- ? AUDIO_STATE_ACTIVE
- : AUDIO_STATE_INACTIVE);
+void CrasAudioHandler::SaveDeviceState(const AudioDevice& device,
+ bool active,
+ DeviceActivateType activate_by) {
+ if (!active) {
+ audio_pref_handler_->SetDeviceActive(device, false, false);
+ } else {
+ switch (activate_by) {
+ case ACTIVATE_BY_USER:
+ audio_pref_handler_->SetDeviceActive(device, true, true);
+ break;
+ case ACTIVATE_BY_PRIORITY:
+ audio_pref_handler_->SetDeviceActive(device, true, false);
+ break;
+ default:
+ // The device is made active due to its previous active state in prefs,
+ // don't change its active state settings in prefs.
+ break;
+ }
}
}
@@ -532,8 +553,8 @@ void CrasAudioHandler::AudioClientRestarted() {
}
void CrasAudioHandler::NodesChanged() {
- // Refresh audio nodes data.
- GetNodes();
+ if (cras_service_available_)
+ GetNodes();
}
void CrasAudioHandler::ActiveOutputNodeChanged(uint64_t node_id) {
@@ -582,6 +603,16 @@ const AudioDevice* CrasAudioHandler::GetDeviceFromId(uint64_t device_id) const {
return &(it->second);
}
+const AudioDevice* CrasAudioHandler::GetDeviceFromStableDeviceId(
+ uint64_t stable_device_id) const {
+ for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
+ it != audio_devices_.end(); ++it) {
+ if (it->second.stable_device_id == stable_device_id)
+ return &(it->second);
+ }
+ return NULL;
+}
+
const AudioDevice* CrasAudioHandler::GetKeyboardMic() const {
for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
it != audio_devices_.end(); it++) {
@@ -655,6 +686,25 @@ void CrasAudioHandler::SetupAdditionalActiveAudioNodeState(uint64_t node_id) {
void CrasAudioHandler::InitializeAudioState() {
ApplyAudioPolicy();
+
+ // Defer querying cras for GetNodes until cras service becomes available.
+ cras_service_available_ = false;
+ chromeos::DBusThreadManager::Get()
+ ->GetCrasAudioClient()
+ ->WaitForServiceToBeAvailable(base::Bind(
+ &CrasAudioHandler::InitializeAudioAfterCrasServiceAvailable,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CrasAudioHandler::InitializeAudioAfterCrasServiceAvailable(
+ bool service_is_available) {
+ if (!service_is_available) {
+ LOG(ERROR) << "Cras service is not available";
+ cras_service_available_ = false;
+ return;
+ }
+
+ cras_service_available_ = true;
GetNodes();
}
@@ -750,62 +800,76 @@ void CrasAudioHandler::GetNodes() {
weak_ptr_factory_.GetWeakPtr()));
}
-bool CrasAudioHandler::ChangeActiveDevice(const AudioDevice& new_active_device,
- uint64_t* current_active_node_id) {
+bool CrasAudioHandler::ChangeActiveDevice(
+ const AudioDevice& new_active_device) {
+ uint64_t& current_active_node_id = new_active_device.is_input
+ ? active_input_node_id_
+ : active_output_node_id_;
// If the device we want to switch to is already the current active device,
// do nothing.
if (new_active_device.active &&
- new_active_device.id == *current_active_node_id) {
+ new_active_device.id == current_active_node_id) {
return false;
}
+ bool found_new_active_device = false;
// Reset all other input or output devices' active status. The active audio
// device from the previous user session can be remembered by cras, but not
// in chrome. see crbug.com/273271.
for (AudioDeviceMap::iterator it = audio_devices_.begin();
it != audio_devices_.end(); ++it) {
if (it->second.is_input == new_active_device.is_input &&
- it->second.id != new_active_device.id)
+ it->second.id != new_active_device.id) {
it->second.active = false;
+ } else if (it->second.is_input == new_active_device.is_input &&
+ it->second.id == new_active_device.id) {
+ found_new_active_device = true;
+ }
+ }
+
+ if (!found_new_active_device) {
+ LOG(ERROR) << "Invalid new active device: " << new_active_device.ToString();
+ return false;
}
// Set the current active input/output device to the new_active_device.
- *current_active_node_id = new_active_device.id;
- audio_devices_[*current_active_node_id].active = true;
+ current_active_node_id = new_active_device.id;
+ audio_devices_[current_active_node_id].active = true;
return true;
}
-bool CrasAudioHandler::NonActiveDeviceUnplugged(size_t old_devices_size,
- size_t new_devices_size,
- uint64_t current_active_node) {
- return (new_devices_size < old_devices_size &&
- GetDeviceFromId(current_active_node));
-}
+void CrasAudioHandler::SwitchToDevice(const AudioDevice& device,
+ bool notify,
+ DeviceActivateType activate_by) {
+ if (!ChangeActiveDevice(device))
+ return;
-void CrasAudioHandler::SwitchToDevice(const AudioDevice& device, bool notify) {
- if (device.is_input) {
- if (!ChangeActiveDevice(device, &active_input_node_id_))
- return;
+ if (device.is_input)
SetupAudioInputState();
- SetActiveInputNode(active_input_node_id_, notify);
- } else {
- if (!ChangeActiveDevice(device, &active_output_node_id_))
- return;
+ else
SetupAudioOutputState();
- SetActiveOutputNode(active_output_node_id_, notify);
- }
+
+ SetActiveDevice(device, notify, activate_by);
}
-bool CrasAudioHandler::HasDeviceChange(
- const AudioNodeList& new_nodes,
- bool is_input,
- AudioDevicePriorityQueue* new_discovered) {
- size_t num_old_devices = 0;
- size_t num_new_devices = 0;
+bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes,
+ bool is_input,
+ AudioDevicePriorityQueue* new_discovered,
+ bool* device_removed,
+ bool* active_device_removed) {
+ *device_removed = false;
for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
it != audio_devices_.end(); ++it) {
- if (is_input == it->second.is_input)
- ++num_old_devices;
+ const AudioDevice& device = it->second;
+ if (is_input != device.is_input)
+ continue;
+ if (!IsDeviceInList(device, new_nodes)) {
+ *device_removed = true;
+ if ((is_input && device.id == active_input_node_id_) ||
+ (!is_input && device.id == active_output_node_id_)) {
+ *active_device_removed = true;
+ }
+ }
}
bool new_or_changed_device = false;
@@ -813,31 +877,31 @@ bool CrasAudioHandler::HasDeviceChange(
new_discovered->pop();
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);
- DeviceStatus status = CheckDeviceStatus(device);
- if (status == NEW_DEVICE)
- new_discovered->push(device);
- if (status == NEW_DEVICE || status == CHANGED_DEVICE) {
- new_or_changed_device = true;
- }
+ if (is_input != it->is_input)
+ continue;
+ // Check if the new device is not in the old device list.
+ AudioDevice device(*it);
+ DeviceStatus status = CheckDeviceStatus(device);
+ if (status == NEW_DEVICE)
+ new_discovered->push(device);
+ if (status == NEW_DEVICE || status == CHANGED_DEVICE) {
+ new_or_changed_device = true;
}
}
- return new_or_changed_device || (num_old_devices != num_new_devices);
+ return new_or_changed_device || *device_removed;
}
CrasAudioHandler::DeviceStatus CrasAudioHandler::CheckDeviceStatus(
const AudioDevice& device) {
- const AudioDevice* device_found = GetDeviceFromId(device.id);
+ const AudioDevice* device_found =
+ GetDeviceFromStableDeviceId(device.stable_device_id);
if (!device_found)
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();
+ LOG(ERROR) << "Different Audio devices with same stable device id:"
+ << " new device: " << device.ToString()
+ << " old device: " << device_found->ToString();
return CHANGED_DEVICE;
} else if (device.active != device_found->active) {
return CHANGED_DEVICE;
@@ -853,6 +917,150 @@ void CrasAudioHandler::NotifyActiveNodeChanged(bool is_input) {
FOR_EACH_OBSERVER(AudioObserver, observers_, OnActiveOutputNodeChanged());
}
+bool CrasAudioHandler::GetActiveDeviceFromUserPref(bool is_input,
+ AudioDevice* active_device) {
+ bool found_active_device = false;
+ bool last_active_device_activate_by_user = false;
+ for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
+ it != audio_devices_.end(); ++it) {
+ AudioDevice device = it->second;
+ if (device.is_input != is_input)
+ continue;
+
+ bool active = false;
+ bool activate_by_user = false;
+ if (!audio_pref_handler_->GetDeviceActive(device, &active,
+ &activate_by_user) ||
+ !active) {
+ continue;
+ }
+
+ if (!found_active_device) {
+ found_active_device = true;
+ *active_device = device;
+ last_active_device_activate_by_user = activate_by_user;
+ continue;
+ }
+
+ // Choose the best one among multiple active devices from prefs.
+ if (activate_by_user) {
+ if (!last_active_device_activate_by_user) {
+ // Device activated by user has higher priority than the one
+ // is not activated by user.
+ *active_device = device;
+ last_active_device_activate_by_user = true;
+ } else {
+ // If there are more than one active devices activated by user in the
+ // prefs, most likely, after the device was shut down, and before it
+ // is rebooted, user has plugged in some previously unplugged audio
+ // devices. For such case, it does not make sense to honor the active
+ // states in the prefs.
+ VLOG(1) << "Found more than one user activated devices in the prefs.";
+ return false;
+ }
+ } else if (!last_active_device_activate_by_user) {
+ // If there are more than one active devices activated by priority in the
+ // prefs, most likely, cras is still enumerating the audio devices
+ // progressively. For such case, it does not make sense to honor the
+ // active states in the prefs.
+ VLOG(1) << "Found more than one active devices by priority in the prefs.";
+ return false;
+ }
+ }
+
+ if (found_active_device && !active_device->is_for_simple_usage()) {
+ // This is an odd case which is rare but possible to happen during cras
+ // initialization depeneding the audio device enumation process. The only
+ // audio node coming from cras is an internal audio device not visible
+ // to user, such as AUDIO_TYPE_POST_MIX_LOOPBACK.
+ return false;
+ }
+
+ return found_active_device;
+}
+
+void CrasAudioHandler::HandleNonHotplugNodesChange(
+ bool is_input,
+ const AudioDevicePriorityQueue& hotplug_nodes,
+ bool has_device_change,
+ bool has_device_removed,
+ bool active_device_removed) {
+ bool has_current_active_node =
+ is_input ? active_input_node_id_ : active_output_node_id_;
+
+ // No device change, extra NodesChanged signal received.
+ if (!has_device_change && has_current_active_node)
+ return;
+
+ if (hotplug_nodes.empty()) {
+ // Unplugged a non-active device.
+ if (has_device_removed) {
+ if (!active_device_removed && has_current_active_node) {
+ // Removed a non-active device, keep the current active device.
+ return;
+ }
+
+ if (active_device_removed) {
+ // Unplugged the current active device.
+ SwitchToTopPriorityDevice(is_input);
+ return;
+ }
+ }
+
+ // Some unexpected error happens on cras side. See crbug.com/586026.
+ // Either cras sent stale nodes to chrome again or cras triggered some
+ // error. Restore the previously selected active.
+ VLOG(1) << "Odd case from cras, the active node is lost unexpectedly. ";
+ SwitchToPreviousActiveDeviceIfAvailable(is_input);
+ } else {
+ // Looks like a new chrome session starts.
+ SwitchToPreviousActiveDeviceIfAvailable(is_input);
+ }
+}
+
+void CrasAudioHandler::HandleHotPlugDevice(
+ const AudioDevice& hotplug_device,
+ const AudioDevicePriorityQueue& device_priority_queue) {
+ bool last_state_active = false;
+ bool last_activate_by_user = false;
+ if (!audio_pref_handler_->GetDeviceActive(hotplug_device, &last_state_active,
+ &last_activate_by_user)) {
+ // |hotplug_device| is plugged in for the first time, activate it if it
+ // is of the highest priority.
+ if (device_priority_queue.top().id == hotplug_device.id) {
+ VLOG(1) << "Hotplug a device for the first time: "
+ << hotplug_device.ToString();
+ SwitchToDevice(hotplug_device, true, ACTIVATE_BY_PRIORITY);
+ }
+ } else if (last_state_active) {
+ VLOG(1) << "Hotplug a device, restore to active: "
+ << hotplug_device.ToString();
+ SwitchToDevice(hotplug_device, true, ACTIVATE_BY_RESTORE_PREVIOUS_STATE);
+ } else {
+ // Do not active the device if its previous state is inactive.
+ VLOG(1) << "Hotplug device remains inactive as its previous state:"
+ << hotplug_device.ToString();
+ }
+}
+
+void CrasAudioHandler::SwitchToTopPriorityDevice(bool is_input) {
+ AudioDevice top_device =
+ is_input ? input_devices_pq_.top() : output_devices_pq_.top();
+ SwitchToDevice(top_device, true, ACTIVATE_BY_PRIORITY);
+}
+
+void CrasAudioHandler::SwitchToPreviousActiveDeviceIfAvailable(bool is_input) {
+ AudioDevice previous_active_device;
+ if (GetActiveDeviceFromUserPref(is_input, &previous_active_device)) {
+ // Switch to previous active device stored in user prefs.
+ SwitchToDevice(previous_active_device, true,
+ ACTIVATE_BY_RESTORE_PREVIOUS_STATE);
+ } else {
+ // No previous active device, switch to the top priority device.
+ SwitchToTopPriorityDevice(is_input);
+ }
+}
+
void CrasAudioHandler::UpdateDevicesAndSwitchActive(
const AudioNodeList& nodes) {
size_t old_output_device_size = 0;
@@ -867,10 +1075,16 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive(
AudioDevicePriorityQueue hotplug_output_nodes;
AudioDevicePriorityQueue hotplug_input_nodes;
+ bool has_output_removed = false;
+ bool has_input_removed = false;
+ bool active_output_removed = false;
+ bool active_input_removed = false;
bool output_devices_changed =
- HasDeviceChange(nodes, false, &hotplug_output_nodes);
+ HasDeviceChange(nodes, false, &hotplug_output_nodes, &has_output_removed,
+ &active_output_removed);
bool input_devices_changed =
- HasDeviceChange(nodes, true, &hotplug_input_nodes);
+ HasDeviceChange(nodes, true, &hotplug_input_nodes, &has_input_removed,
+ &active_input_removed);
audio_devices_.clear();
has_alternative_input_ = false;
has_alternative_output_ = false;
@@ -885,7 +1099,6 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive(
for (size_t i = 0; i < nodes.size(); ++i) {
AudioDevice device(nodes[i]);
audio_devices_[device.id] = device;
-
if (!has_alternative_input_ &&
device.is_input &&
device.type != AUDIO_TYPE_INTERNAL_MIC &&
@@ -906,88 +1119,48 @@ void CrasAudioHandler::UpdateDevicesAndSwitchActive(
}
}
+ // Handle output device changes.
+ HandleAudioDeviceChange(false, output_devices_pq_, hotplug_output_nodes,
+ output_devices_changed, has_output_removed,
+ active_output_removed);
+
+ // Handle input device changes.
+ HandleAudioDeviceChange(true, input_devices_pq_, hotplug_input_nodes,
+ input_devices_changed, has_input_removed,
+ active_input_removed);
+}
+
+void CrasAudioHandler::HandleAudioDeviceChange(
+ bool is_input,
+ const AudioDevicePriorityQueue& devices_pq,
+ const AudioDevicePriorityQueue& hotplug_nodes,
+ bool has_device_change,
+ bool has_device_removed,
+ bool active_device_removed) {
+ uint64_t& active_node_id =
+ is_input ? active_input_node_id_ : active_output_node_id_;
+
+ // No audio devices found.
+ if (devices_pq.empty()) {
+ VLOG(1) << "No " << (is_input ? "input" : "output") << " devices found";
+ active_node_id = 0;
+ NotifyActiveNodeChanged(is_input);
+ return;
+ }
+
// If the previous active device is removed from the new node list,
- // or changed to inactive by cras, reset active_output_node_id_.
+ // or changed to inactive by cras, reset active_node_id.
// See crbug.com/478968.
- const AudioDevice* active_output = GetDeviceFromId(active_output_node_id_);
- if (!active_output || !active_output->active)
- active_output_node_id_ = 0;
- const AudioDevice* active_input = GetDeviceFromId(active_input_node_id_);
- if (!active_input || !active_input->active)
- active_input_node_id_ = 0;
-
- // If audio nodes change is caused by unplugging some non-active audio
- // devices, we wont't change the current active audio devices.
- if (input_devices_changed &&
- !NonActiveDeviceUnplugged(old_input_device_size,
- new_input_device_size,
- active_input_node_id_)) {
- // Some devices like chromeboxes don't have the internal audio input. In
- // that case the active input node id should be reset.
- if (input_devices_pq_.empty()) {
- active_input_node_id_ = 0;
- NotifyActiveNodeChanged(true);
- } else {
- // If there is no current active node, or, no new hot plugged node, select
- // the active node by their priorities.
- if (!active_input_node_id_ || hotplug_input_nodes.empty()) {
- SwitchToDevice(input_devices_pq_.top(), true);
- } else {
- // If user has hot plugged any input nodes, look at the one with highest
- // priority (normally, there is only one hot plugged input node), and
- // consider switch to it depend on its last state stored in preference.
- AudioDeviceState last_state =
- audio_pref_handler_->GetDeviceState(hotplug_input_nodes.top());
- switch (last_state) {
- case AUDIO_STATE_ACTIVE:
- // This node was plugged in before and was selected as the active
- // one
- // before it was unplugged last time, switch to this device.
- SwitchToDevice(hotplug_input_nodes.top(), true);
- break;
- case AUDIO_STATE_NOT_AVAILABLE:
- // This is a new node, not plugged in before, with the highest
- // priority. Switch to this device.
- if (input_devices_pq_.top().id == hotplug_input_nodes.top().id)
- SwitchToDevice(hotplug_input_nodes.top(), true);
- break;
- case AUDIO_STATE_INACTIVE:
- // This node was NOT selected as the active one last time before it
- // got unplugged, so don't switch to it.
- default:
- break;
- }
- }
- }
- }
- if (output_devices_changed &&
- !NonActiveDeviceUnplugged(old_output_device_size,
- new_output_device_size,
- active_output_node_id_)) {
- // ditto input node logic.
- if (output_devices_pq_.empty()) {
- active_output_node_id_ = 0;
- NotifyActiveNodeChanged(false);
- } else {
- if (!active_output_node_id_ || hotplug_output_nodes.empty()) {
- SwitchToDevice(output_devices_pq_.top(), true);
- } else {
- AudioDeviceState last_state =
- audio_pref_handler_->GetDeviceState(hotplug_output_nodes.top());
- switch (last_state) {
- case AUDIO_STATE_ACTIVE:
- SwitchToDevice(hotplug_output_nodes.top(), true);
- break;
- case AUDIO_STATE_NOT_AVAILABLE:
- if (output_devices_pq_.top().id == hotplug_output_nodes.top().id)
- SwitchToDevice(hotplug_output_nodes.top(), true);
- break;
- case AUDIO_STATE_INACTIVE:
- default:
- break;
- }
- }
- }
+ const AudioDevice* active_device = GetDeviceFromId(active_node_id);
+ if (!active_device || !active_device->active)
+ active_node_id = 0;
+
+ if (!active_node_id || hotplug_nodes.empty() || hotplug_nodes.size() > 1) {
+ HandleNonHotplugNodesChange(is_input, hotplug_nodes, has_device_change,
+ has_device_removed, active_device_removed);
+ } else {
+ // Typical user hotplug case.
+ HandleHotPlugDevice(hotplug_nodes.top(), devices_pq);
}
}
« no previous file with comments | « chromeos/audio/cras_audio_handler.h ('k') | chromeos/audio/cras_audio_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698