CTS Camera Test失败分析与HAL适配修复 - 第2节

2.1 Android Camera HAL3 整体架构

Android Camera HAL3(即 Camera3 HAL)是 Android 从 Lollipop(API 21)开始引入的新一代相机硬件抽象层,旨在替代已废弃的 HAL1。HAL3 的核心设计理念是 “流水线 + 元数据驱动”,它将相机设备抽象为一个能够处理同步请求和异步结果的复杂状态机。

关键设计目标: 支持每帧独立控制曝光、增益、白平衡、对焦等参数;支持高速连拍(Burst);支持 ZSL(零快门延迟);支持多帧融合(HDR+、夜景模式);支持 YUV/Raw/JPEG 多路输出流。

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 Camera HAL3 整体架构图 Framework 层 (cameraserver 进程) CameraService | CameraDeviceClient | Camera3Device Camera Provider 进程 ICameraProvider (HIDL/AIDL) | CameraDeviceSession HAL 实现层 (vendor 动态库) camera3_device_t | camera3_callback_ops_t | ISP / V4L2 驱动 HIDL/AIDL 接口:ICameraProvider → IDevice → IStream
CTS 考试要点: CTS 的 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 融合等。
Camera Provider 进程内部组件结构 Camera Provider 进程边界 ICameraProvider getCameraIdList / open / setTorch ICameraDevice open / getResourceCost ICameraDeviceSession processCaptureRequest / flush Buffer Manager Gralloc 分配 / 流转 / 释放 Vendor 3A / ISP 算法 AE / AF / AWB / HDR 融合 V4L2 / 内核驱动 Sensor / CSI / ISP 所有接口通过 HIDL/AIDL 与 Framework 通信,进程间调用有 5 秒超时限制
常见 CTS 失败场景: 如果 Provider 进程在 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_number
settings (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();
};
迁移到 AIDL: 从 Android 11 开始,Google 推荐使用 AIDL 替代 HIDL。AIDL 接口定义在 hardware/interfaces/camera/aidl/ 下,包名为 android.hardware.camera。AIDL 版本支持更高效的 Binder 传输、自动生成的 Java 后端,以及更好的跨进程错误处理。CTS 测试 CameraExtensionCharacteristicsTest 在 Android 12+ 上要求 Provider 同时支持 HIDL 和 AIDL 接口。

2.3.3 关键接口调用流程

一个典型的 capture 请求从 App 到 HAL 的完整接口调用序列如下:

  1. App 调用 CameraCaptureSession.capture()
  2. CameraService 将请求封装为 CaptureRequest,调用 ICameraDeviceSession::processCaptureRequest()
  3. Camera Provider 将 HIDL/AIDL 请求转换为 camera3_capture_request_t,调用 camera3_device_t.ops->process_capture_request()
  4. HAL 实现 将请求下发到 ISP 驱动,等待 sensor 曝光完成
  5. HAL 实现 通过 camera3_callback_ops_t.process_capture_result() 返回结果 metadata 和填充好的 buffer
  6. Camera Provider 将结果通过 HIDL/AIDL 回调返回给 Framework
  7. CameraService 将结果分发给 App 的 CaptureCallback
Capture 请求接口调用序列 App CameraService Provider HAL 实现 ① capture() ② processCaptureRequest() ③ camera3 ops ④ process_capture_result() ⑤ HIDL/AIDL 回调 ⑥ onCaptureCompleted() 整个调用链必须在 5 秒内完成,否则 CTS 测试会因 ANR 或 CameraAccessException 失败

2.3.4 接口适配常见陷阱

CTS 失败高频原因:
  • 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 混乱。

2.4 本章小结