3. Camera HIDL 服务启动流程:CameraProvider启动、HAL服务注册、Treble架构下的服务发现

在Treble架构下,Camera HAL从传统的hw_module_t直连模式演变为独立进程 + HIDL服务化。CameraProvider作为HAL服务的实际载体,其启动、注册与发现机制直接决定了上层Framework能否正确访问底层硬件。本章深入剖析这一流程的三大核心环节:CameraProvider进程启动、HIDL服务注册到hwservicemanager、以及Treble服务发现机制。

3.1 CameraProvider启动流程

CameraProvider是一个独立的Native进程,通常由init.rc触发启动。其启动链路如下:

  1. init进程解析rc文件:系统启动时,init进程读取/vendor/etc/init/android.hardware.camera.provider@X.Y-service.rc,启动对应的Provider服务进程。
  2. main函数入口:Provider进程的main函数实例化CameraProvider对象,并调用registerAsService()。
  3. HIDL服务注册:通过ICameraProvider::registerAsService()将服务实例注册到hwservicemanager。
  4. 服务循环等待:进程进入joinRpcThreadpool(),等待Framework的IPC调用。
关键点:CameraProvider进程的启动时机由class属性控制,通常属于camera或hal类,确保在vendor分区挂载后、Framework启动前完成注册。
性能提示:Provider进程的启动延迟直接影响相机首次打开时间(Cold Launch Latency)。建议在rc文件中使用oneshot + disabled组合,由Framework按需触发启动,避免不必要的资源占用。
CameraProvider启动流程 init.rc 解析 main() 入口 实例化Provider registerAsService() joinRpcThreadpool() rc文件示例 service camera-provider /vendor/bin/hw/ android.hardware.camera .provider@2.4-service

3.2 HIDL服务注册机制

HIDL服务注册的核心是hwservicemanager——一个系统级的服务注册中心,类似于Android Framework层的servicemanager。CameraProvider通过以下步骤完成注册:

步骤 操作 关键函数/接口 说明
1 获取Transport实例 ICameraProvider::getService() 确定使用直通(passthrough)或绑定(binderized)模式
2 构造服务名称 android.hardware.camera.provider@2.4::ICameraProvider/default 格式:package@version::interface/instance
3 调用registerAsService registerAsService("default") 将服务实例注册到hwservicemanager
4 hwservicemanager维护服务表 内部哈希表 服务名 → IBinder映射,支持按instance查询
避坑指南:多个CameraProvider实例(如后摄/前摄分离)必须使用不同的instance名称注册,否则后注册的会覆盖前者,导致部分摄像头无法被发现。推荐命名规范:backward、forward、external。
HIDL服务注册架构 CameraProvider进程 ICameraProvider impl registerAsService() hwservicemanager 服务注册表 服务名 → IBinder Binder IPC 注册成功后,Framework通过hwservicemanager查询服务名获取ICameraProvider代理 服务名格式:android.hardware.camera.provider@2.4::ICameraProvider/<instance>

3.3 Treble架构下的服务发现

Treble架构将Camera HAL服务发现分为直通模式和绑定模式两种路径。Framework通过ICameraProvider::getService()发起查询,hwservicemanager根据服务注册状态返回结果。

3.3.1 服务发现流程

  1. Framework调用getService():CameraService启动时,调用ICameraProvider::getService("default")。
  2. hwservicemanager查询:检查服务注册表中是否存在匹配的服务名。
  3. 返回代理对象:若存在,返回ICameraProvider的Binder代理;若不存在,返回null或阻塞等待。
  4. 多实例发现:通过listServices()枚举所有已注册的CameraProvider实例。
性能优化点:服务发现阶段的超时机制至关重要。默认超时时间为5秒,若Provider进程启动延迟或死锁,会导致CameraService启动阻塞。建议在HAL层实现getService()的异步回调模式,避免主线程阻塞。

3.3.2 直通模式 vs 绑定模式

对比维度 直通模式 (Passthrough) 绑定模式 (Binderized)
进程模型 HAL运行在Framework进程内 HAL运行在独立进程
IPC开销 无IPC,函数直接调用 每次调用经过Binder IPC
隔离性 差,HAL崩溃导致Framework挂掉 好,HAL进程独立崩溃不影响Framework
启动方式 dlopen动态加载 独立进程 + hwservicemanager注册
性能 高,无IPC延迟 中等,增加Binder传输延迟
推荐场景 低端设备、性能敏感场景 中高端设备、稳定性优先
选型建议:Android 10+ 强制要求使用绑定模式。若需兼容低版本,可在manifest.xml中通过transport属性控制:transport="hwbinder"(绑定)或transport="passthrough"(直通)。
Treble服务发现架构 Framework层 CameraService getService("default") hwservicemanager 服务注册表 查询/返回IBinder HAL层 CameraProvider registerAsService() ①查询 ②返回 服务发现时序 1. CameraService启动 → 调用 ICameraProvider::getService("default") 2. hwservicemanager 查询服务注册表 → 找到 CameraProvider 实例 3. 返回 ICameraProvider 的 Binder 代理对象给 CameraService 4. CameraService 通过代理调用 open()、getCameraCharacteristics() 等接口 5. 若服务未注册,getService() 阻塞等待(默认超时5秒)或返回 null 优化建议: • 使用 tryGetService() 非阻塞查询,避免主线程卡死 • 实现服务注册监听回调,替代轮询查询

3.4 服务发现性能压测要点

在性能压测中,服务发现阶段是Camera冷启动的关键瓶颈。以下是需要重点关注的指标:

  • 服务注册延迟:从Provider进程启动到registerAsService()返回的时间,应控制在50ms以内。
  • 服务查询延迟:Framework调用getService()到获取代理的时间,应控制在10ms以内。
  • 多实例枚举耗时:listServices()返回所有Provider实例的时间,应控制在5ms以内。
  • 超时重试次数:服务未就绪时的重试策略,建议指数退避,最大重试3次。
常见问题:在低内存设备上,CameraProvider进程可能被LMK(Low Memory Killer)杀死,导致服务注册丢失。此时Framework的getService()会返回null,CameraService需要实现自动重连机制,重新触发Provider进程启动。

通过深入理解CameraProvider启动、HIDL服务注册与Treble服务发现机制,开发者可以精准定位冷启动延迟、服务不可用等问题的根因,为后续的性能压测与优化奠定基础。