文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android 框架学习(4)—— HIDL

2022-06-06 14:08

关注

一、HIDL定义

        HIDL是用于指定HAL与其用户之间接口的一个接口描述语言(Interface Description Language,发音为“hide-l”)。HIDL允许指定类型和方法调用(会汇集到接口和软件包中)。从更广泛的意义上来说,HIDL是用于在可以独立编译的代码库之间进行通信的系统。
        HIDL旨在用于进程间通信 (IPC)。进程之间的通信经过Binder化。对于必须与进程相关联的代码库,还可以使用直通模式(在 Java 中不受支持)。
        HIDL的设计目的:主要是将Framework和HAL隔离开,Framework可以单独覆盖、更新而不用对HAL做改动。引入HIDL,可以将HAL从

system.img
中移除出去,方便Android版本的升级。

二、HIDL架构模式

        HIDL的演化历程:
在这里插入图片描述

Passthrough模式 Binder化的Passthrough HALs

        什么是Binder化?
        一直以来,供应商进程都使用Binder进程间通信(IPC)技术进行通信。在Android O中,

/dev/binder
设备节点成为了框架进程的专属节点,这意味着供应商进程将无法再访问该节点。供应商进程可以访问
/dev/hwbinder
,但必须将其AIDL接口转为使用HIDL。

三、软件包
软件包前缀 位置
android.hardware.* hardware/interfaces}; // interface methods create(int32_t id) generates (MyStruct s); close(); };

        不含显式

extends
声明的接口会从
android.hidl.base@1.0::IBase
(类似于Java中的
java.lang.Object
)隐式扩展。

五、导入

        

import
语句是用于访问其他软件包中的软件包接口和类型的HIDL机制。
import
语句本身涉及两个实体:

导入实体:可以是软件包或接口。 被导入实体:也可以是软件包或接口。

        导入实体由

import
语句的位置决定。当该语句位于软件包的
types.hal
中时,导入的内容对整个软件包是可见的;这是软件包级导入。当该语句位于接口文件中时,导入实体是接口本身;这是接口级导入。
        被导入实体由
import
关键字后面的值决定。该值不必是完全限定名称;如果某个组成部分被删除了,系统会自动使用当前软件包中的信息填充该组成部分。
        对于完全限定值,支持的导入情形有以下几种:

完整软件包导入

        如果该值是一个软件包名称和版本(语法见下文),则系统会将整个软件包导入至导入实体。

import android.hardware.nfc@1.0;            // import a whole package
部分导入

        如果值为:

一个接口,则系统会将该软件包的
types.hal
和该接口导入至导入实体中。 在
types.hal
中定义的UDT,则系统仅会将该UDT导入至导入实体中(不导入
types.hal
中的其他类型)。 仅类型导入

        如果该值将上文所述的“部分导入”的语法与关键字types而不是接口名称配合使用,则系统仅会导入指定软件包的

types.hal
中的UDT。

import android.hardware.example@1.0::types; // import just types.hal
六、接口继承

        接口可以是之前定义的接口的扩展。扩展可以是以下三种类型中的一种:

接口可以向其他接口添加功能,并按原样纳入其API。 软件包可以向其他软件包添加功能,并按原样纳入其API。 接口可以从软件包或特定接口导入类型。

        接口只能扩展一个其他接口(不支持多重继承)。

七、接口哈希

        哈希是一种旨在防止意外更改接口并确保接口更改经过全面审查的机制。这种机制是必需的,因为HIDL接口带有版本编号,也就是说,接口一经发布便不得再更改,但不会影响应用二进制接口(ABI)的情况(例如更正备注)除外。
        每个软件包根目录(即映射到

hardware/interfaces
android.hardware
或映射到
vendor/foo/hardware/interfaces
vendor.foo
)都必须包含一个列出所有已发布HIDL接口文件的
current.txt
文件。

