4. Camera AIDL 接口设计原则:接口粒度、回调设计、版本管理策略

在 Camera HAL 从 HIDL 向 AIDL 迁移的过程中,接口设计是决定架构可扩展性、跨进程性能以及长期维护成本的核心环节。本章围绕 接口粒度、回调设计 与 版本管理策略 三大原则展开,为后续具体接口定义提供设计依据。

核心观点:AIDL 接口设计应遵循“高内聚、低耦合、单向回调、语义化版本”四大准则,避免过度抽象或过于碎片化的接口定义。

4.1 接口粒度设计原则

接口粒度直接影响跨进程调用的次数与数据吞吐量。粒度过细会导致频繁 Binder 交互,增加延迟;粒度过粗则降低复用性,难以适配多厂商扩展需求。

4.1.1 粒度分级策略

粒度级别 典型场景 Binder 调用次数 推荐度
粗粒度(Batch) 批量配置参数、批量获取结果 1 次 / 批 高(核心路径)
中粒度(Group) 按功能模块分组(如 3A、ISP) 1 次 / 组 中(模块边界)
细粒度(Single) 单个属性 get/set N 次 / 属性 低(仅调试用)
设计建议:核心数据流(如 Request/Result)采用粗粒度批量接口;厂商扩展功能使用中粒度分组接口;仅调试与诊断场景保留细粒度单属性接口。

4.1.2 接口聚合模式

推荐使用 Bundle 模式 将多个相关参数打包为单一 AIDL 结构体,减少跨进程序列化开销。例如将 CaptureRequest 中的所有控制参数聚合为一个 RequestSettings 对象:

// 推荐:聚合接口
interface ICameraDevice {
    void submitRequest(in RequestSettings settings, in OutputConfiguration output);
}

// 不推荐:分散接口
interface ICameraDevice {
    void setExposureTime(long ns);
    void setSensitivity(int iso);
    void setOutputSurface(in Surface surface);
    void submit();
}
注意:聚合粒度不宜过大,避免单个结构体包含超过 50 个字段,否则将增加序列化/反序列化耗时,并降低缓存友好性。

4.2 回调设计原则

回调是 Camera HAL 向 Framework 异步通知事件(如帧完成、错误、3A 收敛)的核心机制。AIDL 回调设计需遵循 单向(oneway)、轻量、可取消 三大原则。

4.2.1 单向回调(Oneway)

所有回调接口必须声明为 oneway,避免回调线程阻塞 HAL 的异步处理流程:

// 正确:oneway 回调
interface ICameraDeviceCallback {
    oneway void onCaptureCompleted(in CaptureResult result);
    oneway void onError(in ErrorCode code, in String message);
}

// 错误:同步回调可能导致死锁
interface ICameraDeviceCallback {
    void onCaptureCompleted(in CaptureResult result);  // 可能阻塞 HAL
}

4.2.2 回调注册与生命周期管理

回调必须支持动态注册与注销,防止内存泄漏或野指针。设计模式如下:

  • 注册:Framework 通过 setCallback() 传入回调对象
  • 注销:Framework 通过 clearCallback() 或传递 null 解除绑定
  • 死亡通知:HAL 端监听 Binder 死亡通知,自动清理回调引用
interface ICameraDevice {
    void setCallback(in ICameraDeviceCallback callback);
    void clearCallback();
}

4.2.3 回调频率控制

高频回调(如预览帧回调)必须支持 节流(Throttling) 或 批量上报,避免 Binder 通道拥塞:

回调类型 频率上限 推荐策略
预览帧回调 30 fps 批量上报(每帧携带多个结果)
3A 状态回调 10 Hz 变化触发(仅状态变化时上报)
错误回调 不限 立即上报(高优先级)
最佳实践:在回调接口中增加 sequenceId 字段,帮助 Framework 端识别回调顺序与丢帧情况。

4.3 版本管理策略

AIDL 接口的版本管理直接决定 HAL 与 Framework 的兼容性。Camera HAL 采用 语义化版本 + 接口冻结 策略,确保向前兼容。

4.3.1 版本号定义规范

版本段 含义 变更示例 兼容性
MAJOR 不兼容的 API 变更 删除接口、修改方法签名 不兼容
MINOR 向下兼容的功能新增 新增接口、新增枚举值 向前兼容
PATCH 向下兼容的缺陷修复 修复序列化 bug、优化性能 完全兼容

4.3.2 接口冻结与扩展机制

已发布的 MAJOR 版本接口必须 冻结,不允许修改已有方法签名。扩展功能通过以下方式实现:

  • 新增接口:在 ICameraDevice 中追加 @VendorExtension 注解的方法
  • 新增枚举值:Framework 端使用 default 分支处理未知枚举
  • 新增回调:通过 ICameraDeviceCallbackV2 继承扩展,不修改原始回调接口
// 版本扩展示例:V2 回调继承 V1
interface ICameraDeviceCallbackV2 extends ICameraDeviceCallback {
    oneway void onCaptureProgressed(in CaptureResult result);  // V2 新增
}

4.3.3 版本协商流程

Framework 与 HAL 在初始化阶段通过 getInterfaceVersion() 进行版本协商:

  1. Framework 调用 getInterfaceVersion() 获取 HAL 支持的版本
  2. Framework 根据自身支持的版本范围,选择最高兼容版本
  3. 若版本不匹配,Framework 降级使用基础功能或报错
版本兼容矩阵:Framework 1.x 兼容 HAL 1.x 和 2.x(降级使用 1.x 功能);Framework 2.x 仅兼容 HAL 2.x 及以上。

4.4 接口设计全景图

以下 SVG 图展示了 Camera AIDL 接口设计中粒度、回调与版本管理的整体关系:

Camera AIDL 接口设计原则全景图 Camera AIDL 接口设计原则全景图 接口粒度 粗粒度(Batch) 中粒度(Group) 细粒度(Single) 聚合模式:Bundle 减少 Binder 调用 提升吞吐量 回调设计 单向(Oneway) 注册/注销管理 频率控制(节流) 死亡通知监听 批量上报优化 避免死锁 版本管理 语义化版本(MAJOR.MINOR.PATCH) 接口冻结机制 版本协商流程 向前兼容 V2 回调继承 降级策略 影响 约束 设计核心原则 高内聚 · 低耦合 · 单向回调 · 语义化版本 · 向前兼容 接口定义 实现与测试 版本发布 设计阶段遵循三大原则 → 实现阶段验证接口合理性 → 发布阶段冻结版本 版本反馈与迭代优化

4.5 设计原则总结

原则 关键决策点 常见反模式 推荐做法
接口粒度 核心路径 vs 扩展路径 每个属性一个接口方法 Bundle 聚合 + 分组接口
回调设计 同步 vs 异步、频率控制 同步回调导致 HAL 阻塞 Oneway + 批量上报
版本管理 兼容性策略、扩展方式 修改已发布接口签名 语义化版本 + 接口冻结
架构决策记录:Camera AIDL 接口设计将采用“粗粒度核心接口 + 中粒度扩展接口 + 细粒度调试接口”三级粒度体系,回调全部使用 oneway 模式,版本管理遵循 MAJOR.MINOR.PATCH 语义化规范,确保 HAL 与 Framework 的长期兼容性。