blob: d10456f9ec3cc61ac34edc154c924e901f236313 [file] [log] [blame]
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Changes from Qualcomm Innovation Center are provided under the following license:
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef ANDROID_HARDWARE_AHAL_ADEVICE_H_
#define ANDROID_HARDWARE_AHAL_ADEVICE_H_
#include <stdlib.h>
#include <unistd.h>
#include <mutex>
#include <vector>
#include <set>
#include <string>
#include <cutils/properties.h>
#include <hardware/audio.h>
#include <system/audio.h>
#include <expat.h>
#include "AudioStream.h"
#include "AudioVoice.h"
#include "PalDefs.h"
#define MAX_PERF_LOCK_OPTS 20
/* HDR Audio use case parameters */
#define AUDIO_PARAMETER_KEY_HDR "hdr_record_on"
#define AUDIO_PARAMETER_KEY_WNR "wnr_on"
#define AUDIO_PARAMETER_KEY_ANS "ans_on"
#define AUDIO_PARAMETER_KEY_ORIENTATION "orientation"
#define AUDIO_PARAMETER_KEY_INVERTED "inverted"
#define AUDIO_PARAMETER_KEY_FACING "facing"
#define AUDIO_PARAMETER_KEY_HDR_CHANNELS "hdr_audio_channel_count"
#define AUDIO_PARAMETER_KEY_HDR_SAMPLERATE "hdr_audio_sampling_rate"
#define AUDIO_MAKE_STRING_FROM_ENUM(X) { #X, X }
#define PAL_MAX_INPUT_DEVICES (PAL_DEVICE_IN_MAX - (PAL_DEVICE_IN_MIN + 1))
#define MIC_INFO_MAP_INDEX(X) (X - (PAL_DEVICE_IN_MIN + 1))
#define XML_READ_BUFFER_SIZE 1024
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define COMPRESS_CAPTURE_AAC_MAX_OUTPUT_BUFFER_SIZE 2048
#define COMPRESS_CAPTURE_AAC_PCM_SAMPLES_IN_FRAME 1024
typedef enum {
TAG_MICROPHONE_CHARACTERISTIC,
TAG_SND_DEVICES,
TAG_INPUT_SND_DEVICE,
TAG_INPUT_SND_DEVICE_TO_MIC_MAPPING,
TAG_SND_DEV,
TAG_MIC_INFO
} mic_xml_tags_t;
typedef struct xml_userdata_t {
char data_buf[XML_READ_BUFFER_SIZE];
size_t offs;
mic_xml_tags_t tag;
} xml_userdata_t;
typedef struct microphone_characteristics_t
{
uint32_t declared_mic_count;
struct audio_microphone_characteristic_t microphone[AUDIO_MICROPHONE_MAX_COUNT];
} microphone_characteristics_t;
typedef struct mic_info_t {
char device_id[AUDIO_MICROPHONE_ID_MAX_LEN];
uint32_t channel_count;
audio_microphone_channel_mapping_t channel_mapping[AUDIO_CHANNEL_COUNT_MAX];
} mic_info_t;
typedef struct snd_device_to_mic_map_t {
mic_info_t microphones[AUDIO_MICROPHONE_MAX_COUNT];
uint32_t mic_count;
} snd_device_to_mic_map_t;
class AudioPatch{
public:
enum PatchType{
PATCH_NONE = -1,
PATCH_PLAYBACK,
PATCH_CAPTURE,
PATCH_DEVICE_LOOPBACK
};
AudioPatch() = default;
AudioPatch(PatchType patch_type,
const std::vector<struct audio_port_config>& sources,
const std::vector<struct audio_port_config>& sinks);
protected:
enum PatchType type = PATCH_NONE;
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
std::vector<struct audio_port_config> sources, sinks;
static audio_patch_handle_t generate_patch_handle_l();
friend class AudioDevice;
};
class AudioDevice {
public:
~AudioDevice();
static std::shared_ptr<AudioDevice> GetInstance();
static std::shared_ptr<AudioDevice> GetInstance(audio_hw_device_t* device);
int Init(hw_device_t **device, const hw_module_t *module);
std::shared_ptr<StreamOutPrimary> CreateStreamOut(
audio_io_handle_t handle,
const std::set<audio_devices_t> &devices,
audio_output_flags_t flags,
struct audio_config *config,
audio_stream_out **stream_out,
const char *address);
void CloseStreamOut(std::shared_ptr<StreamOutPrimary> stream);
int CreateAudioPatch(audio_patch_handle_t* handle,
const std::vector<struct audio_port_config>& sources,
const std::vector<struct audio_port_config>& sinks);
int ReleaseAudioPatch(audio_patch_handle_t handle);
int SetGEFParam(void *data, int length);
int GetGEFParam(void *data, int *length);
std::shared_ptr<StreamOutPrimary> OutGetStream(audio_io_handle_t handle);
std::shared_ptr<StreamOutPrimary> OutGetStream(audio_stream_t* audio_stream);
std::shared_ptr<StreamInPrimary> CreateStreamIn(
audio_io_handle_t handle,
const std::set<audio_devices_t> &devices,
audio_input_flags_t flags,
struct audio_config *config,
const char *address,
audio_stream_in **stream_in,
audio_source_t source);
void CloseStreamIn(std::shared_ptr<StreamInPrimary> stream);
std::shared_ptr<StreamInPrimary> InGetStream(audio_io_handle_t handle);
std::shared_ptr<StreamInPrimary> InGetStream(audio_stream_t* stream_in);
std::shared_ptr<AudioVoice> voice_;
int SetMicMute(bool state);
bool mute_;
int GetMicMute(bool *state);
int SetParameters(const char *kvpairs);
char* GetParameters(const char *keys);
int SetMode(const audio_mode_t mode);
int SetVoiceVolume(float volume);
void SetChargingMode(bool is_charging);
void FillAndroidDeviceMap();
int GetPalDeviceIds(
const std::set<audio_devices_t>& hal_device_id,
pal_device_id_t* pal_device_id);
int usb_card_id_;
int usb_dev_num_;
int dp_controller;
int dp_stream;
int num_va_sessions_ = 0;
pal_speaker_rotation_type current_rotation;
static card_status_t sndCardState;
std::mutex adev_init_mutex;
std::mutex adev_perf_mutex;
uint32_t adev_init_ref_count = 0;
int32_t perf_lock_acquire_cnt = 0;
hw_device_t *GetAudioDeviceCommon();
int perf_lock_handle;
int perf_lock_opts[MAX_PERF_LOCK_OPTS];
int perf_lock_opts_size;
bool hdr_record_enabled = false;
bool wnr_enabled = false;
bool ans_enabled = false;
bool orientation_landscape = true;
bool inverted = false;
int facing = 0; /*0 - none, 1 - back, 2 - front/selfie*/
int hdr_channel_count = 0;
int hdr_sample_rate = 0;
int cameraOrientation = CAMERA_DEFAULT;
bool hac_voip = false;
bool usb_input_dev_enabled = false;
bool usb_out_headset = false;
static bool mic_characteristics_available;
static microphone_characteristics_t microphones;
static snd_device_to_mic_map_t microphone_maps[PAL_MAX_INPUT_DEVICES];
static bool find_enum_by_string(const struct audio_string_to_enum * table, const char * name,
int32_t len, unsigned int *value);
static bool set_microphone_characteristic(struct audio_microphone_characteristic_t *mic);
static int32_t get_microphones(struct audio_microphone_characteristic_t *mic_array, size_t *mic_count);
static void process_microphone_characteristics(const XML_Char **attr);
static bool is_input_pal_dev_id(int deviceId);
static void process_snd_dev(const XML_Char **attr);
static bool set_microphone_map(pal_device_id_t in_snd_device, const mic_info_t *info);
static bool is_built_in_input_dev(pal_device_id_t deviceId);
static void process_mic_info(const XML_Char **attr);
int32_t get_active_microphones(uint32_t channels, pal_device_id_t id,
struct audio_microphone_characteristic_t *mic_array,
uint32_t *mic_count);
static void xml_start_tag(void *userdata, const XML_Char *tag_name,
const XML_Char **attr);
static void xml_end_tag(void *userdata, const XML_Char *tag_name);
static void xml_char_data_handler(void *userdata, const XML_Char *s, int len);
static int parse_xml();
protected:
AudioDevice() {}
std::shared_ptr<AudioVoice> VoiceInit();
static std::shared_ptr<AudioDevice> adev_;
static std::shared_ptr<audio_hw_device_t> device_;
std::vector<std::shared_ptr<StreamOutPrimary>> stream_out_list_;
std::vector<std::shared_ptr<StreamInPrimary>> stream_in_list_;
std::mutex out_list_mutex;
std::mutex in_list_mutex;
std::mutex patch_map_mutex;
btsco_lc3_cfg_t btsco_lc3_cfg;
bool bt_lc3_speech_enabled;
void *offload_effects_lib_;
offload_effects_start_output fnp_offload_effect_start_output_ = nullptr;
offload_effects_stop_output fnp_offload_effect_stop_output_ = nullptr;
bool is_charging_;
void *visualizer_lib_;
visualizer_hal_start_output fnp_visualizer_start_output_ = nullptr;
visualizer_hal_stop_output fnp_visualizer_stop_output_ = nullptr;
std::map<audio_devices_t, pal_device_id_t> android_device_map_;
std::map<audio_patch_handle_t, AudioPatch*> patch_map_;
int add_input_headset_if_usb_out_headset(int *device_count, pal_device_id_t** pal_device_ids, bool conn_state);
};
static inline uint32_t lcm(uint32_t num1, uint32_t num2)
{
uint32_t high = num1, low = num2, temp = 0;
if (!num1 || !num2)
return 0;
if (num1 < num2) {
high = num2;
low = num1;
}
while (low != 0) {
temp = low;
low = high % low;
high = temp;
}
return (num1 * num2)/high;
}
static inline uint32_t nearest_multiple(uint32_t num, uint32_t multiplier)
{
uint32_t remainder = 0;
if (!multiplier)
return num;
remainder = num % multiplier;
if (remainder)
num += (multiplier - remainder);
return num;
}
#endif //ANDROID_HARDWARE_AHAL_ADEVICE_H_