Android HAL类型
在此之前的ANDROID版本当中Android HAL没有什么特殊的特殊的,也么有什么分类,但是从android 8.0开始,Android重构了HAL与Android FW之间的联系结构,所以Android HAL会被区分成以下2种类型:
1,Binderized HALs,从名字上应该是指Binder化的HAL,HAL都被写成了binder service,Android FW是binder client
2,Passthrough HALs,从google的官方介绍来说,这个是对原先HAL的包装,但是最终的binder service 跟binder client都是活在同一个进程当中。这个应该是对老版本HAL的兼容。
3,Same-Process HALs,由于某些性能的因素,这些HALs必须运行在Android Framework 所在的进程当中。
按照google的要求,新设计生产的Android O设备,必须而且只能支持 Binderized HALs,而老版本的设备升级到Android O可以支持 Passthrough HALs,但是有些HAL也必须修改成 Binderized HALs。
HIDL的相关介绍
HIDL的全称是HAL interface definition language(硬件抽象层接口定义语言),在此之前Android 有AIDL,架构在Android binder 之上,用来定义Android 基于Binder通信的Client 与Service之间的接口。HIDL也是类似的作用,只不过定义的是Android Framework与Android HAL实现之间的接口。
在AIDL机制中Android 会提供一系列工具会将用户定义的*.aidl文件编译生成Client端代码与Service端代码,用户仅仅 需要1)在Service端实现所需要实现的接口。2)在Client端调用相关接口。基于Binder机制,在Clinet端的调用会自动通过 binder驱动跨进程到service进程当中。
而在HIDL里,与AIDL比较类似,底层也是基于binder机制。但是也有稍微不一样的地方。为了支持HIDL,Android 对BInder做了一定程度的修改。
使用 passthrough 模式
为了更新运行在Android系统早期版本的设备到Android O操作系统,你可以将传统的(和 legacy遗留的)HALs封装在新的HIDL接口中,这一接口以binderized 和same-process (passthrough)的模式服务于HAL。这种封装对HAL和Android框架都是透明的。
Passthrough模式仅适用于c++的客户端和实现。运行Android早期版本的设备没有Java编写的HALs,因此Java HALs必然使用binderized 的模式。
Passthrough header files
当一个.hal文件被编译后, hidl-gen除了用于binder通信的头文件外,还生成一个额外的 passthrough 头文件 BsFoo.h ;这个头文件定义了dlopened的函数. 由于passthrough HALs 运行在调用它们的相同的进程中,大多数情况下 passthrough 方法被直接通过函数调用 (相同线程)。oneway 方法在他们自己的线程中运行,因为它们并不打算等待HAL来处理它们(这意味着任何在passthrough模式中使用oneway方法的HAL必须是线 程安全的)。
给定一个IFoo.hal文件,BsFoo.h封装了hidl生成的方法以提供额外的特性(比如在另一个线程中运行oneway事务)。这个文件类 似于BpFoo。但是,不是通过binder进行IPC调用,而是直接调用所需的函数。未来HALs可能提供多种实现,例如FooFast HAL和FooAccurate HAL。在这种情况下,将创建每个额外实现的文件(例如:PTFooFast.cpp和PTFooAccurate.cpp)。
Binderizing passthrough HALs
支持passthrough 模式的HAL实现可以binderized 。对于一个HAL 接口a.b.c.d@M.N::IFoo,需要创建两个包:
- a.b.c.d@M.N::IFoo-impl. 包含HAL的实现,并暴露函数IFoo * HIDL_FETCH_IFoo(const char * name)。在legacy hal设备上,这个包是dlopened 的,实现是使用HIDL_FETCH_IFoo实例化的。 您可以使用hidl - gen和- lc + + - impl和- landroidbp - impl生成基本代码。
- a.b.c.d@M.N::IFoo-service. 打开passthrough HAL并将其注册为一个binder化服务,使相同的HAL实现被用作passthrough 和binderized。
给定类型IFoo,您可以调用sp < IFoo > IFoo::getService(string name, bool getStub)来获取IFoo的实例。
如果getStub值是true,getService尝试只以passthrough模式打开HAL。如果getStub为false,则 getService尝试查找到一个binderized 服务;如果失败,则尝试找到passthrough服务。getStub参数除了 defaultPassthroughServiceImplementation不应使用。(使用Android O的设备是完全binderized 的设备,因此不允许以passthrough模式打开一个服务。)
每个 HIDL package包里都含有一个名为types.hal
的文件,该文件中定义了这个包里所有 interface 共享的用户自定义数据类型,并且一般也会导入需要用到的其它包里的数据类型。
当前包中新的定义的 interface 可以继承自从其它包里导入的 interface,这样的继承关系可以使用extend
关键字实现。
由 Google 提供的包叫做core package
,包名始终以android.hardware.
开头,以子系统名
加以区分。比如 NFC 包的名字就应该为android.hardware.nfc
,摄像头包的名字就应该为android.hardware.camera
。这些 core包存放于hardware/interfaces/
目录下。由各芯片厂商和 ODM厂商提供的包叫做non-core package
,包名形式一般以vendor.$(vendorName).hardware.
开头,比如vendor.samsung.hardware.
。这些 non-core包一般存放于vendor/$(vendorName)/interfaces/
目录下。
包的版本使用主、次版本号进行描述,紧随包名之后。比如android.hardware.audio@2.0
表述这个 audio 包的版本是 2.0,主版本号是 2,次版本号是 0。
此外,每个 HIDL 包在被发布后就不能再对其内容进行变动了,如果要增加或修改这个包里的接口或数据类型,应该新建一个新版本的包,在这个新版本的包里进行变更。
编译HIDL
1、项目根目录下运行
./hardware/interfaces/update-makefiles.sh
#!/bin/bash
source $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh
"android.hardware:hardware/interfaces" \
"android.hidl:system/libhidl/transport"
这里执行的时system/tools/hidl/update-makefiles-helper.sh 脚本,传入的参数是
android.hardware:hardware/interfaces
android.hidl:system/libhidl/transport
即 包名:路径名,其实只要第一个参数才处理,这个可以修改update-makefiles-helper.sh 让其处理所有的参数,从而可以处理多个参数。
以O 上面 hardware/interfaces/biometrics 这个HIDL 模块为例子
文件目录结构:
hardware/interfaces/biometrics
Android.bp
这个文件指定编译的目录
fingerprint/2.1/Android.bp
这个文件是通过以下命令生成的
hidl-gen -o $LOC -Landroidbp -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport $PACKAGE
根据hidl-gen 工具说明,-Landroidbp 是为.hal 生成c++ 头文件与c++源文件及.so 库自动生成的编译脚本
这个是编译生成的c++ 头文件与源文件,这些文件的生成就是以后 fingerprint/2.1/Android.bp 这个编译脚本生成的。
.hal 文件生成c++源文件命令
hidl-gen -o $LOC -Lc++-sources -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1
hidl-gen -o $LOC -Lc++-headers -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1
android.hardware.biometrics.fingerprint@2.1_genc++ 对应生成的源文件
这个就是前面的三个.hal 文件对应的生成的源文件
android.hardware.biometrics.fingerprint@2.1_genc++_headers 对应生成的头文件
android.hardware.biometrics.fingerprint@2.1 生成的so 库
fingerprint/2.1/Android.bp 文件中指定生成 android.hardware.biometrics.fingerprint@2.1 库
./fingerprint/2.1/Android.mk
生成这个文件命令:
hidl-gen -o $LOC -Lmakefile -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport $PACKAGE
这个是生成由.hal 生成java 库对应的编译脚本
生成java 库命令:
hidl-gen -o $LOC -Ljava -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1
生成文件如下:
生成 system/framework/android.hardware.biometrics.fingerprint-V2.1-java.jar
system/lib/android.hardware.biometrics.fingerprint@2.1.so
system/framework/android.hardware.biometrics.fingerprint-V2.1-java.jar
vendor/bin/hw/android.hardware.biometrics.fingerprint@2.1-service
vendor/etc/init/android.hardware.biometrics.fingerprint@2.1-service.rc
fingerprint/2.1/default/*
这些文件指定了服务端,这里的Android.mk 指定了生成 android.hardware.biometrics.fingerprint@2.1-service及依赖android.hardware.biometrics.fingerprint@2.1 库的,启动这个服务的rc文件 android.hardware.biometrics.fingerprint@2.1-service.rc。
BiometricsFingerprint.cpp 是对 IBiometricsFingerprint.hal 的实现
service.cpp 就是服务守护进程的实现了。
这就是binder 化的服务端
Binderizing passthrough HALs
支持passthrough 模式的HAL实现可以binderized 。对于一个HAL 接口a.b.c.d@M.N::IFoo,需要创建两个包:
- a.b.c.d@M.N::IFoo-impl. 包含HAL的实现,并暴露函数IFoo * HIDL_FETCH_IFoo(const char * name)。在legacy hal设备上,这个包是dlopened 的,实现是使用HIDL_FETCH_IFoo实例化的。 您可以使用hidl - gen和- lc + + - impl和- landroidbp - impl生成基本代码。
- a.b.c.d@M.N::IFoo-service. 打开passthrough HAL并将其注册为一个binder化服务,使相同的HAL实现被用作passthrough 和binderized。
给定类型IFoo,您可以调用sp < IFoo > IFoo::getService(string name, bool getStub)来获取IFoo的实例。
如果getStub值是true,getService尝试只以passthrough模式打开HAL。如果getStub为false,则 getService尝试查找到一个binderized 服务;如果失败,则尝试找到passthrough服务。getStub参数除了 defaultPassthroughServiceImplementation不应使用。(使用Android O的设备是完全binderized 的设备,因此不允许以passthrough模式打开一个服务。)
这里生成模板文件命令及编译脚本,就是空的实现
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport $PACKAGE
这里就是实现了对 BiometricsFingerprint.cpp 对 IBiometricsFingerprint.hal 的实现,所以你可以直接将这个模板实现你直接的接口就可以了,同时将 android.bp 中模板复制到你自己的Android.mk 中就可以了。
这里与fingerprint/2.1/default/* 是对应的,只是default 下需要定制,直接将模板文件拿过去定制就可以了。
这里可以生成 passthrough HALs,也会以定制成binder 化hal 。
这里生成
android.hardware.biometrics.fingerprint@2.1-impl ,并依赖 android.hardware.biometrics.fingerprint@2.1 库
所以最终生成的目标如下:
system/lib/android.hardware.biometrics.fingerprint@2.1.so
system/framework/android.hardware.biometrics.fingerprint-V2.1-java.jar
vendor/bin/hw/android.hardware.biometrics.fingerprint@2.1-service
vendor/etc/init/android.hardware.biometrics.fingerprint@2.1-service.rc
java 端给到hidl 回调实现:
直接生成各部分脚本:
#!/bin/bash
PACKAGE=android.hardware.biometrics.fingerprint@2.1
#LOC=hardware/interfaces/biometrics/fingerprint/
LOC=android/hardware/biometrics/fingerprint/V2_1/
#make hidl-gen -j64
###system/lib/android.hardware.biometrics.fingerprint@2.1.so
###direct generate c++ source files from .hal
hidl-gen -o $LOC -Lc++-sources -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1
###direct generate c++ header files from .hal
hidl-gen -o $LOC -Lc++-headers -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport android.hardware.biometrics.fingerprint@2.1
###generate compile file for c++ source and header files from .hal ,which will generate c++ source and header files while compile
hidl-gen -o $LOC -Landroidbp -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport $PACKAGE
###vendor/bin/hw/android.hardware.biometrics.fingerprint@2.1-service
###server Implementation
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport $PACKAGE
###server Implementation compile file
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport $PACKAGE
#### system/framework/android.hardware.biometrics.fingerprint-V2.1-java.jar
####generate java files from .hal
hidl-gen -o $LOC -Ljava -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport $PACKAGE
####generate compile files for java files
hidl-gen -o $LOC -Lmakefile -randroid.hardware:hardware/interfaces \
-randroid.hidl:system/libhidl/transport $PACKAGE
https://blog.csdn.net/solid_sdu/article/details/78518537
https://blog.csdn.net/bob_fly1984/article/details/78990994
https://source.android.google.cn/devices/architecture/hidl-cpp/