4. HIDL 基础:HIDL 语言简介、.hal 文件定义、接口与数据类型
HIDL(HAL Interface Definition Language)是 Android 8.0(Treble 项目)引入的接口定义语言,用于在 Framework 进程与 HAL 实现进程之间建立稳定的二进制接口。HIDL 将 HAL 从 libhardware.so 的共享库形式解耦为独立的 binderized HAL 或 passthrough HAL,使得 Framework 可以独立于 HAL 实现进行升级。
核心目标:HIDL 通过 .hal 文件定义接口契约,自动生成 C++/Java 客户端与服务端代码,确保跨进程通信的类型安全与二进制兼容性。
4.1 HIDL 语言简介
HIDL 是一种 描述性接口语言,语法类似 C++ 头文件,但增加了包名、版本号、接口继承等语义。HIDL 文件以 .hal 为扩展名,编译时由 hidl-gen 工具生成目标语言的桩代码。
| 特性 | 说明 |
|---|---|
| 包名(package) | 使用反向域名,如 android.hardware.camera |
| 版本号(version) | 主版本.次版本,如 @3.4,接口升级时主版本递增 |
| 接口(interface) | 定义方法签名,支持单继承 |
| 数据类型 | 基础类型、结构体、枚举、联合体、向量、数组、回调 |
| 传输模式 | Binderized(跨进程)或 Passthrough(同进程直调) |
版本兼容规则:HIDL 接口一旦发布,次版本升级只能增加方法,不能修改或删除已有方法;主版本升级允许不兼容变更。
4.2 .hal 文件定义
一个典型的 .hal 文件包含 包声明、导入语句、类型定义和接口定义。以下以 Camera HAL 的 ICameraDevice.hal 为例:
// packages/services/Camera/libcameraservice/device/ICameraDevice.hal
package android.hardware.camera.device@3.4;
import android.hardware.camera.common@1.0::Status;
import android.hardware.camera.common@1.0::CameraMetadata;
interface ICameraDevice {
// 打开相机设备
open(ICameraDeviceCallback callback) generates (Status status);
// 配置输出流
configureStreams(StreamConfiguration config)
generates (Status status, StreamConfiguration outConfig);
// 提交捕获请求
processCaptureRequest(vec<CaptureRequest> requests,
vec<BufferCache> cachesToRemove)
generates (Status status, uint64_t lastFrameNumber);
// 关闭设备
close() generates (Status status);
};
关键语法元素:
package:定义接口所属的包路径与版本号import:导入其他 .hal 文件中的类型或接口interface:声明接口名称,方法使用方法名(参数) generates (返回值)格式vec<T>:HIDL 向量类型,对应 C++ 的hidl_vec<T>generates:定义同步调用的返回值;异步回调使用oneway关键字
注意:HIDL 不支持方法重载、默认参数、异常抛出。所有错误状态通过
Status 枚举返回。
4.3 接口与数据类型
4.3.1 基础数据类型
| HIDL 类型 | C++ 对应类型 | 说明 |
|---|---|---|
int8_t / uint8_t |
int8_t / uint8_t |
有符号/无符号 8 位整数 |
int32_t / uint32_t |
int32_t / uint32_t |
有符号/无符号 32 位整数 |
int64_t / uint64_t |
int64_t / uint64_t |
有符号/无符号 64 位整数 |
float / double |
float / double |
IEEE 754 浮点数 |
bool |
bool |
布尔值 |
string |
hidl_string |
UTF-8 字符串 |
vec<T> |
hidl_vec<T> |
可变长度向量 |
T[N] |
hidl_array<T, N> |
固定长度数组 |
4.3.2 结构体与枚举
HIDL 支持 struct 和 enum 定义,用于封装复杂数据:
// 定义相机流配置结构体
struct StreamConfiguration {
vec<Stream> streams; // 输出流列表
CameraMetadata sessionParams; // 会话参数
OperationMode operationMode; // 操作模式
};
// 定义操作模式枚举
enum OperationMode : int32_t {
NORMAL = 0,
CONSTRAINED_HIGH_SPEED = 1,
VENDOR_CUSTOM = 0x8000
};
4.3.3 回调接口(Callback)
HIDL 使用 callback 接口实现异步通知。Camera HAL 中典型的回调接口:
interface ICameraDeviceCallback {
// 通知捕获结果
oneway processCaptureResult(vec<CaptureResult> results);
// 通知设备错误
oneway notify(vec<NotifyMsg> msgs);
};
oneway 关键字表示该方法为异步调用,不阻塞发送方,也不产生返回值。
4.4 HIDL 接口通信架构
下图展示了 HIDL 接口在 Camera HAL3 中的通信架构:
4.5 HIDL 接口版本管理
HIDL 使用 语义化版本 管理接口演进,Camera HAL 从 @3.0 演进到 @3.8:
| 版本 | 新增特性 | 兼容性 |
|---|---|---|
| @3.0 | 基础 Camera HAL3 接口 | 基线版本 |
| @3.2 | 支持物理相机、RAW 流 | 向后兼容 @3.0 |
| @3.4 | 支持逻辑相机、多摄像头 | 向后兼容 @3.2 |
| @3.6 | 支持会话参数、高速录制 | 向后兼容 @3.4 |
| @3.8 | 支持深度流、热插拔增强 | 向后兼容 @3.6 |
版本选择建议:新设备应使用最新的稳定版本(如 @3.8),以获取最完整的 Camera 特性支持。Framework 端通过
ICameraDevice::getVersion() 查询 HAL 实现的版本号。
4.6 HIDL 与 AIDL 对比
Android 11 开始引入 AIDL 作为 HIDL 的替代方案,两者在 Camera HAL 中并存:
| 对比维度 | HIDL | AIDL |
|---|---|---|
| 引入版本 | Android 8.0 | Android 11(稳定化) |
| 接口定义 | .hal 文件 | .aidl 文件 |
| 版本管理 | 包名+版本号 | 包名+版本号(类似) |
| 代码生成 | hidl-gen | aidl-cpp / aidl-java |
| 传输层 | Binder / Passthrough | Binder(统一) |
| 未来趋势 | 逐步迁移至 AIDL | 统一接口定义标准 |
迁移注意:Camera HAL 在 Android 14+ 中仍主要使用 HIDL,但新开发的 HAL 模块建议使用 AIDL。HIDL 接口在 Android 13 之后不再新增特性,仅维护兼容性。
4.7 本章小结
- HIDL 是 Android Treble 的核心接口定义语言,通过 .hal 文件定义跨进程通信契约
- .hal 文件包含包声明、导入、类型定义和接口方法,支持基础类型、结构体、枚举、向量和回调
- Camera HAL3 使用
ICameraDevice和ICameraDeviceCallback接口实现请求/响应模式 - HIDL 版本管理遵循语义化规则,次版本只能增加方法,主版本允许不兼容变更
- HIDL 正逐步被 AIDL 取代,但 Camera HAL 在短期内仍以 HIDL 为主