文章目录

    • 一、HAL综述
    • 二、Android各版本HAL的演进
    • 三、传统HAL(<= Android7)
    • 四、HIDL HAL(Android8-10)
      • 1、参考资料
      • 2、概述
      • 2、架构
      • 3、实现一个HIDL HAL
        • 1)HIDL的开发流程
        • 2)HIDL HAL的语法
        • 3)创建HAL接口&生成impl库
        • 4)Service实现
        • 5)Client实现
        • 6)Configurations
      • 4、Passthroug HALS实例分析
      • 5、binderied实例分析
      • 6、same-process HAL
    • 五、AIDL HAL(>=Android11)
      • 1、概述
      • 2、架构
      • 3、AIDL开发流程
      • 4、AIDL-HAL实例分析
        • 1)创建HAL接口&生成impl接口
        • 2)aidl-Service
        • 3)aidl-client-1
        • 4)aidl-client-2
      • 5、stable-c实例分析
      • 6、实现一个ADIL
    • 六、小结
      • 1、AIDL和HIDL的区别?
      • 2、较新的Android版本,如AN14上有多个版本的hal?
      • 3、配置这么多,如何掌握?
      • 4、Binder RPC 、HWBinder RPC 、AIDL for Hal区别?

参考资料:

1、阿豪讲Framework:https://juejin.cn/user/342703355728382/posts

2、术语

1、VINTF : Vendor interface

一、HAL综述

1、HAL:Hardware Abstraction Layer

2、HAL存在的意义

1)HAL是对驱动操作的包装库,操作硬件的具体逻辑可以放到 HAL中(属于算法,如果这部分暴露的话 会让友商反推出硬件IP Core的设计),驱动程序本身只提供基本寄存器操作功能。

3、不同版本的HAL(传统HAL、HIDL HAL、AIDL HAL)开发流程是不同的,HAL(so库)与HIDL/AIDL(进程间通信)要区分开,从推出时间来分类,如下
1)Android 8以前 -> HAL层 以so库和.h文件存在 - 传统HAL
2)Android 8-10 -> HAL层 以进程方式存在 - HIDL HAL
3)Android 10 -> HAL层 以进程方式存在 - AIDL HAL

注意以上Android版本是推出时间,实际上高版本的Android混杂着各个HAL版本(比如Android13 Audio用的是hidl),实在让人混乱!

4、HAL库所在的代码目录

