赞
踩
Android系统架构
HAL 接口定义语言
Treble 是 Google Android 团队的一项重大项目,意在 Android 操作系统框架在架构方面的一项重大改变,旨在让制造商以更低的成本更轻松、更快速地将设备更新到新版 Android 系统。
Android 7.x 及更早版本中没有正式的供应商接口,因此设备制造商必须更新大量 Android 代码才能将设备更新到新版 Android 系统:
Treble 提供了一个稳定的新供应商接口,供设备制造商访问 Android 代码中特定于硬件的部分,这样一来,设备制造商只需更新 Android 操作系统框架,即可跳过芯片制造商直接提供新的 Android 版本:
HAL 接口定义语言(简称 HIDL,发音为“hide-l”)是用于指定 HAL 和其用户之间的接口的一种接口描述语言 (IDL)。HIDL 允许指定类型和方法调用(会汇集到接口和软件包中)。从更广泛的意义上来说,HIDL 是用于在可以独立编译的代码库之间进行通信的系统。
HIDL 旨在用于进程间通信 (IPC)。进程之间的通信经过 Binder 化。对于必须与进程相关联的代码库,还可以使用直通模式(在 Java 中不受支持)。
从以上两个小章节“Project Treble”和“HIDL”可知,Treble 的架构改变建立在 HIDL 的技术之上,也即利用 HIDL 技术实现独立编译的代码库进行通信,从而实现制造商以更低的成本更轻松、更快速地将设备更新到新版 Android 系统。通俗的说是这样,在以往Android更新操作系统,供应商(照相、传感器…)或芯片制造商(高通、MTK…)必须要先进行硬件适配,然后交由制造商(手机品牌)生产手机。这个过程往往比较漫长,也就是为什么 Android 更新版本后,绝大多数手机(Google亲儿子除外)需要很久才能收到系统更新的通知。Treble 就是意在缩短这个过程,HIDL 是基本的技术支撑。
为了更好地实现模块化,Android 8.0 对 Android 操作系统底层进行了重新架构。作为此变化的一部分,运行 Android 8.0 的设备必须支持绑定式或直通式 HAL:
所谓绑定式,仅通过 Binder 化进行传输,这个在 Android AIDL 中已经应用了很久,提供了代码库独立的基本条件。既然是进程间通信,难免会有耗时过程的问题,这对于速度和性能要求特别高地的进程来说,这是不利的,因此可以通过直通式 HAL 来弥补绑定式 HAL 的确定。
必须使用直通式 HAL 的进程:
* android.hardware.graphics.mapper@1.0。将内存映射到其所属的进程中。
* android.hardware.renderscript@1.0。在同一进程中传递项(等同于 openGL)。
HAL 接口定义语言(简称 HIDL,发音为“hide-l”)是用于指定 HAL 和其用户之间的接口的一种接口描述语言 (IDL)。HIDL 允许指定类型和方法调用(会汇集到接口和软件包中)。从更广泛的意义上来说,HIDL 是用于在可以独立编译的代码库之间进行通信的系统。
HIDL 旨在用于进程间通信 (IPC)。进程之间的通信经过 Binder 化。对于必须与进程相关联的代码库,还可以使用直通模式(在 Java 中不受支持)。
HIDL 的演化历程:
HIDL 的目标是,框架可以在无需重新构建 HAL 的情况下进行替换。HAL 将由供应商或 SOC 制造商构建,放置在设备的 /vendor 分区中,这样一来,框架就可以在其自己的分区中通过 OTA 进行替换,而无需重新编译 HAL。
软件包前缀 | 位置 |
---|---|
android.hardware.* | hardware/interfaces/* |
android.frameworks.* | frameworks/hardware/interfaces/* |
android.system.* | system/hardware/interfaces/* |
android.hidl.* | system/libhidl/transport/* |
软件包目录中包含扩展名为 .hal 的文件。每个文件均必须包含一个指定文件所属的软件包和版本的 package 语句。文件 types.hal(如果存在)并不定义接口,而是定义软件包中每个接口可以访问的数据类型。
除了 types.hal 之外,其他 .hal 文件均定义一个接口。接口通常定义如下:
interface IBar extends IFoo { // IFoo is another interface
// embedded types
struct MyStruct {/*...*/};
// interface methods
create(int32_t id) generates (MyStruct s);
close();
};
HIDL 接口服务器(实现接口的对象)可注册为已命名的服务。注册的名称不需要与接口或软件包名称相关。如果没有指定名称,则使用名称“默认”;这应该用于不需要注册同一接口的两个实现的 HAL。例如,在每个接口中定义的服务注册的 C++ 调用是:
status_t status = myFoo->registerAsService();
status_t anotherStatus = anotherFoo->registerAsService("another_foo_service"); // if needed
HIDL 接口的版本包含在接口本身中。版本自动与服务注册关联,并可通过每个 HIDL 接口上的方法调用 (android::hardware::IInterface::getInterfaceVersion()) 进行检索。服务器对象不需要注册,并可通过 HIDL 方法参数传递到其他进程,相应的接收进程会向服务器发送 HIDL 方法调用。
客户端代码按名称和版本请求指定的接口,并对所需的 HAL 类调用 getService:
// C++
sp<V1_1::IFooService> service = V1_1::IFooService::getService();
sp<V1_1::IFooService> alternateService = 1_1::IFooService::getService("another_foo_service");
// Java
V1_1.IFooService; service = V1_1.IFooService.getService(true /* retry */);
V1_1.IFooService; alternateService = 1_1.IFooService.getService("another", true /* retry */);
每个版本的 HIDL 接口都会被视为单独的接口。因此,IFooService 版本 1.1 和 IFooService 版本 2.2 都可以注册为“foo_service”,并且两个接口上的 getService(“foo_service”) 都可获取该接口的已注册服务。因此,在大多数情况下,注册或发现服务均无需提供名称参数(也就是说名称为“默认”)。
以前,Binder 服务通过 servicemanager 注册,其他进程可从中检索这些服务。在 Android O 中,servicemanager 现在专用于框架和应用进程,供应商进程无法再对其进行访问。
不过,供应商服务现在可以使用 vndservicemanager,这是一个使用 /dev/vndbinder(作为构建基础的源代码与框架 servicemanager 相同)而非 /dev/binder 的 servicemanager 的新实例。供应商进程无需更改即可与 vndservicemanager 通信;当供应商进程打开 /dev/vndbinder 时,服务查询会自动转至 vndservicemanager。
vndservicemanager 二进制文件包含在 Android 的默认设备 Makefile 中。
HIDL 是 Android 底层架构的重大变化,这个变化对 Android 的影响非常大,对 Android 版本 OTA、Android 模块化、Android 底层数据传输都产生深远的影响。以后我会和大家分享一些 HIDL 在 Android 中应用的实例。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。