二、CameraProvider启动流程

二、CameraProvider启动流程,第1张

二、CameraProvider启动流程

在第一节中讲解完了 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("legacy/0",6);//maxThreads
}
3、分析 defaultPassthroughServiceImplementation 函数

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

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

status_t registerPassthroughServiceImplementation(std::string name = "default")
{
    //ICameraProvider::getService()
    //getstub = true时,getservice以passthrough模式打开 HAL 实现
    //所以这个会得到 CameraProvider实例化对象,不是binder代理
    sp 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> 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 > get(const hidl_string & fqName,const hidl_string & name) override
{
    sp 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 eachLib)
{
        //fqName = "android.hardware.camera.provider@2.4::ICameraProvider"
        size_t idx - fqName.find("::");
         
        
        std::string packageAndVersion = fqName.substr(0, idx);
 
        
        std::string ifaceName = fqName.substr(idx + strlen("::"));
 
        
        const std::string prefix = packageAndVersion + "-impl";
 
        
        const std::string sym = "HIDL_FETCH_" + ifaceName;
 
        const int dlMode = RTLD_LAZY;
        void *handle = nullptr;
 
        dlerror();
 
        
 
        std::vector 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 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);
            }
            
            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());
 
 
    
 
     err = mModule->setCallbacks(this);
    if (err != OK) {
        ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
        mModule.clear();
        return true;
    }
 
    
    mNumberOfLegacyCameras = mModule->getNumberOfCameras();
    for (int i = 0; i < mNumberOfLegacyCameras; i++) {
        struct camera_info info;
        
        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() 其实就是把主线程也放入线程池中等待请求,防止这个进程退出


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5685636.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存