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服务启动与调用的主干。
3.1 接口层级关系与调用链路
三个核心接口在HIDL服务中的层级关系如下图所示。Framework通过CameraService与HAL通信,首先获取ICameraProvider,再通过Provider获取ICameraDevice,最后通过Device打开ICameraDeviceSession进行数据流处理。
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的完整数据流,涉及三个核心接口的协作:
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行为 |
#ifdef或版本判断宏来适配不同Android版本的HIDL接口差异。例如,Android 12新增的signalStreamFlush()在旧版本中不存在,若直接调用会导致编译错误。推荐使用android::hardware::camera::common::V1_0::helper::CameraModule等辅助类简化版本适配。
通过以上对ICameraProvider、ICameraDevice、ICameraDeviceSession三个核心接口的解析,可以看到Camera HIDL接口设计遵循了清晰的分层原则:Provider负责发现与生命周期,Device负责设备特性与连接,Session负责实际的捕获流水线。理解这些接口的职责与调用关系,是后续进行HIDL服务启动调试和性能优化的基础。