Android Camera原理之camera provider启动

《Android Camera架构》
《Android Camera进程间通信类总结》
《Android Camera模块解析之拍照》
《Android Camera模块解析之视频录制》
《Android Camera原理之CameraDeviceCallbacks回调模块》
《Android Camera原理之openCamera模块(一)》
《Android Camera原理之openCamera模块(二)》
《Android Camera原理之createCaptureSession模块》
《Android Camera原理之setRepeatingRequest与capture模块》
《Android Camera原理之编译》
《Android Camera原理之camera provider启动》
《Android Camera原理之cameraserver与cameraprovider是怎样联系的》
《Android Camera原理之camera service与camera provider session会话与capture request轮转》
《Android Camera原理之camera HAL底层数据结构与类总结》
《Android Camera原理之camera service类与接口关系》

1.camera provider进程介绍:


cameraserver 736 1 274664 69564 binder_thread_read f3de10cc S android.hardware.camera.provider@2.4-service

其中的pid是736,说明camera provider进程启动的时机比较早,而且权限组是 cameraserver

手机上运行的android.hardware.camera.provider@2.4-service进程是支持camera运行的重要进程。

camera架构.jpg

上面这张图比较清楚的表现了camera provider进程在camera架构中位置,作为承上启下的部分,和cameraserver进程和底层的驱动交互,camera provider进程非常重要,camera HAL层几乎全部运行在camera provider进程中完成。

android.hardware.camera.provider@2.4-service在手机启动的时候就会启动起来,下面整体分析一下android.hardware.camera.provider@2.4-service进程的启动过程。

2.camera provider进程启动流程:

首先看下camera provider所在源码中的位置:hardware/interfaces/camera/provider/

cameraprovider代码目录.jpg

可以看出来在hardware/interfaces/camera/provider/2.4/default/ 下面有几个rc文件,Android初始化就是执行这些rc文件,这里执行的是android.hardware.camera.provider@2.4-service.rc文件,看看其中的执行代码。

service vendor.camera-provider-2-4 /vendor/bin/hw/android.hardware.camera.provider@2.4-service
    class hal
    user cameraserver
    group audio camera input drmrpc
    ioprio rt 4
    capabilities SYS_NICE
    writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks

第一行就看到了启动一个 /vendor/bin/hw/android.hardware.camera.provider@2.4-service 进程。

下面列出camera provider进程的启动流程,大家可以先看一下。


camera provider进程启动流程.jpg

service.cpp : hardware/interfaces/camera/provider/2.4/default/service.cpp

CameraProvider : hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp

hardware.c : hardware/libhardware/hardware.c

CameraModule : hardware/interfaces/camera/common/1.0/default/CameraModule.cpp

QCamera2Factory : hardware/qcom/camera/QCamera2Factory.cpp

QCameraFlash : hardware/qcom/camera/QCamera2/util/QCameraFlash.cpp

QCamera3HardwareInterface : hardware/qcom/camera/QCamera2/HAL3/QCamera3HWI.cpp

这儿值得讲一讲的就是native中的函数指针的问题,从camera interfaces中将函数指针映射到camera hal层中。
主要从CameraModule中调用到QCamera2Factory中。期间使用了camera_module_t这个结构体。可以看下 CameraModule::init函数。

int CameraModule::init() {
    ATRACE_CALL();
    int res = OK;
    if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 &&
            mModule->init != NULL) {
        ATRACE_BEGIN("camera_module->init");
        res = mModule->init();
        ATRACE_END();
    }
    mCameraInfoMap.setCapacity(getNumberOfCameras());
    return res;
}

这儿调用的mModule->init(); 这个mModule就是camera_module_t结构体对象,这时候翻看一下《Android Camera原理之camera HAL底层数据结构与类总结》

typedef struct camera_module {
    hw_module_t common;
    int (*get_number_of_cameras)(void);
    int (*get_camera_info)(int camera_id, struct camera_info *info);
    int (*set_callbacks)(const camera_module_callbacks_t *callbacks);
    void (*get_vendor_tag_ops)(vendor_tag_ops_t* ops);
    int (*open_legacy)(const struct hw_module_t* module, const char* id,
            uint32_t halVersion, struct hw_device_t** device);
    int (*set_torch_mode)(const char* camera_id, bool enabled);
    int (*init)();
    void* reserved[5];
} camera_module_t;

结构体中有一些函数指针,我们现在需要搞清楚这些函数指针被映射到什么地方了?
hardware中interface中提供了原生的映射方法,在hardware/libhardware/modules/camera/3_0/CameraHAL.cpp中。

camera_module_t HAL_MODULE_INFO_SYM __attribute__ ((visibility("default"))) = {
    .common = {
        .tag                = HARDWARE_MODULE_TAG,
        .module_api_version = CAMERA_MODULE_API_VERSION_2_2,
        .hal_api_version    = HARDWARE_HAL_API_VERSION,
        .id                 = CAMERA_HARDWARE_MODULE_ID,
        .name               = "Default Camera HAL",
        .author             = "The Android Open Source Project",
        .methods            = &gCameraModuleMethods,
        .dso                = NULL,
        .reserved           = {0},
    },
    .get_number_of_cameras = get_number_of_cameras,
    .get_camera_info       = get_camera_info,
    .set_callbacks         = set_callbacks,
    .get_vendor_tag_ops    = get_vendor_tag_ops,
    .open_legacy           = NULL,
    .set_torch_mode        = NULL,
    .init                  = NULL,
    .reserved              = {0},
};

这是通用的映射,我们手机的芯片会重新这个HAL层接口,例如使用高通芯片的话,会在hardware/qcom/camera/QCamera2/QCamera2Hal.cpp中重写这个函数映射。
实际上可能不是这个路径,根据你本地实际的hal层重新方法来查找这些函数映射。

static hw_module_t camera_common = {
    .tag                    = HARDWARE_MODULE_TAG,
    .module_api_version     = CAMERA_MODULE_API_VERSION_2_4,
    .hal_api_version        = HARDWARE_HAL_API_VERSION,
    .id                     = CAMERA_HARDWARE_MODULE_ID,
    .name                   = "QCamera Module",
    .author                 = "Qualcomm Innovation Center Inc",
    .methods                = &qcamera::QCamera2Factory::mModuleMethods,
    .dso                    = NULL,
    .reserved               = {0}
};

camera_module_t HAL_MODULE_INFO_SYM = {
    .common                 = camera_common,
    .get_number_of_cameras  = qcamera::QCamera2Factory::get_number_of_cameras,
    .get_camera_info        = qcamera::QCamera2Factory::get_camera_info,
    .set_callbacks          = qcamera::QCamera2Factory::set_callbacks,
    .get_vendor_tag_ops     = qcamera::QCamera3VendorTags::get_vendor_tag_ops,
    .open_legacy            = NULL,
    .set_torch_mode         = qcamera::QCamera2Factory::set_torch_mode,
    .init                   = NULL,
    .reserved               = {0}
};

明确这些函数映射之后,接下来可以直接调用到hal层了。再底层就是芯片中复写的核心方法了,暂时不作深入介绍了。

推荐阅读更多精彩内容