3. Camera3Device构造函数:参数解析与内部成员变量初始化

Camera3Device 构造函数是整个 HAL 对接流程的起点。它接收来自 CameraService 的调用参数,完成设备句柄的绑定、内部状态机的初始状态设置、以及关键回调接口的注册。本节将深入解析构造函数的参数含义,并逐一说明内部成员变量的初始化逻辑。

3.1 构造函数签名与参数解析

Camera3Device 的构造函数通常定义在 Camera3Device.cpp 中,其典型签名如下:

Camera3Device::Camera3Device(
    const std::string& cameraId,
    const camera3_device_t* halDevice,
    const sp<ICameraDeviceCallbacks>& deviceCallbacks,
    const sp<ICameraService>& cameraService,
    const std::shared_ptr<CameraProviderManager>& providerManager)
    : mCameraId(cameraId),
      mHalDevice(halDevice),
      mDeviceCallbacks(deviceCallbacks),
      mCameraService(cameraService),
      mProviderManager(providerManager),
      mStatus(CAMERA_DEVICE_STATUS_CLOSED),
      mNextRequestId(1),
      mStreamList(),
      mCallbackOps{},
      mFrameNumberCounter(0),
      mUseHal3v3(false),
      mInitialized(false) {}

下表对每个参数的作用和来源进行详细说明:

参数名 类型 来源 作用说明
cameraId const std::string& CameraService 根据 HAL 上报的摄像头列表分配 唯一标识摄像头设备,如 "0"、"1";用于日志、权限校验和 HAL 设备查找
halDevice const camera3_device_t* CameraProviderManager 通过 open() 调用从 HAL 获取 指向 HAL 层 camera3_device_t 结构体,包含所有 HAL 操作函数指针
deviceCallbacks const sp<ICameraDeviceCallbacks>& CameraService 创建设备时传入 用于 Camera3Device 向 CameraService 上报事件、错误和结果通知
cameraService const sp<ICameraService>& CameraService 自身引用 用于跨进程调用 CameraService 的接口,如策略查询、资源管理等
providerManager const std::shared_ptr<CameraProviderManager>& CameraService 全局单例 管理 HAL 提供者生命周期,用于后续的流配置、模板查询等操作
关键点: halDevice 参数是构造函数中最重要的输入。它不是一个简单的指针,而是 HAL 实现必须填充完整的 camera3_device_t 结构体,其中 ops 字段指向 camera3_device_ops_t,包含 initialize、configure_streams、process_capture_request 等核心函数指针。

3.2 内部成员变量初始化清单

构造函数初始化列表完成后,还会在函数体内执行一系列关键成员变量的初始化。以下按类别列出所有重要成员变量及其初始值:

3.2.1 状态与标识类

  • mStatus:初始化为 CAMERA_DEVICE_STATUS_CLOSED,表示设备尚未打开或初始化。
  • mInitialized:布尔值,初始 false,在 initialize() 方法成功返回后置为 true。
  • mNextRequestId:自增请求 ID 生成器,初始值 1,每次下发 capture request 时递增。
  • mFrameNumberCounter:帧号计数器,初始 0,每收到一个 HAL 结果帧时递增。

3.2.2 HAL 对接类

  • mHalDevice:直接保存传入的 camera3_device_t* 指针。
  • mCallbackOps:类型为 camera3_callback_ops_t 的结构体,初始化为零。在 initialize() 中填充函数指针后传递给 HAL。
  • mUseHal3v3:布尔值,初始 false,在检测到 HAL 版本 >= 3.3 时置为 true,用于区分不同版本的 HAL 行为。

3.2.3 流与请求管理类

  • mStreamList:空列表,类型为 std::vector<camera3_stream_t*>,在 configure_streams() 中被填充。
  • mPendingRequests:空映射表,类型为 std::map<uint32_t, CaptureRequest>,用于跟踪已下发但未完成的请求。
  • mResultQueue:空队列,用于缓存从 HAL 返回的结果帧,等待 CameraService 消费。

