CTS Camera Test失败分析与HAL适配修复 - 第2节
2.1 Android Camera HAL3 整体架构
Android Camera HAL3(即 Camera3 HAL)是 Android 从 Lollipop(API 21)开始引入的新一代相机硬件抽象层,旨在替代已废弃的 HAL1。HAL3 的核心设计理念是 “流水线 + 元数据驱动”,它将相机设备抽象为一个能够处理同步请求和异步结果的复杂状态机。
HAL3 整体架构从上到下分为三层:
- Framework 层(CameraService + CameraDeviceClient): 运行在 cameraserver 进程中,负责接收 App 的 Camera2 API 调用,将其转换为 HAL 接口的 capture request,并处理返回的 capture result。
- Camera Provider 进程(HAL Service): 运行在独立的
cameraserver或provider@2.x-service进程中,通过 HIDL / AIDL 接口与 Framework 通信,内部加载并管理具体的 HAL 实现库(.so)。 - HAL 实现层(Camera HAL Module + Device): 由 SoC 厂商或 OEM 提供的动态库,实现
camera3_device_t和camera3_callback_ops_t等核心结构体,直接与底层 V4L2、ISP 驱动交互。
android.hardware.camera2.cts.CameraExtensionCharacteristicsTest 和 CameraDeviceTest 会直接验证 HAL3 架构中 Provider 进程是否按预期响应 getCameraIdList()、open()、createCaptureSession() 等关键调用。Provider 进程崩溃或超时是 CTS 失败的常见原因。
2.2 Camera Provider 进程
Camera Provider 是 Android Treble 架构引入的关键组件,它将 HAL 实现从 Framework 进程中解耦出来,运行在独立的进程中。在 Android 8.0+ 上,Camera Provider 通过 HIDL(Hardware Interface Definition Language)提供服务;从 Android 11 开始,Google 推荐迁移到 AIDL(Android Interface Definition Language)以实现更好的性能和稳定性。
2.2.1 Provider 进程的生命周期
| 阶段 | 触发时机 | 关键操作 | CTS 验证点 |
|---|---|---|---|
| 注册 | 系统启动时 | HAL 实现调用 HIDL_FETCH_ICameraProvider 注册到 hwservicemanager |
ServiceManager.getService() 能否找到 Provider |
| 枚举 | CameraService 启动时 | 调用 getCameraIdList() 获取可用相机 ID 列表 |
返回的 ID 必须与 camera_info 中的 facing 一致 |
| 打开设备 | App 调用 CameraManager.openCamera() |
调用 open() 创建 ICameraDeviceSession |
超时 5 秒内必须返回有效 session |
| 会话运行 | Capture 请求持续进行 | 处理 processCaptureRequest()、flush() 等 |
每个请求必须在 requestTemplate 规定的超时内返回 result |
| 关闭 | App 释放相机 | 调用 close() 销毁 session |
关闭后 Provider 进程不能有内存泄漏或僵尸线程 |
2.2.2 Provider 进程的典型架构
一个典型的 Camera Provider 进程内部包含以下组件:
- ICameraProvider 接口实现: 负责设备枚举、设备打开、Torch 模式控制等。
- ICameraDevice 接口实现: 代表一个物理相机设备,负责创建 session。
- ICameraDeviceSession 接口实现: 处理 capture request 和 result 回调,是性能关键路径。
- Buffer Manager: 管理 Gralloc 缓冲区分配和流转,支持
ICameraDeviceSession::configureStreams()中的流配置。 - Vendor 扩展模块: 厂商特定的 ISP 调优、3A 算法、HDR 融合等。
open() 或 processCaptureRequest() 中阻塞超过 5 秒,Framework 会抛出 CameraAccessException,CTS 测试用例 CameraDeviceTest#testCameraDeviceOpen 将直接失败。务必在 HAL 实现中避免长时间持锁或同步 I/O 操作。
2.3 HAL 接口定义
Camera HAL3 的核心接口定义在 hardware/libhardware/include/hardware/camera3.h 中。该头文件定义了三个主要结构体:camera3_device_t、camera3_callback_ops_t 和 camera3_stream_t。此外,Treble 架构下的 HIDL/AIDL 接口定义在 hardware/interfaces/camera/ 目录下。
2.3.1 核心 C 结构体接口
| 结构体 | 关键字段 / 方法 | 作用 | CTS 验证内容 |
|---|---|---|---|
camera3_device_t |
ops->initialize()ops->configure_streams()ops->process_capture_request()ops->flush() |
相机设备的主要操作接口,所有 capture 请求都通过此结构体下发 | 验证每个方法是否在超时内返回,参数校验是否正确 |
camera3_callback_ops_t |
process_capture_result()notify() |
HAL 向 Framework 返回 capture result 和异步事件(如快门、错误)的回调接口 | 验证 result 中的 metadata 是否完整,notify 中的错误码是否合规 |
camera3_stream_t |
stream_type (CAMERA3_STREAM_OUTPUT / INPUT)format (HAL_PIXEL_FORMAT_* )usage (Gralloc usage flags)max_buffers |
描述一个数据流(预览、拍照、录像等)的格式、方向和缓冲区需求 | 验证 configure_streams() 返回的 max_buffers 是否满足 CTS 最小要求 |
camera3_capture_request_t |
frame_numbersettings (metadata buffer)input_buffer / output_buffers |
描述一次 capture 请求的帧号、参数设置和输入/输出缓冲区 | 验证 frame_number 是否单调递增,settings 是否被正确解析 |
2.3.2 HIDL / AIDL 接口定义
在 Treble 架构下,Camera Provider 通过 HIDL 接口暴露服务。以下是 Android 10 中 Camera HIDL 接口的核心层次:
// ICameraProvider.hal (android.hardware.camera.provider@2.4)
interface ICameraProvider {
getCameraIdList() generates (Status status, vec<string> cameraIds);
open(string cameraId, ICameraDeviceCallback callback)
generates (Status status, ICameraDevice device);
setTorchMode(string cameraId, bool enabled) generates (Status status);
};
// ICameraDevice.hal (android.hardware.camera.device@3.4)
interface ICameraDevice {
open(ICameraDeviceCallback callback)
generates (Status status, ICameraDeviceSession session);
getResourceCost() generates (Status status, ResourceCost cost);
};
// ICameraDeviceSession.hal (android.hardware.camera.device@3.4)
interface ICameraDeviceSession {
configureStreams(StreamConfiguration config)
generates (Status status, HalStreamConfiguration halConfig);
processCaptureRequest(vec<CaptureRequest> requests,
vec<BufferCache> cachesToRemove)
generates (Status status, uint32_t numRequestProcessed);
flush() generates (Status status);
close();
};
hardware/interfaces/camera/aidl/ 下,包名为 android.hardware.camera。AIDL 版本支持更高效的 Binder 传输、自动生成的 Java 后端,以及更好的跨进程错误处理。CTS 测试 CameraExtensionCharacteristicsTest 在 Android 12+ 上要求 Provider 同时支持 HIDL 和 AIDL 接口。
2.3.3 关键接口调用流程
一个典型的 capture 请求从 App 到 HAL 的完整接口调用序列如下:
- App 调用
CameraCaptureSession.capture() - CameraService 将请求封装为
CaptureRequest,调用ICameraDeviceSession::processCaptureRequest() - Camera Provider 将 HIDL/AIDL 请求转换为
camera3_capture_request_t,调用camera3_device_t.ops->process_capture_request() - HAL 实现 将请求下发到 ISP 驱动,等待 sensor 曝光完成
- HAL 实现 通过
camera3_callback_ops_t.process_capture_result()返回结果 metadata 和填充好的 buffer - Camera Provider 将结果通过 HIDL/AIDL 回调返回给 Framework
- CameraService 将结果分发给 App 的
CaptureCallback
2.3.4 接口适配常见陷阱
- configure_streams() 返回的 max_buffers 过小: CTS 要求至少支持 4 个输出 buffer(预览 + 拍照 + 录像 + ZSL),如果 HAL 返回的
max_buffers小于 4,CameraDeviceTest#testStreamConfiguration会失败。 - process_capture_request() 未正确处理 input_buffer: 对于 reprocessing 请求(如 ZSL),HAL 必须支持
input_buffer不为 NULL 的情况,否则CameraExtensionCharacteristicsTest会失败。 - notify() 中错误码使用不当: 例如在 buffer 丢失时使用
CAMERA3_MSG_ERROR_DEVICE而非CAMERA3_MSG_ERROR_BUFFER,会导致 CTS 认为设备发生致命错误。 - flush() 未正确取消所有待处理请求: CTS 会在
flush()后立即发送新的 capture 请求,如果 HAL 没有完全清理内部状态,会导致后续请求的 frame_number 混乱。