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

Side by Side Diff: chromeos/audio/cras_audio_handler.cc

Issue 1380103003: Store audio device's active state in preference (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromeos/audio/cras_audio_handler.h" 5 #include "chromeos/audio/cras_audio_handler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 25 matching lines...) Expand all
36 bool IsSameAudioDevice(const AudioDevice& a, const AudioDevice& b) { 36 bool IsSameAudioDevice(const AudioDevice& a, const AudioDevice& b) {
37 return a.id == b.id && a.is_input == b.is_input && a.type == b.type 37 return a.id == b.id && a.is_input == b.is_input && a.type == b.type
38 && a.device_name == b.device_name; 38 && a.device_name == b.device_name;
39 } 39 }
40 40
41 bool IsInNodeList(uint64_t node_id, 41 bool IsInNodeList(uint64_t node_id,
42 const CrasAudioHandler::NodeIdList& id_list) { 42 const CrasAudioHandler::NodeIdList& id_list) {
43 return std::find(id_list.begin(), id_list.end(), node_id) != id_list.end(); 43 return std::find(id_list.begin(), id_list.end(), node_id) != id_list.end();
44 } 44 }
45 45
46 bool IsNodeInTheList(uint64_t node_id, const AudioNodeList& node_list) {
47 for (size_t i = 0; i < node_list.size(); ++i) {
48 if (node_id == node_list[i].id)
49 return true;
50 }
51 return false;
52 }
53
54 } // namespace 46 } // namespace
55 47
56 CrasAudioHandler::AudioObserver::AudioObserver() { 48 CrasAudioHandler::AudioObserver::AudioObserver() {
57 } 49 }
58 50
59 CrasAudioHandler::AudioObserver::~AudioObserver() { 51 CrasAudioHandler::AudioObserver::~AudioObserver() {
60 } 52 }
61 53
62 void CrasAudioHandler::AudioObserver::OnOutputNodeVolumeChanged( 54 void CrasAudioHandler::AudioObserver::OnOutputNodeVolumeChanged(
63 uint64_t /* node_id */, 55 uint64_t /* node_id */,
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 // If there is no primary active device, set |node_id| to primary active node. 230 // If there is no primary active device, set |node_id| to primary active node.
239 if ((device->is_input && !active_input_node_id_) || 231 if ((device->is_input && !active_input_node_id_) ||
240 (!device->is_input && !active_output_node_id_)) { 232 (!device->is_input && !active_output_node_id_)) {
241 SwitchToDevice(*device, notify); 233 SwitchToDevice(*device, notify);
242 return; 234 return;
243 } 235 }
244 236
245 AddAdditionalActiveNode(node_id, notify); 237 AddAdditionalActiveNode(node_id, notify);
246 } 238 }
247 239
248 void CrasAudioHandler::ChangeActiveNodes(const NodeIdList& new_active_ids) { 240 void CrasAudioHandler::ChangeActiveNodes(const NodeIdList& new_active_ids) {
jennyz 2015/12/17 22:50:21 What about multiple active audio nodes case?
hychao 2015/12/29 10:57:25 actually I forgot about the multiple active node p
jennyz 2016/01/05 23:46:55 Yes, it makes sense to exclude the new active node
hychao 2016/01/06 06:34:12 Done.
249 // Flags for whether there are input or output nodes passed in from 241 // Flags for whether there are input or output nodes passed in from
250 // |new_active_ids|. If there are no input nodes passed in, we will not 242 // |new_active_ids|. If there are no input nodes passed in, we will not
251 // make any change for input nodes; same for the output nodes. 243 // make any change for input nodes; same for the output nodes.
252 bool request_input_change = false; 244 bool request_input_change = false;
253 bool request_output_change = false; 245 bool request_output_change = false;
254 246
255 // Flags for whether we will actually change active status of input 247 // Flags for whether we will actually change active status of input
256 // or output nodes. 248 // or output nodes.
257 bool make_input_change = false; 249 bool make_input_change = false;
258 bool make_output_change = false; 250 bool make_output_change = false;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 SetInputMuteInternal(mute_on); 380 SetInputMuteInternal(mute_on);
389 FOR_EACH_OBSERVER(AudioObserver, observers_, 381 FOR_EACH_OBSERVER(AudioObserver, observers_,
390 OnInputMuteChanged(input_mute_on_)); 382 OnInputMuteChanged(input_mute_on_));
391 } 383 }
392 384
393 void CrasAudioHandler::SetActiveOutputNode(uint64_t node_id, bool notify) { 385 void CrasAudioHandler::SetActiveOutputNode(uint64_t node_id, bool notify) {
394 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> 386 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->
395 SetActiveOutputNode(node_id); 387 SetActiveOutputNode(node_id);
396 if (notify) 388 if (notify)
397 NotifyActiveNodeChanged(false); 389 NotifyActiveNodeChanged(false);
390
391 // Save state for all output nodes.
392 for (AudioDeviceMap::iterator it = audio_devices_.begin();
393 it != audio_devices_.end(); ++it) {
394 if (it->second.is_input)
395 continue;
396 audio_pref_handler_->SetDeviceState(it->second,
397 it->second.active ? AUDIO_STATE_ACTIVE : AUDIO_STATE_INACTIVE);
398 }
398 } 399 }
399 400
400 void CrasAudioHandler::SetActiveInputNode(uint64_t node_id, bool notify) { 401 void CrasAudioHandler::SetActiveInputNode(uint64_t node_id, bool notify) {
401 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()-> 402 chromeos::DBusThreadManager::Get()->GetCrasAudioClient()->
402 SetActiveInputNode(node_id); 403 SetActiveInputNode(node_id);
403 if (notify) 404 if (notify)
404 NotifyActiveNodeChanged(true); 405 NotifyActiveNodeChanged(true);
406
407 // Save state for all input nodes.
408 for (AudioDeviceMap::iterator it = audio_devices_.begin();
409 it != audio_devices_.end(); ++it) {
410 if (!it->second.is_input)
411 continue;
412 audio_pref_handler_->SetDeviceState(it->second,
413 it->second.active ? AUDIO_STATE_ACTIVE : AUDIO_STATE_INACTIVE);
414 }
405 } 415 }
406 416
407 void CrasAudioHandler::SetVolumeGainPercentForDevice(uint64_t device_id, 417 void CrasAudioHandler::SetVolumeGainPercentForDevice(uint64_t device_id,
408 int value) { 418 int value) {
409 const AudioDevice* device = GetDeviceFromId(device_id); 419 const AudioDevice* device = GetDeviceFromId(device_id);
410 if (!device) 420 if (!device)
411 return; 421 return;
412 422
413 if (device->is_input) 423 if (device->is_input)
414 SetInputNodeGainPercent(device_id, value); 424 SetInputNodeGainPercent(device_id, value);
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 } else { 783 } else {
774 if (!ChangeActiveDevice(device, &active_output_node_id_)) 784 if (!ChangeActiveDevice(device, &active_output_node_id_))
775 return; 785 return;
776 SetupAudioOutputState(); 786 SetupAudioOutputState();
777 SetActiveOutputNode(active_output_node_id_, notify); 787 SetActiveOutputNode(active_output_node_id_, notify);
778 } 788 }
779 } 789 }
780 790
781 bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes, 791 bool CrasAudioHandler::HasDeviceChange(const AudioNodeList& new_nodes,
782 bool is_input, 792 bool is_input,
783 AudioNodeList* new_discovered) { 793 AudioDevicePriorityQueue* new_discovered) {
784 size_t num_old_devices = 0; 794 size_t num_old_devices = 0;
785 size_t num_new_devices = 0; 795 size_t num_new_devices = 0;
786 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); 796 for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
787 it != audio_devices_.end(); ++it) { 797 it != audio_devices_.end(); ++it) {
788 if (is_input == it->second.is_input) 798 if (is_input == it->second.is_input)
789 ++num_old_devices; 799 ++num_old_devices;
790 } 800 }
791 801
792 bool new_or_changed_device = false; 802 bool new_or_changed_device = false;
793 new_discovered->clear(); 803 while (!new_discovered->empty())
804 new_discovered->pop();
794 for (AudioNodeList::const_iterator it = new_nodes.begin(); 805 for (AudioNodeList::const_iterator it = new_nodes.begin();
795 it != new_nodes.end(); ++it) { 806 it != new_nodes.end(); ++it) {
796 if (is_input == it->is_input) { 807 if (is_input == it->is_input) {
797 ++num_new_devices; 808 ++num_new_devices;
798 // Look to see if the new device not in the old device list. 809 // Look to see if the new device not in the old device list.
799 AudioDevice device(*it); 810 AudioDevice device(*it);
800 DeviceStatus status = CheckDeviceStatus(device); 811 DeviceStatus status = CheckDeviceStatus(device);
801 if (status == NEW_DEVICE) 812 if (status == NEW_DEVICE)
802 new_discovered->push_back(*it); 813 new_discovered->push(device);
803 if (status == NEW_DEVICE || status == CHANGED_DEVICE) { 814 if (status == NEW_DEVICE || status == CHANGED_DEVICE) {
804 new_or_changed_device = true; 815 new_or_changed_device = true;
805 } 816 }
806 } 817 }
807 } 818 }
808 return new_or_changed_device || (num_old_devices != num_new_devices); 819 return new_or_changed_device || (num_old_devices != num_new_devices);
809 } 820 }
810 821
811 CrasAudioHandler::DeviceStatus CrasAudioHandler::CheckDeviceStatus( 822 CrasAudioHandler::DeviceStatus CrasAudioHandler::CheckDeviceStatus(
812 const AudioDevice& device) { 823 const AudioDevice& device) {
(...skipping 25 matching lines...) Expand all
838 size_t old_output_device_size = 0; 849 size_t old_output_device_size = 0;
839 size_t old_input_device_size = 0; 850 size_t old_input_device_size = 0;
840 for (AudioDeviceMap::const_iterator it = audio_devices_.begin(); 851 for (AudioDeviceMap::const_iterator it = audio_devices_.begin();
841 it != audio_devices_.end(); ++it) { 852 it != audio_devices_.end(); ++it) {
842 if (it->second.is_input) 853 if (it->second.is_input)
843 ++old_input_device_size; 854 ++old_input_device_size;
844 else 855 else
845 ++old_output_device_size; 856 ++old_output_device_size;
846 } 857 }
847 858
848 AudioNodeList hotplug_output_nodes; 859 AudioDevicePriorityQueue hotplug_output_nodes;
849 AudioNodeList hotplug_input_nodes; 860 AudioDevicePriorityQueue hotplug_input_nodes;
850 bool output_devices_changed = 861 bool output_devices_changed =
851 HasDeviceChange(nodes, false, &hotplug_output_nodes); 862 HasDeviceChange(nodes, false, &hotplug_output_nodes);
852 bool input_devices_changed = 863 bool input_devices_changed =
853 HasDeviceChange(nodes, true, &hotplug_input_nodes); 864 HasDeviceChange(nodes, true, &hotplug_input_nodes);
854 audio_devices_.clear(); 865 audio_devices_.clear();
855 has_alternative_input_ = false; 866 has_alternative_input_ = false;
856 has_alternative_output_ = false; 867 has_alternative_output_ = false;
857 868
858 while (!input_devices_pq_.empty()) 869 while (!input_devices_pq_.empty())
859 input_devices_pq_.pop(); 870 input_devices_pq_.pop();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 // See crbug.com/478968. 902 // See crbug.com/478968.
892 const AudioDevice* active_output = GetDeviceFromId(active_output_node_id_); 903 const AudioDevice* active_output = GetDeviceFromId(active_output_node_id_);
893 if (!active_output || !active_output->active) 904 if (!active_output || !active_output->active)
894 active_output_node_id_ = 0; 905 active_output_node_id_ = 0;
895 const AudioDevice* active_input = GetDeviceFromId(active_input_node_id_); 906 const AudioDevice* active_input = GetDeviceFromId(active_input_node_id_);
896 if (!active_input || !active_input->active) 907 if (!active_input || !active_input->active)
897 active_input_node_id_ = 0; 908 active_input_node_id_ = 0;
898 909
899 // If audio nodes change is caused by unplugging some non-active audio 910 // If audio nodes change is caused by unplugging some non-active audio
900 // devices, the previously set active audio device will stay active. 911 // devices, the previously set active audio device will stay active.
901 // Otherwise, switch to a new active audio device according to their priority. 912 // Otherwise, switch to a new active audio device according to their priority.
jennyz 2015/12/17 22:50:21 The comments for how the active audio device is se
hychao 2015/12/29 10:57:25 Done.
902 if (input_devices_changed && 913 if (input_devices_changed &&
903 !NonActiveDeviceUnplugged(old_input_device_size, 914 !NonActiveDeviceUnplugged(old_input_device_size,
904 new_input_device_size, 915 new_input_device_size,
905 active_input_node_id_)) { 916 active_input_node_id_)) {
906 // Some devices like chromeboxes don't have the internal audio input. In 917 // Some devices like chromeboxes don't have the internal audio input. In
907 // that case the active input node id should be reset. 918 // that case the active input node id should be reset.
908 if (input_devices_pq_.empty()) { 919 if (input_devices_pq_.empty()) {
909 active_input_node_id_ = 0; 920 active_input_node_id_ = 0;
910 NotifyActiveNodeChanged(true); 921 NotifyActiveNodeChanged(true);
911 } else { 922 } else {
912 // If user has hot plugged a new node, we should change to the active 923 // If user has hot plugged a new node, we should change to the active
913 // device to the new node if it has the highest priority; otherwise, 924 // device to the new node if (1) it has the highest priority; or (2)
914 // we should keep the existing active node chosen by user. 925 // the last state before it hot plugged was active; otherwise, we should
926 // keep the existing active node chosen by user.
915 // For all other cases, we will choose the node with highest priority. 927 // For all other cases, we will choose the node with highest priority.
jennyz 2015/12/17 22:50:21 How about change this as: If there is no current a
hychao 2015/12/29 10:57:25 Done.
916 if (!active_input_node_id_ || hotplug_input_nodes.empty() || 928 if (!active_input_node_id_ || hotplug_input_nodes.empty()) {
917 IsNodeInTheList(input_devices_pq_.top().id, hotplug_input_nodes)) {
918 SwitchToDevice(input_devices_pq_.top(), true); 929 SwitchToDevice(input_devices_pq_.top(), true);
930 } else {
jennyz 2015/12/17 22:50:21 How about comment like this: If user has hot plugg
hychao 2015/12/29 10:57:25 Thanks for the suggestion. I broke down and moved
931 AudioDeviceState last_state =
932 audio_pref_handler_->GetDeviceState(hotplug_input_nodes.top());
933 switch (last_state) {
934 case AUDIO_STATE_ACTIVE:
935 SwitchToDevice(hotplug_input_nodes.top(), true);
936 break;
937 case AUDIO_STATE_NOT_AVAILABLE:
jennyz 2015/12/17 22:50:21 This is the case if the device is new, not plugged
hychao 2015/12/29 10:57:25 Done.
938 if (input_devices_pq_.top().id == hotplug_input_nodes.top().id)
939 SwitchToDevice(hotplug_input_nodes.top(), true);
940 break;
941 case AUDIO_STATE_INACTIVE:
jennyz 2015/12/17 22:50:21 No need to add this line, it should fall into defa
hychao 2015/12/29 10:57:25 Thanks for reminding. I think its useful to keep t
942 default:
943 break;
944 }
919 } 945 }
920 } 946 }
921 } 947 }
922 if (output_devices_changed && 948 if (output_devices_changed &&
923 !NonActiveDeviceUnplugged(old_output_device_size, 949 !NonActiveDeviceUnplugged(old_output_device_size,
924 new_output_device_size, 950 new_output_device_size,
925 active_output_node_id_)) { 951 active_output_node_id_)) {
926 // This is really unlikely to happen because all ChromeOS devices have the 952 // This is really unlikely to happen because all ChromeOS devices have the
927 // internal audio output. 953 // internal audio output.
jennyz 2015/12/17 22:50:21 gitto input nodes logic.
hychao 2015/12/29 10:57:25 Done.
928 if (output_devices_pq_.empty()) { 954 if (output_devices_pq_.empty()) {
929 active_output_node_id_ = 0; 955 active_output_node_id_ = 0;
930 NotifyActiveNodeChanged(false); 956 NotifyActiveNodeChanged(false);
931 } else { 957 } else {
932 // ditto input node case. 958 // ditto input node case.
933 if (!active_output_node_id_ || hotplug_output_nodes.empty() || 959 if (!active_output_node_id_ || hotplug_output_nodes.empty()) {
934 IsNodeInTheList(output_devices_pq_.top().id, hotplug_output_nodes)) {
935 SwitchToDevice(output_devices_pq_.top(), true); 960 SwitchToDevice(output_devices_pq_.top(), true);
961 } else {
962 AudioDeviceState last_state =
963 audio_pref_handler_->GetDeviceState(hotplug_output_nodes.top());
964 switch (last_state) {
965 case AUDIO_STATE_ACTIVE:
966 SwitchToDevice(hotplug_output_nodes.top(), true);
967 break;
968 case AUDIO_STATE_NOT_AVAILABLE:
969 if (output_devices_pq_.top().id == hotplug_output_nodes.top().id)
970 SwitchToDevice(hotplug_output_nodes.top(), true);
971 break;
972 case AUDIO_STATE_INACTIVE:
jennyz 2015/12/17 22:50:21 ditto
hychao 2015/12/29 10:57:25 Although the comments are not copied over, I keep
973 default:
974 break;
975 }
936 } 976 }
937 } 977 }
938 } 978 }
939 } 979 }
940 980
941 void CrasAudioHandler::HandleGetNodes(const chromeos::AudioNodeList& node_list, 981 void CrasAudioHandler::HandleGetNodes(const chromeos::AudioNodeList& node_list,
942 bool success) { 982 bool success) {
943 if (!success) { 983 if (!success) {
944 LOG_IF(ERROR, log_errors_) << "Failed to retrieve audio nodes data"; 984 LOG_IF(ERROR, log_errors_) << "Failed to retrieve audio nodes data";
945 return; 985 return;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 hdmi_rediscover_grace_period_duration_in_ms_), 1080 hdmi_rediscover_grace_period_duration_in_ms_),
1041 this, &CrasAudioHandler::UpdateAudioAfterHDMIRediscoverGracePeriod); 1081 this, &CrasAudioHandler::UpdateAudioAfterHDMIRediscoverGracePeriod);
1042 } 1082 }
1043 1083
1044 void CrasAudioHandler::SetHDMIRediscoverGracePeriodForTesting( 1084 void CrasAudioHandler::SetHDMIRediscoverGracePeriodForTesting(
1045 int duration_in_ms) { 1085 int duration_in_ms) {
1046 hdmi_rediscover_grace_period_duration_in_ms_ = duration_in_ms; 1086 hdmi_rediscover_grace_period_duration_in_ms_ = duration_in_ms;
1047 } 1087 }
1048 1088
1049 } // namespace chromeos 1089 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698