3. Camera HIDL接口定义:ICameraProvider、ICameraDevice、ICameraDeviceSession等核心接口解析

在Camera HAL的HIDL服务化架构中,接口定义是连接Framework与HAL实现的契约。Android从Oreo开始引入Treble架构,将Camera HAL接口从传统的hardware/libhardware迁移至HIDL(HAL Interface Definition Language),实现了Framework与HAL的编译时解耦。本章将深入解析三个核心HIDL接口:ICameraProvider、ICameraDevice和ICameraDeviceSession,它们构成了Camera HAL服务启动与调用的主干。

核心概念:ICameraProvider负责设备枚举与生命周期管理;ICameraDevice代表单个物理或逻辑相机设备;ICameraDeviceSession管理具体的捕获会话与请求流。三者形成“Provider → Device → Session”的层级调用链。

3.1 接口层级关系与调用链路

三个核心接口在HIDL服务中的层级关系如下图所示。Framework通过CameraService与HAL通信,首先获取ICameraProvider,再通过Provider获取ICameraDevice,最后通过Device打开ICameraDeviceSession进行数据流处理。

Camera HIDL 核心接口层级调用链路 CameraService (Framework) ICameraProvider ICameraDevice ICameraDeviceSession 调用方向:Framework → Provider → Device → Session,每个接口通过HIDL IPC跨进程通信
工程提示:在调试HIDL服务启动问题时,建议从ICameraProvider的getCameraIdList()返回值入手,确认HAL层是否正确枚举了所有物理相机设备。若返回空列表,则表明Provider注册或初始化失败。

3.2 ICameraProvider 接口详解

ICameraProvider是Camera HAL的入口接口,负责相机设备的发现、查询和生命周期管理。每个Camera HAL实现必须至少提供一个ICameraProvider服务实例。其核心方法如下表所示:

方法名称 输入参数 返回值 功能描述
getCameraIdList() 无 Status + hidl_vec<string> 返回所有可用相机设备的ID列表
getCameraDeviceInterface() string cameraId Status + ICameraDevice 根据cameraId获取对应的ICameraDevice接口
setCallback() ICameraProviderCallback Status 注册回调,用于通知Framework设备热插拔事件
getVendorTags() 无 Status + hidl_vec<VendorTagSection> 返回HAL层自定义的vendor tag列表
isSetTorchModeSupported() 无 Status + bool 查询是否支持闪光灯常亮模式

ICameraProvider的HIDL定义片段(以Android 12为例):

interface ICameraProvider {
    getCameraIdList() generates (Status status, hidl_vec<string> cameraIds);
    getCameraDeviceInterface(string cameraId)
            generates (Status status, ICameraDevice device);
    setCallback(ICameraProviderCallback callback)
            generates (Status status);
    getVendorTags()
            generates (Status status, hidl_vec<VendorTagSection> vendorTagSections);
    isSetTorchModeSupported()
            generates (Status status, bool support);
};
常见问题:若getCameraDeviceInterface()返回Status::INTERNAL_ERROR,通常表明HAL层在初始化特定相机设备时失败。常见原因包括:Sensor驱动未加载、ISP固件校验失败、内存分配不足等。建议在HAL实现中增加详细的ALOGE日志输出。

3.3 ICameraDevice 接口详解

ICameraDevice代表一个具体的相机设备(物理或逻辑)。它负责提供相机静态信息、配置输出流、以及创建捕获会话。ICameraDevice是连接Provider与Session的桥梁。

方法名称 输入参数 返回值 功能描述
getResourceCost() 无 Status + CameraResourceCost 返回相机设备的资源消耗信息(如带宽、功耗)
getCameraCharacteristics() 无 Status + CameraMetadata 返回相机设备的静态特性元数据(如分辨率、AE/AWB能力)
open() ICameraDeviceCallback Status + ICameraDeviceSession 打开相机设备,返回一个ICameraDeviceSession用于捕获
setTorchMode() TorchMode mode Status 设置闪光灯模式(ON/OFF)
dumpState() int fd Status 将设备状态信息输出到指定文件描述符(用于dumpsys)

ICameraDevice的HIDL定义片段:

interface ICameraDevice {
    getResourceCost() generates (Status status, CameraResourceCost cost);
    getCameraCharacteristics()
            generates (Status status, CameraMetadata characteristics);
    open(ICameraDeviceCallback callback)
            generates (Status status, ICameraDeviceSession session);
    setTorchMode(TorchMode mode) generates (Status status);
    dumpState(int fd) generates (Status status);
};
关键点:open()方法是ICameraDevice最核心的接口。它接收一个ICameraDeviceCallback回调接口,用于向Framework通知错误、结果元数据、缓冲区等事件。HAL实现必须在open()中完成硬件初始化(如Sensor上电、ISP配置),若初始化失败应返回Status::CAMERA_IN_USE或Status::INTERNAL_ERROR。

3.4 ICameraDeviceSession 接口详解

ICameraDeviceSession是实际处理捕获请求和返回结果的接口。它管理着从应用层下发Capture Request到HAL处理并返回Capture Result的完整流水线。Session的生命周期从open()成功返回开始,到设备关闭或异常断开结束。

