Home | History | Annotate | Download | only in audio
      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