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 中的通信架构:

Camera HAL3 HIDL 接口通信架构 Framework 进程 CameraService ICameraDevice.hal 客户端 ICameraDeviceCallback 服务端 HAL 进程 Camera HAL 实现 ICameraDevice.hal 服务端 ICameraDeviceCallback 客户端 processCaptureRequest() processCaptureResult() HIDL 通信数据流 Framework 通过 HIDL 接口发送 CaptureRequest → HAL 处理 → 通过 Callback 返回 CaptureResult HIDL 类型转换层 .hal 定义 → hidl-gen 生成 C++ 桩代码 → 自动序列化/反序列化

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 为主