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 3 // found in the LICENSE file. 4 5 #ifndef CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_ 6 #define CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_ 7 8 #include <queue> 9 10 #include "base/basictypes.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/weak_ptr.h" 13 #include "base/observer_list.h" 14 #include "chromeos/audio/audio_device.h" 15 #include "chromeos/audio/audio_pref_observer.h" 16 #include "chromeos/dbus/audio_node.h" 17 #include "chromeos/dbus/cras_audio_client.h" 18 #include "chromeos/dbus/session_manager_client.h" 19 #include "chromeos/dbus/volume_state.h" 20 21 class PrefRegistrySimple; 22 class PrefService; 23 24 namespace chromeos { 25 26 class AudioDevicesPrefHandler; 27 28 class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer, 29 public AudioPrefObserver, 30 public SessionManagerClient::Observer { 31 public: 32 typedef std::priority_queue<AudioDevice, 33 std::vector<AudioDevice>, 34 AudioDeviceCompare> AudioDevicePriorityQueue; 35 36 class AudioObserver { 37 public: 38 // Called when output volume changed. 39 virtual void OnOutputVolumeChanged(); 40 41 // Called when output mute state changed. 42 virtual void OnOutputMuteChanged(); 43 44 // Called when input mute state changed. 45 virtual void OnInputGainChanged(); 46 47 // Called when input mute state changed. 48 virtual void OnInputMuteChanged(); 49 50 // Called when audio nodes changed. 51 virtual void OnAudioNodesChanged(); 52 53 // Called when active audio node changed. 54 virtual void OnActiveOutputNodeChanged(); 55 56 // Called when active audio input node changed. 57 virtual void OnActiveInputNodeChanged(); 58 59 protected: 60 AudioObserver(); 61 virtual ~AudioObserver(); 62 DISALLOW_COPY_AND_ASSIGN(AudioObserver); 63 }; 64 65 // Sets the global instance. Must be called before any calls to Get(). 66 static void Initialize( 67 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); 68 69 // Sets the global instance for testing. 70 static void InitializeForTesting(); 71 72 // Destroys the global instance. 73 static void Shutdown(); 74 75 // Returns true if the global instance is initialized. 76 static bool IsInitialized(); 77 78 // Gets the global instance. Initialize must be called first. 79 static CrasAudioHandler* Get(); 80 81 // Adds an audio observer. 82 virtual void AddAudioObserver(AudioObserver* observer); 83 84 // Removes an audio observer. 85 virtual void RemoveAudioObserver(AudioObserver* observer); 86 87 // Returns true if audio output is muted. 88 virtual bool IsOutputMuted(); 89 90 // Returns true if audio output is muted for a device. 91 virtual bool IsOutputMutedForDevice(uint64 device_id); 92 93 // Returns true if audio input is muted. 94 virtual bool IsInputMuted(); 95 96 // Returns true if audio input is muted for a device. 97 virtual bool IsInputMutedForDevice(uint64 device_id); 98 99 // Returns true if the output volume is below the default mute volume level. 100 virtual bool IsOutputVolumeBelowDefaultMuteLvel(); 101 102 // Gets volume level in 0-100% range (0 being pure silence) for the current 103 // active node. 104 virtual int GetOutputVolumePercent(); 105 106 // Gets volume level in 0-100% range (0 being pure silence) for a device. 107 virtual int GetOutputVolumePercentForDevice(uint64 device_id); 108 109 // Gets gain level in 0-100% range (0 being pure silence) for the current 110 // active node. 111 virtual int GetInputGainPercent(); 112 113 // Gets volume level in 0-100% range (0 being pure silence) for a device. 114 virtual int GetInputGainPercentForDevice(uint64 device_id); 115 116 // Returns node_id of the active output node. 117 virtual uint64 GetActiveOutputNode() const; 118 119 // Returns the node_id of the active input node. 120 virtual uint64 GetActiveInputNode() const; 121 122 // Gets the audio devices back in |device_list|. 123 virtual void GetAudioDevices(AudioDeviceList* device_list) const; 124 125 virtual bool GetActiveOutputDevice(AudioDevice* device) const; 126 127 // Whether there is alternative input/output audio device. 128 virtual bool has_alternative_input() const; 129 virtual bool has_alternative_output() const; 130 131 // Sets volume level to |volume_percent|, whose range is from 0-100%. 132 virtual void SetOutputVolumePercent(int volume_percent); 133 134 // Sets gain level to |gain_percent|, whose range is from 0-100%. 135 virtual void SetInputGainPercent(int gain_percent); 136 137 // Adjusts volume up (positive percentage) or down (negative percentage). 138 virtual void AdjustOutputVolumeByPercent(int adjust_by_percent); 139 140 // Adjusts output volume to a minimum audible level if it is too low. 141 virtual void AdjustOutputVolumeToAudibleLevel(); 142 143 // Mutes or unmutes audio output device. 144 virtual void SetOutputMute(bool mute_on); 145 146 // Mutes or unmutes audio input device. 147 virtual void SetInputMute(bool mute_on); 148 149 // Switches active audio device to |device|. 150 virtual void SwitchToDevice(const AudioDevice& device); 151 152 // Sets volume/gain level for a device. 153 virtual void SetVolumeGainPercentForDevice(uint64 device_id, int value); 154 155 // Sets the mute for device. 156 virtual void SetMuteForDevice(uint64 device_id, bool mute_on); 157 158 // Enables error logging. 159 virtual void LogErrors(); 160 161 protected: 162 explicit CrasAudioHandler( 163 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); 164 virtual ~CrasAudioHandler(); 165 166 private: 167 // CrasAudioClient::Observer overrides. 168 virtual void AudioClientRestarted() OVERRIDE; 169 virtual void NodesChanged() OVERRIDE; 170 virtual void ActiveOutputNodeChanged(uint64 node_id) OVERRIDE; 171 virtual void ActiveInputNodeChanged(uint64 node_id) OVERRIDE; 172 173 // AudioPrefObserver overrides. 174 virtual void OnAudioPolicyPrefChanged() OVERRIDE; 175 176 // SessionManagerClient::Observer overrides. 177 virtual void EmitLoginPromptVisibleCalled() OVERRIDE; 178 179 // Sets the active audio output/input node to the node with |node_id|. 180 void SetActiveOutputNode(uint64 node_id); 181 void SetActiveInputNode(uint64 node_id); 182 183 // Sets up the audio device state based on audio policy and audio settings 184 // saved in prefs. 185 void SetupAudioInputState(); 186 void SetupAudioOutputState(); 187 188 const AudioDevice* GetDeviceFromId(uint64 device_id) const; 189 190 // Initializes audio state, which should only be called when CrasAudioHandler 191 // is created or cras audio client is restarted. 192 void InitializeAudioState(); 193 194 // Applies the audio muting policies whenever the user logs in or policy 195 // change notification is received. 196 void ApplyAudioPolicy(); 197 198 // Sets output volume of |node_id| to |volume|. 199 void SetOutputNodeVolume(uint64 node_id, int volume); 200 201 // Sets output mute state to |mute_on| internally, returns true if output mute 202 // is set. 203 bool SetOutputMuteInternal(bool mute_on); 204 205 // Sets input gain of |node_id| to |gain|. 206 void SetInputNodeGain(uint64 node_id, int gain); 207 208 // Sets input mute state to |mute_on| internally, returns true if input mute 209 // is set. 210 bool SetInputMuteInternal(bool mute_on); 211 212 // Calling dbus to get nodes data. 213 void GetNodes(); 214 215 // Updates the current audio nodes list and switches the active device 216 // if needed. 217 void UpdateDevicesAndSwitchActive(const AudioNodeList& nodes); 218 219 // Returns true if *|current_active_node_id| device is changed to 220 // |new_active_device|. 221 bool ChangeActiveDevice(const AudioDevice& new_active_device, 222 uint64* current_active_node_id); 223 224 // Returns true if the audio nodes change is caused by some non-active 225 // audio nodes unplugged. 226 bool NonActiveDeviceUnplugged(size_t old_devices_size, 227 size_t new_device_size, 228 uint64 current_active_node); 229 230 // Returns true if there is any device change for for input or output, 231 // specified by |is_input|. 232 bool HasDeviceChange(const AudioNodeList& new_nodes, bool is_input); 233 234 // Handles dbus callback for GetNodes. 235 void HandleGetNodes(const chromeos::AudioNodeList& node_list, bool success); 236 237 // Handles the dbus error callback. 238 void HandleGetNodesError(const std::string& error_name, 239 const std::string& error_msg); 240 241 // Returns true if |device| is not found in audio_devices_. 242 bool FoundNewDevice(const AudioDevice& device); 243 244 // Returns a sanitized AudioDevice from |node|. 245 AudioDevice GetSanitizedAudioDevice(const AudioNode& node); 246 247 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler_; 248 base::WeakPtrFactory<CrasAudioHandler> weak_ptr_factory_; 249 ObserverList<AudioObserver> observers_; 250 251 // Audio data and state. 252 AudioDeviceMap audio_devices_; 253 254 AudioDevicePriorityQueue input_devices_pq_; 255 AudioDevicePriorityQueue output_devices_pq_; 256 257 bool output_mute_on_; 258 bool input_mute_on_; 259 int output_volume_; 260 int input_gain_; 261 uint64 active_output_node_id_; 262 uint64 active_input_node_id_; 263 bool has_alternative_input_; 264 bool has_alternative_output_; 265 266 bool output_mute_locked_; 267 bool input_mute_locked_; 268 269 // Failures are not logged at startup, since CRAS may not be running yet. 270 bool log_errors_; 271 272 DISALLOW_COPY_AND_ASSIGN(CrasAudioHandler); 273 }; 274 275 } // namespace chromeos 276 277 #endif // CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_ 278