二、CameraProvider启动流程

CameraService之服务流程图
一、CameraService启动流程
二、CameraProvider启动流程
三、CameraService总流程

在第一节中讲解完了 camera service的启动后,再讲解provier的启动流程
在这里插入图片描述

1、启动脚本

hardware/interfaces/camera/provider/2.4/default/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

2、CameraProvider守护进程启动

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

int main()
{
    ALOGI("Camera provider Service is starting \n");
    android::ProcessState::initWithDriver("/dev/vndbinder");
    /*核心工作都在这个函数 里面*/
    return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0",6);//maxThreads
}

3、分析 defaultPassthroughServiceImplementation 函数

system/libhidl/transport/include/hidl/LegacySupport.h

template<class Interface>
status_t defaultPassthroughServiceImplementation(std::string name,size_t maxThreads = 1)
{
    ...
    //这个函数做了两件事
    //1、得到了CameraProvider
    //2、注册 CameraProvider
    status_t result = registerPassthroughServiceImplementation<Interface>(name); //Interface = ICameraProvider  name = "legacy/0"
    ...
}

4、分析 registerPassthroughServiceImplementation 函数

template<class Interface>
/* 模板函数,Interface = ICameraProvider */
status_t registerPassthroughServiceImplementation(std::string name = "default")
{
    //ICameraProvider::getService()
    //getstub = true时,getservice以passthrough模式打开 HAL 实现
    //所以这个会得到 CameraProvider实例化对象,不是binder代理
    sp<Interface> service = Interface::getService(name,true); //name = legacy/0";
    //这样 service 就已经是 CameraProvider
 
    //将CameraProvider注册为一个服务
    //其他进程如果要使用Camera HAL层 时,通过Binder 得到 了 CameraProvider代理即可
 
    status_t status = service->registerAsService(name);
    return status;
}

5、如何得到 CameraProvider

out/soong/.intermediates/hardware/interfaces/camera/provider/2.4/android.hardware.camera.provider@2.4_genc++/gen/android/hardware/camera/provider/CameraProviderAll.cpp

ICameraProvider::getService(const std::string &serviceName,const bool getStub)
{
    ...
    for(int tries = 0; !getStub &&(vintfHwbinder || (vintfLegacy && tries == 0)); tries++)
    {
        //getStub = false 才走这个分支
    }
 
    if(getStub || vinfPassthru || vintfLegacy)
    {
        //getStub = true 时或者 binder 获取失败时走这个分支
        //getservice 以 passthrough 模式打开 HAL 实现
        const sp<::android::hidl::manager::V1_0::IServiceManager> pm = getPassthroughServiceManager();
        if(pm != unllptr)
        {
            //这里会根据传进来的文件描述符 找到 CameraProivider.cpp生成的so文件 android.hardware.camera.provider@2.4-impl.so
            //descriptor = "android.hardware.camera.provider@2.4::ICameraProvider"
            //然后使用这个库中的HIDL_FETCH_ICameraProvider() 函数得到CameraProvider 实例化对象
            Return<sp<::android::hidl::base::V1_0::IBase>> ret = pm->get(ICameraProvider::descriptor,serviceName);
            if(ret.isOk()) {
                sp<::android::hidl::base::V1_0::IBase> baseInterface = ret;
                if (baseInterface != nullptr) {
                    iface = ICameraProvider::castFrom(baseInterface);
                    if (!getStub || trebleTestingOverride) {
                        iface = new BsCameraProvider(iface);
                    }
                }
            }
        }
    }
         
}

6、分析pm→get函数

system/libhidl/transport/ServiceManagement.cpp

