Fix crash in SpeechRecognizerImpl introduced in AudioParams refactor.
[chromium-blink-merge.git] / chromeos / audio / cras_audio_handler.h
blob343fafd017c4e755168433aabe4b0fdf1f23c183
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.
5 #ifndef CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_
6 #define CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_
8 #include <stdint.h>
9 #include <queue>
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/observer_list.h"
14 #include "base/timer/timer.h"
15 #include "chromeos/audio/audio_device.h"
16 #include "chromeos/audio/audio_pref_observer.h"
17 #include "chromeos/dbus/audio_node.h"
18 #include "chromeos/dbus/cras_audio_client.h"
19 #include "chromeos/dbus/session_manager_client.h"
20 #include "chromeos/dbus/volume_state.h"
22 class PrefRegistrySimple;
23 class PrefService;
25 namespace chromeos {
27 class AudioDevicesPrefHandler;
29 class CHROMEOS_EXPORT CrasAudioHandler : public CrasAudioClient::Observer,
30 public AudioPrefObserver,
31 public SessionManagerClient::Observer {
32 public:
33 typedef std::priority_queue<AudioDevice,
34 std::vector<AudioDevice>,
35 AudioDeviceCompare> AudioDevicePriorityQueue;
36 typedef std::vector<uint64_t> NodeIdList;
38 class AudioObserver {
39 public:
40 // Called when an active output volume changed.
41 virtual void OnOutputNodeVolumeChanged(uint64_t node_id, int volume);
43 // Called when output mute state changed.
44 // |mute_on|: True if output is muted.
45 // |system_adjust|: True if the mute state is adjusted by the system
46 // automatically(i.e. not by user). UI should reflect the system's mute
47 // state, but it should not be too loud, e.g., the volume pop up window
48 // should not be triggered.
49 virtual void OnOutputMuteChanged(bool mute_on, bool system_adjust);
51 // Called when active input node's gain changed.
52 virtual void OnInputNodeGainChanged(uint64_t node_id, int gain);
54 // Called when input mute state changed.
55 virtual void OnInputMuteChanged(bool mute_on);
57 // Called when audio nodes changed.
58 virtual void OnAudioNodesChanged();
60 // Called when active audio node changed.
61 virtual void OnActiveOutputNodeChanged();
63 // Called when active audio input node changed.
64 virtual void OnActiveInputNodeChanged();
66 protected:
67 AudioObserver();
68 virtual ~AudioObserver();
69 DISALLOW_COPY_AND_ASSIGN(AudioObserver);
72 // Sets the global instance. Must be called before any calls to Get().
73 static void Initialize(
74 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler);
76 // Sets the global instance for testing.
77 static void InitializeForTesting();
79 // Destroys the global instance.
80 static void Shutdown();
82 // Returns true if the global instance is initialized.
83 static bool IsInitialized();
85 // Gets the global instance. Initialize must be called first.
86 static CrasAudioHandler* Get();
88 // Adds an audio observer.
89 virtual void AddAudioObserver(AudioObserver* observer);
91 // Removes an audio observer.
92 virtual void RemoveAudioObserver(AudioObserver* observer);
94 // Returns true if keyboard mic exists.
95 virtual bool HasKeyboardMic();
97 // Returns true if audio output is muted for the system.
98 virtual bool IsOutputMuted();
100 // Returns true if audio output is muted for a device.
101 virtual bool IsOutputMutedForDevice(uint64_t device_id);
103 // Returns true if audio input is muted.
104 virtual bool IsInputMuted();
106 // Returns true if audio input is muted for a device.
107 virtual bool IsInputMutedForDevice(uint64_t device_id);
109 // Returns true if the output volume is below the default mute volume level.
110 virtual bool IsOutputVolumeBelowDefaultMuteLevel();
112 // Returns volume level in 0-100% range at which the volume should be muted.
113 virtual int GetOutputDefaultVolumeMuteThreshold();
115 // Gets volume level in 0-100% range (0 being pure silence) for the current
116 // active node.
117 virtual int GetOutputVolumePercent();
119 // Gets volume level in 0-100% range (0 being pure silence) for a device.
120 virtual int GetOutputVolumePercentForDevice(uint64_t device_id);
122 // Gets gain level in 0-100% range (0 being pure silence) for the current
123 // active node.
124 virtual int GetInputGainPercent();
126 // Gets volume level in 0-100% range (0 being pure silence) for a device.
127 virtual int GetInputGainPercentForDevice(uint64_t device_id);
129 // Returns node_id of the primary active output node.
130 virtual uint64_t GetPrimaryActiveOutputNode() const;
132 // Returns the node_id of the primary active input node.
133 virtual uint64_t GetPrimaryActiveInputNode() const;
135 // Gets the audio devices back in |device_list|.
136 // This call can be invoked from I/O thread or UI thread because
137 // it does not need to access CrasAudioClient on DBus.
138 virtual void GetAudioDevices(AudioDeviceList* device_list) const;
140 virtual bool GetPrimaryActiveOutputDevice(AudioDevice* device) const;
142 // Whether there is alternative input/output audio device.
143 virtual bool has_alternative_input() const;
144 virtual bool has_alternative_output() const;
146 // Sets all active output devices' volume level to |volume_percent|, whose
147 // range is from 0-100%.
148 virtual void SetOutputVolumePercent(int volume_percent);
150 // Sets all active input devices' gain level to |gain_percent|, whose range is
151 // from 0-100%.
152 virtual void SetInputGainPercent(int gain_percent);
154 // Adjusts all active output devices' volume up (positive percentage) or down
155 // (negative percentage).
156 virtual void AdjustOutputVolumeByPercent(int adjust_by_percent);
158 // Adjusts all active output devices' volume to a minimum audible level if it
159 // is too low.
160 virtual void AdjustOutputVolumeToAudibleLevel();
162 // Mutes or unmutes audio output device.
163 virtual void SetOutputMute(bool mute_on);
165 // Mutes or unmutes audio input device.
166 virtual void SetInputMute(bool mute_on);
168 // Switches active audio device to |device|.
169 virtual void SwitchToDevice(const AudioDevice& device, bool notify);
171 // Sets volume/gain level for a device.
172 virtual void SetVolumeGainPercentForDevice(uint64_t device_id, int value);
174 // Sets the mute for device.
175 virtual void SetMuteForDevice(uint64_t device_id, bool mute_on);
177 // Activates or deactivates keyboard mic if there's one.
178 virtual void SetKeyboardMicActive(bool active);
180 // Changes the active nodes to the nodes specified by |new_active_ids|.
181 // The caller can pass in the "complete" active node list of either input
182 // nodes, or output nodes, or both. If only input nodes are passed in,
183 // it will only change the input nodes' active status, output nodes will NOT
184 // be changed; similarly for the case if only output nodes are passed.
185 // If the nodes specified in |new_active_ids| are already active, they will
186 // remain active. Otherwise, the old active nodes will be de-activated before
187 // we activate the new nodes with the same type(input/output).
188 virtual void ChangeActiveNodes(const NodeIdList& new_active_ids);
190 // Swaps the left and right channel of the internal speaker.
191 // Swap the left and right channel if |swap| is true; otherwise, swap the left
192 // and right channel back to the normal mode.
193 // If the feature is not supported on the device, nothing happens.
194 virtual void SwapInternalSpeakerLeftRightChannel(bool swap);
196 // Enables error logging.
197 virtual void LogErrors();
199 // If necessary, sets the starting point for re-discovering the active HDMI
200 // output device caused by device entering/exiting docking mode, HDMI display
201 // changing resolution, or chromeos device suspend/resume. If
202 // |force_rediscovering| is true, it will force to set the starting point for
203 // re-discovering the active HDMI output device again if it has been in the
204 // middle of rediscovering the HDMI active output device.
205 virtual void SetActiveHDMIOutoutRediscoveringIfNecessary(
206 bool force_rediscovering);
208 protected:
209 explicit CrasAudioHandler(
210 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler);
211 ~CrasAudioHandler() override;
213 private:
214 friend class CrasAudioHandlerTest;
216 // CrasAudioClient::Observer overrides.
217 void AudioClientRestarted() override;
218 void NodesChanged() override;
219 void ActiveOutputNodeChanged(uint64_t node_id) override;
220 void ActiveInputNodeChanged(uint64_t node_id) override;
222 // AudioPrefObserver overrides.
223 void OnAudioPolicyPrefChanged() override;
225 // SessionManagerClient::Observer overrides.
226 void EmitLoginPromptVisibleCalled() override;
228 // Sets the active audio output/input node to the node with |node_id|.
229 // If |notify|, notifies Active*NodeChange.
230 void SetActiveOutputNode(uint64_t node_id, bool notify);
231 void SetActiveInputNode(uint64_t node_id, bool notify);
233 // Sets up the audio device state based on audio policy and audio settings
234 // saved in prefs.
235 void SetupAudioInputState();
236 void SetupAudioOutputState();
238 // Sets up the additional active audio node's state.
239 void SetupAdditionalActiveAudioNodeState(uint64_t node_id);
241 const AudioDevice* GetDeviceFromId(uint64_t device_id) const;
242 const AudioDevice* GetKeyboardMic() const;
244 // Initializes audio state, which should only be called when CrasAudioHandler
245 // is created or cras audio client is restarted.
246 void InitializeAudioState();
248 // Applies the audio muting policies whenever the user logs in or policy
249 // change notification is received.
250 void ApplyAudioPolicy();
252 // Sets output volume of |node_id| to |volume|.
253 void SetOutputNodeVolume(uint64_t node_id, int volume);
255 void SetOutputNodeVolumePercent(uint64_t node_id, int volume_percent);
257 // Sets output mute state to |mute_on| internally, returns true if output mute
258 // is set.
259 bool SetOutputMuteInternal(bool mute_on);
261 // Sets input gain of |node_id| to |gain|.
262 void SetInputNodeGain(uint64_t node_id, int gain);
264 void SetInputNodeGainPercent(uint64_t node_id, int gain_percent);
266 // Sets input mute state to |mute_on| internally.
267 void SetInputMuteInternal(bool mute_on);
269 // Calling dbus to get nodes data.
270 void GetNodes();
272 // Updates the current audio nodes list and switches the active device
273 // if needed.
274 void UpdateDevicesAndSwitchActive(const AudioNodeList& nodes);
276 // Returns true if *|current_active_node_id| device is changed to
277 // |new_active_device|.
278 bool ChangeActiveDevice(const AudioDevice& new_active_device,
279 uint64_t* current_active_node_id);
281 // Returns true if the audio nodes change is caused by some non-active
282 // audio nodes unplugged.
283 bool NonActiveDeviceUnplugged(size_t old_devices_size,
284 size_t new_device_size,
285 uint64_t current_active_node);
287 // Returns true if there is any device change for for input or output,
288 // specified by |is_input|.
289 // The new discovered nodes are returned in |new_discovered|.
290 bool HasDeviceChange(const AudioNodeList& new_nodes,
291 bool is_input,
292 AudioNodeList* new_discovered);
294 // Handles dbus callback for GetNodes.
295 void HandleGetNodes(const chromeos::AudioNodeList& node_list, bool success);
297 // Handles the dbus error callback.
298 void HandleGetNodesError(const std::string& error_name,
299 const std::string& error_msg);
301 // Adds an active node.
302 // If there is no active node, |node_id| will be switched to become the
303 // primary active node. Otherwise, it will be added as an additional active
304 // node.
305 void AddActiveNode(uint64_t node_id, bool notify);
307 // Adds |node_id| into additional active nodes.
308 void AddAdditionalActiveNode(uint64_t node_id, bool notify);
310 // Removes |node_id| from additional active nodes.
311 void RemoveActiveNodeInternal(uint64_t node_id, bool notify);
313 void UpdateAudioAfterHDMIRediscoverGracePeriod();
315 bool IsHDMIPrimaryOutputDevice() const;
317 void StartHDMIRediscoverGracePeriod();
319 bool hdmi_rediscovering() const { return hdmi_rediscovering_; }
321 void SetHDMIRediscoverGracePeriodForTesting(int duration_in_ms);
323 enum DeviceStatus {
324 OLD_DEVICE,
325 NEW_DEVICE,
326 CHANGED_DEVICE,
329 // Checks if |device| is a newly discovered, changed, or existing device for
330 // the nodes sent from NodesChanged signal.
331 DeviceStatus CheckDeviceStatus(const AudioDevice& device);
333 void NotifyActiveNodeChanged(bool is_input);
335 scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler_;
336 base::ObserverList<AudioObserver> observers_;
338 // Audio data and state.
339 AudioDeviceMap audio_devices_;
341 AudioDevicePriorityQueue input_devices_pq_;
342 AudioDevicePriorityQueue output_devices_pq_;
344 bool output_mute_on_;
345 bool input_mute_on_;
346 int output_volume_;
347 int input_gain_;
348 uint64_t active_output_node_id_;
349 uint64_t active_input_node_id_;
350 bool has_alternative_input_;
351 bool has_alternative_output_;
353 bool output_mute_locked_;
355 // Failures are not logged at startup, since CRAS may not be running yet.
356 bool log_errors_;
358 // Timer for HDMI re-discovering grace period.
359 base::OneShotTimer<CrasAudioHandler> hdmi_rediscover_timer_;
360 int hdmi_rediscover_grace_period_duration_in_ms_;
361 bool hdmi_rediscovering_;
363 base::WeakPtrFactory<CrasAudioHandler> weak_ptr_factory_;
365 DISALLOW_COPY_AND_ASSIGN(CrasAudioHandler);
368 } // namespace chromeos
370 #endif // CHROMEOS_AUDIO_CRAS_AUDIO_HANDLER_H_