3. Camera HAL HIDL 接口定义:核心接口 .hal 文件结构解析

在 Android Camera HAL 的 HIDL 架构中,ICameraProvider、ICameraDevice 和 ICameraDeviceSession 是三个最核心的接口定义。它们构成了从 Framework 到 HAL 的通信骨架,分别对应设备发现、设备打开与会话管理的完整生命周期。本节将逐一解析这三个接口的 .hal 文件结构,并梳理其方法签名与数据流向。

3.1 接口层次与职责划分

三个接口在 Camera HAL 初始化流程中承担不同角色,其层次关系如下表所示:

接口名称 定义文件 核心职责 生命周期阶段
ICameraProvider ICameraProvider.hal 枚举可用 Camera 设备、返回设备接口 服务注册与设备发现
ICameraDevice ICameraDevice.hal 打开 Camera 设备、创建会话 设备打开与配置
ICameraDeviceSession ICameraDeviceSession.hal 处理请求流、返回结果、控制流 数据流处理与关闭
架构要点: 三个接口遵循“提供者 → 设备 → 会话”的链式调用模型。Framework 通过 ICameraProvider 获取设备列表,再通过 ICameraDevice 打开具体设备,最后通过 ICameraDeviceSession 进行实际的拍照或预览操作。

3.2 ICameraProvider 接口结构

ICameraProvider 是 Camera HAL 的入口接口,定义在 android.hardware.camera.provider@2.x 包中。其核心方法包括设备枚举与接口回调注册。

// ICameraProvider.hal (简化结构)
package android.hardware.camera.provider@2.6;

interface ICameraProvider {
    /**
     * 返回当前可用的 Camera 设备列表及对应接口。
     * @return Status 状态码
     * @return vec<CameraIdAndStreamCombinations> 设备ID与流组合列表
     */
    getCameraIdList() generates (Status status,
            vec<CameraIdAndStreamCombinations> cameraIdList);

    /**
     * 注册设备状态回调,用于监听设备热插拔事件。
     * @param callback ICameraDeviceStatusCallback 实例
     * @return Status 状态码
     */
    setCallback(ICameraDeviceStatusCallback callback)
            generates (Status status);

    /**
     * 获取 Camera 设备的具体接口。
     * @param cameraId 设备标识符
     * @return Status 状态码
     * @return ICameraDevice 设备接口
     */
    getCameraDeviceInterface(string cameraId)
            generates (Status status, ICameraDevice device);
};

关键设计要点:

  • getCameraIdList():返回的 CameraIdAndStreamCombinations 结构体包含了设备 ID 及其支持的流组合,Framework 据此判断设备能力。
  • setCallback():通过 ICameraDeviceStatusCallback 回调接口,HAL 可以主动通知 Framework 设备状态变化(如 USB Camera 插入/拔出)。
  • getCameraDeviceInterface():返回 ICameraDevice 接口,是链式调用的关键桥梁。
工程提示: 在实现 ICameraProvider 时,getCameraIdList() 的返回顺序会影响 Framework 的默认 Camera 选择逻辑。通常将后置 Camera 放在列表首位。

3.3 ICameraDevice 接口结构

ICameraDevice 代表一个具体的 Camera 硬件设备,定义在 android.hardware.camera.device@2.x 包中。它负责设备打开、资源分配与会话创建。

// ICameraDevice.hal (简化结构)
package android.hardware.camera.device@2.6;

interface ICameraDevice {
    /**
     * 获取 Camera 设备的元数据(静态特性)。
     * @return Status 状态码
     * @return CameraMetadata 静态特性元数据
     */
    getCameraCharacteristics() generates (Status status,
            CameraMetadata cameraCharacteristics);

    /**
     * 打开设备并创建会话。
     * @param inputConfiguration 输入配置(用于 reprocess)
     * @param requestTemplate 请求模板(如预览、拍照)
     * @param callback ICameraDeviceCallback 回调
     * @return Status 状态码
     * @return ICameraDeviceSession 会话接口
     */
    open(InputConfiguration inputConfiguration,
         int32_t requestTemplate,
         ICameraDeviceCallback callback)
            generates (Status status, ICameraDeviceSession session);

    /**
     * 关闭设备,释放资源。
     * @return Status 状态码
     */
    close() generates (Status status);
};

