Android Audio系统分析(二)加载HAL

我们知道,最终控制是从AudioFlinger调用了HAL层的,那么这文就从AudioFlinger开始分析

AudioFlinger初始化

frameworks/av/media/mediaserver/main_mediaserver.cpp

1
2
3
4
int main(int argc __unused, char** argv)
{
AudioFlinger::instantiate();
}

frameworks/av/services/audioflinger/AudioFlinger.cpp

1
2
3
4
5
6
class AudioFlinger :
public BinderService<AudioFlinger>,
public BnAudioFlinger
{

}

frameworks/native/include/binder/BinderService.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}

static void instantiate() { publish(); }
};

这里可以看到,最终调用publish()就是一套进程间Service,初始化是通过强指针引用(constsp&),将AudioFlinger参考初始化为实体,供外部调用。

加载

frameworks/av/services/audioflinger/AudioFlinger.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static const char * const audio_interfaces[] = {
AUDIO_HARDWARE_MODULE_ID_PRIMARY,/*"primary" - 本机中的codec - hardware/libhardware/include/hardware/audio.h*/
AUDIO_HARDWARE_MODULE_ID_A2DP,/*"a2dp" - a2dp设备,蓝牙高保真音频*/
AUDIO_HARDWARE_MODULE_ID_USB,/*usb - usb-audio设备*/
};

AudioFlinger::AudioHwDevice* AudioFlinger::findSuitableHwDev_l(
audio_module_handle_t module,
audio_devices_t devices)
{
for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
loadHwModule_l(audio_interfaces[i]);
}

audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
int rc = load_audio_interface(name, &dev);
}
1
2
3
4
5
6
7
static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
{
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));
rc = audio_hw_device_open(mod, dev);
}

hardware/libhardware/hardware.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module)
{
if (inst)
snprintf(name, PATH_MAX, "%s.%s", class_id, inst);
else
strlcpy(name, class_id, PATH_MAX);

snprintf(prop_name, sizeof(prop_name), "ro.hardware.%s", name);
if (property_get(prop_name, prop, NULL) > 0) {
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}

/* Loop through the configuration variants looking for a module */
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT; i++) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
if (hw_module_exists(path, sizeof(path), name, prop) == 0) {
goto found;
}
}

/* Nothing found, try the default */
if (hw_module_exists(path, sizeof(path), name, "default") == 0) {
goto found;
}
}

frameworks/av/services/audioflinger/AudioFlinger.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
/* 1. 定义audio_hw_device_t 结构指针 */
audio_hw_device_t *dev;

/* 2. 传入引用 */
int rc = load_audio_interface(name, &dev);
rc = dev->init_check(dev);

/* 3. 存至类成员中mAudioHwDevs */
audio_module_handle_t handle = nextUniqueId();
mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
}

这里是从findSuitableHwDev_l开始,调用位置在上一篇有入口,这里就不多提了

最终打开的路经为:/system/lib/hw/audio.primary.rk30board.so参考,最终接入口传在了audio_hw_device_t指针结构体中

注:audio_hw_device_t结构体定义位置:/libhardware/include/hardware/audio.h

所以,此时,hal的audio已经化身了AudioHwDevice类,audio_hw_device_t变成了类成员mHwDevice(hwDevice)

frameworks/av/services/audioflinger/AudioFlinger.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class AudioHwDevice {
public:
enum Flags {
AHWD_CAN_SET_MASTER_VOLUME = 0x1,
AHWD_CAN_SET_MASTER_MUTE = 0x2,
};

AudioHwDevice(audio_module_handle_t handle,
const char *moduleName,
audio_hw_device_t *hwDevice,
Flags flags)
: mHandle(handle), mModuleName(strdup(moduleName))
, mHwDevice(hwDevice)
, mFlags(flags) { }
audio_hw_device_t *hwDevice() const { return mHwDevice; }
};

从构造函数来看,接下来就是搜hwDevice()方法,在AudioFlinger.cpp有好多地方调用,它就是hal的audio

文章作者: 二十I邊界
文章链接: https://xuie0000.com/post/2016-10-24-2019/Android-Audio系统分析(二)加载HAL.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 二十I邊界