hardware/* 部分厂商开源的硬件适配层HAL代码

hardware/libhardware_legacy //旧的HAL层库

hardware/libhardware //HAL层实库

5、厂家闭源,厂家需要实现什么?

通过OS里面开源例子来了解学习

二、Android各版本HAL的演进

1、参考资料

1)Android8 HAL变迁: https://juejin.cn/post/7359954143916425251

2) Android HIDL HAL 接口定义语言详解:https://blog.csdn.net/qq_19923217/article/details/88398660

3)AN14 添加HAL层:https://blog.csdn.net/baidu_41666295/article/details/145503951

每一篇博文 都有参考的意义(不同开发者的知识域都不同,角度不同 即表述的内容也不同,应该各取精华)

2、Android版本对HAL有过几次改革,因此需要了解演进的背景和变化对理解几种HAL层的设计有很大的帮助;

1)尤其是网络上的各类资料,充斥着不同的Android版本,注意区分和分辨;

2)在不同版本上又应该如何选择实现HAL的方式?首先确定硬件厂商,而厂商不同,各自的选择也不同~

3、先理解Android系统各厂家合作模式:
在这里插入图片描述

1)Google : 负责Android系统开发、维护、迭代;

2)芯片厂商:负责适配硬件(vendor),定制Framework,有实力的话会帮忙解bug,加特性;

3)终端厂商:负责进一步定制Framework,有实力的话也会解BUG和加特性;

4、Treble架构(Android 8 / O)

由于系统发布比较频繁,而芯片厂和厂商更新版本代价较高(移植适配,测试耗时耗力),导致下游厂家不愿升级,间接损害Google的利益,Google为了解决升级问题,将芯片厂商从Framework抽离开来,实现互相升级不受影响,这就是Android8引入的Treble架构(代价是大大增加了复杂度),看图:
在这里插入图片描述

1、划分之后,System(放Framework部分)/ Vendor(放厂商部分)分区中的native程序/库(NDK)只能链接各自的库,而这由系统权限设置管理,Framework要访问Vendor的HAL接口,只能通过进程间通信实现;

扩展,Android 9推出product分区(存放终端厂商的针对特定设备的系统配置、应用程序、资源文件)

2、但难免有vendor和Framework互相依赖库,这些“特别的库”被分类出来如下(了解下即可)
1)LL-NDK(low level vendor native development kit),可以framework和vender进程链接,由google来维护,例子:
libEGL.so
libGLESv1_CM.so
libvndksupport.so
2)VNDK : Vendor Native Development Kit(Android 8.0引入,将系统分区和供应商分区分离,保持Android核心系统的纯净性,供应商可以使用VNDK开发自己的HAL,包含在system.img中 - 即VNDK升级与否让供应商决定,可以不升级在新的Android版本上使用)

目录示例:
android\prebuilts\vndk\v30\arm\arch-arm-armv7-a-neon\shared\vndk-coreVNDK深入剖析:https://blog.csdn.net/learnframework/article/details/134889443
bp中使用proprietary/vendor-only指定

3)SP-HAL:same-Process HAL(framework负责加载的hal库,由google来维护),链接的so库 称为VNDK-SP,需为VNDK或LL-NDK, 例子:
android.hardware.graphics.mapper@2.0-impl.so
android.hardware.renderscrip@1.0-impl.so
4)VNDK-SP:链接LL-NDK/VNDK的SP-HAL

这些特性怎么体现?

1、由SEpolicy强制执行,在te文件或Andorid.bp指定属性;

目录示例:
android\prebuilts\vndk\v30\arm\arch-arm-armv7-a-neon\shared\vndk-sp

3、随着库和进程被隔离开,Framework访问HAL层只能通过进程通信的方式,因此基于binder设计出HIDL HAL;

4、进一步地,Android9之后推出apex,同样也是为了方便第三方对系统组件的更新;

三、传统HAL(<= Android7)

1、HAL应知应会

1、传统的HAL,即厂家提供.so和.h,在需要访问硬件的时候dlopen,调用对应接口
>>既然是厂家实现,Google需要提供demo以保证规范,在哪里?
以audio为例
1)
android\hardware\libhardware\modules\audio //旧架构
android\hardware\libhardware_legacy\audio //新架构
厂家参照这个demo实现自家的audio hal(使用哪个架构,视乎厂家,无论哪个架构,接口都是一样的),并生成so库提供第三方集成
2)qcom开源出来源码实现:
android\hardware\qcom\audio\hal  //对应新架构
android\hardware\qcom\audio\legacy //对应旧架构2、传统hal必须按照一定规范来写,用库函数 来加载3、传统的HAL在高版本被弃用?还有必要去了解?
1)没有完全弃用,Android推出新的架构,不会一下子丢弃旧的方式,厂商会逐渐过渡 甚至一直保留都有可能;

2、代码分析

1、在系统服务代码中使用以下方法加载 HAL 模块
const hw_module_t *module;
hw_get_module(AUDIO_HARDWARE_MODULE_ID, &module); //会根据名字去对应目录查找并加载具体实现如下:
1)
android\hardware\libhardware\hardware.c
typedef struct hw_module_t {struct hw_module_methods_t* methods;
}
2)
hw_get_module(const char *id, struct hw_module_t **module)
--hw_get_module_by_class(id, module)
----load(class_id, path, module)
------dlopen(path)
------dlsym(handle, sym) //找到结构体(hw_module_t),存在module指针中3)例:audio_hw_module实现
struct audio_hw_module{struct hw_module_t common;
};
struct audio_module HAL_MODULE_INFO_SYM = {.common = {.tag = HARDWARE_MODULE_TAG,.module_api_version = AUDIO_MODULE_API_VERSION_0_1,.hal_api_version = HARDWARE_HAL_API_VERSION,.id = AUDIO_HARDWARE_MODULE_ID,.name = "QCOM Audio HAL",.author = "Code Aurora Forum",.methods = &hal_module_methods,},
};2、HAL什么时候被加载?最好是对应服务拉起的时候去加载,而事实也是如此
比如AudioFlinger 在启动时通过 hw_get_module方法加载传统hal库,并调用 create() 方法实例化接口3、例:Vibrator(Vibrator实现相对简单易懂,是学习的好例子)
1)负责加载传统Vibrator HAL库对应的Service进程
frameworks/base/services/core/java/com/android/server/VibratorService.java //注意此传统hal service实现与AIDL hal实现的VibratorService 是有区别的!2)C语言中的继承
typedef struct vibrator_device {struct hw_device_t common;int (*vibrator_on)(struct vibrator_device* vibradev, unsigned int timeout_ms);int (*vibrator_off)(struct vibrator_device* vibradev);
} vibrator_device_t;
通过指针巧妙实现C语言中的“继承”,vibrator_device(子类) 和 hw_device_t(父类)指针可以相互转换

四、HIDL HAL(Android8-10)

1、参考资料

1)HIDL Hal 开发指南3-HIDL HAL实例程序: https://juejin.cn/post/7360612648043708456

2)Android HAL 与 HIDL 开发笔记:https://evilpan.com/2020/11/01/hidl-basics/

3)HIDL实战(千里马):https://juejin.cn/post/7336743827826065459

2、概述

1、HIDL HAL是什么?

1)HIDL全称HAL interface definition language,而HIDL HAL则为,使用HIDL语言描述HAL层的对外接口,

2)注意HIDL语言只是一个Google提供的辅助工具,必须使用?不是,自己也可以自行实现所有代码

2、与传统HAL的区别?

1)传统HAL:用户<->HAL<->驱动

2)HIDL HAL:用户(client) <-> HIDL(hidl-gen) <-> HAL(service) <-> 驱动

3、Android8后推出的,为了能独立升级Framework和Vendor,按照规定格式和步骤编写代码即可;

2、架构

在这里插入图片描述

1、进程间通讯

对应的设备节点:/dev/hwbinder、/dev/vndbinder

通讯模型:client -> hwbinder/vndbinder-> service -> … -> kernel

2、Client调用的角色通常是什么?

1)framework/vendor java/native进程

3、service的形式,如何分辨?

1)形式:func(client) →binder那套(.hal 文件→hidl-gen工具-> impl.so)→ func(service,一般进测名有@)

1、
console:/ $ ps -A | grep android.hardware
system         219     1    9728   4852 0                   0 S android.hardware.keymaster@3.0-service
audioserver    235     1   21268   8916 0                   0 S android.hardware.audio@2.0-service
bluetooth      236     1    7716   3408 0                   0 S android.hardware.bluetooth@1.0-service
cameraserver   237     1   28412  11948 0                   0 S android.hardware.camera.provider@2.4-service
media          238     1   10232   4312 0                   0 S android.hardware.cas@1.0-service2、
adb shell service list

2)HIDL HAL的库和进程 命名规范

1、@是分隔符,hidl-gen添加生成的,后面跟着版本号;

2、android.hardware.graphics.composer@1.0-service //Android.硬件.图形.合成器@版本号-服务端;

3)设备中的路径

system/bin/*

4、HIDL HAL的类型

1)根据service访问硬件的形式不同再细分为binderied和Passthrough;

2)为什么搞这么多分类?能简单的谁也不想复杂!

1、系统迭代升级带来的复杂度增加,不可避免;

2、涉及多个厂商,增加机制来实现互相配合;

3)文字总体来说不易理解和吸收,先上图
在这里插入图片描述

1、说明

passthrough:为了复用传统HAL,sevice按照传统HAL的一套去加载HAL so库;

binderied:sevice进程集成HAL层接口,直接访问硬件,优先使用这种,尤其是适配新硬件时;

另外Android还提供一种,直接framework进程,加载HAL层库访问硬件的方式,称为Same-Process HAL这样性能是最佳的,但不解耦;

2、passthrough、binderized、same-Process

binderized与passthrough的区别?>> hal的实现直接在HAL进程中,不再是传统so库
如何选择passthrough、binderized?passthrough是为了厂商过渡使用,而新的硬件应选择binderized方式;

3、实现一个HIDL HAL

通信流程:HIDL Client -> HIDL Service -> driver,重点实现Client->Service,访问driver按照类型后面逐一分析

1)HIDL的开发流程

先上图
在这里插入图片描述

3)说明

1、写一个HIDL HAL涉及的文件
1)可执行程序类:client、hidl.so、service
2)配置类:rc、te、current.txt 、xml
3)工具类(生成源码、bp):hidl_gen、sh2、hidl-gen + hal 工具只是一个“开发过程中”可选用的工具,自己编写也完全OK;
1)hidl_gen 生成HWBinder通信部分的框架,接口实现需要我们去填充
2)最终还是我们常见的形式:client <-> .so(.h) <-> service  //client完全调用so接口通讯即可,servie 有用户代码(实现接口)和用于进程间通讯的框架代码(这个也是纯调用so接口即可)3、谁来调用工具hidl_gen 根据hal生成框架代码?
1)可以使用shell调用工具;
2)也可以使用bp,新增字段hidl_interface,记得hal只是中间文件;3、aidl/hidl tool源码
android\system\tools\4、hidl lib
android\system\libhidl5、用到的的shell脚本
1)android\hardware\interfaces\update-makefiles.sh
source $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh  //将此sh的接口变量暴露出来,相当于include
do_makefiles_update \   //调用函数"android.hardware:hardware/interfaces" \"android.hidl:system/libhidl/transport"2)android\system\tools\hidl\update-makefiles-helper.sh
function do_makefiles_update() { //调用hidl-gen工具}
2)HIDL HAL的语法
1、从hidl-gen工具来理解hal
hidl-gen -o hardware/interfaces/hidl_example/1.0/default -Lc++-impl -randroid.hardware:hardware/interfaces android.hardware.hidl_example@1.0
-o //输出目录
-L //生成类型
-r //指定package_name:root_dir
android.hardware.hidl_example@1.0 //package name注意,在hal中包名和路径不是一一对应的,其中-r传入的相当于“环境变量”,用于映射包名 对应的实际路径
package android.hardware.hidl_example@1.0;  处理过程:根据包名(android.hardware)匹配根目录,拼接根目录:hardware/interfaces/hidl_example,其中“@”是hidl/aidl特有的语法,跟.其实是一样的,这样的设计有助于简化包名,import会更间接些;2、hal中的import语句 同 package 同理,需要配合hidl-gen工具使用
import @1.0::IBootControl;3、HIDL文件组成,与AIDL一样,分两部分:1)interface.hal与type.hal
4、default目录,由hidl_gen创建,用户指定:/hardware/interfaces/boot/1.0/default/4、hidl 的bp语法
1)
hidl_interface {interfaces:["android.hidl.base@1.0",   //依赖的接口,位于 system/libhidl/transport/base/1.0/IBase.hal,同时这也是package_name]
}
3)创建HAL接口&生成impl库
1、编写接口
package android.hardware.hidl_example@1.0;
interface IExample {write(string ioctl) generates (int32_t result, string value);
};
2、hidl-gen生成框架代码文件,也可以自己捣鼓实现
3、在代码文件 实现接口具体内容
4、hidl-gen生成Android.bp,也可以自己捣鼓实现
hidl_interface {name: "android.hardware.hidl_example@1.0",root: "android.hardware",srcs: ["Example.hal",],interfaces: ["android.hidl.base@1.0",],gen_java: true,
}注:hidl-gen会生成两部分:
1、需要暴露给开发者,生成在default/目录中
2、不需要暴露(getService等等),系统整编时会生成在out/soong/.intermediates/hardware/interfaces/
4)Service实现
1、与binder相似,较为统一和简单,使用hwbinder库接口注册服务
int main(int, char* []) {sp<IExample> hidl_example = new Example();configureRpcThreadpool(1, true /* callerWillJoin */);if (hidl_example->registerAsService() != OK) {ALOGE("registerAsService failed");return 1;}joinRpcThreadpool();ALOGE("Service exited");return 1;
}
5)Client实现
1、与binder相似,较为统一和简单,使用hwbinder库接口获取服务
int main() {android::sp<IExample> service = IExample::getService();if (service == nullptr) {printf("Failed to get service\n");return -1;}service->write("welcome to HIDL", [&]int32_t result, string value){printf("result %d %s\n", result, value.c_str());}); return 0;
}
6)Configurations
基础文件准备好,剩下就是将其对接系统,让系统帮我们做事!主要有几个部分
1、上电启动怎么做? -> rc 配置文件2、selinux限制权限怎么办? ->te 配置文件
1)接口hash值(通过函数所有的字符来计算hash值):/hardware/interfaces/current.txt
2)selinux - 规则先不管,只知道要加即可(main.te object.te object.txt)3、注册信息? -> manifest.xml 配置文件,
1)称为VINTF(vendor interface),注册hwservicemanager的服务需要添加一个VINTF对象,作用是用来收集设备信息并生成可查询的API,用xml格式表示,包含hal接口版本\binder类型等。
2)设备路径:vendor/etc/vintf/manifest.xml
3)为什么不放在代码里面填充?配置分离,调试的时候不需要重新编译,在线改就好!
4)一般格式
<hal format="hidl"><name>android.hardware.hidl_example</name><transport>hwbinder</transport><version>1.0</version><interface><name>IExample</name><instance>default</instance></interface>

