#ifndef MEDIA_AUDIO_ANDROID_AUDIO_MANAGER_ANDROID_H_
#define MEDIA_AUDIO_ANDROID_AUDIO_MANAGER_ANDROID_H_
#include "base/android/jni_android.h"
#include "base/android/requires_api.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "media/audio/android/aaudio_bluetooth_output.h"
#include "media/audio/android/aaudio_input.h"
#include "media/audio/android/audio_device.h"
#include "media/audio/android/audio_device_id.h"
#include "media/audio/audio_manager_base.h"
#include "media/base/audio_parameters.h"
namespace media {
class MuteableAudioOutputStream;
class MEDIA_EXPORT AudioManagerAndroid : public AudioManagerBase {
public:
struct JniAudioDevice {
public:
JniAudioDevice(int id,
std::optional<std::string> name,
int type,
std::vector<int> sample_rates);
JniAudioDevice(const JniAudioDevice&);
JniAudioDevice& operator=(const JniAudioDevice&);
JniAudioDevice(JniAudioDevice&&);
JniAudioDevice& operator=(JniAudioDevice&&);
~JniAudioDevice();
int id;
std::optional<std::string> name;
int type;
std::vector<int> sample_rates;
};
class JniDelegate {
public:
virtual ~JniDelegate() = default;
virtual void InitDeviceListener() = 0;
virtual void InitScoStateListener() = 0;
virtual std::vector<JniAudioDevice> GetDevices(bool inputs) = 0;
virtual std::optional<std::vector<JniAudioDevice>>
GetCommunicationDevices() = 0;
virtual int GetMinInputFramesPerBuffer(int sample_rate, int channels) = 0;
virtual bool AcousticEchoCancelerIsAvailable() = 0;
virtual base::TimeDelta GetOutputLatency() = 0;
virtual void SetCommunicationAudioModeOn(bool on) = 0;
virtual bool SetCommunicationDevice(std::string_view device_id) = 0;
virtual void MaybeSetBluetoothScoState(bool state) = 0;
virtual int GetNativeOutputSampleRate() = 0;
virtual bool IsAudioLowLatencySupported() = 0;
virtual int GetAudioLowLatencyOutputFramesPerBuffer() = 0;
virtual int GetMinOutputFramesPerBuffer(int sample_rate, int channels) = 0;
virtual AudioParameters::Format GetHdmiOutputEncodingFormats() = 0;
virtual int GetLayoutWithMaxChannels() = 0;
};
AudioManagerAndroid(std::unique_ptr<AudioThread> audio_thread,
AudioLogFactory* audio_log_factory);
AudioManagerAndroid(const AudioManagerAndroid&) = delete;
AudioManagerAndroid& operator=(const AudioManagerAndroid&) = delete;
~AudioManagerAndroid() override;
void InitializeIfNeeded();
bool HasAudioOutputDevices() override;
bool HasAudioInputDevices() override;
void GetAudioInputDeviceNames(AudioDeviceNames* device_names) override;
void GetAudioOutputDeviceNames(AudioDeviceNames* device_names) override;
AudioParameters GetInputStreamParameters(
const std::string& device_id) override;
AudioOutputStream* MakeAudioOutputStream(
const AudioParameters& params,
const std::string& device_id,
const LogCallback& log_callback) override;
AudioInputStream* MakeAudioInputStream(
const AudioParameters& params,
const std::string& device_id,
const LogCallback& log_callback) override;
void ReleaseOutputStream(AudioOutputStream* stream) override;
void ReleaseInputStream(AudioInputStream* stream) override;
const std::string_view GetName() override;
AudioOutputStream* MakeLinearOutputStream(
const AudioParameters& params,
const LogCallback& log_callback) override;
AudioOutputStream* MakeLowLatencyOutputStream(
const AudioParameters& params,
const std::string& device_id,
const LogCallback& log_callback) override;
AudioOutputStream* MakeBitstreamOutputStream(
const AudioParameters& params,
const std::string& device_id,
const LogCallback& log_callback) override;
AudioInputStream* MakeLinearInputStream(
const AudioParameters& params,
const std::string& device_id,
const LogCallback& log_callback) override;
AudioInputStream* MakeLowLatencyInputStream(
const AudioParameters& params,
const std::string& device_id,
const LogCallback& log_callback) override;
void SetMute(JNIEnv* env, jboolean muted);
void OnScoStateChanged(JNIEnv* env, jboolean state);
void SetOutputVolumeOverride(double volume);
bool HasOutputVolumeOverride(double* out_volume) const;
base::TimeDelta GetOutputLatency();
static AudioParameters::Format GetHdmiOutputEncodingFormats();
void OnStartAAudioInputStream(AAudioInputStream* stream);
void OnStopAAudioInputStream(AAudioInputStream* stream);
void SetJniDelegateForTesting(std::unique_ptr<JniDelegate> jni_delegate);
protected:
void ShutdownOnAudioThread() override;
AudioParameters GetPreferredOutputStreamParameters(
const std::string& output_device_id,
const AudioParameters& input_params) override;
private:
using DeviceCache =
base::flat_map<android::AudioDeviceId, android::AudioDevice>;
using OutputStreams =
base::flat_set<raw_ptr<MuteableAudioOutputStream, CtnExperimental>>;
using BluetoothOutputStreams =
base::flat_set<raw_ptr<AAudioBluetoothOutputStream, CtnExperimental>>;
using InputStreams =
base::flat_set<raw_ptr<AudioInputStream, CtnExperimental>>;
enum class AudioDeviceDirection {
kInput,
kOutput,
};
JniDelegate& GetJniDelegate();
bool HasNoAudioInputStreams();
void GetDeviceNames(AudioDeviceNames* device_names,
AudioDeviceDirection direction);
void GetCommunicationDeviceNames(AudioDeviceNames* device_names);
void UpdateDeviceCache(AudioDeviceDirection direction);
const DeviceCache& GetDeviceCache(AudioDeviceDirection direction) const;
std::optional<android::AudioDevice> GetDeviceForAAudioStream(
std::string_view id_string,
AudioDeviceDirection direction);
int SelectSampleRate(const android::AudioDevice& device,
std::optional<int> preferred_sample_rate);
int GetOptimalOutputFramesPerBuffer(int sample_rate, int channels);
ChannelLayoutConfig GetLayoutWithMaxChannels();
void DoSetMuteOnAudioThread(bool muted);
void DoSetVolumeOnAudioThread(double volume);
void OnScoStateChangedOnAudioThread(bool state);
std::unique_ptr<JniDelegate> jni_delegate_;
bool is_bluetooth_sco_enabled_ = false;
DeviceCache input_device_cache_;
DeviceCache output_device_cache_;
OutputStreams output_streams_;
BluetoothOutputStreams bluetooth_output_streams_;
InputStreams input_streams_requiring_sco_;
bool communication_mode_is_on_;
bool output_volume_override_set_;
double output_volume_override_;
};
}
#endif