3. HAL 启动流程分析:CameraProvider 启动、HIDL 服务注册、CameraDeviceSession 创建流程
Camera HAL 的启动流程是 Android 相机子系统初始化的核心骨架。理解从 CameraProvider 进程启动到最终 CameraDeviceSession 可用的完整链路,是定位 HAL 层启动失败、服务注册超时、Session 创建异常等问题的前提。本章将按时间顺序拆解三个关键阶段:CameraProvider 进程启动与初始化、HIDL 服务注册与发现、CameraDeviceSession 创建流程。
3.1 CameraProvider 进程启动与初始化
CameraProvider 是 Camera HAL 的守护进程,由 cameraserver 通过 hwservicemanager 触发启动。其启动流程分为以下步骤:
- init.rc 触发:系统启动时,
init进程解析android.hardware.camera.provider@<version>-service.rc,启动对应的 Provider 可执行文件。 - HIDL 框架加载:Provider 进程入口调用
defaultPassthroughServiceImplementation()或直接注册ICameraProvider服务。 - HAL 库加载:Provider 通过
dlopen()加载厂商实现的camera.provider.so,获取ICameraProvider接口实例。 - CameraModule 初始化:调用
HAL_module_t的open()方法,初始化底层硬件抽象层。 - 服务注册:将
ICameraProvider实例注册到hwservicemanager,等待cameraserver获取。
排查要点:若 Provider 进程启动后立即退出,检查
logcat -b all | grep CameraProvider 中的 dlopen 错误或 init.rc 中 seccomp 策略导致的系统调用拦截。
版本差异:Android 12+ 使用
camera.provider@2.7 及以上版本,引入了 ICameraDeviceCallback 的异步回调机制;Android 10 及以下使用 @2.4 或 @2.5,服务注册方式略有不同。
3.2 HIDL 服务注册与发现机制
CameraProvider 注册到 hwservicemanager 后,cameraserver 通过服务发现机制获取 Provider 句柄。该过程涉及以下关键组件:
| 组件 | 角色 | 关键方法/接口 |
|---|---|---|
| hwservicemanager | 系统级服务注册中心,管理所有 HIDL 服务 | get(), add(), registerForNotifications() |
| CameraProvider | HAL 服务提供者,暴露 ICameraProvider 接口 |
getCameraIdList(), setCallback() |
| cameraserver | 相机服务端,消费 Provider 服务 | waitForService(), onServiceRegistered() |
| CameraService | 上层相机服务,管理 CameraDevice 生命周期 | enumerateCameras(), connectDevice() |
服务注册与发现的标准时序如下:
- Provider 注册:调用
hwservicemanager::add("android.hardware.camera.provider@2.7::ICameraProvider/default", provider)。 - cameraserver 监听:通过
hwservicemanager::registerForNotifications()注册服务上线回调。 - 服务发现:收到通知后,调用
waitForService()获取 Provider 的 Binder 代理。 - CameraService 绑定:通过 Provider 的
getCameraIdList()获取可用 Camera ID 列表。
常见问题:若
cameraserver 长时间卡在 waitForService(),检查 hwservicemanager 是否正常运行,以及 Provider 进程是否因 SELinux 权限被 kill。使用 lshal 命令可查看当前已注册的 HIDL 服务列表。
3.3 CameraDeviceSession 创建流程
当应用调用 CameraManager.openCamera() 时,系统触发 CameraDeviceSession 的创建。该流程跨越应用进程、CameraService、CameraProvider 和 HAL 层,涉及多个接口调用和状态转换。
Session 创建的核心步骤:
| 步骤 | 调用方 | 目标接口 | 关键操作 |
|---|---|---|---|
| 1 | 应用 | CameraManager.openCamera() |
传入 Camera ID 和状态回调 |
| 2 | CameraService | ICameraProvider::getCameraIdList() |
验证 Camera ID 有效性 |
| 3 | CameraService | ICameraProvider::setCallback() |
注册设备状态回调 |
| 4 | CameraService | ICameraProvider::getCameraDeviceInterface() |
获取 ICameraDevice 接口 |
| 5 | CameraService | ICameraDevice::open() |
打开 HAL 设备,返回 ICameraDeviceSession |
| 6 | HAL | camera3_device_t::open() |
初始化硬件资源,分配 Stream 缓冲区 |
| 7 | CameraService | ICameraDeviceSession::configureStreams() |
配置输出流和输入流 |
实战排查:Session 创建失败时,重点关注
getCameraDeviceInterface() 返回的 ICameraDevice 是否为 null,以及 open() 调用是否返回 Status::INTERNAL_ERROR。在 HAL 层,camera3_device_t::open() 中的 camera3_callback_ops_t 注册失败是常见原因。
3.4 启动流程常见问题与排查思路
以下表格总结了 HAL 启动流程中三个阶段的典型问题及排查方向:
| 阶段 | 典型问题 | 排查方向 |
|---|---|---|
| Provider 启动 | Provider 进程闪退或无法启动 | 检查 init.rc 权限、seccomp 策略、dlopen 日志、SELinux avc 拒绝 |
| 服务注册 | cameraserver 无法发现 Provider | 使用 lshal 确认服务是否注册;检查 hwservicemanager 进程状态 |
| Session 创建 | openCamera 返回错误或超时 | 检查 getCameraDeviceInterface() 返回值;分析 HAL 层 open 日志 |
调试命令速查:
adb shell lshal | grep camera — 查看已注册的 Camera HIDL 服务adb shell dumpsys media.camera — 查看 CameraService 内部状态adb logcat -b all -s CameraProvider cameraserver CameraService — 过滤启动相关日志