//pm->get(ICameraProvider::descriptor, serviceName);
//ICameraProvider::descriptor = "android.hardware.camera.provider@2.4::ICameraProvider"
Return <sp<IBase>> get(const hidl_string & fqName,const hidl_string & name) override
{
    sp<IBase> ret = nullptr;
    //打开库 openLibs
    //这里使用了匿名回调函数,一会回过头分析 回调函数,先看 openLibs
    openLibs(fqName,[&](void * handle,const std::string &lib,const std::string &sym)   
    {
        IBase* (*generator)(const char* name);
        //分析完openLibs() 知道这里就是得到 HIDL_FETCH_IcameraProvider() 函数
        *(void **)(&generator) = dlsym(handle,sym.c_str());
        //调用 HIDL_FETCH_IcameraProvider() 函数得到 CameraProvider 实例化对象
        //后面分析 HIDL_FETCH_IcameraProvider()函数
        ret = (*generator)(name.c_str());
        registerReference(fqName,name);
    }
    //所以返回的是CameraProvider 实例化 对象
    return ret;
}

7、分析 openLibs 函数

static void openLibs(const std::string& fqName,std::function<bool (void *,const std::string&,const std::string&)> eachLib)
{
        //fqName = "android.hardware.camera.provider@2.4::ICameraProvider"
        size_t idx - fqName.find("::");
         
        /* 得到 "android.hardware.camera.provider@2.4" 字符串 */
        std::string packageAndVersion = fqName.substr(0, idx);
 
        /* 得到 "ICameraProvider" 字符串 */
        std::string ifaceName = fqName.substr(idx + strlen("::"));
 
        /* 得到 "android.hardware.camera.provider@2.4-impl" 字符串 */
        const std::string prefix = packageAndVersion + "-impl";
 
        /* 得到 "HIDL_FETCH_ICameraProvider" 字符串 */
        const std::string sym = "HIDL_FETCH_" + ifaceName;
 
        const int dlMode = RTLD_LAZY;
        void *handle = nullptr;
 
        dlerror();
 
        /*在这 4个 目录下 搜索 "android.hardware.camera.provider@2.4-impl" */
 
        std::vector<std::string> paths = {HAL_LIBRARY_PATH_ODM,
                                      HAL_LIBRARY_PATH_VENDOR,
                                      HAL_LIBRARY_PATH_VNDK_SP,
                                      HAL_LIBRARY_PATH_SYSTEM};
 
        for (const std::string & path : paths) {
        std::vector<std::string> libs = search(path,prefix,".so");
        for(const std::string &lib : libs) {
            const std::string fullPath = path + lib;
             
            /*打开库*/
            if(path != HAL_LIBRARY_PATH_SYSTEM) {
                handle = android_load_sphal_library(fullPath.c_str(),dlMode);
            }else {
                handle = dlopen(fullPath.c_str(),dlMode);
            }
            /*调用回调函数,这个回调函数是匿名,在上面 openlibs()有说到*/
            if(!eachLib(handle,lib,sym)) {
                return;
            }
        }
    }
}

8、分析 HIDL_FETCH_ICameraProvider 函数

CameraProvider.cpp

//(*generator)(name.c_str()) --> HIDL_FETCH_ICameraProvider(const char* name)  name = "legacy/0"
ICameraProvider* HIDL_FETCH_ICameraProvider(const char *name)
{
    if(strcmp(name,kLegacyProviderName) != 0) {
        return nullptr;
    }
 
    //在这个地方 获取到了 CameraProvider,但是在构造函数中,打开了 HAL层
    //这样 CameraProvider 与 Camera HAL 联系起来了
    CameraProvider* provider = new CameraProvider();
    return provider;
}

9、CameraProvider构造函数

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

//调用父类的构造函数
CameraProvider::CameraProvider():
camera_module_callbacks_t(sCameraDeviceStatusChange,sTorchModeStatusChange) {
    mInitFailed = initialize();
}

10、CameraProvider::initialize

bool CameraProvider::initialize()
{
    camera_module_t *rawModule;
    int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,(const hw_module_t **)&rawModule)
    if (err < 0) {
        ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
        return true;
    }
 
    err = mModule->init();
    if (err != OK) {
        ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
        mModule.clear();
        return true;
    }
    ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
 
 
    /*设置回调,在cameraProvider()构造函数中 构造的回调函数
     class CameraProvider 继承于 class camera_module_callbacks_t,所以可以这样调用
     看意思是 camera 状态改变的时候 HAL层会调用 这个回调 通知 CameraProvider*/
 
     err = mModule->setCallbacks(this);
    if (err != OK) {
        ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
        mModule.clear();
        return true;
    }
 
    /*获得camera 的个数*/
    mNumberOfLegacyCameras = mModule->getNumberOfCameras();
    for (int i = 0; i < mNumberOfLegacyCameras; i++) {
        struct camera_info info;
        /* 获得每一个 camera 的信息 */
        auto rc = mModule->getCameraInfo(i, &info);
        if (rc != NO_ERROR) {
            ALOGE("%s: Camera info query failed!", __func__);
            mModule.clear();
            return true;
        }
         
        if (checkCameraVersion(i, info) != OK) {
            ALOGE("%s: Camera version check failed!", __func__);
            mModule.clear();
            return true;
        }
        char cameraId[kMaxCameraIdLen];
        snprintf(cameraId, sizeof(cameraId), "%d", i);
        std::string cameraIdStr(cameraId);
        mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
        addDeviceNames(i);
    }
    return false;
}

11、CameraProvider 服务注册 请求处理

system/libhidl/transport/HidlTransportSupport.cpp

得到 CameraProvider 实例化对象之后马上就注册了 CameraProvider 实例化对象

然后调用 joinRpcThreadpool() 函数进入循环等待请求

当然,其实在注册 CameraProvider 实例化对象的时候调用了 startThreadPool() 函数就已经有线程在等待了,startThreadPool()会调用 joinRpcThreadpool() 函数

而这里的 joinRpcThreadpool() 其实就是把主线程也放入线程池中等待请求,防止这个进程退出

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值