概述
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
最后
以上就是干净牛排为你收集整理的【Android AudioFrameWork】AudioPolicyManager loadHwModule详解的全部内容,希望文章能够帮你解决【Android AudioFrameWork】AudioPolicyManager loadHwModule详解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复