【Android AudioFrameWork】AudioPolicyManager loadHwModule详解

AudioPolicyManager 构造函数中,
第一步是解析audio policy相关的xml文件,
第二步就是根据xml中hal的name来加载对应的audio hal,
直接上loadHwModule的流程图(以android 8.1.0版本为例).

在这里插入图片描述

局部函数详解:
1、load 函数
打开对应.so后,加载 struct audio_module HAL_MODULE_INFO_SYM 结构体地址,
并强转为 struct hw_module_t* 类型

2、audio_hw_device_open 函数
调用audio hal中audio_module (等价于audio_module_t)的methods中的open函数.
即audio_hw中hal_module_methods的open函数,即 adev_open

3、primary audio hal中的 adev_open 函数
申请一全局的audio_device adev 结构体填充各种数据,返回 adev->device.common(hw_device_t类型)的地址,
强转为audio_hw_device_t (即struct audio_hw_device) 类型

从流程图看出,

1. loadHwModule 本质

loadHwModule本质在于 openDevice,即打开对应的audio hal,
返回一sp<DeviceHalInterface> device 的句柄,
(见DevicesFactoryHalHybrid::openDevice, 如下:);

status_t DevicesFactoryHalHybrid::openDevice(const char *name, sp<DeviceHalInterface> *device) {
   	if (mHidlFactory != 0 && strcmp(AUDIO_HARDWARE_MODULE_ID_A2DP, name) != 0) {
        	return mHidlFactory->openDevice(name, device);
    	}
    	return mLocalFactory->openDevice(name, device);
}

从代码可以看出, A2DP audio hal 使用local模式,其余的audio hal使用 hidl模式

2. openDevice 本质

loadHwModule中返回的device本质为 new DeviceHalHidl(result), result的类型 sp<IDevice> result,
(见 DevicesFactoryHalHidl::openDevice, 如下);

status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
    if (mDevicesFactory == 0) return NO_INIT;
    IDevicesFactory::Device hidlDevice;
    status_t status = nameFromHal(name, &hidlDevice);
    if (status != OK) return status;
    Result retval = Result::NOT_INITIALIZED;
    Return<void> ret = mDevicesFactory->openDevice(
            hidlDevice,
            [&](Result r, const sp<IDevice>& result) {
                retval = r;
                if (retval == Result::OK) {
                    *device = new DeviceHalHidl(result);
                }
            });
    if (ret.isOk()) {
        if (retval == Result::OK) return OK;
        else if (retval == Result::INVALID_ARGUMENTS) return BAD_VALUE;
        else return NO_INIT;
    }
    return FAILED_TRANSACTION;
}
3. DevicesFactoryHalHidl::openDevice 内result的由来

result本质为 new PrimaryDevice(halDevice), 或 new Device(halDevice)
(见DevicesFactory::openDevice, 如下:);

Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb)  {
    audio_hw_device_t *halDevice;
    Result retval(Result::INVALID_ARGUMENTS);
    sp<IDevice> result;
    const char* moduleName = deviceToString(device);
    if (moduleName != nullptr) {
        int halStatus = loadAudioInterface(moduleName, &halDevice);
        if (halStatus == OK) {
            if (device == IDevicesFactory::Device::PRIMARY) {
                result = new PrimaryDevice(halDevice);
            } else {
                result = new ::android::hardware::audio::V2_0::implementation::
                    Device(halDevice);
            }
            retval = Result::OK;
        } else if (halStatus == -EINVAL) {
            retval = Result::NOT_INITIALIZED;
        }
    }
    _hidl_cb(retval, result);
    return Void();
}

从代码可以看出, primary audio hal, 通过PrimaryDevice访问 Device类
而 usb audio hal 和 r_submix hal 直接访问 Device类

4. halDevice的由来

halDevice类型为 audio_hw_device_t* (又称 struct audio_hw_device*), 本质是底层audio hal (如 audio_hw.c)返回的一个全局变量struct audio_device adev 中的成员 adev->device.common (struct hw_device_t 类型)的地址,并强转为的struct audio_hw_device类型,
(注:struct audio_hw_device结构体的第一个成员是 struct hw_device_t类型,故上层使用返回的地址时(上层为mDevice),即在使用struct audio_hw_device类型的变量,即 adev->device, 故上层可以通过mDevice直接调用底层的各种函数方法.)

最后,笔者所研究的平台,Audio HAL 共有四个,分别为 primary, a2dp, usb 和 r_submix.
其中,a2dp audio hal仍然使用Local模式,其余三种使用Hidl模式。
最常用的是 primary audio hal, 几乎囊括了所有audio的场景,所以研究audio hal,主要研究 primary audio hal即可。

备注: 此文中流程图下载链接,如没有积分无法下载,可以留言邮箱,邮件给你。
https://download.csdn.net/download/u012188065/10811494

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值