2. HIDL 基础概念:接口定义语言、语法、包名与版本管理、函数与数据类型

HIDL(HAL Interface Definition Language)是 Android 系统为 Treble 架构设计的接口定义语言,用于在 Framework 进程与 HAL 实现进程之间建立稳定的二进制契约。理解 HIDL 的核心概念是编写可维护、可调试 Camera HAL 服务的前提。

2.1 HIDL 接口定义语言概述

HIDL 是一种 描述性语言,它不定义业务逻辑,只定义接口的 形状(Shape):包括包名、版本、接口名称、方法签名、数据类型和回调结构。编译器(hidl-gen)根据 .hal 文件生成 C++ 或 Java 的客户端/服务端桩代码。

关键设计原则:HIDL 强制接口与实现分离,所有跨进程通信(IPC)都通过 Binder 或直通(Passthrough)模式进行,确保 HAL 实现可以独立升级而不影响 Framework。
HIDL 接口定义与代码生成流程 .hal 接口定义文件 包名 + 版本 + 方法 + 类型 hidl-gen 编译器 解析 .hal → 生成桩代码 C++ / Java 桩代码 Binder 化 / 直通化 说明: • 客户端(Framework)通过桩代码调用服务端(HAL)方法 • 服务端继承桩代码中的接口基类,实现具体业务逻辑 • 所有 IPC 细节(序列化、反序列化、Binder 事务)由桩代码自动处理

2.2 .hal 文件语法结构

一个标准的 .hal 文件由 包声明、导入声明、接口定义 三部分组成。以下是一个 Camera HAL 中常用的 ICameraDevice.hal 简化示例:

// 包声明:package + 完整路径 + @版本号
package android.hardware.camera.device@3.4;

// 导入其他包中的类型
import android.hardware.camera.common@1.0::Status;
import android.hardware.camera.common@1.0::CameraMetadata;

// 接口定义:interface IMyCameraDevice {
interface ICameraDevice {
    // 方法:返回类型 + 方法名 + 参数列表
    getCameraCharacteristics()
        generates (Status status, CameraMetadata characteristics);

    // 方法:带输入参数和回调
    configureStreams(vec<Stream> streams)
        generates (Status status, int32_t halStreamCount);

    // 单向回调(oneway):不阻塞调用方
    oneway notify(CameraEvent event);
};
语法要点:
  • 包声明 必须与文件系统路径严格对应,例如 android/hardware/camera/device/3.4/ICameraDevice.hal
  • 版本号 使用 @major.minor 格式,@3.4 表示 major=3, minor=4
  • 方法返回值 使用 generates 关键字,而非 returns
  • 单向方法 使用 oneway 修饰,不等待服务端处理完成

2.3 包名与版本管理

HIDL 的包名(Package Name)和版本号共同构成接口的唯一标识。版本管理遵循 语义化版本 原则:

版本段 含义 变更规则 示例
Major(主版本) 不兼容的接口变更 删除/修改方法签名、删除类型字段 @3.0 → @4.0
Minor(次版本) 向后兼容的扩展 新增方法、新增类型、新增字段 @3.0 → @3.1

在 Camera HAL 中,版本演进遵循以下模式:

// 基础版本:定义核心接口
android.hardware.camera.device@3.0

// 次版本扩展:新增特性,不破坏旧接口
android.hardware.camera.device@3.2  // 新增物理相机支持
android.hardware.camera.device@3.4  // 新增会话参数

// 主版本升级:重构接口
android.hardware.camera.device@4.0  // 完全重写流配置流程
版本兼容性陷阱:在 Camera HAL 调试中,常见的问题是 Framework 请求 @3.4 接口,但 HAL 服务只注册了 @3.2,导致服务无法被发现。务必使用 lshal 命令确认注册的版本号与 manifest.xml 中声明的一致。
HIDL 版本演进与兼容性矩阵 @3.0 基础版 @3.2 扩展版 @3.4 扩展版 @4.0 重构版 兼容性规则: • @3.2 客户端可以调用 @3.0 服务端(降级兼容) • @3.0 客户端不能调用 @3.2 服务端的新方法(需要版本检查) • @4.0 与 @3.x 完全不兼容,必须同时更新 Framework 和 HAL

2.4 函数定义与数据类型

2.4.1 函数定义规则

HIDL 函数定义包含 方法名、输入参数、输出参数 和可选的 调用方式:

// 同步方法:调用方等待服务端返回
getCameraCharacteristics()
    generates (Status status, CameraMetadata characteristics);

// 带输入参数的同步方法
configureStreams(vec<Stream> streams)
    generates (Status status, int32_t halStreamCount);

// 单向方法:不等待返回,无 generates
oneway notify(CameraEvent event);

// 回调方法:服务端主动调用客户端
interface ICameraDeviceCallback {
    onCaptureResult(CaptureResult result);
};

2.4.2 内置数据类型

类型分类 具体类型 说明 Camera HAL 典型用途
整数类型 int8_t, uint8_t, int32_t, uint32_t, int64_t 固定宽度整数 帧序号、错误码、流 ID
浮点类型 float, double IEEE 754 浮点数 曝光时间、增益值、物理尺寸
布尔类型 bool true / false 功能开关、状态标志
字符串类型 string UTF-8 编码 设备名称、版本信息
枚举类型 enum 具名整数常量 相机状态、错误类型、格式枚举
结构体 struct 复合数据类型 Stream 配置、CaptureResult
联合体 union 共享内存的多种类型 元数据值(int/float/string 之一)
向量 vec<T> 动态数组 流列表、元数据项列表
安全回调 hidl_callback 函数指针封装 异步结果通知

2.4.3 自定义类型示例

在 Camera HAL 中,Stream 结构体是核心数据类型之一:

struct Stream {
    int32_t id;                    // 流唯一标识
    int32_t streamType;            // 0: 输出, 1: 输入, 2: 双向
    int32_t width;                 // 图像宽度
    int32_t height;                // 图像高度
    int32_t format;                // 像素格式(如 HAL_PIXEL_FORMAT_YCbCr_420_888)
    vec<uint8_t> bufferHandle;     // 图形缓冲区句柄
    int32_t usage;                 // 缓冲区使用标志(GRALLOC_USAGE_*)
    int32_t rotation;              // 旋转角度(0/90/180/270)
};

enum StreamType : int32_t {
    OUTPUT = 0,
    INPUT = 1,
    BIDIRECTIONAL = 2
};
调试提示:在 HIDL 服务启动阶段,最常见的类型相关错误是 枚举值不匹配。例如 Framework 发送 StreamType::OUTPUT = 0,但 HAL 实现误判为 INPUT = 1。建议在 HAL 入口处打印所有枚举参数的原始整数值,与 .hal 文件定义逐一比对。
HIDL 数据类型层级关系 HIDL 数据类型 基本类型 复合类型 容器类型 特殊类型 int/float bool/string struct enum vec<T> string hidl_callback

2.5 小结

本章涵盖了 HIDL 的核心基础概念:

  • 接口定义语言 作为 Framework 与 HAL 之间的契约,通过 hidl-gen 生成跨进程通信桩代码
  • .hal 文件语法 包含包声明、导入、接口和方法定义,严格遵循文件系统路径映射
  • 包名与版本管理 采用语义化版本,主版本不兼容、次版本向后扩展
  • 函数与数据类型 提供丰富的内置类型和自定义结构体,满足 Camera HAL 复杂的参数传递需求