4、Passthroug HALS实例分析

参考:https://juejin.cn/post/7361204571827535924

1)重点分析HIDL Service -> driver部分,

例子:hardware/interfaces/vibrator/1.0
为了复用传统HAL  >> 大部分都是这种?位于hardware/interfaces/都是这种,判断标准是?1、VINTF
<transport>hwbinder</transport>1、
AN9:
android\frameworks\base\services\core\jni\com_android_server_VibratorService.cpp一、HAL层服务端
1、android/hardware/interfaces/vibrator/1.0/default/service.cpp
defaultPassthroughServiceImplementation<IVibrator>();2、android/system/libhidl/transport/include/hidl/LegacySupport.h
defaultPassthroughServiceImplementation<IVibrator>();
--registerPassthroughServiceImplementation
----sp<Interface> service = Interface::getService(name, true /* getStub*/); //此接口由系统编译时生成,注意getStub参数传入true
----return service->registerAsService(name); //注册hal服务3、系统编译生成(根据hal的Android.bp文件生成)
out/soong/.intermediates/hardware/interfaces/vibrator/1.0/android.hardware.vibrator@1.0_genc++/gen/android/hardware/vibrator/1.0/VibratorAll.cpp
::android::sp<IVibrator> IVibrator::getService(const std::string &serviceName, const bool getStub) {return ::android::hardware::details::getServiceInternal<BpHwVibrator>(serviceName, true, getStub);
}3、android/system/libhidl/transport/include/hidl/HidlTransportSupport.h
getServiceInternal
--getRawServiceInternal4、system/libhidl/transport/ServiceManagement.cpp
1) getRawServiceInternal
--sm = defaultServiceManager1_1();// 获取 HwServiceManager 代理端对象。
--Return<Transport> transportRet = sm->getTransport(descriptor, instance); //获取vintf中的transport参数passthrough HAL 是 hwbinder
--
if (getStub || vintfPassthru || vintfLegacy) {const sp<IServiceManager> pm = getPassthroughServiceManager();if (pm != nullptr) {sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr); //调用PassthroughServiceManager 的 get 函数if (!getStub || trebleTestingOverride) {base = wrapPassthrough(base);}return base;}}2) Return<sp<IBase>> get(const hidl_string& fqName, const hidl_string& name) override {openLibs()ret = (*generator)(name.c_str()); //调用HIDL_FETCH_IVibrator加载传统HAL库
}5、android/hardware/interfaces/vibrator/1.0/default/Vibrator.cpp
IVibrator* HIDL_FETCH_IVibrator(const char * /*hal*/) {vibrator_device_t *vib_device;const hw_module_t *hw_module = nullptr;int ret = hw_get_module(VIBRATOR_HARDWARE_MODULE_ID, &hw_module);if (ret == 0) {ret = vibrator_open(hw_module, &vib_device);if (ret != 0) {ALOGE("vibrator_open failed: %d", ret);}} else {ALOGE("hw_get_module %s failed: %d", VIBRATOR_HARDWARE_MODULE_ID, ret);}if (ret == 0) {return new Vibrator(vib_device);} else {ALOGE("Passthrough failed to open legacy HAL.");return nullptr;}
}

