Android HIDL 介绍

原文链接 https://blog.csdn.net/lei7143/article/details/80931412



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


do_makefiles_update \
  "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


 .hal  文件生成c++头文件命令
 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/

发布了0 篇原创文章 · 获赞 9 · 访问量 1729
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览