本文基于android7.0分析
在介绍解析音频配置文件文章中 已经说了,系统音频库的加载与否取决audio_policy.conf
是否有配置其信息。
当将audio_policy.conf
解析完成之后,接下来就是根据解析好的配置文件数据去加载系统音频库,我们继续看到
AudioPolicyManager.cpp
构造函数,源码位于:
\frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.cpp
...
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
:
#ifdef AUDIO_POLICY_TEST
Thread(false),
#endif //AUDIO_POLICY_TEST
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
mA2dpSuspended(false),
mAudioPortGeneration(1),
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
mBeaconMuted(false),
mTtsOutputAvailable(false),
mMasterMono(false)
{
...
for (size_t i = 0; i < mHwModules.size(); i++) {
mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
if (mHwModules[i]->mHandle == 0) {
ALOGW("could not open HW module %s", mHwModules[i]->getName());
continue;
}
...
}
...
}
mpClientInterface 常量为 AudioPolicyClientInterface对象
,源码位于:
\hardware\libhardware_legacy\include\hardware_legacy\AudioPolicyClientInterface.h
AudioPolicyClient对象
,实现 AudioPolicyClientInterface.h
AudioPolicyClient对象
定义在
\frameworks\av\services\audiopolicy\service\AudioPolicyService.h
AudioPolicyClient对象
实现在:
\frameworks\av\services\audiopolicy\service\AudioPolicyClientImpl.cpp
遍历 解析配置文件后的 mHwModules 所有的子HwModule ,
从 mHwModules[i]->getName()
可以看到加载系统音频库只用到了 HwModule 的name 属性值
以 primary
为例子
找到 AudioPolicyClient对象
实现
audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
ALOGW("%s: could not get AudioFlinger", __func__);
return AUDIO_MODULE_HANDLE_NONE;
}
return af->loadHwModule(name);
最终调用到 AudioFlinger
源码位于:
\frameworks\av\services\audioflinger\AudioFlinger.cpp
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{
if (name == NULL) {
return AUDIO_MODULE_HANDLE_NONE;
}
if (!settingsAllowed()) {
return AUDIO_MODULE_HANDLE_NONE;
}
Mutex::Autolock _l(mLock);
return loadHwModule_l(name);
}
// loadHwModule_l() must be called with AudioFlinger::mLock held
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
ALOGW("loadHwModule() module %s already loaded", name);
return mAudioHwDevs.keyAt(i);
}
}
audio_hw_device_t *dev;
int rc = load_audio_interface(name, &dev);
if (rc) {
ALOGE("loadHwModule() error %d loading module %s", rc, name);
return AUDIO_MODULE_HANDLE_NONE;
}
mHardwareStatus = AUDIO_HW_INIT;
rc = dev->init_check(dev);
mHardwareStatus = AUDIO_HW_IDLE;
if (rc) {
ALOGE("loadHwModule() init check error %d for module %s", rc, name);
return AUDIO_MODULE_HANDLE_NONE;
}
// Check and cache this HAL's level of support for master mute and master
// volume. If this is the first HAL opened, and it supports the get
// methods, use the initial values provided by the HAL as the current
// master mute and volume settings.
AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
{ // scope for auto-lock pattern
AutoMutex lock(mHardwareLock);
if (0 == mAudioHwDevs.size()) {
mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
if (NULL != dev->get_master_volume) {
float mv;
if (OK == dev->get_master_volume(dev, &mv)) {
mMasterVolume = mv;
}
}
mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
if (NULL != dev->get_master_mute) {
bool mm;
if (OK == dev->get_master_mute(dev, &mm)) {
mMasterMute = mm;
}
}
}
mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
if ((NULL != dev->set_master_volume) &&
(OK == dev->set_master_volume(dev, mMasterVolume))) {
flags = static_cast<AudioHwDevice::Flags>(flags |
AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
}
mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
if ((NULL != dev->set_master_mute) &&
(OK == dev->set_master_mute(dev, mMasterMute))) {
flags = static_cast<AudioHwDevice::Flags>(flags |
AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
}
mHardwareStatus = AUDIO_HW_IDLE;
}
audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",
name, dev->common.module->name, dev->common.module->id, handle);
return handle;
}
可以看到 mAudioHwDevs 是一个
DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*> mAudioHwDevs;
key value 的集合容器,
通过 mAudioHwDevs 容器 装载所有的系统音频对象 AudioHwDevice
AudioHwDevice对象
位于:
\frameworks\av\services\audioflinger\AudioHwDevice.h
加载每个音频库之前,会遍历 mAudioHwDevs 中是否已经加载,加载成功则不会再次加载
如果没有加载,则来到 load_audio_interface
函数
static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
{
const hw_module_t *mod;
int rc;
rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,
AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
if (rc) {
goto out;
}
rc = audio_hw_device_open(mod, dev);
ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__,
AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
if (rc) {
goto out;
}
if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
rc = BAD_VALUE;
goto out;
}
return 0;
out:
*dev = NULL;
return rc;
}
可以看到其实就是一个系统硬件抽象层加载过程,这里不再累赘,大家参考之前的文章:
Android开发之HAL层
加载成功后,输出音频硬件抽象层模块音频设备结构体,audio_hw_device_t
,作为AudioHwDevice
对象的第三个参数
定义在:hardware\libhardware\include\hardware\audio.h
struct audio_hw_device {
/**
* Common methods of the audio device. This *must* be the first member of audio_hw_device
* as users of this structure will cast a hw_device_t to audio_hw_device pointer in contexts
* where it's known the hw_device_t references an audio_hw_device.
*/
struct hw_device_t common;
/**
* used by audio flinger to enumerate what devices are supported by
* each audio_hw_device implementation.
*
* Return value is a bitmask of 1 or more values of audio_devices_t
*
* NOTE: audio HAL implementations starting with
* AUDIO_DEVICE_API_VERSION_2_0 do not implement this function.
* All supported devices should be listed in audio_policy.conf
* file and the audio policy manager must choose the appropriate
* audio module based on information in this file.
*/
uint32_t (*get_supported_devices)(const struct audio_hw_device *dev);
/**
* check to see if the audio hardware interface has been initialized.
* returns 0 on success, -ENODEV on failure.
*/
int (*init_check)(const struct audio_hw_device *dev);
/** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
int (*set_voice_volume)(struct audio_hw_device *dev, float volume);
/**
* set the audio volume for all audio activities other than voice call.
* Range between 0.0 and 1.0. If any value other than 0 is returned,
* the software mixer will emulate this capability.
*/
int (*set_master_volume)(struct audio_hw_device *dev, float volume);
/**
* Get the current master volume value for the HAL, if the HAL supports
* master volume control. AudioFlinger will query this value from the
* primary audio HAL when the service starts and use the value for setting
* the initial master volume across all HALs. HALs which do not support
* this method may leave it set to NULL.
*/
int (*get_master_volume)(struct audio_hw_device *dev, float *volume);
/**
* set_mode is called when the audio mode changes. AUDIO_MODE_NORMAL mode
* is for standard audio playback, AUDIO_MODE_RINGTONE when a ringtone is
* playing, and AUDIO_MODE_IN_CALL when a call is in progress.
*/
int (*set_mode)(struct audio_hw_device *dev, audio_mode_t mode);
/* mic mute */
int (*set_mic_mute)(struct audio_hw_device *dev, bool state);
int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state);
/* set/get global audio parameters */
int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs);
/*
* Returns a pointer to a heap allocated string. The caller is responsible
* for freeing the memory for it using free().
*/
char * (*get_parameters)(const struct audio_hw_device *dev,
const char *keys);
/* Returns audio input buffer size according to parameters passed or
* 0 if one of the parameters is not supported.
* See also get_buffer_size which is for a particular stream.
*/
size_t (*get_input_buffer_size)(const struct audio_hw_device *dev,
const struct audio_config *config);
/** This method creates and opens the audio hardware output stream.
* The "address" parameter qualifies the "devices" audio device type if needed.
* The format format depends on the device type:
* - Bluetooth devices use the MAC address of the device in the form "00:11:22:AA:BB:CC"
* - USB devices use the ALSA card and device numbers in the form "card=X;device=Y"
* - Other devices may use a number or any other string.
*/
int (*open_output_stream)(struct audio_hw_device *dev,
audio_io_handle_t handle,
audio_devices_t devices,
audio_output_flags_t flags,
struct audio_config *config,
struct audio_stream_out **stream_out,
const char *address);
void (*close_output_stream)(struct audio_hw_device *dev,
struct audio_stream_out* stream_out);
/** This method creates and opens the audio hardware input stream */
int (*open_input_stream)(struct audio_hw_device *dev,
audio_io_handle_t handle,
audio_devices_t devices,
struct audio_config *config,
struct audio_stream_in **stream_in,
audio_input_flags_t flags,
const char *address,
audio_source_t source);
void (*close_input_stream)(struct audio_hw_device *dev,
struct audio_stream_in *stream_in);
/** This method dumps the state of the audio hardware */
int (*dump)(const struct audio_hw_device *dev, int fd);
/**
* set the audio mute status for all audio activities. If any value other
* than 0 is returned, the software mixer will emulate this capability.
*/
int (*set_master_mute)(struct audio_hw_device *dev, bool mute);
/**
* Get the current master mute status for the HAL, if the HAL supports
* master mute control. AudioFlinger will query this value from the primary
* audio HAL when the service starts and use the value for setting the
* initial master mute across all HALs. HALs which do not support this
* method may leave it set to NULL.
*/
int (*get_master_mute)(struct audio_hw_device *dev, bool *mute);
/**
* Routing control
*/
/* Creates an audio patch between several source and sink ports.
* The handle is allocated by the HAL and should be unique for this
* audio HAL module. */
int (*create_audio_patch)(struct audio_hw_device *dev,
unsigned int num_sources,
const struct audio_port_config *sources,
unsigned int num_sinks,
const struct audio_port_config *sinks,
audio_patch_handle_t *handle);
/* Release an audio patch */
int (*release_audio_patch)(struct audio_hw_device *dev,
audio_patch_handle_t handle);
/* Fills the list of supported attributes for a given audio port.
* As input, "port" contains the information (type, role, address etc...)
* needed by the HAL to identify the port.
* As output, "port" contains possible attributes (sampling rates, formats,
* * channel masks, gain controllers...) for this port.
*/
int (*get_audio_port)(struct audio_hw_device *dev,
struct audio_port *port);
/* Set audio port configuration */
int (*set_audio_port_config)(struct audio_hw_device *dev,
const struct audio_port_config *config);
};
typedef struct audio_hw_device audio_hw_device_t;
看到audio_hw_device_t
也可以验证之前我们在Android开发之HAL层
提到的硬件抽象层模块的每一个硬件设备都必须自定义一个硬件设备结构体,且他的第一个成员变量的类型必须是hw_device_t ,且里面定义了许多其他的函数指针,
接着会以此调用其 函数指针 init_check、get_master_volume、get_master_mute、set_master_volume、set_master_mute
并同时赋予hardware_call_state
状态,依次为:AUDIO_HW_INIT、AUDIO_HW_IDLE、AUDIO_HW_GET_MASTER_VOLUME、AUDIO_HW_GET_MASTER_MUTE、AUDIO_HW_SET_MASTER_VOLUME、AUDIO_HW_SET_MASTER_MUTE、AUDIO_HW_IDLE
hardware_call_state
定义在:
\frameworks\av\services\audioflinger\AudioFlinger.h
// for dump, indicates which hardware operation is currently in progress (but not stream ops)
enum hardware_call_state {
AUDIO_HW_IDLE = 0, // no operation in progress
AUDIO_HW_INIT, // init_check
AUDIO_HW_OUTPUT_OPEN, // open_output_stream
AUDIO_HW_OUTPUT_CLOSE, // unused
AUDIO_HW_INPUT_OPEN, // unused
AUDIO_HW_INPUT_CLOSE, // unused
AUDIO_HW_STANDBY, // unused
AUDIO_HW_SET_MASTER_VOLUME, // set_master_volume
AUDIO_HW_GET_ROUTING, // unused
AUDIO_HW_SET_ROUTING, // unused
AUDIO_HW_GET_MODE, // unused
AUDIO_HW_SET_MODE, // set_mode
AUDIO_HW_GET_MIC_MUTE, // get_mic_mute
AUDIO_HW_SET_MIC_MUTE, // set_mic_mute
AUDIO_HW_SET_VOICE_VOLUME, // set_voice_volume
AUDIO_HW_SET_PARAMETER, // set_parameters
AUDIO_HW_GET_INPUT_BUFFER_SIZE, // get_input_buffer_size
AUDIO_HW_GET_MASTER_VOLUME, // get_master_volume
AUDIO_HW_GET_PARAMETER, // get_parameters
AUDIO_HW_SET_MASTER_MUTE, // set_master_mute
AUDIO_HW_GET_MASTER_MUTE, // get_master_mute
};
并且set_master_volume
成功调用返回OK
,将flags设置为AHWD_CAN_SET_MASTER_VOLUME
,set_master_mute
成功调用返回OK
,则设置为AHWD_CAN_SET_MASTER_MUTE
,如果两者都成功调用OK
,则flags设置为AHWD_CAN_SET_MASTER_VOLUME+AHWD_CAN_SET_MASTER_MUTE
,作为AudioHwDevice
对象的第四个参数。
最后添加到mAudioHwDevs容器
,其中一个音频抽象层动态连接库就加载完成。