5、binderied实例分析

1)重点分析HIDL Service -> driver

例子:android\hardware\interfaces\vibrator\1.3
基于Passthrough进行简单分析1、VINTF
<transport>hwbinder</transport>2、服务端
1)android\hardware\interfaces\vibrator\1.3\example\service.cpp
int main() {configureRpcThreadpool(1, true);status_t status = registerVibratorService();
}status_t registerVibratorService() {sp<IVibrator> vibrator = new Vibrator();return vibrator->registerAsService();
}2)android\hardware\interfaces\vibrator\1.3\example\Vibrator.cpp
HAL访问driver实现3、客户端(java service -> jni -> getservice)
frameworks/base/services/core/java/com/android/server/VibratorService.java
本身是一个 Binder 服务端向 App 提供服务,同时也是一个 HwBinder 客户端通过 JNI 访问到 HAL 服务端4、JNI
android\frameworks\base\services\core\jni\com_android_server_VibratorService.cpp (AN9)Return<R> halCall(Return<R> (I::* fn)(Args0...), Args1&&... args1) {// Assume that if getService returns a nullptr, HAL is not available on the// device.static sp<I> sHal = I::getService();  //获取hal服务static bool sAvailable = sHal != nullptr;if (!sAvailable) {return NullptrStatus<R>();}
}

