• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   // Returns volume level in 0-100% range at which the volume should be muted.
103   virtual int GetOutputDefaultVolumeMuteThreshold();
104 
105   // Gets volume level in 0-100% range (0 being pure silence) for the current
106   // active node.
107   virtual int GetOutputVolumePercent();
108 
109   // Gets volume level in 0-100% range (0 being pure silence) for a device.
110   virtual int GetOutputVolumePercentForDevice(uint64 device_id);
111 
112   // Gets gain level in 0-100% range (0 being pure silence) for the current
113   // active node.
114   virtual int GetInputGainPercent();
115 
116   // Gets volume level in 0-100% range (0 being pure silence) for a device.
117   virtual int GetInputGainPercentForDevice(uint64 device_id);
118 
119   // Returns node_id of the active output node.
120   virtual uint64 GetActiveOutputNode() const;
121 
122   // Returns the node_id of the active input node.
123   virtual uint64 GetActiveInputNode() const;
124 
125   // Gets the audio devices back in |device_list|.
126   virtual void GetAudioDevices(AudioDeviceList* device_list) const;
127 
128   virtual bool GetActiveOutputDevice(AudioDevice* device) const;
129 
130   // Whether there is alternative input/output audio device.
131   virtual bool has_alternative_input() const;
132   virtual bool has_alternative_output() const;
133 
134   // Sets volume level to |volume_percent|, whose range is from 0-100%.
135   virtual void SetOutputVolumePercent(int volume_percent);
136 
137   // Sets gain level to |gain_percent|, whose range is from 0-100%.
138   virtual void SetInputGainPercent(int gain_percent);
139 
140   // Adjusts volume up (positive percentage) or down (negative percentage).
141   virtual void AdjustOutputVolumeByPercent(int adjust_by_percent);
142 
143   // Adjusts output volume to a minimum audible level if it is too low.
144   virtual void AdjustOutputVolumeToAudibleLevel();
145 
146   // Mutes or unmutes audio output device.
147   virtual void SetOutputMute(bool mute_on);
148 
149   // Mutes or unmutes audio input device.
150   virtual void SetInputMute(bool mute_on);
151 
152   // Switches active audio device to |device|.
153   virtual void SwitchToDevice(const AudioDevice& device);
154 
155   // Sets volume/gain level for a device.
156   virtual void SetVolumeGainPercentForDevice(uint64 device_id, int value);
157 
158   // Sets the mute for device.
159   virtual void SetMuteForDevice(uint64 device_id, bool mute_on);
160 
161   // Enables error logging.
162   virtual void LogErrors();
163 
164  protected:
165   explicit CrasAudioHandler(
166       scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler);
167   virtual ~CrasAudioHandler();
168 
169  private:
170   // CrasAudioClient::Observer overrides.
171   virtual void AudioClientRestarted() OVERRIDE;
172   virtual void NodesChanged() OVERRIDE;
173   virtual void ActiveOutputNodeChanged(uint64 node_id) OVERRIDE;
174   virtual void ActiveInputNodeChanged(uint64 node_id) OVERRIDE;
175 
176   // AudioPrefObserver overrides.
177   virtual void OnAudioPolicyPrefChanged() OVERRIDE;
178 
179   // SessionManagerClient::Observer overrides.
180   virtual void EmitLoginPromptVisibleCalled() OVERRIDE;
181 
182   // Sets the active audio output/input node to the node with |node_id|.
183   void SetActiveOutputNode(uint64 node_id);
184   void SetActiveInputNode(uint64 node_id);
185 
186   // Sets up the audio device state based on audio policy and audio settings
187   // saved in prefs.
188   void SetupAudioInputState();
189   void SetupAudioOutputState();
190 
191   const AudioDevice* GetDeviceFromId(uint64 device_id) const;
192 
193   // Initializes audio state, which should only be called when CrasAudioHandler
194   // is created or cras audio client is restarted.
195   void InitializeAudioState();
196 
197   // Applies the audio muting policies whenever the user logs in or policy
198   // change notification is received.
199   void ApplyAudioPolicy();
200 
201   // Sets output volume of |node_id| to |volume|.
202   void SetOutputNodeVolume(uint64 node_id, int volume);
203 
204   // Sets output mute state to |mute_on| internally, returns true if output mute
205   // is set.
206   bool SetOutputMuteInternal(bool mute_on);
207 
208   // Sets input gain of |node_id| to |gain|.
209   void SetInputNodeGain(uint64 node_id, int gain);
210 
211   // Sets input mute state to |mute_on| internally, returns true if input mute
212   // is set.
213   bool SetInputMuteInternal(bool mute_on);
214 
215   // Calling dbus to get nodes data.
216   void GetNodes();
217 
218   // Updates the current audio nodes list and switches the active device
219   // if needed.
220   void UpdateDevicesAndSwitchActive(const AudioNodeList& nodes);
221 
222   // Returns true if *|current_active_node_id| device is changed to
223   // |new_active_device|.
224   bool ChangeActiveDevice(const AudioDevice& new_active_device,
225                           uint64* current_active_node_id);
226 
227   // Returns true if the audio nodes change is caused by some non-active
228   // audio nodes unplugged.
229   bool NonActiveDeviceUnplugged(size_t old_devices_size,
230                                 size_t new_device_size,
231                                 uint64 current_active_node);
232 
233   // Returns true if there is any device change for for input or output,
234   // specified by |is_input|.
235   bool HasDeviceChange(const AudioNodeList& new_nodes, bool is_input);
236 
237   // Handles dbus callback for GetNodes.
238   void HandleGetNodes(const chromeos::AudioNodeList& node_list, bool success);
239 
240   // Handles the dbus error callback.
241   void HandleGetNodesError(const std::string& error_name,
242                            const std::string& error_msg);
243 
244   // Returns true if |device| is not found in audio_devices_.
245   bool FoundNewDevice(const AudioDevice& device);
246 
247   // Returns a sanitized AudioDevice from |node|.
248   AudioDevice GetSanitizedAudioDevice(const AudioNode& node);
249 
250   scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler_;
251   base::WeakPtrFactory<CrasAudioHandler> weak_ptr_factory_;
252   ObserverList<AudioObserver> observers_;
253 
254   // Audio data and state.
255   AudioDeviceMap audio_devices_;
256 
257   AudioDevicePriorityQueue input_devices_pq_;
258   AudioDevicePriorityQueue output_devices_pq_;
259 
260   bool output_mute_on_;
261   bool input_mute_on_;
262   int output_volume_;
263   int input_gain_;
264   uint64 active_output_node_id_;
265   uint64 active_input_node_id_;
266   bool has_alternative_input_;
267   bool has_alternative_output_;
268 
269   bool output_mute_locked_;
270   bool input_mute_locked_;
271 
272   // Failures are not logged at startup, since CRAS may not be running yet.
273   bool log_errors_;
274 
275   DISALLOW_COPY_AND_ASSIGN(CrasAudioHandler);
276 };
277 
278 }  // namespace chromeos
279 
280 #endif  // CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_
281