2. HAL3接口定义:ICameraDevice.hal与ICameraDeviceSession.hal的核心接口方法

在Android Camera HAL3架构中,ICameraDevice.hal和ICameraDeviceSession.hal是连接Framework与HAL实现的核心契约。前者负责设备级别的生命周期管理与流配置,后者负责具体Capture请求的提交与结果回调。理解这两个接口的核心方法,是掌握Camera3Device初始化流程的关键前提。

关键认知:ICameraDevice相当于“相机设备管理器”,ICameraDeviceSession相当于“一次拍照会话的工作引擎”。Framework通过ICameraDevice打开设备并创建Session,之后所有拍照操作都通过ICameraDeviceSession完成。

2.1 ICameraDevice.hal 核心接口方法

ICameraDevice.hal定义了Camera HAL设备对外暴露的入口方法,主要包括设备打开、资源销毁、流配置协商以及Session创建。下表列出了其核心方法及语义:

方法名 输入参数 返回值 核心语义
open() ICameraDeviceCallback callback Status 打开相机设备,注册Framework回调接口,用于上报设备状态与错误
close() 无 Status 关闭相机设备,释放所有HAL侧资源,终止所有活跃Session
getResourceCost() 无 ResourceCost 返回设备资源消耗信息(如内存、ISP带宽),供CameraService做资源调度
getCameraInfo() 无 CameraInfo 返回设备静态信息(朝向、是否支持闪光灯、传感器方向等)
isSessionConfigurationSupported() StreamConfiguration config bool 查询给定的流配置组合是否被HAL支持,用于Framework预检
createDefaultRequest() RequestTemplate type CaptureRequest 根据模板类型(PREVIEW/STILL_CAPTURE等)生成默认CaptureRequest
createSession() StreamConfiguration config, ICameraDeviceSessionCallback cb Status + ICameraDeviceSession 创建新的Camera Session,返回Session接口实例,是初始化流程的终点
实现要点:createSession()是ICameraDevice中最复杂的方法。HAL实现需要在此方法中完成Stream的分配、ISP管线的预配置、BufferQueue的绑定,并返回一个可用的ICameraDeviceSession实例。Framework会在此方法返回后立即开始下发Capture请求。

下面通过SVG图展示ICameraDevice.hal接口在Camera3Device初始化流程中的调用关系:

ICameraDevice.hal 接口调用关系图 CameraService ICameraDevice HAL CameraProvider open(callback) HAL实现 ICameraDevice 核心方法 open() / close() getResourceCost() getCameraInfo() isSessionConfigSupported() createDefaultRequest() createSession() 初始化流程关键路径 open() → getCameraInfo() → isSessionConfigSupported() → createSession() createSession()返回ICameraDeviceSession后,初始化阶段结束,进入Capture阶段

2.2 ICameraDeviceSession.hal 核心接口方法

ICameraDeviceSession.hal是实际执行拍照任务的接口。一旦Session创建成功,Framework便通过此接口下发Capture请求、回收Buffer、处理结果。其核心方法如下:

方法名 输入参数 返回值 核心语义
processCaptureRequest() CaptureRequest[] requests, BufferCache[] caches Status 提交一组Capture请求,HAL按序处理并返回结果
flush() 无 Status 清空所有待处理请求,立即结束当前所有正在执行的Capture
close() 无 Status 关闭Session,释放所有流资源和内部管线
configureStreams() StreamConfiguration config Status (部分HAL版本)动态重新配置流,用于Session内切换分辨率或格式
signalStreamFlush() Stream[] streams, int flushType Status 通知HAL指定流即将被停止,HAL需完成当前帧后不再输出
switchToOffline() Stream[] streamsToKeep Status + IOfflineSession 将指定流切换到离线模式,释放Camera管线资源但仍可输出已捕获帧
常见实现陷阱:processCaptureRequest()必须支持批量提交(数组形式),HAL实现需要维护一个请求队列。如果HAL在processCaptureRequest()中同步阻塞,会导致Framework ANR。正确的做法是:立即返回Status::OK,通过ICameraDeviceSessionCallback异步上报结果。

下面通过SVG图展示ICameraDeviceSession.hal接口在Capture阶段的工作流程:

ICameraDeviceSession.hal Capture请求处理流程 CameraFramework ICameraDeviceSession HAL Pipeline processCaptureRequest() HAL处理 异步回调:notify() / processCaptureResult() ICameraDeviceSession 核心方法 processCaptureRequest() flush() close() configureStreams() signalStreamFlush() switchToOffline()

2.3 两个接口的职责边界与协作关系