3.2.4 同步与线程安全类

  • mLock:Mutex 类型,用于保护所有成员变量的并发访问。
  • mResultSignal:Condition 类型,用于通知结果处理线程有新结果到达。
设计意图: 构造函数只做轻量级初始化,不执行任何 HAL 调用。真正的 HAL 初始化(调用 halDevice->ops->initialize())延迟到 initialize() 方法中执行,这样可以避免在构造阶段因 HAL 异常导致对象创建失败。

3.3 初始化流程的 SVG 架构图

下图展示了 Camera3Device 构造函数执行过程中,参数传入与内部成员变量初始化的完整数据流:

Camera3Device 构造函数初始化流程 Camera3Device 构造函数初始化流程 CameraService HAL Provider CameraProviderManager cameraId halDevice providerManager Camera3Device 构造函数 初始化列表 成员变量赋值 回调结构体清零 内部成员变量 mCameraId = "0" mHalDevice = camera3_device_t* mStatus = CLOSED mCallbackOps = {0} mNextRequestId = 1 说明:构造函数仅完成参数绑定和状态初始化,不调用任何 HAL 接口函数。 真正的 HAL 初始化(initialize)在后续的 open() 流程中执行。

3.4 回调结构体初始化细节

mCallbackOps 是 Camera3Device 与 HAL 之间的通信桥梁。构造函数中将其清零,然后在 initialize() 方法中填充以下函数指针:

// 在 Camera3Device::initialize() 中
mCallbackOps = {
    .notify = [](const camera3_callback_ops_t* ops,
                 const camera3_notify_msg_t* msg) {
        auto* self = static_cast<Camera3Device*>(ops->userData);
        self->handleNotify(msg);
    },
    .process_capture_result = [](const camera3_callback_ops_t* ops,
                                  const camera3_capture_result_t* result) {
        auto* self = static_cast<Camera3Device*>(ops->userData);
        self->handleCaptureResult(result);
    },
    .userData = this  // 指向 Camera3Device 自身实例
};
常见错误: 如果构造函数中 mCallbackOps 没有清零,或者 userData 未正确设置为 this,HAL 在回调时会导致空指针访问或错误的类型转换,引发进程崩溃。务必在构造函数中执行 memset(&mCallbackOps, 0, sizeof(mCallbackOps)) 或使用零初始化语法。

3.5 初始化顺序与依赖关系

构造函数内部成员变量的初始化顺序遵循严格的依赖关系,下表列出各成员的初始化顺序及其依赖:

初始化顺序 成员变量 依赖项 说明
1 mCameraId 无 字符串拷贝,独立初始化
2 mHalDevice 无 指针赋值,不进行有效性检查
3 mDeviceCallbacks 无 sp 智能指针引用计数增加
4 mCameraService 无 sp 智能指针引用计数增加
5 mProviderManager 无 shared_ptr 引用计数增加
6 mStatus 无 枚举值直接赋值
7 mNextRequestId 无 整数直接赋值
8 mCallbackOps 无 结构体零初始化
9 mStreamList 无 默认构造空 vector
10 mFrameNumberCounter 无 整数直接赋值
设计原则: 所有成员变量的初始化都不依赖其他成员变量的值,因此初始化顺序仅由声明顺序决定。C++ 保证初始化列表按照成员变量在类中声明的顺序执行,而非初始化列表中的书写顺序。务必保持声明顺序与初始化列表顺序一致,避免潜在的未定义行为。

3.6 构造函数执行后的状态检查

构造函数执行完毕后,Camera3Device 对象处于以下状态:

  • 设备状态:CLOSED,尚未与 HAL 建立通信。
  • HAL 指针:已保存,但未调用任何 HAL 函数。
  • 回调接口:结构体已清零,尚未注册到 HAL。
  • 流列表:为空,未配置任何数据流。
  • 请求队列:为空,无待处理请求。

此时,Camera3Device 对象已经可以安全地返回给 CameraService,但还不能处理任何捕获请求。后续的 initialize() 调用将完成 HAL 回调注册和设备初始化,使对象进入 OPEN 状态。