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

Posted we1less

tags:

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

本章开始分析camera框架 主要是自己用来加深理解的 内含HIDL的调用流程

camera provider 启动


android.hardware.camera.provider@2.4-service.rc

路径  hardware/interfaces/camera/provider/2.4/default/android.hardware.camera.provider@2.4-service.rc

跟普通服务类似就是以一个rc文件启动的,在之前的文章中我们分析过rc文件是如何启动服务的

android8.1系统启动过程(四) 解析init.rc_we1less的博客-CSDN博客

service 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

在android启动的过程中,init进程调用该脚本启动 camera provider 服务。根据该目录下的 Android.bp 可以知道,其实就是运行该目录下 service.cpp 编译的可执行文件 


main

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

        驱动可通过vndbinder与其他HAL模块通信,默认创建直通式的camera provider 服务,在Treble架构下,存在了3个binder设备,分别是/dev/binder、/dev/vndbinder、/dev/hwbinder,上层需要通过binder库来访问这些binder设备,而/dev/binder和/dev/vndbinder都是由libbinder来访问,因此需要指定打开的binder设备。

int main()
{
    ALOGI("Camera provider Service is starting.");
    // The camera HAL may communicate to other vendor components via
    // /dev/vndbinder
    android::ProcessState::initWithDriver("/dev/vndbinder");
    return defaultPassthroughServiceImplementation<ICameraProvider>("legacy/0", /*maxThreads*/ 6);
}

defaultPassthroughServiceImplementation

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

        配置binder线程个数,然后调用registerPassthroughServiceImplementation

template<class Interface>
__attribute__((warn_unused_result))
status_t defaultPassthroughServiceImplementation(std::string name,
                                            size_t maxThreads = 1) {
    configureRpcThreadpool(maxThreads, true); //配置binder线程个数
    status_t result = registerPassthroughServiceImplementation<Interface>(name);
    ...
    joinRpcThreadpool();
    return 0;
}

registerPassthroughServiceImplementation

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

        调用 HIDL 生成的接口 ICameraProvider::getService,得到BpHwCameraProvider,name = "legacy/0" , getStub = true, 为直通模式

        注册 cameraprovider, name = "legacy/0" // 后面其他服务通过HwServiceManager get service是就是是此名称

template<class Interface>
__attribute__((warn_unused_result))
status_t registerPassthroughServiceImplementation(
        std::string name = "default") {
    sp<Interface> service = Interface::getService(name, true /* getStub */);
    //调用ICameraProvider接口类的getService
    ...
    //注册 cameraprovider, name = "legacy/0"
	// 后面其他服务通过HwServiceManager get service是就是是此名称
    status_t status = service->registerAsService(name);
    ...
    return status;
}

ICameraProvider::getService

路径  

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

        这地方就是调用链了              

#include <hidl/HidlTransportSupport.h>
...
const char* ICameraProvider::descriptor("android.hardware.camera.provider@2.4::ICameraProvider");
...
// static
::android::sp<ICameraProvider> ICameraProvider::getService(const std::string &serviceName, const bool getStub) {
    return ::android::hardware::details::getServiceInternal<BpHwCameraProvider>(serviceName, true, getStub);
}

getServiceInternal

路径  system/libhidl/transport/include/hidl/HidlTransportSupport.h

        因为BpType = BpHwCameraProvider,所以IType = typename BpType::Pure

        因为在out/soong/.intermediates/hardware/interfaces/camera/provider/2.4/android.hardware.camera.provider@2.4_genc++_headers/gen/android/hardware/camera/provider/2.4/BpHwCameraProvider.h

这个文件中有定义    typedef ICameraProvider Pure;

        所以 IType::descriptor == ICameraProvider::descriptor  参见CameraProviderAll的代码可知:

        IType::descriptor = android.hardware.camera.provider@2.4::ICameraProvider

        instance = "legacy/0"

template <typename BpType, typename IType = typename BpType::Pure,
          typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>,
          typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>>
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
    using ::android::hidl::base::V1_0::IBase;

    sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
    ...
    if (base->isRemote()) {
        // getRawServiceInternal guarantees we get the proper class
        return sp<IType>(new BpType(toBinder<IBase>(base)));
    }

    return IType::castFrom(base);
}