6、same-process HAL

例子:hardware/interfaces/graphics/mapper
参考:https://blog.csdn.net/learnframework/article/details/134724489
基于Passthrough进行简单分析1、直接链接so库,可以提高性能,但不解耦
>> 与Passthrougth 加载传统hal的区别?没有跨进程通信
2、same-Process : 客户端依然通过getservice接口去获取hal层接口;
3、same-process的方式较少,主要是显示相关,并且由google维护1、VINTF
<transport arch="32+64">passthrough</transport>2、与Passthrough相近,差异在于
1)只有so(该库会在client调用getservice时加载),没有service产生
android\hardware\interfaces\graphics\mapper\2.0\default\Android.bp
cc_library_shared {name: "android.hardware.graphics.mapper@2.0-impl",
...
}2)
android\hardware\interfaces\graphics\mapper\2.0\default\passthrough.cpp
extern "C" IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {return GrallocLoader::load(); //load 传统hal库(比如gralloc_msm8909.so)
}3)加载传统hal库
android\hardware\interfaces\graphics\mapper\2.0\utils\passthrough\include\mapper-passthrough\2.0\GrallocLoader.h
static IMapper* load() {const hw_module_t* module = loadModule();auto hal = createHal(module);return createMapper(std::move(hal));
}static const hw_module_t* loadModule() {const hw_module_t* module;int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);return module;
}

五、AIDL HAL(>=Android11)

1、概述

AIDL:Android interface definition language

1)使用:https://www.jianshu.com/p/d1fac6ccee98

2)知乎详解:https://zhuanlan.zhihu.com/p/338093696

3)Developers:https://developer.android.google.cn/guide/components/aidl?hl=zh-cn

小结:

1、Android的IPC通信机制,按照它定义的规则来即可;

2、应用层的原理,AIDL是Android独有的一门进程间通信语言,我们编写*.aidl文件,AS自动翻译为复杂一些的*.java文件;

3、HIDL HAL -> AIDL HAL的变化使得 JAVA应用层可直接访问HAL,是有进步的。

2、架构

来源:https://juejin.cn/post/7366848656615374883
在这里插入图片描述

1、访问HAL依然采用进程间通讯(binder);

2、模型:client -> binder -> service ->hw_get_module(),回到传统的AIDL binder通讯,使用AIDL工具生成进程间通讯代码;

3、相较于HIDL(HIDL本质上是AIDL的复制版本),不再细分进程间通信类型,CPP/JAVA层统一使用AIDL,这样更加灵活高效;

4、针对一些显示相关的hal,要求性能高,系统进程直接通过dlopen访问hal (空间换效率)- 称为stable-c hal,那么APP访问HAL只需要一个跨进程通信;

5、AIDL的使用详解(APP):https://blog.csdn.net/u014294681/article/details/88126988

3、AIDL开发流程

1、aidl工具,与hidl类似
android\system\tools\aidl
1)
// aidl executable
cc_binary_host {name: "aidl",defaults: ["aidl_defaults"],srcs: ["main.cpp"],static_libs: ["libaidl-common","libbase","liblog",],
}
2)生成四种服务端代码(CPP/JAVA/NDK/RUST),转换实现的源码
转换为CPP:aidl_to_cpp.cpp (依赖libbinder)
转换为JAVA: aidl_to_java.cpp
转换为ndk :aidl_to_ndk.cpp (也是cpp代码,依赖libbinder_ndk,Google更推荐)
转换为rust:aidl_to_rust.cpp

4、AIDL-HAL实例分析

