3. HAL3 接口规范详解:camera3_device_ops、camera3_callback_ops、关键数据结构
HAL3 接口是 Android Camera 子系统与硬件抽象层之间的核心契约。当 CameraProvider 枚举设备失败或 HAL3 通信链路中断时,根因往往是对这些接口规范的理解偏差或实现遗漏。本章深入剖析 camera3_device_ops、camera3_callback_ops 以及关键数据结构,为后续的链路调试打下坚实基础。
3.1 接口总览与分层模型
HAL3 接口位于 Camera Framework(CameraService)与 Camera HAL 实现之间。其核心交互模型如下:
核心原则: Framework 通过
camera3_device_ops 向 HAL 下发请求,HAL 通过 camera3_callback_ops 异步返回结果。任何一方的实现不完整或生命周期管理错误,都会导致枚举失败或通信超时。
3.2 camera3_device_ops 函数指针表
camera3_device_ops 是 HAL 暴露给 Framework 的操作接口,定义在 hardware/libhardware/include/hardware/camera3.h 中。它是一个包含多个函数指针的结构体,Framework 通过调用这些函数来驱动相机硬件。
| 函数指针 | 用途 | 调试关注点 |
|---|---|---|
initialize |
初始化设备,注册 callback_ops | 必须在此函数中保存 callback_ops 指针;返回 0 表示成功 |
configure_streams |
配置输出/输入流(分辨率、格式、方向) | 检查 stream 配置是否被 HAL 拒绝;常见失败原因:不支持的尺寸或格式 |
construct_default_request_settings |
返回默认的 capture request settings | 返回的 metadata 必须包含所有必要的 control 字段;返回 NULL 会导致枚举失败 |
process_capture_request |
处理一次 capture 请求 | 检查 request 中的 settings 和 output_buffers 是否有效 |
flush |
清空所有正在处理的请求 | 必须在 1000ms 内完成;超时会导致 ANR |
dump |
输出调试信息到 fd | 用于 dumpsys 调试;实现空函数即可 |
调试技巧: 在
initialize 和 configure_streams 入口处添加 ALOGV 日志,打印传入的参数。枚举失败时,优先检查 construct_default_request_settings 是否返回了非空 metadata。
3.3 camera3_callback_ops 回调接口
camera3_callback_ops 是 Framework 提供给 HAL 的回调接口,HAL 通过它异步通知 Framework 事件和结果。该结构体在 initialize 时由 Framework 传入。
| 回调函数 | 触发时机 | 调试关注点 |
|---|---|---|
process_capture_result |
一次 capture 完成时 | 必须为每个 request 调用一次;result 中的 metadata 不能为 NULL |
notify |
错误、快门事件等发生时 | 错误类型包括 ERROR_REQUEST、ERROR_RESULT、ERROR_BUFFER 等 |
常见陷阱: HAL 必须在
initialize 中保存 callback_ops 指针,并在后续所有回调中使用。如果保存的指针被覆盖或释放,Framework 将收到无效回调,导致通信链路断裂。
3.4 关键数据结构详解
HAL3 通信涉及多个核心数据结构,理解它们的生命周期和所有权是调试的基础。
3.4.1 camera3_stream_t
描述一个图像流(输出或输入)。关键字段包括:
stream_type:CAMERA3_STREAM_OUTPUT(输出)、CAMERA3_STREAM_INPUT(输入)或 CAMERA3_STREAM_BIDIRECTIONAL(双向)。width/height:图像尺寸。format:像素格式,如 HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED。usage:GRALLOC_USAGE_* 标志,指示 buffer 用途。max_buffers:HAL 请求的最大 buffer 数量。
3.4.2 camera3_capture_request_t
描述一次 capture 请求。关键字段包括:
frame_number:帧序号,必须唯一且递增。settings:指向 metadata 的指针,包含 3A 参数、AE 模式等。input_buffer:输入 buffer(用于 reprocessing)。num_output_buffers/output_buffers:输出 buffer 数组。
3.4.3 camera3_capture_result_t
描述一次 capture 的结果。关键字段包括:
frame_number:对应 request 的帧序号。result:指向 metadata 的指针,包含最终 3A 状态、传感器时间戳等。num_output_buffers/output_buffers:已填充的输出 buffer。partial_result:部分结果计数,用于分阶段返回 metadata。
3.5 枚举失败与通信链路调试要点
当 CameraProvider 枚举失败时,通常与以下 HAL3 接口实现问题相关:
- initialize 未正确保存 callback_ops:后续所有回调都将失败,Framework 无法收到通知。
- construct_default_request_settings 返回 NULL:Framework 无法获取默认配置,直接判定 HAL 不可用。
- configure_streams 返回非 0:流配置被 HAL 拒绝,常见于不支持的尺寸或格式。
- process_capture_result 未调用或调用顺序错误:导致 Framework 等待结果超时。
- metadata 中缺少必要字段:如 ANDROID_SENSOR_TIMESTAMP、ANDROID_CONTROL_AE_STATE 等。
调试建议: 在 HAL 的
initialize、configure_streams、construct_default_request_settings 和 process_capture_request 入口处添加详细的 ALOGV 日志,打印所有关键参数。使用 adb logcat -s CameraHal 过滤日志,快速定位问题点。