4. HAL3 接口实现:ICameraDevice、ICameraDeviceSession、ICameraDeviceCallback

在 Android Camera HAL3 架构中,HIDL(HAL Interface Definition Language)接口是 Framework 与 HAL 实现之间的核心契约。正确实现 ICameraDevice、ICameraDeviceSession 和 ICameraDeviceCallback 三个接口,是保证相机功能正常、性能达标以及通过 CTS 测试的基础。本章将深入剖析每个接口的职责、关键方法以及实现时的性能与兼容性要点。

4.1 接口总览与职责划分

三个 HIDL 接口构成了 HAL 层的“设备-会话-回调”三角模型,其职责分工如下表所示:

接口名称 核心职责 生命周期 关键方法数
ICameraDevice 设备级管理:打开/关闭相机、创建会话、查询静态信息 从 HAL 加载到设备关闭 ~5 个
ICameraDeviceSession 会话级控制:配置流、提交请求、捕获结果回调 从 open() 到 close() 或 flush() ~10 个
ICameraDeviceCallback 异步通知:结果返回、错误上报、缓冲区释放 由 Framework 实现,HAL 调用 ~4 个
实现要点:三个接口必须严格遵循 HIDL 定义的 oneway 和同步调用语义。ICameraDevice 和 ICameraDeviceSession 的方法通常由 Framework 同步调用,而 ICameraDeviceCallback 的方法均为 oneway(异步),HAL 实现不得在回调中执行耗时操作。

4.2 ICameraDevice 接口实现

ICameraDevice 是 HAL 暴露给 Framework 的第一个入口点。其核心方法包括:

  • getCameraCharacteristics():返回相机静态元数据(如传感器尺寸、AE/AWB 能力、支持的分辨率列表)。
    性能要点:此方法在相机打开时被频繁调用,建议将元数据预编译为二进制 buffer,避免每次动态构造。
  • open():创建并返回一个 ICameraDeviceSession 实例。这是性能关键路径,必须在 500ms 内完成(CTS 要求)。
    实现要点:延迟初始化硬件资源(如 ISP、Sensor),仅在首次提交请求时真正启动。
  • close():释放所有硬件和内存资源。必须保证幂等性,多次调用不崩溃。
  • setTorchMode():控制闪光灯常亮模式。需注意与 session 内闪光灯控制的互斥逻辑。
CTS 避坑:getCameraCharacteristics() 返回的 android.scaler.availableStreamConfigurations 必须与 session 实际支持的流完全一致。任何不一致都会导致 CTS 测试项 android.hardware.camera2.cts.CameraCharacteristicsTest 失败。

4.3 ICameraDeviceSession 接口实现

ICameraDeviceSession 是 HAL3 最核心的接口,负责处理所有捕获请求和结果返回。其关键方法按功能分组如下:

4.3.1 流配置与管道控制

  • configureStreams():配置输出流(如预览、拍照、录像)和输入流(如 reprocess)。
    性能要点:此方法调用时,HAL 应重新计算 ISP 管线带宽,避免不必要的硬件复位。CTS 要求配置时间 < 100ms。
  • processCaptureRequest():提交单个捕获请求。这是性能调优的核心战场。
    实现要点:请求入队后应立即返回,实际处理在后台线程进行。使用 lock-free 队列减少 Framework 侧等待时间。
  • flush():清空所有待处理请求,并等待正在处理的请求完成。CTS 要求 flush 在 1000ms 内返回。

4.3.2 结果与错误通知

  • processCaptureRequest() 的结果返回:通过 ICameraDeviceCallback 的 processCaptureResult() 方法异步返回。每个请求必须返回至少一个 partial result 和一个 final result。
  • notify():通过 ICameraDeviceCallback 上报错误(如请求超时、缓冲区错误)。
性能优化技巧:对于预览流,建议在 processCaptureRequest() 中直接复用上一次的 metadata buffer,仅更新时间戳和 3A 状态,减少内存分配开销。对于拍照流,则需保证完整的 metadata 填充。

4.4 ICameraDeviceCallback 接口实现

ICameraDeviceCallback 由 Framework 实现,HAL 通过它向 Framework 传递结果和事件。HAL 实现者需要正确调用以下方法:

回调方法 调用时机 实现要求
processCaptureResult() 每个捕获请求完成时(可多次调用,用于 partial result) 必须按请求顺序返回;partial result 的 metadata 必须包含 android.sensor.timestamp
notify() 发生错误或事件时(如请求超时、缓冲区错误) 必须填充正确的 ErrorCode;不得在回调中阻塞
requestStreamBuffers() HAL 需要 Framework 分配缓冲区时(可选) 仅当 HAL 支持 buffer management 模式时使用
returnStreamBuffers() HAL 使用完缓冲区后归还 必须与 requestStreamBuffers 配对调用
关键约束:所有回调方法都是 oneway(异步),HAL 实现不得在回调中等待 Framework 响应。如果 HAL 在回调中执行同步 IPC 调用,会导致死锁(Framework 侧可能持有锁等待回调返回)。

4.5 接口交互流程与性能关键路径

下图展示了从打开相机到提交请求的完整交互流程,并标注了性能关键路径:

HAL3 接口交互流程与性能关键路径 Framework ICameraDevice ICameraDeviceSession ① open() ② 创建 Session ③ configureStreams() ISP 管线配置 ④ processCaptureRequest() 请求队列处理 ⑤ processCaptureResult() Framework 回调 性能关键路径标注 ① open():必须在 500ms 内完成,建议延迟初始化硬件 ③ configureStreams():必须在 100ms 内完成,避免硬件复位 ④ processCaptureRequest():入队时间 < 1ms,使用 lock-free 队列

4.6 实现要点总结与 CTS 验证对照

下表将接口实现要点与对应的 CTS 测试项关联,便于开发者在实现时进行自检:

接口 实现要点 对应 CTS 测试项
ICameraDevice getCameraCharacteristics() 返回的静态信息必须与硬件能力一致 CameraCharacteristicsTest
ICameraDeviceSession configureStreams() 必须支持所有声明的流组合;processCaptureRequest() 必须按序返回结果 CameraExtensionSessionTest、CaptureRequestTest
ICameraDeviceCallback processCaptureResult() 必须包含 android.sensor.timestamp;notify() 必须正确上报错误码 CameraDeviceTest、ResultTest
跨接口 flush() 后所有待处理请求必须通过 notify() 上报 ERROR_REQUEST FlushTest
调试建议:在实现初期,建议在 HAL 侧增加详细的日志输出,记录每个接口方法的调用时间、参数和返回值。使用 adb shell dumpsys media.camera 可以查看 Framework 侧收集的 HAL 性能数据,帮助定位接口实现中的性能瓶颈。