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 typedef std::vector<uint64> NodeIdList; 36 37 class AudioObserver { 38 public: 39 // Called when output volume changed. 40 virtual void OnOutputVolumeChanged(); 41 42 // Called when output mute state changed. 43 virtual void OnOutputMuteChanged(); 44 45 // Called when input mute state changed. 46 virtual void OnInputGainChanged(); 47 48 // Called when input mute state changed. 49 virtual void OnInputMuteChanged(); 50 51 // Called when audio nodes changed. 52 virtual void OnAudioNodesChanged(); 53 54 // Called when active audio node changed. 55 virtual void OnActiveOutputNodeChanged(); 56 57 // Called when active audio input node changed. 58 virtual void OnActiveInputNodeChanged(); 59 60 protected: 61 AudioObserver(); 62 virtual ~AudioObserver(); 63 DISALLOW_COPY_AND_ASSIGN(AudioObserver); 64 }; 65 66 // Sets the global instance. Must be called before any calls to Get(). 67 static void Initialize( 68 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); 69 70 // Sets the global instance for testing. 71 static void InitializeForTesting(); 72 73 // Destroys the global instance. 74 static void Shutdown(); 75 76 // Returns true if the global instance is initialized. 77 static bool IsInitialized(); 78 79 // Gets the global instance. Initialize must be called first. 80 static CrasAudioHandler* Get(); 81 82 // Adds an audio observer. 83 virtual void AddAudioObserver(AudioObserver* observer); 84 85 // Removes an audio observer. 86 virtual void RemoveAudioObserver(AudioObserver* observer); 87 88 // Returns true if keyboard mic exists. 89 virtual bool HasKeyboardMic(); 90 91 // Returns true if audio output is muted for the system. 92 virtual bool IsOutputMuted(); 93 94 // Returns true if audio output is muted for a device. 95 virtual bool IsOutputMutedForDevice(uint64 device_id); 96 97 // Returns true if audio input is muted. 98 virtual bool IsInputMuted(); 99 100 // Returns true if audio input is muted for a device. 101 virtual bool IsInputMutedForDevice(uint64 device_id); 102 103 // Returns true if the output volume is below the default mute volume level. 104 virtual bool IsOutputVolumeBelowDefaultMuteLevel(); 105 106 // Returns volume level in 0-100% range at which the volume should be muted. 107 virtual int GetOutputDefaultVolumeMuteThreshold(); 108 109 // Gets volume level in 0-100% range (0 being pure silence) for the current 110 // active node. 111 virtual int GetOutputVolumePercent(); 112 113 // Gets volume level in 0-100% range (0 being pure silence) for a device. 114 virtual int GetOutputVolumePercentForDevice(uint64 device_id); 115 116 // Gets gain level in 0-100% range (0 being pure silence) for the current 117 // active node. 118 virtual int GetInputGainPercent(); 119 120 // Gets volume level in 0-100% range (0 being pure silence) for a device. 121 virtual int GetInputGainPercentForDevice(uint64 device_id); 122 123 // Returns node_id of the primary active output node. 124 virtual uint64 GetPrimaryActiveOutputNode() const; 125 126 // Returns the node_id of the primary active input node. 127 virtual uint64 GetPrimaryActiveInputNode() const; 128 129 // Gets the audio devices back in |device_list|. 130 virtual void GetAudioDevices(AudioDeviceList* device_list) const; 131 132 virtual bool GetPrimaryActiveOutputDevice(AudioDevice* device) const; 133 134 // Whether there is alternative input/output audio device. 135 virtual bool has_alternative_input() const; 136 virtual bool has_alternative_output() const; 137 138 // Sets all active output devices' volume level to |volume_percent|, whose 139 // range is from 0-100%. 140 virtual void SetOutputVolumePercent(int volume_percent); 141 142 // Sets all active input devices' gain level to |gain_percent|, whose range is 143 // from 0-100%. 144 virtual void SetInputGainPercent(int gain_percent); 145 146 // Adjusts all active output devices' volume up (positive percentage) or down 147 // (negative percentage). 148 virtual void AdjustOutputVolumeByPercent(int adjust_by_percent); 149 150 // Adjusts all active output devices' volume to a minimum audible level if it 151 // is too low. 152 virtual void AdjustOutputVolumeToAudibleLevel(); 153 154 // Mutes or unmutes audio output device. 155 virtual void SetOutputMute(bool mute_on); 156 157 // Mutes or unmutes audio input device. 158 virtual void SetInputMute(bool mute_on); 159 160 // Switches active audio device to |device|. 161 virtual void SwitchToDevice(const AudioDevice& device, bool notify); 162 163 // Sets volume/gain level for a device. 164 virtual void SetVolumeGainPercentForDevice(uint64 device_id, int value); 165 166 // Sets the mute for device. 167 virtual void SetMuteForDevice(uint64 device_id, bool mute_on); 168 169 // Activates or deactivates keyboard mic if there's one. 170 virtual void SetKeyboardMicActive(bool active); 171 172 // Changes the active nodes to the nodes specified by |new_active_ids|. 173 // The caller can pass in the "complete" active node list of either input 174 // nodes, or output nodes, or both. If only input nodes are passed in, 175 // it will only change the input nodes' active status, output nodes will NOT 176 // be changed; similarly for the case if only output nodes are passed. 177 // If the nodes specified in |new_active_ids| are already active, they will 178 // remain active. Otherwise, the old active nodes will be de-activated before 179 // we activate the new nodes with the same type(input/output). 180 virtual void ChangeActiveNodes(const NodeIdList& new_active_ids); 181 182 // Enables error logging. 183 virtual void LogErrors(); 184 185 protected: 186 explicit CrasAudioHandler( 187 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); 188 virtual ~CrasAudioHandler(); 189 190 private: 191 friend class CrasAudioHandlerTest; 192 193 // CrasAudioClient::Observer overrides. 194 virtual void AudioClientRestarted() OVERRIDE; 195 virtual void NodesChanged() OVERRIDE; 196 virtual void ActiveOutputNodeChanged(uint64 node_id) OVERRIDE; 197 virtual void ActiveInputNodeChanged(uint64 node_id) OVERRIDE; 198 199 // AudioPrefObserver overrides. 200 virtual void OnAudioPolicyPrefChanged() OVERRIDE; 201 202 // SessionManagerClient::Observer overrides. 203 virtual void EmitLoginPromptVisibleCalled() OVERRIDE; 204 205 // Sets the active audio output/input node to the node with |node_id|. 206 // If |notify|, notifies Active*NodeChange. 207 void SetActiveOutputNode(uint64 node_id, bool notify); 208 void SetActiveInputNode(uint64 node_id, bool notify); 209 210 // Sets up the audio device state based on audio policy and audio settings 211 // saved in prefs. 212 void SetupAudioInputState(); 213 void SetupAudioOutputState(); 214 215 // Sets up the additional active audio node's state. 216 void SetupAdditionalActiveAudioNodeState(uint64 node_id); 217 218 const AudioDevice* GetDeviceFromId(uint64 device_id) const; 219 const AudioDevice* GetKeyboardMic() const; 220 221 // Initializes audio state, which should only be called when CrasAudioHandler 222 // is created or cras audio client is restarted. 223 void InitializeAudioState(); 224 225 // Applies the audio muting policies whenever the user logs in or policy 226 // change notification is received. 227 void ApplyAudioPolicy(); 228 229 // Sets output volume of |node_id| to |volume|. 230 void SetOutputNodeVolume(uint64 node_id, int volume); 231 232 void SetOutputNodeVolumePercent(uint64 node_id, int volume_percent); 233 234 // Sets output mute state to |mute_on| internally, returns true if output mute 235 // is set. 236 bool SetOutputMuteInternal(bool mute_on); 237 238 // Sets input gain of |node_id| to |gain|. 239 void SetInputNodeGain(uint64 node_id, int gain); 240 241 void SetInputNodeGainPercent(uint64 node_id, int gain_percent); 242 243 // Sets input mute state to |mute_on| internally, returns true if input mute 244 // is set. 245 bool SetInputMuteInternal(bool mute_on); 246 247 // Calling dbus to get nodes data. 248 void GetNodes(); 249 250 // Updates the current audio nodes list and switches the active device 251 // if needed. 252 void UpdateDevicesAndSwitchActive(const AudioNodeList& nodes); 253 254 // Returns true if *|current_active_node_id| device is changed to 255 // |new_active_device|. 256 bool ChangeActiveDevice(const AudioDevice& new_active_device, 257 uint64* current_active_node_id); 258 259 // Returns true if the audio nodes change is caused by some non-active 260 // audio nodes unplugged. 261 bool NonActiveDeviceUnplugged(size_t old_devices_size, 262 size_t new_device_size, 263 uint64 current_active_node); 264 265 // Returns true if there is any device change for for input or output, 266 // specified by |is_input|. 267 bool HasDeviceChange(const AudioNodeList& new_nodes, bool is_input); 268 269 // Handles dbus callback for GetNodes. 270 void HandleGetNodes(const chromeos::AudioNodeList& node_list, bool success); 271 272 // Handles the dbus error callback. 273 void HandleGetNodesError(const std::string& error_name, 274 const std::string& error_msg); 275 276 // Adds an active node. 277 // If there is no active node, |node_id| will be switched to become the 278 // primary active node. Otherwise, it will be added as an additional active 279 // node. 280 void AddActiveNode(uint64 node_id, bool notify); 281 282 // Adds |node_id| into additional active nodes. 283 void AddAdditionalActiveNode(uint64 node_id, bool notify); 284 285 // Removes |node_id| from additional active nodes. 286 void RemoveActiveNodeInternal(uint64 node_id, bool notify); 287 288 // Returns true if |device| is not found in audio_devices_, or it is found 289 // but changed its |active| property. 290 bool FoundNewOrChangedDevice(const AudioDevice& device); 291 292 void NotifyActiveNodeChanged(bool is_input); 293 294 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler_; 295 ObserverList<AudioObserver> observers_; 296 297 // Audio data and state. 298 AudioDeviceMap audio_devices_; 299 300 AudioDevicePriorityQueue input_devices_pq_; 301 AudioDevicePriorityQueue output_devices_pq_; 302 303 bool output_mute_on_; 304 bool input_mute_on_; 305 int output_volume_; 306 int input_gain_; 307 uint64 active_output_node_id_; 308 uint64 active_input_node_id_; 309 bool has_alternative_input_; 310 bool has_alternative_output_; 311 312 bool output_mute_locked_; 313 bool input_mute_locked_; 314 315 // Failures are not logged at startup, since CRAS may not be running yet. 316 bool log_errors_; 317 318 base::WeakPtrFactory<CrasAudioHandler> weak_ptr_factory_; 319 320 DISALLOW_COPY_AND_ASSIGN(CrasAudioHandler); 321 }; 322 323 } // namespace chromeos 324 325 #endif // CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_ 326