接口设计要点:

  • getCameraCharacteristics():返回的 CameraMetadata 包含传感器尺寸、支持的分辨率、AE/AWB 范围等静态信息,Framework 据此配置流。
  • open():是初始化流程中最关键的方法。它接收 requestTemplate(如 TEMPLATE_PREVIEW、TEMPLATE_STILL_CAPTURE)和 ICameraDeviceCallback 回调,返回 ICameraDeviceSession 接口。
  • close():释放设备资源,包括关闭传感器、释放 ISP 管线等。

3.4 ICameraDeviceSession 接口结构

ICameraDeviceSession 是实际处理 Camera 数据流的接口,定义在 android.hardware.camera.device@2.x 包中。它负责请求提交、结果返回与流控制。

// ICameraDeviceSession.hal (简化结构)
package android.hardware.camera.device@2.6;

interface ICameraDeviceSession {
    /**
     * 配置输出流。
     * @param streams 输出流配置列表
     * @param config 配置参数
     * @return Status 状态码
     * @return StreamConfiguration 配置结果
     */
    configureStreams(vec<Stream> streams,
                     StreamConfigurationMode config)
            generates (Status status,
                       StreamConfiguration outConfiguration);

    /**
     * 提交捕获请求。
     * @param request 捕获请求(包含帧号、设置、Buffer 等)
     * @return Status 状态码
     * @return int32_t 帧号
     */
    processCaptureRequest(vec<CaptureRequest> requests,
                          vec<BufferCache> cachesToRemove)
            generates (Status status,
                       int32_t frameNumber);

    /**
     * 刷新当前请求队列。
     * @return Status 状态码
     */
    flush() generates (Status status);

    /**
     * 关闭会话,释放流资源。
     * @return Status 状态码
     */
    close() generates (Status status);
};

核心方法说明:

  • configureStreams():在开始数据流之前必须调用,用于配置输出流的格式、尺寸和方向。HAL 在此阶段分配 Buffer 和 ISP 资源。
  • processCaptureRequest():提交一个或多个捕获请求,每个请求包含帧号、3A 设置、输出 Buffer 句柄等。HAL 处理完成后通过回调返回结果。
  • flush():清空当前请求队列,用于快速停止或切换流。

3.5 接口调用流程与数据流向

下图展示了三个接口在 Camera HAL 初始化阶段的调用顺序与数据流向:

Camera HAL 初始化 HIDL 接口调用流程 Framework / CameraService ICameraProvider ICameraDevice ICameraDeviceSession Camera HAL 实现层 getCameraIdList() getCameraDeviceInterface() open() processCaptureRequest() 调用链说明 1. Framework 通过 Provider 获取设备列表 2. 通过 Device 打开设备 3. 通过 Session 处理请求

3.6 接口版本演进与兼容性

Camera HIDL 接口从 2.4 版本演进到 2.6 版本,每次升级都增加了新特性。下表总结了主要版本间的关键变化:

版本 新增/变更内容 影响接口
2.4 基础接口定义,支持基本拍照/预览 全部
2.5 增加 CameraIdAndStreamCombinations 结构体 ICameraProvider
2.6 增加 flush() 方法、BufferCache 机制 ICameraDeviceSession
兼容性注意: 在实现 HAL 时,必须声明支持的接口版本。如果 HAL 实现的是 2.4 版本,Framework 使用 2.6 接口调用 flush() 时会返回 UNKNOWN_TRANSACTION 错误。建议始终实现最新版本以获得完整功能支持。

3.7 接口定义中的关键数据类型

除了方法签名外,.hal 文件中还定义了多个重要的数据类型,这些类型在接口间传递数据:

  • CameraMetadata:使用 hidl_vec<uint8_t> 序列化的元数据,遵循 Camera Metadata 规范(如 ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE)。
  • Stream:描述输出流的配置,包含 streamId、width、height、format、usage 等字段。
  • CaptureRequest:包含 frameNumber、settings(元数据)、outputBuffers(Buffer 句柄列表)等。
  • BufferCache:用于 Buffer 复用机制,减少内存分配开销。

这些数据类型在 .hal 文件中通过 struct 或 enum 定义,编译后生成对应的 C++ 类,供 HAL 实现层直接使用。