例子:android\hardware\interfaces\vibrator\aidl
这里给出的是HAL层实现的整体框架和实例,没有实现访问硬件的HAL接口,厂商可以参照这个来 开发自己的aidl-hal1、文件树
│ Android.bp
├─aidl_api //历史aidl版本
│  └─android.hardware.vibrator
│      ├─1
│      ├─2
│      └─current
├─android //aidl文件
│  └─hardware
│      └─vibrator
│              ActivePwle.aidl
│              Braking.aidl
│              BrakingPwle.aidl
│              CompositeEffect.aidl
│              CompositePrimitive.aidl
│              Effect.aidl
│              EffectStrength.aidl
│              IVibrator.aidl
│              IVibratorCallback.aidl
│              IVibratorManager.aidl
│              PrimitivePwle.aidl
├─default //service及hal层接口实现
│  │  Android.bp //可借助aidl生成,开发人员需要调整
│  │  android.hardware.vibrator.xml
│  │  fuzzer.cpp
│  │  main.cpp  //aidl-service
│  │  vibrator-default.rc
│  │  Vibrator.cpp  //兼容旧的api,可借助aidl生成,接口需要开发人员实现
│  │  VibratorManager.cpp //新API,可借助aidl生成,接口需要开发人员实现
│  ├─apex //apex组件配置文件
│  │      Android.bp
│  │      apex_manifest.json
│  │      com.android.hardware.vibrator.avbpubkey
│  │      com.android.hardware.vibrator.pem
│  │      com.android.hardware.vibrator.pk8
│  │      com.android.hardware.vibrator.rc
│  │      com.android.hardware.vibrator.x509.pem
│  │      file_contexts
│  ├─example_java_client //APP访问HAL示例程序(APP -> AIDL HAL服务,不需经过Framework)
│  │  │  Android.bp
│  │  │  AndroidManifest.xml
│  │  │  getter.cpp
│  │  │  jarjar.txt
│  │  └─example
│  │      └─vib
│  │              MyActivity.java
│  └─include
│      └─vibrator-impl
│              Vibrator.h
│              VibratorManager.h
└─vts //测试套件
1)创建HAL接口&生成impl接口
1、
aidl_interface {name: "android.hardware.vibrator",vendor_available: true,host_supported: true,srcs: ["android/hardware/vibrator/*.aidl",],stability: "vintf",
}生成两部分:
1、需要暴露给开发者,生成在default/目录中 >> 构建库 libvibratorexampleimpl
2、不需要暴露,生成在out/soong/.... >> 构建库 android.hardware.vibrator-V2-ndk
2)aidl-Service
1、android\hardware\interfaces\vibrator\aidl\default\Android.bp
cc_library_static {name: "libvibratorexampleimpl",shared_libs: ["libbase","libbinder_ndk","android.hardware.vibrator-V2-ndk",],srcs: ["Vibrator.cpp","VibratorManager.cpp",],
}2、
android\hardware\interfaces\vibrator\aidl\default\Vibrator.cpp
android\hardware\interfaces\vibrator\aidl\default\VibratorManager.cpp
实现hal接口aidl-service端是如何连接厂商的库的? 亦或aidl-service由厂商来管控?>> 应该是的,hidl也应如此!3、
cc_binary {name: "android.hardware.vibrator-service.example",shared_libs: ["libbase","libbinder_ndk","android.hardware.vibrator-V2-ndk",],static_libs: ["libvibratorexampleimpl",],srcs: ["main.cpp"],
}
可以看出是用的是aidl生成的ndk服务器代码2、android\hardware\interfaces\vibrator\aidl\default\main.cpp
int main() {ABinderProcess_setThreadPoolMaxThreadCount(0);// make a default vibrator serviceauto vib = ndk::SharedRefBase::make<Vibrator>();binder_status_t status = AServiceManager_addService(vib->asBinder().get(), Vibrator::makeServiceName("default").c_str());CHECK_EQ(status, STATUS_OK);// make the vibrator manager service with a different vibratorauto managedVib = ndk::SharedRefBase::make<Vibrator>();auto vibManager = ndk::SharedRefBase::make<VibratorManager>(std::move(managedVib));status = AServiceManager_addService(vibManager->asBinder().get(),VibratorManager::makeServiceName("default").c_str());CHECK_EQ(status, STATUS_OK);ABinderProcess_joinThreadPool();return EXIT_FAILURE;  // should not reach
}
将Vibrator和VibratorManager通过AServiceManager_addService接口注册服务
3)aidl-client-1
1)APP->AIDL-HAL
android\hardware\interfaces\vibrator\aidl\default\example_java_client\example\vib\MyActivity.java
import android.hardware.vibrator.IVibrator;
public class MyActivity extends Activity {public void onCreate(Bundle b){System.loadLibrary("example_vib_getter");IVibrator v = IVibrator.Stub.asInterface(gimme("android.hardware.vibrator.IVibrator/default")); //获取服务端接口,凭证是"android.hardware.vibrator.IVibrator/default"}
}1、两个 App 的构建,一个在 Vendor 分区,一个在 Product 分区,不同分区的权限由SEpolicy来指定
2、如何指定app的运行分区? bp里面有字段可用(Android 10以上才可用),非运行分区,而是安装分区,分区被设置权限
4)aidl-client-2
1、APP -> Framework
1)frameworks/base/core/java/android/app/Activity.java
public Object getSystemService(@ServiceName @NonNull String name) {return super.getSystemService(name);
}
2)frameworks/base/core/java/android/view/ContextThemeWrapper.java
public Object getSystemService(String name) {return getBaseContext().getSystemService(name);
}
3)frameworks/base/core/java/android/app/ContextImpl.java
public Object getSystemService(String name) {return SystemServiceRegistry.getSystemService(this, name);
}
4)frameworks/base/core/java/android/app/SystemServiceRegistry.java
static abstract class CachedServiceFetcher<T> implements ServiceFetcher<T> {public final T getService(ContextImpl ctx) {service = createService(ctx); //创建一个SystemVibratorManagerret = service; return ret;}
}public class SystemVibratorManager  extends VibratorManager {private final IVibratorManagerService mService;
}2、framework->JNI->aidl hal
1)frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
addService. 向 ServiceManager 注册一个 VibratorManagerService (binder) 服务。2)VibratorManagerService调用JNI
frameworks/base/services/core/jni/com_android_server_vibrator_VibratorManagerService.cppstatic vibrator::ManagerHalController* gManager GUARDED_BY(gManagerMutex) = nullptr;
static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject callbackListener) {std::unique_ptr<NativeVibratorManagerService> service =std::make_unique<NativeVibratorManagerService>(env, callbackListener);{std::lock_guard<std::mutex> lock(gManagerMutex);gManager = service->hal();}return reinterpret_cast<jlong>(service.release());
}3)android\frameworks\native\services\vibratorservice\VibratorHalController.cpp
libvibratorservice.so >> 此库与传统的 hal VibratorService(java) 是有区别的!
一路调用
ManagerHalController() 构造函数中 connectManagerHal
--connectManagerHal
----waitForVintfServicedefaultServiceManager 获取服务,name:"android.hardware.vibrator.IVibrator/default")
/android/frameworks/native/libs/binder/include/binder/IServiceManager.h
template<typename INTERFACE>
sp<INTERFACE> waitForVintfService(const String16& instance = String16("default")) {return waitForDeclaredService<INTERFACE>(INTERFACE::descriptor + String16("/") + instance);
}template<typename INTERFACE>
sp<INTERFACE> waitForDeclaredService(const String16& name) {const sp<IServiceManager> sm = defaultServiceManager();if (!sm->isDeclared(name)) return nullptr;return interface_cast<INTERFACE>(sm->waitForService(name));
}

