Android Camera Provider启动流程 (androidP)(HIDL)

Posted we1less

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Camera Provider启动流程 (androidP)(HIDL)相关的知识,希望对你有一定的参考价值。

本篇文章是继续上一篇分析的Android Camera(一) Provider启动流程 (androidP)(HIDL)_we1less的博客-CSDN博客


总结一下:所以在这个流程中

这个路径下的  hardware/interfaces/camera/provider/2.4/default/service.cpp

CameraProviderServicereturn defaultPassthroughServiceImplementation就是以直通式向ServiceManager中注册一个服务,这个服务是由

/vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so

这个动态库的HIDL_FETCH_ICameraProvider()函数提供的new CameraProvider()

这个CameraProviderinitialize()函数中以同样的方式load进一个动态库,这个动态库的路径为

/vendor/lib/hw/camera.xxxx.so,同时保存在new CameraModule(rawModule);中这样就能利用这个指针访问so中的方法了。


sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);

路径  system/libhidl/transport/ServiceManagement.cpp

上一篇说到get函数同时上一篇文章中也总结了

        fullPath = /vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so

        lib = android.hardware.camera.provider@2.4-impl.so

        sym = HIDL_FETCH_ICameraProvider

        handle = dlopen(fullPath.c_str(), dlMode);

        关于dlopendlsym函数已经在这里介绍dlopen / dlsym函数(动态链接库)_we1less的博客-CSDN博客

        fullPath = /vendor/lib/hw/android.hardware.camera.provider@2.4-impl.so

        那么generator就变成了fullPath路径下的so文件中的HIDL_FETCH_ICameraProvider函数得到CameraProvider的实例对象并保存在ret, 所以get()函数将返回 ret

Return<sp<IBase>> get(const hidl_string& fqName,
                      const hidl_string& name) override {
    sp<IBase> ret = nullptr;
    /* [&] 此处为Lambda表达式,简单理解为函数指针即可,先执行 openLibs() */
    openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
        /* handle :dlopen() 的返回值
         * lib :android.hardware.camera.provider@2.4-impl.so
         * sym :HIDL_FETCH_ICameraProvider
         */
        IBase* (*generator)(const char* name);
        *(void **)(&generator) = dlsym(handle, sym.c_str());
        ...
        //赋值返回
        ret = (*generator)(name.c_str());
        ...
    });
    return ret;
}

HIDL_FETCH_ICameraProvider

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

        传递进来的 name 为 legacy/0,而 kLegacyProviderName 定义为 legacy/0

        创建CameraProvider对象,构造函数将会调用initialize() 函数

        关于hw_get_module如何运作的这里给出这几篇篇作为参考【HAL】hw_get_module分析:加载HAL层库,获取camx模块接口_mrhjlong-CSDN博客

Android--hw_get_module解析_Tinghua_M的博客-CSDN博客_hw_get_module

用法可以参考我这篇Android 从上到下写一个例子 本地服务(二)_we1less的博客-CSDN博客

至此,已获得CameraProvider实例对象,最终返回赋值给 registerPassthroughServiceImplementation() 函数中的 service 

ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
    if (strcmp(name, kLegacyProviderName) == 0) {
        CameraProvider* provider = new CameraProvider();
        ...
        return provider;
    } else if (strcmp(name, kExternalProviderName) == 0) {
        ExternalCameraProvider* provider = new ExternalCameraProvider();
        return provider;
    }
    ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
    return nullptr;
}


bool CameraProvider::initialize() {
    camera_module_t *rawModule;
    int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
            (const hw_module_t **)&rawModule);
    ...
    /* rawModule 将指向 HAL 中的 camera_module_t 类型结构体,
     * 此时,CameraProvider 与 camera HAL 绑定成功,可以通过
     * CameraProvider操作camera HAL
     */
    /* 创建 CameraModule 对象 */
    /* CameraModule.cpp:android/hardware/interfaces/camera/common/1.0/default */
    mModule = new CameraModule(rawModule);
    /* mModule->init()主要完成以下操作:
     * 1. 当camera HAL的 module_api_version >= CAMERA_MODULE_API_VERSION_2_4,将调用HAL->init()
     * 2. 通过 HAL getNumberOfCameras() 获取设置camera数量,并将该参数设置为 mCameraInfoMap 容器的大小
     * */
    err = mModule->init();
    ...
    err = mModule->setCallbacks(this);
    ...
    mNumberOfLegacyCameras = mModule->getNumberOfCameras();
    for (int i = 0; i < mNumberOfLegacyCameras; i++) {
        struct camera_info info;
        /* 将获取camera信息并保存,其中将有HAL version信息,应用
         * 层将会检查HAL层版本信息从而确认调用不同的API实现相机应用
         */
        auto rc = mModule->getCameraInfo(i, &info);
        ...
        char cameraId[kMaxCameraIdLen];
        snprintf(cameraId, sizeof(cameraId), "%d", i);
        std::string cameraIdStr(cameraId);
        mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;

        addDeviceNames(i);
    }

    return false; // mInitFailed
}

CameraModule中的相关函数

路径  hardware/interfaces/camera/common/1.0/default/CameraModule.cpp

        mModule->init(); 这个mModule就是camera_module_t结构体对象

        camera_module_t 定义在 hardware/libhardware/include/hardware/camera_common.h

CameraModule::CameraModule(camera_module_t *module) {
    ...
    mModule = module;
}

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;
}

//hardware/libhardware/include/hardware/camera_common.h
#define CAMERA_HARDWARE_MODULE_ID "camera"
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;

status_t status = service->registerAsService(name);

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

        最后将这个service add进去这部分的可以参考这篇Android P HIDL 之 CameraProvider_a185531353的博客-CSDN博客

::android::status_t ICameraProvider::registerAsService(const std::string &serviceName) {
    ::android::hardware::details::onRegistration("android.hardware.camera.provider@2.4", "ICameraProvider", serviceName);

    const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm
            = ::android::hardware::defaultServiceManager();
    if (sm == nullptr) {
        return ::android::INVALID_OPERATION;
    }
    ::android::hardware::Return<bool> ret = sm->add(serviceName.c_str(), this);
    return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;
}

以上是关于Android Camera Provider启动流程 (androidP)(HIDL)的主要内容,如果未能解决你的问题,请参考以下文章

CameraProvider进程-Android12

CameraProvider进程-Android12

Android:权限拒绝:以撤销权限启动 Intent android.permission.CAMERA

Android Camera CameraService启动流程 (androidP)

Android Camera CameraService启动流程 (androidP)

Android深入四大组件Content Provider的启动过程