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