ICameraDevice与ICameraDeviceSession的职责边界非常清晰,理解这一点有助于正确实现HAL:

  • 生命周期归属:ICameraDevice管理设备级别的生命周期(open/close),ICameraDeviceSession管理会话级别的生命周期(process/flush/close)。一个ICameraDevice可以依次创建多个Session,但同一时间只能有一个活跃Session。
  • 流配置归属:流配置(StreamConfiguration)的协商在ICameraDevice侧完成(isSessionConfigurationSupported),但流的实际创建和绑定在ICameraDeviceSession的createSession(或configureStreams)中执行。
  • 数据路径归属:所有Capture请求、结果回调、Buffer操作全部通过ICameraDeviceSession完成。ICameraDevice不参与任何帧处理。
  • 错误上报归属:设备级别的致命错误(如硬件断开)通过ICameraDeviceCallback上报;会话级别的错误(如某个Stream超时)通过ICameraDeviceSessionCallback上报。
设计原则:HAL实现中,ICameraDevice应当是一个轻量级的工厂类,只负责设备打开、信息查询和Session创建。所有重量级的资源分配、ISP配置、Buffer管理都应当封装在ICameraDeviceSession的实现类中。这样当Session关闭时,可以彻底释放资源而不影响设备对象。

2.4 接口方法在HAL实现中的典型代码骨架

以下是一个简化的HAL实现骨架,展示ICameraDevice和ICameraDeviceSession核心方法的实现模式:

// ICameraDevice HAL 实现片段
Return<Status> CameraDeviceImpl::open(
    const sp<ICameraDeviceCallback>& callback) {
    // 1. 保存Framework回调
    mCallback = callback;
    // 2. 初始化硬件资源(电源、时钟、I2C)
    // 3. 启动传感器预览流(可选)
    mSensor = new CameraSensor();
    mSensor->powerOn();
    return Status::OK;
}

Return<Status, sp<ICameraDeviceSession>> 
CameraDeviceImpl::createSession(
    const StreamConfiguration& config,
    const sp<ICameraDeviceSessionCallback>& cb) {
    // 1. 验证流配置合法性
    for (auto& stream : config.streams) {
        if (!isStreamFormatSupported(stream.format)) {
            return {Status::BAD_VALUE, nullptr};
        }
    }
    // 2. 创建Session实现
    sp<CameraSessionImpl> session = new CameraSessionImpl(mSensor, config, cb);
    // 3. 初始化ISP管线、分配Buffer
    session->initializePipeline();
    // 4. 返回Session接口
    return {Status::OK, session};
}

// ICameraDeviceSession HAL 实现片段
Return<Status> CameraSessionImpl::processCaptureRequest(
    const hidl_vec<CaptureRequest>& requests,
    const hidl_vec<BufferCache>& caches) {
    for (auto& req : requests) {
        // 1. 将请求加入内部队列
        mRequestQueue.push_back(req);
        // 2. 触发硬件处理(非阻塞)
        mSensor->triggerCapture(req);
        // 3. 通过回调异步上报结果
        //    mCallback->processCaptureResult(result);
    }
    return Status::OK;
}

Return<Status> CameraSessionImpl::flush() {
    // 1. 清空请求队列
    mRequestQueue.clear();
    // 2. 终止当前正在执行的Capture
    mSensor->abortCapture();
    // 3. 通知Framework所有未完成的请求已丢弃
    return Status::OK;
}
代码风格建议:HAL实现中,所有可能阻塞的操作(如硬件寄存器读写、Buffer分配)都应当放在工作线程中执行,避免在Binder调用线程中直接阻塞。processCaptureRequest()的返回值仅表示请求是否被成功接收,不代表Capture已经完成。

2.5 接口版本演进与兼容性说明

Android Camera HAL3接口经历了多次小版本迭代,不同Android版本对接口方法的要求有所不同:

Android版本 HAL版本 新增/变更方法 兼容性说明
Android 8.0 HAL3.2 基础接口稳定 所有方法必须实现
Android 9.0 HAL3.3 新增signalStreamFlush() 可选实现,Framework会检查HAL是否支持
Android 10.0 HAL3.4 新增switchToOffline() 可选实现,用于多摄像头并发场景
Android 11+ HAL3.5+ 优化Buffer管理接口 向后兼容,新增方法通过capability标志位查询
兼容性风险:如果HAL实现未实现某个可选方法(如switchToOffline()),Framework会在调用前通过ICameraDevice::isSessionConfigurationSupported()或设备能力查询来避免调用。但如果HAL声明支持了某个能力却未正确实现对应方法,会导致运行时崩溃或死锁。