5、stable-c实例分析

与HIDL中的same-process有什么差别?
1)本质上没有差别,stable-c对应的就是same-process,但使用的框架不同,一个是HIDL框架(库)、一个是AIDL框架(库)例子:android\hardware\interfaces\graphics\mapper\stable-c1、
android\hardware\interfaces\graphics\mapper\stable-c\imapper5_abicheck.cpp
AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {}_Nullable* _Nonnull  标注非空,通常用于代码注释和静态分析工具2、对外接口定义(框架)- libimapper_providerutils.so
android\hardware\interfaces\graphics\mapper\stable-c\implutils\include\android\hardware\graphics\mapper\utils\IMapperProvider.h3、实现 - mapper.minigbm.so (链接libimapper_providerutils.so,继承方式 实现 具体实现)
android\external\minigbm\cros_gralloc\mapper_stablec\Mapper.cpp

6、实现一个ADIL

1、https://juejin.cn/post/7369117524481966130
2、https://blog.csdn.net/learnframework/article/details/134945726
>跟着写一个例子,实践!

六、小结

1、AIDL和HIDL的区别?

AIDL用于应用程序与framework之间的IPC通信(java层)- Binder

HIDL用于framework与HAL层通信(C++层)- HwBinder

无论Binder/HwBinder都是使用Binder驱动完成通信;

AIDL还是HIDL,我们只需关注

1、如何新增接口?

2、查看/调试现有架构 - 只需关注client接口 ↔ service接口,中间过程不需太多关注!

2、较新的Android版本,如AN14上有多个版本的hal?

1)传统HAL / HIDL HAL / AIDL HAL是同时存在,源码都会保留,配置根据系统来配置!

2)视乎芯片厂商(主芯片/IOT)的选择,不一定跟着Google新的架构走!

3)不同版本的Android系统源代码 AIDL 与 HIDL的service也不尽相同

3、配置这么多,如何掌握?

实操、记录和总结!

4、Binder RPC 、HWBinder RPC 、AIDL for Hal区别?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/86543.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/86543.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/86543.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【WebSocket】学习总结

是一种协议&#xff1b; 作用与Web应用程序和服务端之间&#xff1b; 实时的、双向的&#xff1b; 通过单一的TCP提供了持久化连接&#xff1b; 优势&#xff1a; 实时、双向、可以减少网络的负载&#xff1b; 劣势&#xff1a; 需要客户端和服务端双方都支持&#xff1b; 连续…

“组件协作”模式之策略模式

目录 策略模式引例动机 Motivation模式定义结构要点总结 策略模式 引例 税务计算系统&#xff0c;根据各个国家的税法&#xff0c;进行税务计算。各个国家税法规定差别很大&#xff0c;需对应进行相应的实现。 常规解耦前写法 使用if-else语句或switch-case语句进行结构化分…

VS Git巨坑 切换分支失败导致原分支被修改

VS2013Git 首先当前分支&#xff08;分支A&#xff09;的变更已经提交&#xff0c;应该可以正常切换分支。 想切换到一个比较老的分支B&#xff08;跟当前分支存在较大差异&#xff0c;增加了很多文件&#xff09;&#xff0c;VS中提示切换失败&#xff0c;当前分支仍然是分支A…

uniapp页面间通信uni.$on与通过uni.navigateTo中eventChannal的方式的区别

背景。无意间开发uniapp程序用到了页面跳转数据传递的两种方式。但各用于什么场景&#xff0c;有什么区别记录一下。大模型给的内容较多&#xff0c;贴出一些结论。eventChannel文档链接uni.$emit文档链接 页面跳转而非全局事件通知&#xff0c;优先选择eventChanel的方式。 首…

理解对话上下文

1、pom依赖 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><langchain4j.version>…

【Java高频面试问题】数据库篇

【Java高频面试问题】数据库篇 为什么MySQL选择B树作为索引一、B 树的优势特性二、与常见数据结构的对比 索引优化一、索引类型及使用场景二、索引优化核心策略1. 避免索引失效场景2. 性能优化实践3. 表结构与架构优化 三、高频面试问题参考答案总结&#xff1a;面试核心要点 数…

《Whisper:开启语音识别新时代的钥匙》

Whisper 模型:技术革新的基石 在当今科技飞速发展的时代,自动语音识别(ASR)技术作为人工智能领域的关键分支,正深刻地改变着人们的生活与工作方式。从智能语音助手到实时字幕生成,从语音交互设备到智能客服系统,ASR 技术无处不在,为人们带来了前所未有的便利与效率提升…

关于 pdd:anti_content参数分析与逆向