getRawServiceInternal

路径  system/libhidl/transport/ServiceManagement.cpp

        获取 hwservicemanager 服务, 用于获取Service的client端即BpXXX代理类

        descriptor = android.hardware.camera.provider@2.4::ICameraProvider

        getStub = false 时,一般用于其他服务获取cameraprovider服务

        getStub = true 用于服务启动过程 我们从服务启动的角度继续分析

sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
                                                             const std::string& instance,
                                                             bool retry, bool getStub) {
    using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;
    using ::android::hidl::base::V1_0::IBase;
    using ::android::hidl::manager::V1_0::IServiceManager;
    sp<Waiter> waiter;
    // 获取 hwservicemanager 服务, 用于获取Service的client端即BpXXX代理类
    const sp<IServiceManager1_1> sm = defaultServiceManager1_1();
    ...
    // getStub = false 时,走此流程,拿到 cameraprovider 
	// 一般用于其他服务获取cameraprovider服务
	// 比如cameraservice 获取 cameraprovider时,拿到<sp<IBase>>,之后会New BpHwCameraProvider
	// 通过 BpHwCameraProvider类调用HIDL通信
    for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
        ...
        Return<sp<IBase>> ret = sm->get(descriptor, instance);
        ...
    }
    ...
    //getStub = true 是走此流程,用于服务启动过程
    if (getStub || vintfPassthru || vintfLegacy) {
        const sp<IServiceManager> pm = getPassthroughServiceManager();
        if (pm != nullptr) {
            // 返回CameraProvider实例,CameraProvider是ICameraProvider的子类
        	// ICameraProvider是IBase的子类
            sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
            ...
            return base;
        }
    }

    return nullptr;
}

getPassthroughServiceManager

路径  system/libhidl/transport/ServiceManagement.cpp

        PassthroughServiceManager 是 IServiceManager1_1 的子类,重写了get等方法后面就是调用此get方法,而get方法中则调用了openLibs方法其中传递进去一个匿名函数

        在openLibs方法中

        fqName = descriptor = android.hardware.camera.provider@2.4::ICameraProvider

        packageAndVersion = android.hardware.camera.provider@2.4

sp<IServiceManager1_0> getPassthroughServiceManager() {
    return getPassthroughServiceManager1_1();
}

sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
    // PassthroughServiceManager 是 IServiceManager1_1 的子类,重写了get等方法
	// 后面就是调用此get方法
    static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
    return manager;
}

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

Return<sp<IBase>> get(const hidl_string& fqName,
                      const hidl_string& name) override {
    sp<IBase> ret = nullptr;

    openLibs(fqName, /*接下来的参数这样的写法是一个匿名的函数*/[&](void* handle, const std::string &lib, const std::string &sym) {
        IBase* (*generator)(const char* name);
        *(void **)(&generator) = dlsym(handle, sym.c_str());
        ...
        ret = (*generator)(name.c_str());
        ...
    });

    return ret;
}


static void openLibs(
    const std::string& fqName,
    const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
                                             const std::string& /* sym */)>& eachLib) {
    //fqName looks like android.hardware.foo@1.0::IFoo
    //获取 :: 位置
    size_t idx = fqName.find("::");
    ...
    // packageAndVersion = android.hardware.camera.provider@2.4
    std::string packageAndVersion = fqName.substr(0, idx);
    //ifaceName = ICameraProvider
    std::string ifaceName = fqName.substr(idx + strlen("::"));
    //得到库名 prefix = android.hardware.camera.provider@2.4-impl
    const std::string prefix = packageAndVersion + "-impl";
    //函数名 sym = HIDL_FETCH_ICameraProvider
    const std::string sym = "HIDL_FETCH_" + ifaceName;

    constexpr int dlMode = RTLD_LAZY;
    void* handle = nullptr;

    dlerror(); // clear

    static std::string halLibPathVndkSp = android::base::StringPrintf(
        HAL_LIBRARY_PATH_VNDK_SP_FOR_VERSION, details::getVndkVersionStr().c_str());
    std::vector<std::string> paths = {HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR,
                                      halLibPathVndkSp, HAL_LIBRARY_PATH_SYSTEM};

...
}

以上是关于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的启动过程