3. Camera HAL3核心规范:接口定义、设备结构体与回调机制
Camera HAL3 是 Android 相机子系统的核心抽象层,它定义了 Framework 与硬件厂商实现之间的标准契约。本章深入剖析 HAL3 的三大支柱:接口定义、camera3_device_t 结构体和 camera3_callback_ops_t 回调。理解这些规范是进行 Treble 架构下 HAL 适配的基础。
3.1 HAL3 接口定义:从 open() 到 close() 的生命周期
HAL3 接口以 camera_module_t 为入口,通过 camera3_device_t 暴露操作。核心接口函数定义了 Camera 设备的完整生命周期:
| 接口函数 | 所属结构体 | 功能描述 | 关键参数 |
|---|---|---|---|
open() |
camera_module_t | 打开指定 Camera 设备,返回 camera3_device_t | hw_module_t*, const char* id, hw_device_t** |
initialize() |
camera3_device_ops_t | 初始化设备,注册回调接口 | const camera3_callback_ops_t* |
configure_streams() |
camera3_device_ops_t | 配置数据流(输入/输出流) | camera3_stream_configuration_t* |
construct_default_request_settings() |
camera3_device_ops_t | 构造指定模板的默认请求设置 | camera3_request_template_t |
process_capture_request() |
camera3_device_ops_t | 提交一次捕获请求 | camera3_capture_request_t* |
flush() |
camera3_device_ops_t | 刷新所有待处理的请求 | 无 |
close() |
hw_device_t | 关闭设备,释放资源 | hw_device_t* |
适配要点: Treble 架构下,
open() 和 close() 由 HAL 服务端实现,Framework 通过 HIDL/Binder 通信间接调用。务必确保 initialize() 在 configure_streams() 之前被调用,否则流配置会失败。
以下是一个典型的 HAL3 接口调用序列(简化版):
// 1. 打开设备
camera3_device_t *device;
module->common.methods->open(&module->common, "0", (hw_device_t**)&device);
// 2. 初始化并注册回调
device->ops->initialize(device, &g_callback_ops);
// 3. 配置流
camera3_stream_configuration_t config;
// ... 填充 config ...
device->ops->configure_streams(device, &config);
// 4. 提交请求
camera3_capture_request_t request;
// ... 填充 request ...
device->ops->process_capture_request(device, &request);
// 5. 关闭设备
device->common.close((hw_device_t*)device);
3.2 camera3_device_t 结构体:HAL 设备的核心抽象
camera3_device_t 是 HAL3 中代表单个 Camera 设备的结构体。它继承自 hw_device_t,并包含指向操作函数集的指针。其定义如下:
typedef struct camera3_device {
hw_device_t common; // 继承的硬件设备基类
camera3_device_ops_t *ops; // 设备操作函数指针
void *priv; // 厂商私有数据指针
} camera3_device_t;
三个字段的作用:
- common:
hw_device_t基类,包含 tag、version、close() 等通用字段。HAL 适配时必须正确填充 tag 为HARDWARE_DEVICE_TAG,version 为HAL_DEVICE_API_VERSION(3, 0)或更高。 - ops:指向
camera3_device_ops_t结构体的指针,该结构体包含所有设备操作函数(如 initialize、configure_streams、process_capture_request 等)。 - priv:厂商私有数据指针,用于存储设备上下文、传感器驱动句柄、ISP 配置等。Framework 不直接访问此字段。
Treble 适配关键: 在 Treble 架构中,
camera3_device_t 的分配和初始化通常发生在 HAL 服务端进程。Framework 通过 HIDL 接口获取设备句柄,但实际的内存管理由 HAL 实现负责。建议在 priv 中存储一个指向厂商自定义设备上下文的结构体指针,避免全局变量。
3.3 camera3_callback_ops_t 回调:异步结果通知机制
HAL3 采用异步模型:Framework 提交请求后,HAL 通过 camera3_callback_ops_t 回调接口返回结果。该结构体定义了三个关键回调函数:
typedef struct camera3_callback_ops {
void (*process_capture_result)(const struct camera3_callback_ops *,
const camera3_capture_result_t *result);
void (*notify)(const struct camera3_callback_ops *,
const camera3_notify_msg_t *msg);
void (*process_capture_result_with_phys_dev)(const struct camera3_callback_ops *,
const camera3_capture_result_t *result,
const camera3_physical_camera_metadata_t *phys_result);
} camera3_callback_ops_t;
| 回调函数 | 触发时机 | 传递数据 | 线程安全要求 |
|---|---|---|---|
process_capture_result |
捕获完成(部分或全部) | camera3_capture_result_t(包含 metadata、buffer、partial_result) | 必须可重入,可并发调用 |
notify |
错误、快门事件、请求错误等 | camera3_notify_msg_t(包含消息类型和具体数据) | 必须可重入,可并发调用 |
process_capture_result_with_phys_dev |
逻辑相机多物理设备场景 | 包含物理设备元数据 | 必须可重入,可并发调用 |
常见陷阱:
- 回调函数可能从 HAL 内部的任意线程调用,实现中必须保证线程安全。
process_capture_result可能被多次调用(partial result 机制),每次返回部分结果,直到partial_result等于num_capture_requests才表示完整。- 不要在回调中执行耗时操作(如 I/O、加锁等待),否则会阻塞 HAL 的 pipeline。
3.4 三者的协作关系
camera3_device_t、camera3_device_ops_t 和 camera3_callback_ops_t 三者构成了 HAL3 的核心三角:
- camera3_device_t 是“设备对象”,承载状态和私有数据。
- camera3_device_ops_t 是“操作接口”,Framework 通过它下发命令。
- camera3_callback_ops_t 是“通知通道”,HAL 通过它异步返回结果。
在 Treble 架构中,这个三角关系被封装在 HAL 服务端进程内。Framework 通过 HIDL 接口 ICameraDevice 间接调用 camera3_device_ops_t,而回调则通过 HIDL 的 ICameraDeviceCallback 反向传递。理解原生 HAL3 的接口定义,是理解 Treble 适配层的基础。
实践建议: 在开始 Treble 适配前,先在原生 HAL3 环境下验证这三个核心接口的正确性。使用 CTS 的
CameraHAL3Test 测试用例,确保 initialize → configure_streams → process_capture_request → 回调返回的完整链路通畅。