# current.txt files support comments starting with a ‘#' character
# this file, for instance, would be vendor/foo/hardware/interfaces/current.txt
# Each line has a SHA-256 hash followed by the name of an interface.
# They have been shortened in this doc for brevity but they are
# 64 characters in length in an actual current.txt file.
d4ed2f0e...995f9ec4 vendor.awesome.foo@1.0::IFoo # comments can also go here
# types.hal files are also noted in types.hal files
c84da9f5...f8ea2648 vendor.awesome.foo@1.0::types
# Multiple hashes can be in the file for the same interface. This can be used
# to note how ABI sustaining changes were made to the interface.
# For instance, here is another hash for IFoo:
# Fixes type where "FooCallback" was misspelled in comment on "FooStruct"
822998d7...74d63b8c vendor.awesome.foo@1.0::IFoo

        

hidl-gen
是安卓架构HIDL编译工具。它的源码目录为
system/tools/hidl
,编译生成的可执行文件路径为
out/host/linux-x86/bin/hidl-gen
,可以手动将哈希添加到
current.txt
文件中,也可以使用
hidl-gen
添加。以下代码段提供了可与
hidl-gen
搭配使用来管理
current.txt
文件的命令示例(哈希已缩短):

$ hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0::types
9626fd18...f9d298a6 vendor.awesome.nfc@1.0::types
$ hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0::INfc
07ac2dc9...11e3cf57 vendor.awesome.nfc@1.0::INfc
$ hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0
9626fd18...f9d298a6 vendor.awesome.nfc@1.0::types
07ac2dc9...11e3cf57 vendor.awesome.nfc@1.0::INfc
f2fe5442...72655de6 vendor.awesome.nfc@1.0::INfcClientCallback
$ hidl-gen -L hash -r vendor.awesome:vendor/awesome/hardware/interfaces -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport vendor.awesome.nfc@1.0 >> vendor/awesome/hardware/interfaces/current.txt

        

hidl-gen
生成的每个接口定义库都包含哈希,通过调用
IBase::getHashChain
可检索这些哈希。

八、注册服务

        HIDL接口服务器(实现接口的对象)可注册为已命名的服务。注册的名称不需要与接口或软件包名称相关。如果没有指定名称,则使用名称“默认”;这应该用于不需要注册同一接口的两个实现的 HAL。例如,在每个接口中定义的服务注册的C++调用是:

status_t status = myFoo->registerAsService();
status_t anotherStatus = anotherFoo->registerAsService("another_foo_service");  // if need

        HIDL接口的版本包含在接口本身中。版本自动与服务注册关联,并可通过每个HIDL接口上的方法调用

android::hardware::IInterface::getInterfaceVersion()
)进行检索。服务器对象不需要注册,并可通过HIDL方法参数传递到其他进程,相应的接收进程会向服务器发送HIDL方法调用。

九、发现服务

        客户端代码按名称和版本请求指定的接口,并对所需的HAL类调用

getService

// C++
sp service = V1_1::IFooService::getService();
sp alternateService = 1_1::IFooService::getService("another_foo_service");
// Java
V1_1.IFooService; service = V1_1.IFooService.getService(true );
V1_1.IFooService; alternateService = 1_1.IFooService.getService("another", true );

        每个版本的HIDL接口都会被视为单独的接口。因此,IFooService版本1.1和IFooService版本2.2都可以注册为

foo_service
,并且两个接口上的
getService("foo_service")
都可获取该接口的已注册服务。因此,在大多数情况下,注册或发现服务均无需提供名称参数(也就是说名称为“默认”)。

十、服务终止通知

        想要在Service终止时收到通知的客户端会接收到框架传送的终止通知。要接收通知,客户端必须:

将HIDL类/接口
hidl_death_recipient
(位于C++代码中,而非HIDL中)归入子类。 替换其
serviceDied()
方法。 实例化
hidl_death_recipient
子类的对象。 在要监控的服务上调用
linkToDeath()
方法,并传入
IDeathRecipient
的接口对象。请注意,此方法并不具备在其上调用它的终止接收方或代理的所有权。

        伪代码示例:

class IMyDeathReceiver : hidl_death_recipient {
  virtual void serviceDied(uint64_t cookie,
                           wp& service) override {
    log("RIP service %d!", cookie);  // Cookie should be 42
  }
};
....
IMyDeathReceiver deathReceiver = new IMyDeathReceiver();
m_importantService->linkToDeath(deathReceiver, 42);

作者:jaronho


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 资料下载
  • 历年真题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容
咦!没有更多了?去看看其它编程学习网 内容吧