方法名称 输入参数 返回值 功能描述
constructDefaultRequestSettings() RequestTemplate type Status + CameraMetadata 返回指定模板(如PREVIEW/STILL_CAPTURE)的默认请求参数
configureStreams() StreamConfiguration config Status + HalStreamConfiguration 配置输出流(分辨率、格式、数据空间等),是捕获前的关键步骤
processCaptureRequest() hidl_vec<CaptureRequest> requests Status + uint32_t numRequestProcessed 提交一组捕获请求到HAL处理,HAL通过回调返回结果
flush() 无 Status 刷新所有正在处理的请求,停止当前捕获
close() 无 Status 关闭Session,释放所有硬件资源

ICameraDeviceSession的HIDL定义片段:

interface ICameraDeviceSession {
    constructDefaultRequestSettings(RequestTemplate type)
            generates (Status status, CameraMetadata requestTemplate);
    configureStreams(StreamConfiguration requestedConfiguration)
            generates (Status status, HalStreamConfiguration halConfiguration);
    processCaptureRequest(hidl_vec<CaptureRequest> requests)
            generates (Status status, uint32_t numRequestProcessed);
    flush() generates (Status status);
    close() generates (Status status);
};
调试技巧:在调试预览或拍照流程时,重点关注configureStreams()的返回值。若HAL返回Status::ILLEGAL_ARGUMENT,通常是因为请求的流配置(如分辨率超出Sensor能力、格式不支持)与CameraCharacteristics中声明的SCALER_AVAILABLE_STREAM_CONFIGURATIONS不匹配。

3.5 接口调用流程与数据流

下图展示了从应用层下发Capture Request到HAL返回Capture Result的完整数据流,涉及三个核心接口的协作:

Capture Request 处理流程与接口协作 1. 应用下发Request 2. processCaptureRequest() 3. HAL处理流水线 4. 回调通知Framework 5. ICameraDeviceCallback 6. 应用收到Result ICameraDeviceCallback 关键回调方法 • processCaptureResult(): 返回捕获结果元数据(AE/AWB/AF状态、时间戳等) • notify(): 通知错误事件(如请求超时、缓冲区丢失、设备错误) configureStreams() 配置流程 • Framework下发 StreamConfiguration(包含所有输出流的宽/高/格式/数据空间) • HAL返回 HalStreamConfiguration(确认每个流的最终配置,如overrideFormat、bufferUsage) • 配置成功后,HAL内部完成ISP管线重配置、内存分配等操作

3.6 接口实现要点与常见问题

  • ICameraProvider实现要点:
    • 必须在getCameraIdList()中返回稳定的cameraId顺序,避免Framework缓存失效。
    • setCallback()注册的回调必须妥善保存,用于热插拔通知(如USB Camera插拔)。
    • 若HAL支持多个Provider实例(如前后摄分离),需确保每个Provider的cameraId不冲突。
  • ICameraDevice实现要点:
    • getCameraCharacteristics()返回的元数据必须与HAL实际能力一致,否则会导致Framework层校验失败。
    • open()方法中,若设备已被占用,应返回Status::CAMERA_IN_USE而非INTERNAL_ERROR。
    • 建议在open()中完成硬件初始化后,立即调用ICameraDeviceCallback::notify()发送CameraDeviceError::CAMERA_DEVICE_ERROR_NONE表示设备就绪。
  • ICameraDeviceSession实现要点:
    • configureStreams()必须支持动态重配置(如从预览切换到录像),且需正确处理流数量变化。
    • processCaptureRequest()支持批量提交(hidl_vec),HAL应尽量并行处理以提高吞吐量。
    • flush()必须尽快停止所有正在处理的请求,并通过回调返回BufferStatus::ERROR给Framework。
避坑指南:在实现processCaptureRequest()时,HAL必须保证每个提交的Request都有对应的回调返回(无论是成功还是失败)。若HAL丢失了某个Request的回调,Framework会触发ERROR_REQUEST并可能导致Session关闭。建议在HAL内部维护一个Request ID队列,确保每个ID都有对应的processCaptureResult()或notify()回调。

3.7 接口版本演进与兼容性

Camera HIDL接口从Android 8.0(Oreo)的1.0版本演进到Android 12的3.7版本,每次升级都增加了新功能或优化了性能。下表总结了关键版本变化:

Android版本 HIDL版本 主要变更
8.0 (Oreo) 1.0 初始Treble架构,引入ICameraProvider/ICameraDevice/ICameraDeviceSession
9.0 (Pie) 2.0 增加逻辑相机(Multi-Camera)支持,ICameraDevice增加isStreamCombinationSupported()
10.0 (Q) 3.0 引入HalStreamConfiguration中的physicalCameraId字段,支持物理流配置
11.0 (R) 3.5 增加ICameraDeviceSession::repeatingRequest()优化预览性能
12.0 (S) 3.7 增加ICameraDeviceSession::signalStreamFlush(),优化流关闭时的flush行为
兼容性建议:在实现HAL时,建议使用#ifdef或版本判断宏来适配不同Android版本的HIDL接口差异。例如,Android 12新增的signalStreamFlush()在旧版本中不存在,若直接调用会导致编译错误。推荐使用android::hardware::camera::common::V1_0::helper::CameraModule等辅助类简化版本适配。

通过以上对ICameraProvider、ICameraDevice、ICameraDeviceSession三个核心接口的解析,可以看到Camera HIDL接口设计遵循了清晰的分层原则:Provider负责发现与生命周期,Device负责设备特性与连接,Session负责实际的捕获流水线。理解这些接口的职责与调用关系,是后续进行HIDL服务启动调试和性能优化的基础。