| // Copyright 2013 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROMEOS_ASH_COMPONENTS_AUDIO_CRAS_AUDIO_HANDLER_H_ |
| #define CHROMEOS_ASH_COMPONENTS_AUDIO_CRAS_AUDIO_HANDLER_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <cstdint> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include "base/component_export.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/observer_list.h" |
| #include "base/scoped_observation_traits.h" |
| #include "base/timer/timer.h" |
| #include "chromeos/ash/components/audio/audio_device.h" |
| #include "chromeos/ash/components/audio/audio_device_metrics_handler.h" |
| #include "chromeos/ash/components/audio/audio_devices_pref_handler.h" |
| #include "chromeos/ash/components/audio/audio_pref_observer.h" |
| #include "chromeos/ash/components/audio/audio_selection_notification_handler.h" |
| #include "chromeos/ash/components/audio/public/mojom/cros_audio_config.mojom-shared.h" |
| #include "chromeos/ash/components/dbus/audio/audio_node.h" |
| #include "chromeos/ash/components/dbus/audio/cras_audio_client.h" |
| #include "chromeos/ash/components/dbus/audio/fake_cras_audio_client.h" |
| #include "chromeos/ash/components/dbus/audio/voice_isolation_ui_appearance.h" |
| #include "chromeos/ash/components/dbus/audio/volume_state.h" |
| #include "media/base/video_facing.h" |
| #include "mojo/public/cpp/bindings/pending_remote.h" |
| #include "mojo/public/cpp/bindings/receiver.h" |
| #include "mojo/public/cpp/bindings/remote.h" |
| #include "services/media_session/public/mojom/media_controller.mojom.h" |
| #include "services/media_session/public/mojom/media_session.mojom.h" |
| #include "ui/events/devices/microphone_mute_switch_monitor.h" |
| |
| namespace base { |
| class SingleThreadTaskRunner; |
| } |
| |
| namespace ash { |
| |
| class AudioDevicesPrefHandler; |
| |
| // Callback to handle response of methods without result. |
| // |result| is true if the method call is successfully completed, otherwise |
| // false. |
| using VoidCrasAudioHandlerCallback = base::OnceCallback<void(bool result)>; |
| |
| // Callback to handle the dbus message for whether noise cancellation is |
| // supported by the board. |
| using OnNoiseCancellationSupportedCallback = base::OnceCallback<void()>; |
| |
| // Callback to handle the dbus message for whether style transfer is |
| // supported by the board. |
| using OnStyleTransferSupportedCallback = base::OnceCallback<void()>; |
| |
| // Callback to handle the dbus message for whether hfp_mic_sr is |
| // supported by the board. |
| using OnHfpMicSrSupportedCallback = base::OnceCallback<void()>; |
| |
| // Callback to handle the dbus message for whether spatial_audio is |
| // supported by the board. |
| using OnSpatialAudioSupportedCallback = base::OnceCallback<void()>; |
| |
| // This class is not thread safe. The public functions should be called on |
| // browser main thread. |
| class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_AUDIO) CrasAudioHandler |
| : public CrasAudioClient::Observer, |
| public ui::MicrophoneMuteSwitchMonitor::Observer, |
| public AudioPrefObserver, |
| public media::VideoCaptureObserver, |
| public media_session::mojom::MediaControllerObserver { |
| public: |
| typedef std::vector<uint64_t> NodeIdList; |
| |
| enum class SurveyType { |
| kGeneral, |
| kBluetooth, |
| kOutputProc, |
| }; |
| |
| static constexpr char kSurveyNameKey[] = "SurveyName"; |
| static constexpr char kSurveyNameGeneral[] = "GENERAL"; |
| static constexpr char kSurveyNameBluetooth[] = "BLUETOOTH"; |
| static constexpr char kSurveyNameOutputProc[] = "OUTPUTPROC"; |
| |
| // Key-value mapping type for audio survey specific data. |
| // For audio satisfaction survey, it contains |
| // - StreamType: Usage of the stream, e.g., multimedia. |
| // - ClientType: Client of the stream, e.g., Chrome or ARC++. |
| // - NodeType: Pair of the active input/output device types, e.g., USB_USB. |
| // The content can be extended when other types of survey is added. |
| typedef base::flat_map<std::string, std::string> AudioSurveyData; |
| class AudioSurvey { |
| public: |
| AudioSurvey(); |
| ~AudioSurvey(); |
| AudioSurvey(const AudioSurvey&) = delete; |
| AudioSurvey& operator=(const AudioSurvey&) = delete; |
| |
| SurveyType type() const { return type_; } |
| AudioSurveyData data() const { return data_; } |
| |
| void set_type(SurveyType type) { type_ = type; } |
| void clear_data() { data_.clear(); } |
| void AddData(std::string key, std::string value) { |
| data_.emplace(key, value); |
| } |
| |
| private: |
| SurveyType type_; |
| AudioSurveyData data_; |
| }; |
| |
| // A Delegate class to expose chrome browser functionality to ash. |
| class Delegate { |
| public: |
| Delegate() = default; |
| |
| Delegate(const Delegate&) = delete; |
| Delegate& operator=(const Delegate&) = delete; |
| |
| virtual ~Delegate() = default; |
| |
| // Opens the OS Settings audio page. |
| virtual void OpenSettingsAudioPage() const = 0; |
| }; |
| |
| static constexpr int32_t kSystemAecGroupIdNotAvailable = -1; |
| |
| // Grace period for removing notification. |
| static constexpr base::TimeDelta kRemoveNotificationDelay = |
| base::Milliseconds(5000); |
| |
| enum class InputMuteChangeMethod { |
| kKeyboardButton, |
| kPhysicalShutter, |
| kOther, |
| }; |
| |
| // This enum is used to record UMA histogram values and should not be |
| // reordered. Please keep in sync with `AudioSettingsChangeSource` in |
| // src/tools/metrics/histograms/enums.xml. |
| enum class AudioSettingsChangeSource { |
| kSystemTray = 0, |
| kOsSettings, |
| kAccelerator, |
| kVideoConferenceTray, |
| kMaxValue = kVideoConferenceTray, |
| }; |
| |
| static constexpr base::TimeDelta kMetricsDelayTimerInterval = |
| base::Seconds(2); |
| static constexpr char kForceRespectUiGainsHistogramName[] = |
| "Cras.ForceRespectUiGains"; |
| static constexpr char kInputGainChangedSourceHistogramName[] = |
| "Cras.InputGainChangedSource"; |
| static constexpr char kInputGainChangedHistogramName[] = |
| "Cras.InputGainChanged"; |
| static constexpr char kInputGainMuteSourceHistogramName[] = |
| "Cras.InputGainMutedSource"; |
| static constexpr char kOutputVolumeChangedSourceHistogramName[] = |
| "Cras.OutputVolumeChangedSource"; |
| static constexpr char kOutputVolumeMuteSourceHistogramName[] = |
| "Cras.OutputVolumeMutedSource"; |
| static constexpr char kNoiseCancellationEnabledSourceHistogramName[] = |
| "Cras.NoiseCancellationEnabledSource"; |
| static constexpr char kVoiceIsolationEnabledChangeSourceHistogramName[] = |
| "Cras.VoiceIsolationEnabledChangeSource"; |
| static constexpr char kVoiceIsolationPreferredEffectChangeHistogramName[] = |
| "Cras.VoiceIsolationPreferredEffectChange"; |
| static constexpr char kSpatialAudioHistogramName[] = "Cras.SpatialAudio"; |
| |
| class AudioObserver { |
| public: |
| AudioObserver(const AudioObserver&) = delete; |
| AudioObserver& operator=(const AudioObserver&) = delete; |
| |
| // Called when an active output volume changed. |
| virtual void OnOutputNodeVolumeChanged(uint64_t node_id, int volume); |
| |
| // Called when output mute state changed. |
| virtual void OnOutputMuteChanged(bool mute_on); |
| |
| // Called when active input node's gain changed. |
| virtual void OnInputNodeGainChanged(uint64_t node_id, int gain); |
| |
| // Called when input mute state changed. |
| virtual void OnInputMuteChanged(bool mute_on, InputMuteChangeMethod method); |
| |
| // Called when the state of input mute hw switch state changes. |
| virtual void OnInputMutedByMicrophoneMuteSwitchChanged(bool muted); |
| |
| // Called when the state of input mute by security curtain changes. |
| virtual void OnInputMutedBySecurityCurtainChanged(bool muted); |
| |
| // Called when audio nodes changed. |
| virtual void OnAudioNodesChanged(); |
| |
| // Called when active audio node changed. |
| virtual void OnActiveOutputNodeChanged(); |
| |
| // Called when active audio input node changed. |
| virtual void OnActiveInputNodeChanged(); |
| |
| // Called when output channel remixing changed. |
| virtual void OnOutputChannelRemixingChanged(bool mono_on); |
| |
| // Called when voice isolation UI appearance changed. |
| virtual void OnVoiceIsolationUIAppearanceChanged( |
| VoiceIsolationUIAppearance appearance); |
| |
| // Called when noise cancellation state changed. |
| virtual void OnNoiseCancellationStateChanged(); |
| |
| // Called when style transfer state changed. |
| virtual void OnStyleTransferStateChanged(); |
| |
| // Called when force respect ui gains state changed. |
| virtual void OnForceRespectUiGainsStateChanged(); |
| |
| // Called when hfp_mic_sr state changed. |
| virtual void OnHfpMicSrStateChanged(); |
| |
| // Called when hotword is detected. |
| virtual void OnHotwordTriggered(uint64_t tv_sec, uint64_t tv_nsec); |
| |
| // Called when spatial audio state changed. |
| virtual void OnSpatialAudioStateChanged(); |
| |
| // Called when the battery level change is reported over the Hands-Free |
| // Profile for a Bluetooth headset. |
| // The address is a Bluetooth address as 6 bytes written in hexadecimal and |
| // separated by colons. Example: 00:11:22:33:44:FF |
| // The level ranges from 0 to 100. Erroneous value reported by the headset |
| // will be ignored and won't trigger this callback. |
| virtual void OnBluetoothBatteryChanged(const std::string& address, |
| uint32_t level); |
| |
| // Called when the number of input streams with permission per client type |
| // changed. |
| virtual void OnNumberOfInputStreamsWithPermissionChanged(); |
| |
| // Called when an initial output stream is opened. |
| virtual void OnOutputStarted(); |
| |
| // Called when the last output stream is closed. |
| virtual void OnOutputStopped(); |
| |
| // Called when an initial output stream, not in chrome, is opened. |
| virtual void OnNonChromeOutputStarted(); |
| |
| // Called when the last output stream is closed, not in chrome. |
| virtual void OnNonChromeOutputStopped(); |
| |
| // Called when the audio survey like to trigger an audio survey. |
| // CRAS owns the trigger to send out an audio survey as opposed to trigger |
| // from any Chrome/UI elements as CRAS has the most context to determine |
| // when to sent out audio survey, for example when an input stream living |
| // for >= 30 seconds is closed. |
| // CRAS also has full control on what data to send to Chrome. These survey |
| // specific data will be attached with each survey response for analysis. |
| // Currently this supports general audio and Bluetooth audio surveys. |
| // The survey to trigger is determined by the type of the `AudioSurvey` |
| // passed in. |
| virtual void OnSurveyTriggered(const AudioSurvey& survey); |
| |
| // Called when a speak-on-mute is detected. |
| virtual void OnSpeakOnMuteDetected(); |
| |
| // Called when num-stream-ignore-ui-gains state is changed. |
| virtual void OnNumStreamIgnoreUiGainsChanged(int32_t num); |
| |
| // Called when number of ARC streams is changed. |
| virtual void OnNumberOfArcStreamsChanged(int32_t num); |
| |
| protected: |
| AudioObserver(); |
| virtual ~AudioObserver(); |
| }; |
| |
| enum class ClientType { |
| CHROME = 0, |
| ARC, |
| VM_TERMINA, |
| VM_PLUGIN, |
| VM_BOREALIS, |
| UNKNOWN, |
| }; |
| |
| // Sets the global instance. Must be called before any calls to Get(). |
| static void Initialize( |
| mojo::PendingRemote<media_session::mojom::MediaControllerManager> |
| media_controller_manager, |
| scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); |
| |
| // Same as Initialize function but also initializing a delegate class. |
| static void InitializeDelegate( |
| mojo::PendingRemote<media_session::mojom::MediaControllerManager> |
| media_controller_manager, |
| scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler, |
| std::unique_ptr<Delegate> delegate); |
| |
| // Sets the global instance for testing. |
| // Consider using |ScopedCrasAudioHandlerForTesting| instead, as that |
| // guarantees things get properly cleaned up. |
| static void InitializeForTesting(); |
| |
| // Destroys the global instance. |
| static void Shutdown(); |
| |
| // Gets the global instance. Initialize must be called first. |
| static CrasAudioHandler* Get(); |
| |
| CrasAudioHandler(const CrasAudioHandler&) = delete; |
| CrasAudioHandler& operator=(const CrasAudioHandler&) = delete; |
| |
| // Overrides media::VideoCaptureObserver. |
| void OnVideoCaptureStarted(media::VideoFacingMode facing) override; |
| void OnVideoCaptureStopped(media::VideoFacingMode facing) override; |
| |
| // Overrides media_session::mojom::MediaControllerObserver. |
| void MediaSessionInfoChanged( |
| media_session::mojom::MediaSessionInfoPtr session_info) override; |
| void MediaSessionMetadataChanged( |
| const std::optional<media_session::MediaMetadata>& metadata) override; |
| void MediaSessionActionsChanged( |
| const std::vector<media_session::mojom::MediaSessionAction>& actions) |
| override {} |
| void MediaSessionChanged( |
| const std::optional<base::UnguessableToken>& request_id) override {} |
| void MediaSessionPositionChanged( |
| const std::optional<media_session::MediaPosition>& position) override; |
| |
| // ui::MicrophoneMuteSwitchMonitor::Observer: |
| void OnMicrophoneMuteSwitchValueChanged(bool muted) override; |
| |
| // Adds an audio observer. |
| void AddAudioObserver(AudioObserver* observer); |
| |
| // Removes an audio observer. |
| void RemoveAudioObserver(AudioObserver* observer); |
| |
| // Returns true if keyboard mic exists. |
| bool HasKeyboardMic(); |
| |
| // Returns true if hotword input device exists. |
| bool HasHotwordDevice(); |
| |
| // Returns true if audio output is muted for the system. |
| bool IsOutputMuted(); |
| |
| // Returns true if audio output is muted for a device. |
| bool IsOutputMutedForDevice(uint64_t device_id); |
| |
| // Returns true if audio output is muted for the system by policy. |
| bool IsOutputMutedByPolicy(); |
| |
| // Returns true if audio output is muted for the system by security curtain. |
| bool IsOutputMutedBySecurityCurtain(); |
| |
| // Returns true if audio input is muted. |
| bool IsInputMuted(); |
| |
| // Returns true if audio input is muted for the system by security curtain. |
| bool IsInputMutedBySecurityCurtain(); |
| |
| // Returns true if audio input is muted for a device. |
| bool IsInputMutedForDevice(uint64_t device_id); |
| |
| // Returns true if the output volume is below the default mute volume level. |
| bool IsOutputVolumeBelowDefaultMuteLevel(); |
| |
| // Returns volume level in 0-100% range at which the volume should be muted. |
| int GetOutputDefaultVolumeMuteThreshold() const; |
| |
| // Gets volume level in 0-100% range (0 being pure silence) for the current |
| // active node. |
| int GetOutputVolumePercent(); |
| |
| // Gets volume level in 0-100% range (0 being pure silence) for a device. |
| int GetOutputVolumePercentForDevice(uint64_t device_id); |
| |
| // Gets gain level in 0-100% range (0 being pure silence) for the current |
| // active node. |
| int GetInputGainPercent(); |
| |
| // Gets volume level in 0-100% range (0 being pure silence) for a device. |
| int GetInputGainPercentForDevice(uint64_t device_id); |
| |
| // Returns node_id of the primary active output node. |
| uint64_t GetPrimaryActiveOutputNode() const; |
| |
| // Returns the node_id of the primary active input node. |
| uint64_t GetPrimaryActiveInputNode() const; |
| |
| // Gets the audio devices back in |device_list|. |
| void GetAudioDevices(AudioDeviceList* device_list) const; |
| |
| // Gets the simple usage input or output audio devices. |
| static AudioDeviceList GetSimpleUsageAudioDevices( |
| const AudioDeviceMap& audio_devices, |
| bool is_input); |
| |
| const AudioDeviceMap& GetAudioDevicesMapForTesting( |
| bool is_current_device) const; |
| |
| // Gets the primary active output device in |device|. |
| // Returns true if the primary active output device is successfully obtained. |
| // Returns false if no active device is obtained or |device| is null. |
| bool GetPrimaryActiveOutputDevice(AudioDevice* device) const; |
| |
| // Gets the primary active input device in |device|. |
| // Returns true if the primary active input device is successfully obtained. |
| // Returns false if no active device is obtained or |device| is null. |
| bool GetPrimaryActiveInputDevice(AudioDevice* device) const; |
| |
| // Returns the device matched with |type|. Assuming there is only one device |
| // matched the |type|, if there is more than one matched devices, it will |
| // return the first one found. |
| const AudioDevice* GetDeviceByType(AudioDeviceType type); |
| |
| // Returns a map contains number of input streams with permission per |
| // ClientType. If a ClientType is not in the map, we assume the number is 0. |
| base::flat_map<ClientType, uint32_t> GetNumberOfInputStreamsWithPermission() |
| const; |
| |
| // Gets the default output buffer size in frames. |
| void GetDefaultOutputBufferSize(int32_t* buffer_size) const; |
| |
| // Requests to get the audio effect dlcs. |
| void RequestGetAudioEffectDlcs(); |
| |
| // Handles dbus callback for GetAudioEffectDlcs. |
| void HandleGetAudioEffectDlcs(std::optional<std::string> audio_effect_dlcs); |
| |
| // Returns the required DLCs of the supported audio effects. |
| std::optional<std::vector<std::string>> GetAudioEffectDlcs() const; |
| |
| // Request client for the voice isolation UI appearance parameters. |
| void RequestVoiceIsolationUIAppearance(); |
| |
| // Get the voice isolation UI appearance parameters. |
| VoiceIsolationUIAppearance GetVoiceIsolationUIAppearance(); |
| |
| // Set the voice isolation UI appearance parameters for testing. |
| void SetVoiceIsolationUIAppearanceForTesting( |
| cras::AudioEffectType toggle_type, |
| uint32_t effect_mode_options, |
| bool show_effect_fallback_message); |
| |
| // Gets the pref state of input voice isolation. |
| bool GetVoiceIsolationState() const; |
| |
| // Refreshes the input device voice isolation state in CrasAudioClient. |
| void RefreshVoiceIsolationState(); |
| |
| // Records the source of the voice isolation state change to Histograms. |
| void RecordVoiceIsolationEnabledChangeSource( |
| AudioSettingsChangeSource source); |
| |
| // Gets the pref state of input voice isolation preferred effect mode. |
| uint32_t GetVoiceIsolationPreferredEffect() const; |
| |
| // Refreshes the preferred effect mode of voice isolation. |
| void RefreshVoiceIsolationPreferredEffect(); |
| |
| // Records the voice isolation preferred effect to Histograms. |
| void RecordVoiceIsolationPreferredEffectChange( |
| audio_config::mojom::AudioEffectType preferred_effect); |
| |
| // Returns noise cancellation supported if: |
| // - Overall board/device supports noise cancellation |
| // - Audio device has bit for Noise Cancellation set in `audio_effect`. |
| bool IsNoiseCancellationSupportedForDevice(uint64_t device_id); |
| |
| // Gets the pref state of input noise cancellation. |
| bool GetNoiseCancellationState() const; |
| |
| // Updates noise cancellation state in `CrasAudioClient` and |
| // `AudioDevicesPrefHandler` to the provided value. `source` records to |
| // metrics who changed the noise cancellation state. |
| void SetNoiseCancellationState(bool noise_cancellation_on, |
| AudioSettingsChangeSource source); |
| |
| // Get if noise cancellation is supported by the board. |
| void RequestNoiseCancellationSupported( |
| OnNoiseCancellationSupportedCallback callback); |
| |
| // Simulate noise cancellation support in a test. |
| void SetNoiseCancellationSupportedForTesting(bool supported); |
| |
| // Returns style transfer supported if: |
| // - Overall board/device supports style transfer |
| // - Audio device has bit for style transfer set in `audio_effect`. |
| bool IsStyleTransferSupportedForDevice(uint64_t device_id); |
| |
| // Gets the pref state of input style transfer. |
| bool GetStyleTransferState() const; |
| |
| // Updates style transfer state in `CrasAudioClient` and |
| // `AudioDevicesPrefHandler` to the provided value. |
| void SetStyleTransferState(bool style_transfer_on); |
| |
| // Get if style transfer is supported by the board. |
| void RequestStyleTransferSupported(OnStyleTransferSupportedCallback callback); |
| |
| // Simulate style transfer support in a test. |
| void SetStyleTransferSupportedForTesting(bool supported); |
| |
| // Gets the state of input force respect ui gains state. |
| bool GetForceRespectUiGainsState() const; |
| |
| // Refreshes the input device force respect ui gains state. |
| void RefreshForceRespectUiGainsState(); |
| |
| // Makes a DBus call to set the state of input force respect ui gains. |
| void SetForceRespectUiGainsState(bool state); |
| |
| // Returns hfp_mic_sr supported. |
| bool IsHfpMicSrSupportedForDevice(uint64_t device_id); |
| |
| // Gets if hfp_mic_sr is supported by the board. |
| void RequestHfpMicSrSupported(OnHfpMicSrSupportedCallback callback); |
| |
| // Simulates hfp_mic_sr support in a test. |
| void SetHfpMicSrSupportedForTesting(bool supported); |
| |
| // Gets the pref state of hfp_mic_sr. |
| bool GetHfpMicSrState() const; |
| |
| // Refreshes the input device hfp_mic_sr state. |
| void RefreshHfpMicSrState(); |
| |
| // Updates hfp_mic_sr state in `CrasAudioClient` and |
| // `AudioDevicesPrefHandler` to the provided value. `source` records to |
| // metrics who changed the hfp_mic_sr state. |
| void SetHfpMicSrState(bool hfp_mic_sr_on, AudioSettingsChangeSource source); |
| |
| // Returns spatial audio supported. |
| bool IsSpatialAudioSupportedForDevice(uint64_t device_id); |
| |
| // Gets if spatial audio is supported by the board. |
| void RequestSpatialAudioSupported(OnSpatialAudioSupportedCallback callback); |
| |
| // Gets the state of spatial audio state. |
| bool GetSpatialAudioState() const; |
| |
| // Refreshes the spatial audio state. |
| void RefreshSpatialAudioState(); |
| |
| // Makes a DBus call to set the state of spatial audio. |
| void SetSpatialAudioState(bool state); |
| |
| // Simulate spatial audio support in a test. |
| void SetSpatialAudioSupportedForTesting(bool supported); |
| |
| // Whether there is alternative input/output audio device. |
| bool has_alternative_input() const; |
| bool has_alternative_output() const; |
| |
| // Sets the current display |rotation| to CrasAudioHandler and updates the |
| // |rotation| to the internal speaker. |
| void SetDisplayRotation(cras::DisplayRotation rotation); |
| |
| // Sets all active output devices' volume levels to |volume_percent|, whose |
| // range is from 0-100%. |
| void SetOutputVolumePercent(int volume_percent); |
| |
| // Sets all active input devices' gain level to |gain_percent|, whose range is |
| // from 0-100%. |
| void SetInputGainPercent(int gain_percent); |
| |
| // Adjusts all active output devices' volume up (positive percentage) or down |
| // (negative percentage). |
| void AdjustOutputVolumeByPercent(int adjust_by_percent); |
| |
| // Adjusts all active output devices' volume higher by one volume step. |
| void IncreaseOutputVolumeByOneStep(int one_step_percent); |
| |
| // Adjusts all active output devices' volume lower by one volume step |
| void DecreaseOutputVolumeByOneStep(int one_step_percent); |
| |
| // Adjusts all active output devices' volume to a minimum audible level if it |
| // is too low. |
| void AdjustOutputVolumeToAudibleLevel(); |
| |
| // Mutes or unmutes audio output device. |
| void SetOutputMute(bool mute_on); |
| |
| // Mutes or unmutes audio output device including the `source` to record to |
| // metrics. |
| void SetOutputMute(bool mute_on, |
| CrasAudioHandler::AudioSettingsChangeSource source); |
| |
| // Mutes or unmutes audio output device by security curtain |
| void SetOutputMuteLockedBySecurityCurtain(bool mute_on); |
| |
| // Mutes or unmutes audio input device. |
| void SetInputMute(bool mute_on, InputMuteChangeMethod method); |
| |
| // Mutes or unmutes audio input device including the `source` to record to |
| // metrics. |
| void SetInputMute(bool mute_on, |
| InputMuteChangeMethod method, |
| CrasAudioHandler::AudioSettingsChangeSource source); |
| |
| // Mutes or unmutes audio input device by security curtain |
| void SetInputMuteLockedBySecurityCurtain(bool mute); |
| |
| // Switches active audio device to |device|. |activate_by| indicates why |
| // the device is switched to active: by user's manual choice, by priority, |
| // or by restoring to its previous active state. |
| void SwitchToDevice(const AudioDevice& device, |
| bool notify, |
| DeviceActivateType activate_by); |
| |
| // Opens the OS Settings audio page. |
| void OpenSettingsAudioPage(); |
| |
| // Sets volume/gain level for a device. |
| void SetVolumeGainPercentForDevice(uint64_t device_id, int value); |
| |
| // Sets the mute for device. |
| void SetMuteForDevice(uint64_t device_id, bool mute_on); |
| |
| // Sets the mute for device including the `source` to record to metrics. |
| void SetMuteForDevice(uint64_t device_id, |
| bool mute_on, |
| CrasAudioHandler::AudioSettingsChangeSource source); |
| |
| // Activates or deactivates keyboard mic if there's one. |
| void SetKeyboardMicActive(bool active); |
| |
| // Enables or disables the speak-on-mute detection. |
| void SetSpeakOnMuteDetection(bool som_on); |
| |
| // Enable or disable sidetone; |
| void SetSidetoneEnabled(bool enabled); |
| |
| // Enable or disable input stream ewma power report. |
| void SetEwmaPowerReportEnabled(bool enabled); |
| |
| // Returns the last reported ewma power. |
| double GetEwmaPower(); |
| |
| // Get whether the sidetone is enabled or not |
| bool GetSidetoneEnabled() const; |
| |
| // Based on the output device, get whether sidetone is available or not. |
| bool IsSidetoneSupported() const; |
| |
| // Request to CRAS to check whether the current device support sidetone or |
| // not. |
| void UpdateSidetoneSupportedState(); |
| |
| // Handles dbus callback for GetNodes. |
| void HandleGetSidetoneSupported(std::optional<bool> available); |
| |
| // Changes the active nodes to the nodes specified by |new_active_ids|. |
| // The caller can pass in the "complete" active node list of either input |
| // nodes, or output nodes, or both. If only input nodes are passed in, |
| // it will only change the input nodes' active status, output nodes will NOT |
| // be changed; similarly for the case if only output nodes are passed. |
| // If the nodes specified in |new_active_ids| are already active, they will |
| // remain active. Otherwise, the old active nodes will be de-activated before |
| // we activate the new nodes with the same type(input/output). |
| // DEPRECATED in favor of |SetActiveInputNodes| and |SetActiveOutputNodes|. |
| void ChangeActiveNodes(const NodeIdList& new_active_ids); |
| |
| // Sets the set of active input nodes. Empty |node_ids| will deactivate all |
| // input devices. |
| // |node_ids| is expected to contain only existing input node IDs - the |
| // method will fail if this is not the case. |
| // Returns whether the acive nodes were successfully set. |
| bool SetActiveInputNodes(const NodeIdList& node_ids); |
| |
| // Sets the set of active output nodes. Empty |node_ids| will deactivate all |
| // output devices. |
| // |node_ids| is expected to contain only existing output node IDs - the |
| // method will fail if this is not the case. |
| // Returns whether the acive nodes were successfully set. |
| bool SetActiveOutputNodes(const NodeIdList& node_ids); |
| |
| // Sets |hotword_model| to the given |node_id|. |
| // |hotword_model| is expected to be in format <language>_<region> with lower |
| // cases. E.g., "en_us". |
| // The callback will receive a boolean which indicates if the hotword model is |
| // successfully set. |
| void SetHotwordModel(uint64_t node_id, |
| const std::string& hotword_model, |
| VoidCrasAudioHandlerCallback callback); |
| |
| // Swaps the left and right channel of the internal speaker. |
| // Swap the left and right channel if |swap| is true; otherwise, swap the left |
| // and right channel back to the normal mode. |
| // If the feature is not supported on the device, nothing happens. |
| void SwapInternalSpeakerLeftRightChannel(bool swap); |
| |
| // Accessibility mono audio setting: sets the output mono or not. |
| void SetOutputMonoEnabled(bool enabled); |
| |
| // If necessary, sets the starting point for re-discovering the active HDMI |
| // output device caused by device entering/exiting docking mode, HDMI display |
| // changing resolution, or chromeos device suspend/resume. If |
| // |force_rediscovering| is true, it will force to set the starting point for |
| // re-discovering the active HDMI output device again if it has been in the |
| // middle of rediscovering the HDMI active output device. |
| void SetActiveHDMIOutoutRediscoveringIfNecessary(bool force_rediscovering); |
| |
| const AudioDevice* GetDeviceFromId(uint64_t device_id) const; |
| |
| // Returns true the device has dual internal microphones(front and rear). |
| bool HasDualInternalMic() const; |
| |
| // There are some audio devices which are not meant for simple usage. Keyboard |
| // mic is an example of a non simple device. There are cases when we need to |
| // know programmatically if there is an audio input device for simple usage |
| // available. Checking `active_input_node_id_` being non zero is not |
| // sufficient in this case. A non simple device can be the active input node |
| // during cras initialization depeneding the audio device enumeration process. |
| // This function returns true if an input device for simple usage is |
| // available. |
| bool HasActiveInputDeviceForSimpleUsage() const; |
| |
| // Returns true if |device| is front or rear microphone. |
| bool IsFrontOrRearMic(const AudioDevice& device) const; |
| |
| // Switches to either front or rear microphone depending on the |
| // the use case. It should be called from a user initiated action. |
| void SwitchToFrontOrRearMic(); |
| |
| bool input_muted_by_microphone_mute_switch() const { |
| return input_muted_by_microphone_mute_switch_; |
| } |
| |
| // Returns if system AEC is supported in CRAS or not. |
| bool system_aec_supported() const; |
| |
| // Returns if noise cancellation is supported in CRAS or not. |
| bool noise_cancellation_supported() const; |
| |
| // Returns if style transfer is supported in CRAS or not. |
| bool style_transfer_supported() const; |
| |
| // Returns if hfp_mic_sr is supported in CRAS or not. |
| bool hfp_mic_sr_supported() const; |
| |
| // Returns the system AEC group ID. If no group ID is specified, -1 is |
| // returned. |
| int32_t system_aec_group_id() const; |
| |
| // Returns if system NS is supported in CRAS or not. |
| bool system_ns_supported() const; |
| |
| // Returns if system AGC is supported in CRAS or not. |
| bool system_agc_supported() const; |
| |
| // Returns number of streams ignoring UI gains. |
| int32_t num_stream_ignore_ui_gains() const; |
| |
| // Returns if spatial audio is supported in CRAS or not. |
| bool spatial_audio_supported() const; |
| |
| // Asks CRAS to resend BluetoothBatteryChanged signal, used in cases when |
| // Chrome cleans up the stored battery information but still has the device |
| // connected afterward. For example: User logout. |
| void ResendBluetoothBattery(); |
| |
| void SetPrefHandlerForTesting( |
| scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); |
| |
| int32_t NumberOfNonChromeOutputStreams() const; |
| int32_t NumberOfChromeOutputStreams() const; |
| int32_t NumberOfArcStreams() const; |
| |
| // Simulate number of ARC streams changing in a test. |
| void SetNumberOfArcStreamsForTesting(int32_t num); |
| |
| protected: |
| CrasAudioHandler( |
| mojo::PendingRemote<media_session::mojom::MediaControllerManager> |
| media_controller_manager, |
| scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); |
| CrasAudioHandler( |
| mojo::PendingRemote<media_session::mojom::MediaControllerManager> |
| media_controller_manager, |
| scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler, |
| std::unique_ptr<Delegate> delegate); |
| ~CrasAudioHandler() override; |
| |
| private: |
| friend class CrasAudioHandlerTest; |
| |
| // A helper function to set up CrasAudioHandler. |
| void SetupCrasAudioHandler( |
| scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler); |
| |
| // CrasAudioClient::Observer overrides. |
| void AudioClientRestarted() override; |
| void NodesChanged() override; |
| void ActiveOutputNodeChanged(uint64_t node_id) override; |
| void ActiveInputNodeChanged(uint64_t node_id) override; |
| void OutputNodeVolumeChanged(uint64_t node_id, int volume) override; |
| void InputNodeGainChanged(uint64_t node_id, int gain) override; |
| void HotwordTriggered(uint64_t tv_sec, uint64_t tv_nsec) override; |
| void BluetoothBatteryChanged(const std::string& address, |
| uint32_t level) override; |
| void NumberOfInputStreamsWithPermissionChanged( |
| const base::flat_map<std::string, uint32_t>& num_input_streams) override; |
| void NumberOfActiveStreamsChanged() override; |
| void SurveyTriggered(const base::flat_map<std::string, std::string>& |
| survey_specific_data) override; |
| void SpeakOnMuteDetected() override; |
| void EwmaPowerReported(double power) override; |
| void NumberOfNonChromeOutputStreamsChanged() override; |
| void NumStreamIgnoreUiGains(int32_t num) override; |
| void NumberOfArcStreamsChanged() override; |
| void SidetoneSupportedChanged(bool supported) override; |
| void AudioEffectUIAppearanceChanged( |
| VoiceIsolationUIAppearance appearance) override; |
| |
| // AudioPrefObserver overrides. |
| void OnAudioPolicyPrefChanged() override; |
| void OnVoiceIsolationPrefChanged() override; |
| |
| // Sets the |active_device| to be active. |
| // If |notify|, notifies Active*NodeChange. |
| // Saves device active states in prefs. |activate_by| indicates how |
| // the device was activated. |
| void SetActiveDevice(const AudioDevice& active_device, |
| bool notify, |
| DeviceActivateType activate_by); |
| |
| // Shared implementation for |SetActiveInputNodes| and |SetActiveOutputNodes|. |
| bool SetActiveNodes(const NodeIdList& node_ids, bool is_input); |
| |
| // Sets list of active input or output nodes to |devices|. |
| // If |is_input| is set, active input nodes will be set, otherwise active |
| // output nodes will be set. |
| // For each device in |devices| it is expected device.is_input == is_input. |
| void SetActiveDevices(const AudioDeviceList& devices, bool is_input); |
| |
| // Saves |device|'s state in pref. If |active| is true, |activate_by| |
| // indicates how |device| is activated. |
| void SaveDeviceState(const AudioDevice& device, |
| bool active, |
| DeviceActivateType activate_by); |
| |
| // Sets up the audio device state based on audio policy and audio settings |
| // saved in prefs. |
| void SetupAudioInputState(); |
| void SetupAudioOutputState(); |
| |
| // Sets up the additional active audio node's state. |
| void SetupAdditionalActiveAudioNodeState(uint64_t node_id); |
| |
| AudioDevice ConvertAudioNodeWithModifiedPriority(const AudioNode& node); |
| |
| const AudioDevice* GetDeviceFromStableDeviceId( |
| bool is_input, |
| uint64_t stable_device_id) const; |
| |
| const AudioDevice* GetKeyboardMic() const; |
| |
| const AudioDevice* GetHotwordDevice() const; |
| |
| // Initializes audio state, which should only be called when CrasAudioHandler |
| // is created or cras audio client is restarted. |
| void InitializeAudioState(); |
| |
| void InitializeAudioAfterCrasServiceAvailable(bool service_is_available); |
| |
| // Applies the audio muting policies whenever the user logs in or policy |
| // change notification is received. |
| void ApplyAudioPolicy(); |
| |
| // Helper method to apply the conditional audio output mute change. |
| void UpdateAudioOutputMute(); |
| |
| // Sets output volume of |node_id| to |volume|. |
| void SetOutputNodeVolume(uint64_t node_id, int volume); |
| |
| void SetOutputNodeVolumePercent(uint64_t node_id, int volume_percent); |
| |
| // Sets output mute state to |mute_on| internally, returns true if output mute |
| // is set. |
| bool SetOutputMuteInternal(bool mute_on); |
| |
| // Sets input gain of |node_id| to |gain|. |
| void SetInputNodeGain(uint64_t node_id, int gain); |
| |
| void SetInputNodeGainPercent(uint64_t node_id, int gain_percent); |
| |
| // Sets input mute state to |mute_on| internally. |
| void SetInputMuteInternal(bool mute_on); |
| |
| // Calls CRAS over D-Bus to get nodes data. |
| void GetNodes(); |
| |
| // Calls CRAS over D-Bus to get the number of active output streams. |
| void GetNumberOfOutputStreams(); |
| |
| void GetNumberOfNonChromeOutputStreams(); |
| |
| // Calls CRAS over D-Bus to get the number of ARC streams. |
| void GetNumberOfArcStreams(); |
| |
| // Updates the current audio nodes list and switches the active device |
| // if needed. |
| void UpdateDevicesAndSwitchActive(const AudioNodeList& nodes); |
| |
| // Returns true if the current active device is changed to |
| // |new_active_device|. |
| bool ChangeActiveDevice(const AudioDevice& new_active_device); |
| |
| // Returns true if there are any device changes for input or output |
| // specified by |is_input|, by comparing |audio_devices_| with |new_nodes|. |
| // Passes the new nodes discovered in *|new_discovered|. |
| // *|device_removed| indicates if any devices have been removed. |
| // *|active_device_removed| indicates if the current active device has been |
| // removed. |
| bool HasDeviceChange(const AudioNodeList& new_nodes, |
| bool is_input, |
| AudioDeviceList* new_discovered, |
| AudioDeviceList* removed_devices, |
| bool* active_device_removed); |
| |
| // Handles dbus callback for GetNodes. |
| void HandleGetNodes(std::optional<AudioNodeList> node_list); |
| |
| void HandleGetNumActiveOutputStreams( |
| std::optional<int> num_active_output_streams); |
| |
| // Adds an active node. |
| // If there is no active node, |node_id| will be switched to become the |
| // primary active node. Otherwise, it will be added as an additional active |
| // node. |
| void AddActiveNode(uint64_t node_id, bool notify); |
| |
| // Adds |node_id| into additional active nodes. |
| void AddAdditionalActiveNode(uint64_t node_id, bool notify); |
| |
| // Removes |node_id| from additional active nodes. |
| void RemoveActiveNodeInternal(uint64_t node_id, bool notify); |
| |
| void UpdateAudioAfterHDMIRediscoverGracePeriod(); |
| |
| bool IsHDMIPrimaryOutputDevice() const; |
| |
| void StartHDMIRediscoverGracePeriod(); |
| |
| bool hdmi_rediscovering() const { return hdmi_rediscovering_; } |
| |
| void SetHDMIRediscoverGracePeriodForTesting(int duration_in_ms); |
| bool ShouldSwitchToHotPlugDevice(const AudioDevice& hotplug_device) const; |
| |
| enum DeviceStatus { |
| OLD_DEVICE, |
| NEW_DEVICE, |
| CHANGED_DEVICE, |
| }; |
| |
| // Checks if |device| is a newly discovered, changed, or existing device for |
| // the nodes sent from NodesChanged signal. |
| DeviceStatus CheckDeviceStatus(const AudioDevice& device); |
| |
| void NotifyActiveNodeChanged(bool is_input); |
| |
| // Returns true if it retrieves an active audio device from user preference |
| // among the current |audio_devices_|. |
| bool GetActiveDeviceFromUserPref(bool is_input, AudioDevice* device); |
| |
| // Pauses all active streams. |
| void PauseAllStreams(); |
| |
| // Handles either input or output device changes, specified by |is_input|. |
| void HandleAudioDeviceChange(bool is_input, |
| const AudioDeviceList& devices, |
| const AudioDeviceList& hotplug_nodes, |
| bool has_device_change, |
| bool has_device_removed, |
| bool active_device_removed); |
| |
| // Handles non-hotplug nodes change cases. |
| void HandleNonHotplugNodesChange(bool is_input, |
| const AudioDeviceList& devices, |
| const AudioDeviceList& hotplug_nodes, |
| bool has_device_change, |
| bool has_device_removed, |
| bool active_device_removed); |
| |
| // Handles the regular user hotplug case with user priority. |
| void HandleHotPlugDeviceByUserPriority(const AudioDevice& hotplug_device); |
| |
| // Switch to the top priority device in |devices|. |devices| must be a list |
| // of devices with the same direction. |
| void SwitchToTopPriorityDevice(const AudioDeviceList& devices); |
| |
| // Switch to previous active device if it is found, otherwise, switch |
| // to the top priority device. |
| void SwitchToPreviousActiveDeviceIfAvailable(bool is_input, |
| const AudioDeviceList& devices); |
| |
| // Activates the internal mic attached with the camera specified by |
| // |camera_facing|. |
| void ActivateMicForCamera(media::VideoFacingMode camera_facing); |
| |
| // Activates the front or rear mic that is consistent with the active camera. |
| // Note: This should only be called for the dural camera/mic use case. |
| void ActivateInternalMicForActiveCamera(); |
| |
| // Returns the microphone for the camera with |camera_facing|. |
| const AudioDevice* GetMicForCamera(media::VideoFacingMode camera_facing); |
| |
| bool IsCameraOn() const; |
| |
| // Returns true if there are any external devices. |
| bool HasExternalDevice(bool is_input) const; |
| |
| // Calling dbus to get default output buffer size. |
| void GetDefaultOutputBufferSizeInternal(); |
| |
| // Handle dbus callback for GetDefaultOutputBufferSize. |
| void HandleGetDefaultOutputBufferSize(std::optional<int> buffer_size); |
| |
| // Calling dbus to get current number of input streams with permission and |
| // storing the result in number_of_input_streams_with_permission_. |
| void GetNumberOfInputStreamsWithPermissionInternal(); |
| |
| // Static function converts |client_type_str| to ClientType which used by |
| // HandleGetNumberOfInputStreamsWithPermission. |
| static ClientType ConvertClientTypeStringToEnum(std::string client_type_str); |
| |
| // Handle dbus callback for GetNumberOfInputStreamsWithPermission. |
| void HandleGetNumberOfInputStreamsWithPermission( |
| std::optional<base::flat_map<std::string, uint32_t>> num_input_streams); |
| void HandleGetNumberOfNonChromeOutputStreams( |
| std::optional<int32_t> num_output_streams); |
| |
| // Handle dbus callback for GetNumberOfArcStreams. |
| void HandleGetNumberOfArcStreams(std::optional<int32_t> num_arc_streams); |
| |
| // Calling dbus to get system AEC supported flag. |
| void GetSystemAecSupported(); |
| |
| // Handle dbus callback for GetVoiceIsolationUIAppearance. |
| void HandleGetVoiceIsolationUIAppearance( |
| std::optional<VoiceIsolationUIAppearance> appearance); |
| |
| // Resets Voice Isolation preferred effect in pref if: |
| // 1. UIAppearance says show no effect modes and pref has value. |
| // -> Reset pref to 0. |
| // 2. UIAppearance says show some effect modes and pref is 0. |
| // -> Default set to Style Transfer. |
| // Otherwise, keep the pref value. |
| // The pref is directly connected with the UI radio buttons in |
| // chrome/browser/resources/ash/settings/device_page/audio.html. |
| void ResetVoiceIsolationPreferredEffectIfNeeded(); |
| |
| // Handle dbus callback for GetSystemNoiseCancellationSupported. |
| void HandleGetNoiseCancellationSupported( |
| OnNoiseCancellationSupportedCallback callback, |
| std::optional<bool> system_noise_cancellation_supported); |
| |
| // Handle dbus callback for GetSystemStyleTransferSupported. |
| void HandleGetStyleTransferSupported( |
| OnStyleTransferSupportedCallback callback, |
| std::optional<bool> system_style_transfer_supported); |
| |
| // Handle dbus callback for IsHfpMicSrSupported. |
| void HandleGetHfpMicSrSupported(OnHfpMicSrSupportedCallback callback, |
| std::optional<bool> hfp_mic_sr_supported); |
| |
| // Handle dbus callback for GetSystemAecSupported. |
| void HandleGetSystemAecSupported(std::optional<bool> system_aec_supported); |
| |
| // Calling dbus to get the system AEC group id if available. |
| void GetSystemAecGroupId(); |
| |
| // Handle dbus callback for GetSystemAecGroupId. |
| void HandleGetSystemAecGroupId(std::optional<int32_t> system_aec_group_id); |
| |
| // Calling dbus to get system NS supported flag. |
| void GetSystemNsSupported(); |
| |
| // Handle dbus callback for GetSystemNsSupported. |
| void HandleGetSystemNsSupported(std::optional<bool> system_ns_supported); |
| |
| // Calling dbus to get system AGC supported flag. |
| void GetSystemAgcSupported(); |
| |
| // Handle dbus callback for GetSystemAgcSupported. |
| void HandleGetSystemAgcSupported(std::optional<bool> system_agc_supported); |
| |
| // Handle dbus callback for IsSpatialAudioSupported. |
| void HandleGetSpatialAudioSupported( |
| OnSpatialAudioSupportedCallback callback, |
| std::optional<bool> spatial_audio_supported); |
| |
| void OnVideoCaptureStartedOnMainThread(media::VideoFacingMode facing); |
| void OnVideoCaptureStoppedOnMainThread(media::VideoFacingMode facing); |
| |
| void BindMediaControllerObserver(); |
| |
| // Handle null Metadata from MediaSession. |
| void HandleMediaSessionMetadataReset(); |
| |
| // Calls CRAS over D-Bus to get the number of streams ignoring Ui Gains. |
| void GetNumStreamIgnoreUiGains(); |
| |
| // Handle dbus callback for GetNumStreamIgnoreUiGains. |
| void HandleGetNumStreamIgnoreUiGains( |
| std::optional<int32_t> num_stream_ignore_ui_gains); |
| |
| // Checks if a given set of devices is seen before. If seen, return the |
| // preferred device. |
| const std::optional<AudioDevice> GetPreferredDeviceIfDeviceSetSeenBefore( |
| bool is_input, |
| const AudioDeviceList& devices) const; |
| |
| // Syncs device preference set map with currently activated device, called |
| // whenever user perefences have changed. |
| void SyncDevicePrefSetMap(bool is_input); |
| |
| // Handles the regular user hotplug case. Show notification for unseen device |
| // set. |
| void HandleHotPlugDeviceWithNotification(const AudioDevice& hotplug_device); |
| |
| // Handles the audio selection notification being removed. |
| void HandleRemoveNotification(bool is_input); |
| |
| // Handles the system boots or restarts case. |
| // - If the device boots with only one device, activate it automatically. |
| // - If the device set was seen before, activate the preferred one. |
| // - Otherwise if a 3.5mm headphone is connected, activate it and don't show |
| // notification. |
| // - Otherwise activate the most recent activated device and show |
| // notification. |
| // - Otherwise if there is an internal device, activate it and show |
| // notification. |
| // - Otherwise when no most recent activated device and no internal device (a |
| // brand new chromebox), activate the highest priority device based on the |
| // pre-determined priority list and show notification. |
| void HandleSystemBoots(bool is_input, const AudioDeviceList& devices); |
| |
| // Activates the most recently active device. Return false if no device in the |
| // most recently active device list is currently connected, otherwise |
| // return true. |
| bool ActivateMostRecentActiveDevice(bool is_input); |
| |
| // Static helper function to abstract the |AudioSurvey| from input |
| // |survey_specific_data|. |
| static std::unique_ptr<CrasAudioHandler::AudioSurvey> AbstractAudioSurvey( |
| const base::flat_map<std::string, std::string>& survey_specific_data); |
| |
| mojo::Remote<media_session::mojom::MediaControllerManager> |
| media_controller_manager_; |
| |
| mojo::Remote<media_session::mojom::MediaController> |
| media_session_controller_remote_; |
| |
| mojo::Receiver<media_session::mojom::MediaControllerObserver> |
| media_controller_observer_receiver_{this}; |
| |
| scoped_refptr<AudioDevicesPrefHandler> audio_pref_handler_; |
| base::ObserverList<AudioObserver>::Unchecked observers_; |
| |
| // Handles firing of audio selection related metrics. |
| AudioDeviceMetricsHandler audio_device_metrics_handler_; |
| |
| // Handles creation and display of audio selection notification. |
| AudioSelectionNotificationHandler audio_selection_notification_handler_; |
| |
| // Timer for remove notification. |
| base::OneShotTimer remove_notification_timer_for_input_; |
| base::OneShotTimer remove_notification_timer_for_output_; |
| |
| // Audio data and state. |
| AudioDeviceMap audio_devices_; |
| |
| // Previous audio devices before new device is connected or current device is |
| // disconnected. Used for histogram purpose to understand the context when the |
| // system makes a switch or not switch decision. |
| AudioDeviceMap previous_audio_devices_; |
| |
| bool output_mute_on_ = false; |
| bool input_mute_on_ = false; |
| int output_volume_ = 0; |
| int input_gain_ = 0; |
| uint64_t active_output_node_id_ = 0; |
| uint64_t active_input_node_id_ = 0; |
| bool has_alternative_input_ = false; |
| bool has_alternative_output_ = false; |
| |
| bool output_mute_forced_by_policy_ = false; |
| bool output_mute_forced_by_security_curtain_ = false; |
| bool input_mute_forced_by_security_curtain_ = false; |
| |
| // Audio output channel counts. |
| int32_t output_channels_ = 2; |
| bool output_mono_enabled_ = false; |
| |
| // Timer for HDMI re-discovering grace period. |
| base::OneShotTimer hdmi_rediscover_timer_; |
| int hdmi_rediscover_grace_period_duration_in_ms_ = 2000; |
| bool hdmi_rediscovering_ = false; |
| |
| bool cras_service_available_ = false; |
| |
| bool initializing_audio_state_ = false; |
| int init_volume_; |
| uint64_t init_node_id_; |
| int init_volume_count_ = 0; |
| |
| bool front_camera_on_ = false; |
| bool rear_camera_on_ = false; |
| |
| // Default output buffer size in frames. |
| int32_t default_output_buffer_size_ = 512; |
| |
| base::flat_map<ClientType, uint32_t> number_of_input_streams_with_permission_; |
| |
| VoiceIsolationUIAppearance voice_isolation_ui_appearance_; |
| bool system_aec_supported_ = false; |
| std::optional<std::vector<std::string>> audio_effect_dlcs_; |
| bool noise_cancellation_supported_ = false; |
| bool style_transfer_supported_ = false; |
| int32_t system_aec_group_id_ = kSystemAecGroupIdNotAvailable; |
| bool system_ns_supported_ = false; |
| bool system_agc_supported_ = false; |
| bool hfp_mic_sr_supported_ = false; |
| bool spatial_audio_supported_ = false; |
| |
| int num_active_output_streams_ = 0; |
| int32_t num_active_nonchrome_output_streams_ = 0; |
| |
| bool fetch_media_session_duration_ = false; |
| |
| // Whether the audio input is muted because the microphone mute switch is on. |
| // In this case, input mute changes will be disabled. |
| bool input_muted_by_microphone_mute_switch_ = false; |
| |
| // Whether the speak-on-mute detection is enabled in CRAS. |
| bool speak_on_mute_detection_on_ = false; |
| |
| // Whether the sidetone is enabled in CRAS. |
| bool sidetone_enabled_ = false; |
| |
| // Whether the current has sidetone available or not. |
| bool sidetone_supported_ = false; |
| |
| // Whether the ewma power report is enabled in CRAS. |
| bool ewma_power_report_enabled_ = false; |
| |
| // The last reported ewma power. |
| double ewma_power_ = 0; |
| |
| // Indicates whether the audio selection notification should be displayed. |
| bool should_show_notification_ = false; |
| |
| // Task runner of browser main thread. All member variables should be accessed |
| // on this thread. |
| scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
| |
| cras::DisplayRotation display_rotation_ = cras::DisplayRotation::ROTATE_0; |
| |
| int num_stream_ignore_ui_gains_ = 0; |
| |
| int32_t num_arc_streams_ = 0; |
| |
| std::unique_ptr<Delegate> delegate_; |
| |
| base::WeakPtrFactory<CrasAudioHandler> weak_ptr_factory_{this}; |
| }; |
| |
| // Helper class that will initialize the `CrasAudioHandler` for testing in its |
| // constructor, and clean things up in its destructor. |
| class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_AUDIO) |
| ScopedCrasAudioHandlerForTesting { |
| public: |
| // `ScopedCrasAudioHandlerForTesting` expects that there is no audio client |
| // running. This class starts and shuts down an audio client automatically at |
| // its constructor and destructor. |
| ScopedCrasAudioHandlerForTesting(); |
| ScopedCrasAudioHandlerForTesting(const ScopedCrasAudioHandlerForTesting&) = |
| delete; |
| ScopedCrasAudioHandlerForTesting& operator=( |
| const ScopedCrasAudioHandlerForTesting&) = delete; |
| ~ScopedCrasAudioHandlerForTesting(); |
| |
| CrasAudioHandler& Get(); |
| |
| private: |
| std::unique_ptr<FakeCrasAudioClient> fake_cras_audio_client_; |
| }; |
| |
| } // namespace ash |
| |
| namespace base { |
| |
| template <> |
| struct ScopedObservationTraits<ash::CrasAudioHandler, |
| ash::CrasAudioHandler::AudioObserver> { |
| static void AddObserver(ash::CrasAudioHandler* source, |
| ash::CrasAudioHandler::AudioObserver* observer) { |
| source->AddAudioObserver(observer); |
| } |
| static void RemoveObserver(ash::CrasAudioHandler* source, |
| ash::CrasAudioHandler::AudioObserver* observer) { |
| source->RemoveAudioObserver(observer); |
| } |
| }; |
| |
| } // namespace base |
| |
| #endif // CHROMEOS_ASH_COMPONENTS_AUDIO_CRAS_AUDIO_HANDLER_H_ |