Android HIDL 简介
Android HIDL 简介
Qidi 2017.08.01 (Markdown & Haroopad)
注意:本文基于 Android 8.0 进行分析。
0、特别声明
本文是在 HIDL 刚出现、官方还没对外发布正式文档时撰写的。如今 Google 已经全面修订并公开了本文涉及的所有内容,对此话题感兴趣的朋友可以直接前往 https://source.android.com/devices/architecture/hidl 进行学习。
2021.01.26 Qidi
1、HIDL 的概念
HIDL 读作 hide-l,全称是 Hardware Interface Definition Language。它在 Android Project Treble 中被起草,在 Android 8.0 中被全面使用,其诞生目的是使 Android 可以在不重新编译 HAL 的情况下对 Framework 进行 OTA 升级。
HIDL 与 Android Vendor Test Suite (VTS) 测试有紧密的联系。关于 VTS 的介绍可以看我写的《Android Vendor Test Suite (VTS) 的概念、作用及测试方法》这篇文章。
使用 HIDL 描述的 HAL 描述文件替换旧的用头文件描述的 HAL 文件的过程称为 *** HAL 的 binder 化(binderization)。所有运行 Android O 的设备都必须只支持 binder 化后的 HAL 模块。**
已发布的 HIDL package包位于 Android 代码库的hardware/interfaces/
或vendor/<vendorName>
目录下。使用 HDIL 描述的 HAL 接口存放在这些目录下的.hal
文件中。比如我们可以在hardware/interfaces/audio/2.0/
目录下找到部分 Audio HAL 描述文件,如下:
Android.bp
Android.mk
IDevice.hal
IDevicesFactory.hal
IPrimaryDevice.hal
IStream.hal
IStreamIn.hal
IStreamOutCallback.hal
IStreamOut.hal
types.hal
2、HIDL 基础语法
HIDL 的语法和 C 语言有点类似,支持嵌套声明,但不支持前向声明和预处理指令。以下是一些常用标记符和数据类型:
- 标记符
- /* */ 多行注释
- // 单行注释
- [empty] 表明当前项的值为空
- ? 放置在项前,表明该项为可选项
- … 表明该序列包含0个或多个如前述使用分隔符隔开的项
- , 逗号用于分隔序列中的元素
- ; 分号用于标记每个元素的结束位置
- @entry 当前HAL模块被使用时应当被最先调用的接口
- @exit 当前HAL模块被调用时应当被最后调用的接口
- @callflow(next={“name_a”, “name_b”, “name_c”}) 当前接口被调用后可能被调用的接口列表。其中name_a接口被调用的概率最大,name_c接口被调用的概率最小。如果只存在1个可能被调用的接口,那么花括号{ }可以省略不写。如果给定的接口名无效,则会导致VTS编译失败。
- @callflow(next={"*"}) 当前接口被调用后可能会调用任意接口
- 数据类型
- struct 这个关键字定义一个结构体,格式与C++同
- union 这个关键字定义一个联合体,格式与C++同
- MQDescriptorSync & MQDescriptorUnsync 这2个关键字分别定义同步和非同步的FMQ(Fast Message Queue)描述符
- memory 这个关键字用来声明HIDL中未被映射的共享内存
- pointer 用这个关键字声明的pointer类型数据只能在HIDL内部使用
- bitfield< T>模板 这个关键字用来定义一个与模板T相同的可进行位操作的数据。其中T是一个由用户定义的枚举数据类型
- 有限数组 任何HIDL结构体中可被包含的数据类型都可以声明有限数组
- 字符串 字符串在HIDL中以UTF8编码存储,所以在和由Java实现的接口进行交互时需要将编码格式转换为UTF16
- vec< T>模板 这个关键字用来定义一个包含模板T的可变大小的buffer数据。其中T可以是除句柄外的任何HIDL内建或用户自定义数据类型
- 用户自定义数据类型 用户可以自定义enum、struct、union类型的数据。定义enum数据的格式与C++11同,定义struct数据的格式与C同,定义union数据的格式与C同
- 关键字
- interface 用于声明HAL模块中的一个接口,是构成.hal文件的基本单元,可以从其它interface继承而来
- package 用于声明当前.hal文件中各interface接口所属的包
- import 用于导入其它包里声明的interface或数据类型,以便在当前.hal文件中使用
- 示例
- 结构体声明
struct Point {int32_t x;int32_t y;
};
- 嵌套声明
interface IFoo {uint32_t[3][4][5][6] multidimArray;vec<vec<vec<int8_t>>> multidimVector;vec<bool[4]> arrayVec;struct foo {struct bar {uint32_t val;};bar b;}struct baz {foo f;foo.bar fb; // HIDL uses dots to access nested type names}…
- bitfield< T> 数据声明
enum Flag : uint8_t { // 用户定义的枚举类型数据HAS_FOO = 1 << 0,HAS_BAR = 1 << 1,HAS_BAZ = 1 << 2
};
typedef bitfield<Flag> Flags; // 声明一个可进行位操作的数据
setFlags(Flags flags) generates (bool success);
- 有限数组声明
struct foo {uint32_t[3] x; // array is contained in foo
};
- 用户自定义enum数据
enum Color : uint32_t { RED = 0, GREEN, BLUE = 2 } // GREEN == 1
- 一个完整的.hal文件
package android.hardware.audio@2.0; // 当前package包名
import android.hardware.audio.common@2.0; // 导入其它package包
import IDevice; // 导入其它.hal
interface IDevicesFactory { // 定义一个interfacetypedef android.hardware.audio@2.0::Result Result;enum Device : int32_t { // 定义数据类型PRIMARY,A2DP,USB,R_SUBMIX,STUB};/*** Opens an audio device. To close the device, it is necessary to release* references to the returned device object.** @param device device type.* @return retval operation completion status. Returns INVALID_ARGUMENTS* if there is no corresponding hardware module found,* NOT_INITIALIZED if an error occured while opening the hardware* module.* @return result the interface for the created device.*/openDevice(Device device) generates (Result retval, IDevice result); // 定义一个方法
};
3、HIDL 文件的组织结构
每个 HIDL package包里都含有一个名为types.hal
的文件,该文件中定义了这个包里所有 interface 共享的用户自定义数据类型,并且一般也会导入需要用到的其它包里的数据类型。
当前包中新的定义的 interface 可以继承自从其它包里导入的 interface,这样的继承关系可以使用extend
关键字实现。比如下面示例中的 1.1 版本包中的 IQuux 接口就继承自 1.0 版本包中的 IQuux 接口:
// types.hal
package android.hardware.example@1.1
import android.hardware.example@1.0 // 导入1.0的包// IQuux.hal
package android.hardware.example@1.1
interface IQuux extends @1.0::IQuux { // 继承1.0包中的接口fromBarToFoo(foo.bar b) generates (foo f); // 直接使用fromBarToFoo方法而不再在当前包中声明
}
由 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 包在被发布后就不能再对其内容进行变动了,如果要增加或修改这个包里的接口或数据类型,应该新建一个新版本的包,在这个新版本的包里进行变更。
参考资料:
[1] 《HIDL_General_Users_Guide_1_17_17.pdf》
[2] 《VTSAnnotationsinHIDL.pdf》
[3] 《HIDLHALVersioningandExtensions.pdf》
Android HIDL 简介相关推荐
- 【译】Android系统简介—— Activity
续上一篇,继续介绍Android系统.上一篇: [译]Android系统简介 本文主要介绍构建Android应用的一些主要概念: Activity Activity是应用程序中一个单独的有UI的页面( ...
- Android ViewTreeObserver简介-------------转
Android ViewTreeObserver简介 一.结构 public final class ViewTreeObserver extends Object java.lang.Object ...
- android radiooptions简介
android radiooptions简介 RILD负责modem和RILJ端的通信,信息分两种:unsolicited和solicited,前者是由modem主动上报的,诸如时区更新.通话状态.网 ...
- Android 的简介和体系结构中每个层的功能。
Android 的简介和体系结构中每个层的功能. 1.简介 Android是由Google公司和开放手机联盟领导并开发的一种基于Linux的自由且开放源代码的操作系统,主要使用于移动设备. Andro ...
- Android字体简介
Android字体简介 Android系统默认支持三种字体,分别为:"sans","serif","monospace". android. ...
- Android OkHttp3简介和使用详解
一 OKHttp简介 OKHttp是一个处理网络请求的开源项目,Android 当前最火热网络框架,由移动支付Square公司贡献,用于替代HttpUrlConnection和Apache HttpC ...
- android添加hidl,android hidl
1.定义.hal接口文件,如: 在vendor/sprd/interface中新建目录hello,其中定义好hidl接口,如: 1 package [email protected]1.0;2 3 i ...
- android 教程概要,Android精通教程-第一节Android入门简介
前言 大家好,我是 Vic,今天给大家带来Android精通教程-第一节Android入门简介的概述,希望你们喜欢 每日一句 If life were predictable it would cea ...
- Android HIDL第一个HelloWorld demo
原址 写在前面 程序员有个癖好,无论是学习什么新知识,都喜欢以HelloWorld作为一个简单的例子来开头,咱们也不例外. OK,咱这里都是干货,废话就不多说啦,学习HIDL呢咱们还是需要一些准备工作 ...
最新文章
- Linux命令之ssh
- LDD3学习之short
- urllib2使用总结
- Node.js webpack中url-loader处理图片路径
- 信息系统项目管理师--项目整体管理
- 设计模式(二) 工厂模式
- 分享珍藏很久的Python学习知识手册
- mac远程桌面连接windows_web浏览器通过Myrtille连接Windows远程桌面
- python2.7 pyqt4创建qtapp_python-2.7 – 向TabWidget pyqt4添加加号按钮
- 9块钱,构建个私有网盘,关键不限速
- Transaction marked as rollbackOnly异常处理 Duplicate entry 'xxx' for key
- 如何防止远程程序与RDS PG连接中断
- Douglas Peucker算法的C#实现
- 27. Minimize casting
- 【元胞自动机】基于matlab保守策略元胞自动机三车道(开放辅路,软件园影响)交通流模型【含Matlab源码 1295期】
- php纯文本源码,[PHP源码]文章原创度检测源码
- OpenAI祭出120亿参数魔法模型!从文本描述生成的图像栩栩如生,仿佛拥有人类的想象力...
- Android DES加密解密
- FT232驱动安装不成功的解决方案
- 解决windows xp 局域网共享