一、逆向目标 目标&#xff1a;获取pdd商品列表接口数据网址&#xff1a;aHR0cHM6Ly93d3cucGluZHVvZHVvLmNvbS9ob21lL2hvbWUv 二、逆向步骤 2.1 anti_content 入口定位 >1 找到需加密参数 >2 全局搜索定位 这里只出来一个结果&#xff0c;很明显&#xff0c;点进去。 …

限流系列之五:TDMQ RabbitMQ Serverless 版限流机制深度解析与实践指南

导语 分布式集群限流是保障云服务高可用性的核心技术手段&#xff0c;其意义不仅在于防止系统过载&#xff0c;更是构建弹性架构、优化资源效率、实现业务可持续性的关键策略。未来&#xff0c;随着边缘计算和 Serverless 的普及&#xff0c;限流技术将进一步与底层基础设施深…

官方链接内容整理的 Spark-TTS Windows 安装完整流程

官方链接内容整理的 Spark-TTS Windows 语音克隆 安装完整流程 官方链接内容整理的 Spark-TTS Windows 安装完整流程&#xff1a; Spark TTS&#xff1a;基于大型语言模型的文本转语音模型 Spark-TTS 是一个先进的文本转语音系统&#xff0c;利用大型语言模型&#xff08;LLM…

Spring Cloud Config动态刷新实战指南

以下是利用 Spring Cloud Config + Bus 实现配置动态刷新的完整步骤和原理说明: 一、核心原理 消息总线机制 Bus 通过消息代理(如 RabbitMQ/Kafka)建立公共 Topic(默认 springCloudBus),当配置变更时,任一服务触发刷新请求,消息会广播至所有监听该 Topic 的服务实例,实…

Linux 修改密码教程

Linux 修改密码教程 Linux 系统中修改密码是非常常见的管理操作&#xff0c;无论是修改当前用户密码还是其他用户的密码&#xff0c;通常都可以通过终端完成。本文将详细介绍如何在 Linux 系统中修改密码&#xff0c;并包括修改其他用户密码的方法。 1. 修改当前用户密码 修改…

正则表达式详解:从基础到高级应用的全面指南

文章大纲 引言&#xff1a;什么是正则表达式&#xff1f; 在编程和文本处理领域&#xff0c;正则表达式&#xff08;Regular Expression&#xff0c;简称 regex&#xff09;是一种强大的工具&#xff0c;用于描述和匹配文本中的特定模式。它本质上是一种由字符和特殊符号组成…

flutter结合ai工具(其他语言通用)

一、为什么Flutter开发者需要免费AI工具&#xff1f; 1. 减少重复性编码 Flutter开发中&#xff0c;UI组件、网络请求、状态管理等代码高度重复&#xff0c;AI可自动生成这些代码。 示例&#xff1a;输入"创建一个Material Design风格的登录页面"&#xff0c;AI工具…

鸿蒙容器组件 Row 全解析:水平布局技术与多端适配指南

一、引言&#xff1a;Row 组件 —— 水平布局的核心引擎 在鸿蒙全场景应用开发中&#xff0c;Row 容器组件作为水平布局的标准载体&#xff0c;通过声明式语法实现子组件的有序水平排列。作为线性布局体系的重要组成部分&#xff0c;其简洁的属性体系与强大的适配能力&#xf…

基于 PCIe 架构的处理器系统

处理器系统A 在有些处理器系统中&#xff0c;没有直接提供PCI总线&#xff0c;此时需要使用PCIe桥&#xff0c;将PCIe链路转换为PCI总线之后&#xff0c;才能连接PCI设备 在这种结构中&#xff0c;RC由两个FSB-to-PCIe桥和存储器控制器组成。 FSB是Front Side Bus的缩写&…

Qt 与 Halcon 联合开发五:为何与如何将耗时算法移入子线程

在 Qt 应用程序开发中&#xff0c;界面响应速度直接影响用户体验。而在集成图像处理库如 Halcon 的项目中&#xff0c;耗时算法一旦运行于主线程中&#xff0c;极易造成界面卡顿甚至假死。本篇文章将围绕耗时算法必须移入子线程执行这一核心原则&#xff0c;结合 Qt 与 Halcon …

聚焦OpenVINO与OpenCV颜色通道转换的实践指南

颜色通道顺序问题&#xff1a;OpenVINO模型RGB输入与OpenCV BGR格式的转换 在计算机视觉任务中&#xff0c;框架间的颜色通道差异常导致模型推理错误。以下方法解决OpenVINO模型需要RGB输入而OpenCV默认输出BGR的问题。 理解核心差异 OpenCV的imread()函数遵循BGR通道顺序&a…

【软考高级系统架构论文】论企业集成平台的理解与应用

论文真题 企业集成平台 (Enterprise Integration Platform, EIP) 是支持企业信息集成的环境,其主要功能是为企业中的数据、系统和应用等多种对象的协同运行提供各种公共服务及运行时的支撑环境。企业集成平台能够根据业务模型的变化快速地进行信息系统的配置和调整,保证不同…

LabVIEW光谱仪设计

采用LabVIEW 开发平台&#xff0c;搭配品牌硬件构建光谱仪系统&#xff0c;实现光谱数据的高效采集、分析与显示&#xff0c;展现 LabVIEW 在仪器开发中的快速集成与灵活扩展能力。 ​ 应用场景 科研领域&#xff1a;用于材料光谱特性研究、光学实验数据分析&#xff0c;支持高…