cras_audio_handler.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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 21class PrefRegistrySimple; 22class PrefService; 23 24namespace chromeos { 25 26class AudioDevicesPrefHandler; 27 28class 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 keyboard mic exists. 88 virtual bool HasKeyboardMic(); 89 90 // Returns true if audio output is muted for the system. 91 virtual bool IsOutputMuted(); 92 93 // Returns true if audio output is muted for a device. 94 virtual bool IsOutputMutedForDevice(uint64 device_id); 95 96 // Returns true if audio input is muted. 97 virtual bool IsInputMuted(); 98 99 // Returns true if audio input is muted for a device. 100 virtual bool IsInputMutedForDevice(uint64 device_id); 101 102 // Returns true if the output volume is below the default mute volume level. 103 virtual bool IsOutputVolumeBelowDefaultMuteLevel(); 104 105 // Returns volume level in 0-100% range at which the volume should be muted. 106 virtual int GetOutputDefaultVolumeMuteThreshold(); 107 108 // Gets volume level in 0-100% range (0 being pure silence) for the current 109 // active node. 110 virtual int GetOutputVolumePercent(); 111 112 // Gets volume level in 0-100% range (0 being pure silence) for a device. 113 virtual int GetOutputVolumePercentForDevice(uint64 device_id); 114 115 // Gets gain level in 0-100% range (0 being pure silence) for the current 116 // active node. 117 virtual int GetInputGainPercent(); 118 119 // Gets volume level in 0-100% range (0 being pure silence) for a device. 120 virtual int GetInputGainPercentForDevice(uint64 device_id); 121 122 // Returns node_id of the primary active output node. 123 virtual uint64 GetPrimaryActiveOutputNode() const; 124 125 // Returns the node_id of the primary active input node. 126 virtual uint64 GetPrimaryActiveInputNode() const; 127 128 // Gets the audio devices back in |device_list|. 129 virtual void GetAudioDevices(AudioDeviceList* device_list) const; 130 131 virtual bool GetPrimaryActiveOutputDevice(AudioDevice* device) const; 132 133 // Whether there is alternative input/output audio device. 134 virtual bool has_alternative_input() const; 135 virtual bool has_alternative_output() const; 136 137 // Sets all active output devices' volume level to |volume_percent|, whose 138 // range is from 0-100%. 139 virtual void SetOutputVolumePercent(int volume_percent); 140 141 // Sets all active input devices' gain level to |gain_percent|, whose range is 142 // from 0-100%. 143 virtual void SetInputGainPercent(int gain_percent); 144 145 // Adjusts all active output devices' volume up (positive percentage) or down 146 // (negative percentage). 147 virtual void AdjustOutputVolumeByPercent(int adjust_by_percent); 148 149 // Adjusts all active output devices' volume to a minimum audible level if it 150 // is too low. 151 virtual void AdjustOutputVolumeToAudibleLevel(); 152 153 // Mutes or unmutes audio output device. 154 virtual void SetOutputMute(bool mute_on); 155 156 // Mutes or unmutes audio input device. 157 virtual void SetInputMute(bool mute_on); 158 159 // Switches active audio device to |device|. 160 virtual void SwitchToDevice(const AudioDevice& device); 161 162 // Sets volume/gain level for a device. 163 virtual void SetVolumeGainPercentForDevice(uint64 device_id, int value); 164 165 // Sets the mute for device. 166 virtual void SetMuteForDevice(uint64 device_id, bool mute_on); 167 168 // Activates or deactivates keyboard mic if there's one. 169 virtual void SetKeyboardMicActive(bool active); 170 171 // Adds an active node. 172 // If there is no active node, |node_id| will be switched to become the 173 // primary active node. Otherwise, it will be added as an additional active 174 // node. 175 virtual void AddActiveNode(uint64 node_id); 176 177 // Removes an active audio node. 178 // If |node_id| is the only active input/output node, or is an additional 179 // active input/output node, it will be removed and becomes inactive. 180 // Note: It is not proper call this api to remove the primary active node 181 // while there are additional active nodes. 182 virtual void RemoveActiveNode(uint64 node_id); 183 184 // Removes all active audio nodes, including the primary active ones. 185 virtual void RemoveAllActiveNodes(); 186 187 // Enables error logging. 188 virtual void LogErrors(); 189 190 protected: 191 explicit CrasAudioHandler( 192 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); 193 virtual ~CrasAudioHandler(); 194 195 private: 196 friend class CrasAudioHandlerTest; 197 198 // CrasAudioClient::Observer overrides. 199 virtual void AudioClientRestarted() OVERRIDE; 200 virtual void NodesChanged() OVERRIDE; 201 virtual void ActiveOutputNodeChanged(uint64 node_id) OVERRIDE; 202 virtual void ActiveInputNodeChanged(uint64 node_id) OVERRIDE; 203 204 // AudioPrefObserver overrides. 205 virtual void OnAudioPolicyPrefChanged() OVERRIDE; 206 207 // SessionManagerClient::Observer overrides. 208 virtual void EmitLoginPromptVisibleCalled() OVERRIDE; 209 210 // Sets the active audio output/input node to the node with |node_id|. 211 void SetActiveOutputNode(uint64 node_id); 212 void SetActiveInputNode(uint64 node_id); 213 214 // Sets up the audio device state based on audio policy and audio settings 215 // saved in prefs. 216 void SetupAudioInputState(); 217 void SetupAudioOutputState(); 218 219 // Sets up the additional active audio node's state. 220 void SetupAdditionalActiveAudioNodeState(uint64 node_id); 221 222 const AudioDevice* GetDeviceFromId(uint64 device_id) const; 223 const AudioDevice* GetKeyboardMic() const; 224 225 // Initializes audio state, which should only be called when CrasAudioHandler 226 // is created or cras audio client is restarted. 227 void InitializeAudioState(); 228 229 // Applies the audio muting policies whenever the user logs in or policy 230 // change notification is received. 231 void ApplyAudioPolicy(); 232 233 // Sets output volume of |node_id| to |volume|. 234 void SetOutputNodeVolume(uint64 node_id, int volume); 235 236 void SetOutputNodeVolumePercent(uint64 node_id, int volume_percent); 237 238 // Sets output mute state to |mute_on| internally, returns true if output mute 239 // is set. 240 bool SetOutputMuteInternal(bool mute_on); 241 242 // Sets input gain of |node_id| to |gain|. 243 void SetInputNodeGain(uint64 node_id, int gain); 244 245 void SetInputNodeGainPercent(uint64 node_id, int gain_percent); 246 247 // Sets input mute state to |mute_on| internally, returns true if input mute 248 // is set. 249 bool SetInputMuteInternal(bool mute_on); 250 251 // Calling dbus to get nodes data. 252 void GetNodes(); 253 254 // Updates the current audio nodes list and switches the active device 255 // if needed. 256 void UpdateDevicesAndSwitchActive(const AudioNodeList& nodes); 257 258 // Returns true if *|current_active_node_id| device is changed to 259 // |new_active_device|. 260 bool ChangeActiveDevice(const AudioDevice& new_active_device, 261 uint64* current_active_node_id); 262 263 // Returns true if the audio nodes change is caused by some non-active 264 // audio nodes unplugged. 265 bool NonActiveDeviceUnplugged(size_t old_devices_size, 266 size_t new_device_size, 267 uint64 current_active_node); 268 269 // Returns true if there is any device change for for input or output, 270 // specified by |is_input|. 271 bool HasDeviceChange(const AudioNodeList& new_nodes, bool is_input); 272 273 // Handles dbus callback for GetNodes. 274 void HandleGetNodes(const chromeos::AudioNodeList& node_list, bool success); 275 276 // Handles the dbus error callback. 277 void HandleGetNodesError(const std::string& error_name, 278 const std::string& error_msg); 279 280 // Adds |node_id| into additional active nodes. 281 void AddAdditionalActiveNode(uint64 node_id); 282 283 // Removes |node_id| from additional active nodes. 284 void RemoveActiveNodeInternal(uint64 node_id); 285 286 // Returns true if |device| is not found in audio_devices_, or it is found 287 // but changed its |active| property. 288 bool FoundNewOrChangedDevice(const AudioDevice& device); 289 290 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler_; 291 ObserverList<AudioObserver> observers_; 292 293 // Audio data and state. 294 AudioDeviceMap audio_devices_; 295 296 AudioDevicePriorityQueue input_devices_pq_; 297 AudioDevicePriorityQueue output_devices_pq_; 298 299 bool output_mute_on_; 300 bool input_mute_on_; 301 int output_volume_; 302 int input_gain_; 303 uint64 active_output_node_id_; 304 uint64 active_input_node_id_; 305 bool has_alternative_input_; 306 bool has_alternative_output_; 307 308 bool output_mute_locked_; 309 bool input_mute_locked_; 310 311 // Failures are not logged at startup, since CRAS may not be running yet. 312 bool log_errors_; 313 314 base::WeakPtrFactory<CrasAudioHandler> weak_ptr_factory_; 315 316 DISALLOW_COPY_AND_ASSIGN(CrasAudioHandler); 317}; 318 319} // namespace chromeos 320 321#endif // CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_ 322