Android P HIDL 之 CameraProvider

Android P HIDL 以及 CameraProvider

一. 相关文件

// 须要本身实现的

Service.cpp (hardware\interfaces\camera\provider\2.4\default)
CameraProvider.cpp (hardware\interfaces\camera\provider\2.4\default) 

// 经过HIDL自动生成

CameraProviderAll.cpp (out\soong.intermediates\hardware\interfaces\camera\provider\2.4
\android.hardware.camera.provider@2.4_genc++\gen
\android\hardware\camera\provider\2.4) 
BnHwCameraProvider.h (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 (out\soong.intermediates\hardware\interfaces\camera\provider\2.4
\android.hardware.camera.provider@2.4_genc++_headers\gen
\android\hardware\camera\provider\2.4) 

二. CameraProvider 进程启动

Service.cpp (hardware\interfaces\camera\provider\2.4\default)

2.1 main函数

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

2.2 defaultPassthroughServiceImplementation函数

template<class Interface>
__attribute__((warn_unused_result))
status_t defaultPassthroughServiceImplementation(std::string name,
                                            size_t maxThreads = 1) {
	// 主要就是open /dev/hwbinder 并配置线程数
	// 后面分析
    configureRpcThreadpool(maxThreads, true); 
    // new cameraprovider and register cameraprovider 
    // 后面分析
    status_t result = registerPassthroughServiceImplementation<Interface>(name);

    if (result != OK) {
        return result;
    }
	
	// 循环 获取并执行其余服务发送过来的消息,经过 BINDER_WRITE_READ 获取消息
	// 后面分析
    joinRpcThreadpool();
    return UNKNOWN_ERROR;
}

2.3 configureRpcThreadpool 函数

configureRpcThreadpool -> configureBinderRpcThreadpool -> ProcessState::self -> ProcessState::ProcessState(open_driver and mmap) -> setThreadPoolConfigurationc++

void configureRpcThreadpool(size_t maxThreads, bool callerWillJoin) {
    // TODO(b/32756130) this should be transport-dependent
    configureBinderRpcThreadpool(maxThreads, callerWillJoin);
}

void configureBinderRpcThreadpool(size_t maxThreads, bool callerWillJoin) {
    ProcessState::self()->setThreadPoolConfiguration(maxThreads, callerWillJoin /*callerJoinsPool*/);
}

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    // 若是不是第一次即gProcess != NULL 
    // 则直接返回
    if (gProcess != NULL) {
        return gProcess;
    }
    // new ProcessState 咱们看一下其构造函数
    // gProcess 是一个全局变量
    gProcess = new ProcessState(DEFAULT_BINDER_VM_SIZE);
    return gProcess;
}

ProcessState::ProcessState(size_t mmap_size)
    : mDriverFD(open_driver()) // open /dev/hwbinder
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mSpawnThreadOnStart(true)
    , mThreadPoolSeq(1)
    , mMmapSize(mmap_size)
{
    if (mDriverFD >= 0) {
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        // mmap the binder, 在内核分配内存,用于存放服务之间的cmdData
        mVMStart = mmap(0, mMmapSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using /dev/hwbinder failed: unable to mmap transaction memory.\n");
            close(mDriverFD);
            mDriverFD = -1;
        }
    }
    else {
        ALOGE("Binder driver could not be opened. Terminating.");
    }
}

status_t ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool) {
    LOG_ALWAYS_FATAL_IF(maxThreads < 1, "Binder threadpool must have a minimum of one thread.");
    status_t result = NO_ERROR;

    size_t kernelMaxThreads = maxThreads - 1;
    // ioctl BINDER_SET_MAX_THREADS,具体请看本人博客 binder 之 内核分析
    if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &kernelMaxThreads) != -1) {
        AutoMutex _l(mLock);
        mMaxThreads = maxThreads;
        mSpawnThreadOnStart = !callerJoinsPool;
    } else {
        result = -errno;
        ALOGE("Binder ioctl to set max threads failed: %s", strerror(-result));
    }
    return result;
}

2.4 registerPassthroughServiceImplementation函数

template<class Interface>
__attribute__((warn_unused_result))
status_t registerPassthroughServiceImplementation(
        std::string name = "default") {

	// 调用 HIDL 生成的接口 ICameraProvider::getService,获得BpHwCameraProvider
	// name = "legacy/0" , getStub = true, 为直通模式
	// 下面分析
    sp<Interface> service = Interface::getService(name, true /* getStub */);

    if (service == nullptr) {
        ALOGE("Could not get passthrough implementation for %s/%s.",
            Interface::descriptor, name.c_str());
        return EXIT_FAILURE;
    }

    LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
            Interface::descriptor, name.c_str());

	// 注册 cameraprovider, name = "legacy/0"
	// 后面其余服务经过HwServiceManager get service是就是是此名称
    status_t status = service->registerAsService(name);

    if (status == OK) {
        ALOGI("Registration complete for %s/%s.",
            Interface::descriptor, name.c_str());
    } else {
        ALOGE("Could not register service %s/%s (%d).",
            Interface::descriptor, name.c_str(), status);
    }

    return status;
}

2.4.1 Interface::getService (ICameraProvider::getService)

文件路径:CameraProviderAll.cpp 

(out\soong.intermediates\hardware\interfaces\camera\provider
\2.4\android.hardware.camera.provider@2.4_genc++\gen
\android\hardware\camera\provider\2.4)
::android::sp<ICameraProvider> ICameraProvider::getService(const std::string &serviceName, const bool getStub) {
    return ::android::hardware::details::getServiceInternal<BpHwCameraProvider>(serviceName, true, getStub);
}

// HidlTransportSupport.h (system\libhidl\transport\include\hidl) 6375 2019-6-19
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;

	// IType::descriptor = android.hardware.camera.provider@2.4::ICameraProvider
	// instance = "legacy/0"
    sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);

    if (base == nullptr) {
        return nullptr;
    }
    if (base->isRemote()) {
        // getRawServiceInternal guarantees we get the proper class
        // 咱们上面拿到的是BnHwBase类,经过toBinder转换为BnHwCameraProvider类
        return sp<IType>(new BpType(toBinder<IBase>(base)));
    }

    return IType::castFrom(base);
}

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();
    if (sm == nullptr) {
        ALOGE("getService: defaultServiceManager() is null");
        return nullptr;
    }
    
    Return<Transport> transportRet = sm->getTransport(descriptor, instance);

    if (!transportRet.isOk()) {
        ALOGE("getService: defaultServiceManager()->getTransport returns %s",
              transportRet.description().c_str());
        return nullptr;
    }
    Transport transport = transportRet;
    const bool vintfHwbinder = (transport == Transport::HWBINDER);
    const bool vintfPassthru = (transport == Transport::PASSTHROUGH);

#ifdef ENFORCE_VINTF_MANIFEST

#ifdef LIBHIDL_TARGET_DEBUGGABLE
    const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
    const bool trebleTestingOverride = env && !strcmp(env, "true");
    const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;
#else // ENFORCE_VINTF_MANIFEST but not LIBHIDL_TARGET_DEBUGGABLE
    const bool trebleTestingOverride = false;
    const bool vintfLegacy = false;
#endif // LIBHIDL_TARGET_DEBUGGABLE

#else // not ENFORCE_VINTF_MANIFEST
    const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
    const bool trebleTestingOverride = env && !strcmp(env, "true");
    const bool vintfLegacy = (transport == Transport::EMPTY);
#endif // ENFORCE_VINTF_MANIFEST
	
	// getStub = false 时,走此流程,拿到 cameraprovider 
	// 用于其余服务获取cameraprovider服务
	// 好比cameraservice 获取 cameraprovider时,拿到<sp<IBase>>,以后会New BpHwCameraProvider
	// 经过 BpHwCameraProvider类调用HIDL通讯
	// 详见下面client端分析
    for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {
        if (waiter == nullptr && tries > 0) {
            waiter = new Waiter(descriptor, instance, sm);
        }
        if (waiter != nullptr) {
            waiter->reset();  // don't reorder this -- see comments on reset()
        }
        
        // 调用 ServiceManager::get 
        // 返回的是 Bp端 CameraProvider 代理类
        // 下面分析
        Return<sp<IBase>> ret = sm->get(descriptor, instance);
        if (!ret.isOk()) {
            ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",
                  ret.description().c_str(), descriptor.c_str(), instance.c_str());
            break;
        }
        sp<IBase> base = ret;
        if (base != nullptr) {
            Return<bool> canCastRet =
                details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);

            if (canCastRet.isOk() && canCastRet) {
                if (waiter != nullptr) {
                    waiter->done();
                }
                return base; // still needs to be wrapped by Bp class.
            }

            if (!handleCastError(canCastRet, descriptor, instance)) break;
        }

        // In case of legacy or we were not asked to retry, don't.
        if (vintfLegacy || !retry) break;

        if (waiter != nullptr) {
            ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());
            waiter->wait(true /* timeout */);
        }
    }

    if (waiter != nullptr) {
        waiter->done();
    }

	// getStub = true 是走此流程,用于服务启动过程
    if (getStub || vintfPassthru || vintfLegacy) {
    	// 详见下面Service端分析 2.4.3
        const sp<IServiceManager> pm = getPassthroughServiceManager();
        if (pm != nullptr) {
        	// 返回CameraProvider实例,CameraProvider是ICameraProvider的子类
        	// ICameraProvider是IBase的子类
            sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
            if (!getStub || trebleTestingOverride) {
                base = wrapPassthrough(base);
            }
            return base;
        }
    }

    return nullptr;
}

2.4.2 获取Service client端分析

getStub = false 时,走此流程,拿到 cameraprovider
用于其余服务获取cameraprovider服务
好比cameraservice 获取 cameraprovider时,拿到<sp>,以后会New BpHwCameraProvider
经过 BpHwCameraProvider类调用HIDL通讯cookie

// 默认模式,即绑定模式获取服务的调用接口
sp<IServiceManager1_1> defaultServiceManager1_1() {
    {
        AutoMutex _l(details::gDefaultServiceManagerLock);
        // 若是不是第一次调用,即gDefaultServiceManager != nullptr
        // 则直接返回 gDefaultServiceManager
        if (details::gDefaultServiceManager != nullptr) {
            return details::gDefaultServiceManager;
        }

        if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {
            // HwBinder not available on this device or not accessible to
            // this process.
            return nullptr;
        }
		// 等待HwServiceManager启动
		// 经过判断 hwservicemanager.ready 属性值
        waitForHwServiceManager();

        while (details::gDefaultServiceManager == nullptr) {
            details::gDefaultServiceManager =
            // getContextObject 返回 handle 是 0 的服务,即 HwServiceManager
                    fromBinder<IServiceManager1_1, BpHwServiceManager, BnHwServiceManager>(
                        ProcessState::self()->getContextObject(nullptr));
            if (details::gDefaultServiceManager == nullptr) {
                LOG(ERROR) << "Waited for hwservicemanager, but got nullptr.";
                sleep(1);
            }
        }
    }

    return details::gDefaultServiceManager;
}

// Methods from ::android::hidl::manager::V1_0::IServiceManager follow.
Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,
                                      const hidl_string& hidlName) {
    const std::string fqName = hidlFqName;
    const std::string name = hidlName;

    if (!mAcl.canGet(fqName, getBinderCallingContext())) {
        return nullptr;
    }
	
	// 在map中查找服务是否已经启动
	// 若没有启动的话,调用tryStartService
	// 实际上就是跑进去设置一个属性值,SetProperty("ctl.interface_start", fqName + "/" + name)
    auto ifaceIt = mServiceMap.find(fqName);
    if (ifaceIt == mServiceMap.end()) {
        tryStartService(fqName, hidlName);
        return nullptr;
    }

    const PackageInterfaceMap &ifaceMap = ifaceIt->second;
    // 在 ifaceMap 查找此服务
    const HidlService *hidlService = ifaceMap.lookup(name);

    if (hidlService == nullptr) {
        tryStartService(fqName, hidlName);
        return nullptr;
    }
    
    // 获取Service启动时注册到HwServiceManager中的服务
    sp<IBase> service = hidlService->getService();
    if (service == nullptr) {
        tryStartService(fqName, hidlName);
        return nullptr;
    }

    return service;
}

2.4.3 server端流程分析

// getPassthroughServiceManager 过程
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;
		
		// open lib 
        openLibs(fqName, /*匿名函数做为形参*/[&](void* handle, const std::string &lib, const std::string &sym) {
        	// 这是一个匿名函数
        	// openLibs 中调用 eachLib 即调用此函数
            IBase* (*generator)(const char* name);
            *(void **)(&generator) = dlsym(handle, sym.c_str());
            if(!generator) {
                const char* error = dlerror();
                LOG(ERROR) << "Passthrough lookup opened " << lib
                           << " but could not find symbol " << sym << ": "
                           << (error == nullptr ? "unknown error" : error);
                dlclose(handle);
                return true;
            }
			// 调用 HIDL_FETCH_ICameraProvider
			// 返回CameraProvider实例
            ret = (*generator)(name.c_str());

            if (ret == nullptr) {
                dlclose(handle);
                return true; // this module doesn't provide this instance name
            }

            // Actual fqname might be a subclass.
            // This assumption is tested in vts_treble_vintf_test
            using ::android::hardware::details::getDescriptor;
            std::string actualFqName = getDescriptor(ret.get());
            CHECK(actualFqName.size() > 0);
            registerReference(actualFqName, name);
            return false;
        });
		// 返回CameraProvider实例
        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
        // 以前有提到过 
        // IType::descriptor = android.hardware.camera.provider@2.4::ICameraProvider
        size_t idx = fqName.find("::"); // 获取 :: 位置

        if (idx == std::string::npos ||
                idx + strlen("::") + 1 >= fqName.size()) {
            LOG(ERROR) << "Invalid interface name passthrough lookup: " << fqName;
            return;
        }
		
		// packageAndVersion = 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;

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

#ifdef LIBHIDL_TARGET_DEBUGGABLE
        const char* env = std::getenv("TREBLE_TESTING_OVERRIDE");
        const bool trebleTestingOverride = env && !strcmp(env, "true");
        if (trebleTestingOverride) {
            // Load HAL implementations that are statically linked
            handle = dlopen(nullptr, dlMode);
            if (handle == nullptr) {
                const char* error = dlerror();
                LOG(ERROR) << "Failed to dlopen self: "
                           << (error == nullptr ? "unknown error" : error);
            } else if (!eachLib(handle, "SELF", sym)) {
                return;
            }

            const char* vtsRootPath = std::getenv("VTS_ROOT_PATH");
            if (vtsRootPath && strlen(vtsRootPath) > 0) {
                const std::string halLibraryPathVtsOverride =
                    std::string(vtsRootPath) + HAL_LIBRARY_PATH_SYSTEM;
                paths.insert(paths.begin(), halLibraryPathVtsOverride);
            }
        }
#endif

        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;
				
				// dlopen lib
                if (path == HAL_LIBRARY_PATH_SYSTEM) {
                    handle = dlopen(fullPath.c_str(), dlMode); 
                } else {
                    handle = android_load_sphal_library(fullPath.c_str(), dlMode);
                }

                if (handle == nullptr) {
                    const char* error = dlerror();
                    LOG(ERROR) << "Failed to dlopen " << lib << ": "
                               << (error == nullptr ? "unknown error" : error);
                    continue;
                }
				// 调用匿名函数
                if (!eachLib(handle, lib, sym)) {
                    return;
                }
            }
        }
    }

2.4.4 CameraProvider实例化HIDL_FETCH_ICameraProvider

接上面 openLibs 调用 HIDL_FETCH_ICameraProviderapp

ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
    if (strcmp(name, kLegacyProviderName) == 0) {
    	// new CameraProvider
    	// 看看构造函数都干了些什么事
        CameraProvider* provider = new CameraProvider();
        if (provider == nullptr) {
            ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
            return nullptr;
        }
        if (provider->isInitFailed()) {
            ALOGE("%s: camera provider init failed!", __FUNCTION__);
            delete provider;
            return nullptr;
        }
        return provider;
    } else if (strcmp(name, kExternalProviderName) == 0) {
        ExternalCameraProvider* provider = new ExternalCameraProvider();
        return provider;
    }
    ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
    return nullptr;
}

CameraProvider::CameraProvider() :
        camera_module_callbacks_t({sCameraDeviceStatusChange,
                                   sTorchModeStatusChange}) {
    mInitFailed = 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;
    }
	// 套个乌龟壳
    mModule = new CameraModule(rawModule);
    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());

    // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
    if (!setUpVendorTags()) {
        ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
    }

    // Setup callback now because we are going to try openLegacy next
    err = mModule->setCallbacks(this);
    if (err != OK) {
        ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
        mModule.clear();
        return true;
    }

    mPreferredHal3MinorVersion =
        property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion", 3);
    ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
    switch(mPreferredHal3MinorVersion) {
        case 2:
        case 3:
            // OK
            break;
        default:
            ALOGW("Unknown minor camera device HAL version %d in property "
                    "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",
                    mPreferredHal3MinorVersion);
            mPreferredHal3MinorVersion = 3;
    }

    mNumberOfLegacyCameras = mModule->getNumberOfCameras();
    for (int i = 0; i < mNumberOfLegacyCameras; i++) {
        int frameworkId = mModule->getFrameworkCameraId(i);

        struct camera_info info;
        auto rc = mModule->getCameraInfo(frameworkId, &info);
        if (rc != NO_ERROR) {
            ALOGE("%s: Camera info query failed!", __func__);
            mModule.clear();
            return true;
        }

        if (checkCameraVersion(frameworkId, info) != OK) {
            ALOGE("%s: Camera version check failed!", __func__);
            mModule.clear();
            return true;
        }

        char cameraId[kMaxCameraIdLen];
        snprintf(cameraId, sizeof(cameraId), "%d", frameworkId);
        std::string cameraIdStr(cameraId);
        mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;

        addDeviceNames(frameworkId);
    }

    return false; // mInitFailed
}

2.5 注册CameraProvider

// status_t status = service->registerAsService(name);
::android::status_t ICameraProvider::registerAsService(const std::string &serviceName) {
    ::android::hardware::details::onRegistration("android.hardware.camera.provider@2.4", "ICameraProvider", serviceName);
	// 获取 HwServiceManager
    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;
}

// _hidl_add
::android::hardware::Return<bool> BpHwServiceManager::_hidl_add(::android::hardware::IInterface *_hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::android::hardware::hidl_string& name, const ::android::sp<::android::hidl::base::V1_0::IBase>& service) {
    #ifdef __ANDROID_DEBUGGABLE__
    bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();
    const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();
    #else
    (void) _hidl_this_instrumentor;
    #endif // __ANDROID_DEBUGGABLE__
    atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::add::client");
    #ifdef __ANDROID_DEBUGGABLE__
    if (UNLIKELY(mEnableInstrumentation)) {
        std::vector<void *> _hidl_args;
        _hidl_args.push_back((void *)&name);
        _hidl_args.push_back((void *)&service);
        for (const auto &callback: mInstrumentationCallbacks) {
            callback(InstrumentationEvent::CLIENT_API_ENTRY, "android.hidl.manager", "1.0", "IServiceManager", "add", &_hidl_args);
        }
    }
    #endif // __ANDROID_DEBUGGABLE__

    ::android::hardware::Parcel _hidl_data;
    ::android::hardware::Parcel _hidl_reply;
    ::android::status_t _hidl_err;
    ::android::hardware::Status _hidl_status;

    bool _hidl_out_success;

    _hidl_err = _hidl_data.writeInterfaceToken(BpHwServiceManager::descriptor);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    size_t _hidl_name_parent;

    _hidl_err = _hidl_data.writeBuffer(&name, sizeof(name), &_hidl_name_parent);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    _hidl_err = ::android::hardware::writeEmbeddedToParcel(
            name,
            &_hidl_data,
            _hidl_name_parent,
            0 /* parentOffset */);

    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    if (service == nullptr) {
        _hidl_err = _hidl_data.writeStrongBinder(nullptr);
    } else {
    // toBinder 会经过传入的 IBase 构造出 BnCameraProvider 
        ::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::toBinder<
                ::android::hidl::base::V1_0::IBase>(service);
        if (_hidl_binder.get() != nullptr) {
        	// 将_hidl_binder放入_hidl_data
            _hidl_err = _hidl_data.writeStrongBinder(_hidl_binder);
        } else {
            _hidl_err = ::android::UNKNOWN_ERROR;
        }
    }
    if (_hidl_err != ::android::OK) { goto _hidl_error; }
	// 开启线程
    ::android::hardware::ProcessState::self()->startThreadPool();
    // 进程间通讯
    // 经过binder,调用ServiceManager.cpp(HwServiceManager服务于) 中的 add 函数
    _hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(2 /* add */, _hidl_data, &_hidl_reply);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    _hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    if (!_hidl_status.isOk()) { return _hidl_status; }

    _hidl_err = _hidl_reply.readBool(&_hidl_out_success);
    if (_hidl_err != ::android::OK) { goto _hidl_error; }

    atrace_end(ATRACE_TAG_HAL);
    #ifdef __ANDROID_DEBUGGABLE__
    if (UNLIKELY(mEnableInstrumentation)) {
        std::vector<void *> _hidl_args;
        _hidl_args.push_back((void *)&_hidl_out_success);
        for (const auto &callback: mInstrumentationCallbacks) {
            callback(InstrumentationEvent::CLIENT_API_EXIT, "android.hidl.manager", "1.0", "IServiceManager", "add", &_hidl_args);
        }
    }
    #endif // __ANDROID_DEBUGGABLE__

    _hidl_status.setFromStatusT(_hidl_err);
    return ::android::hardware::Return<bool>(_hidl_out_success);

_hidl_error:
    _hidl_status.setFromStatusT(_hidl_err);
    return ::android::hardware::Return<bool>(_hidl_status);
}

// ServiceManager.cpp
Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) {
    bool isValidService = false;

    if (service == nullptr) {
        return false;
    }

    auto callingContext = getBinderCallingContext();

    auto ret = service->interfaceChain([&](const auto &interfaceChain) {
        if (interfaceChain.size() == 0) {
            return;
        }

        // First, verify you're allowed to add() the whole interface hierarchy
        for(size_t i = 0; i < interfaceChain.size(); i++) {
            const std::string fqName = interfaceChain[i];

            if (!mAcl.canAdd(fqName, callingContext)) {
                return;
            }
        }

        {
            // For IBar extends IFoo if IFoo/default is being registered, remove
            // IBar/default. This makes sure the following two things are equivalent
            // 1). IBar::castFrom(IFoo::getService(X))
            // 2). IBar::getService(X)
            // assuming that IBar is declared in the device manifest and there
            // is also not an IBaz extends IFoo.
            const std::string childFqName = interfaceChain[0];
            const PackageInterfaceMap &ifaceMap = mServiceMap[childFqName];
            const HidlService *hidlService = ifaceMap.lookup(name);
            if (hidlService != nullptr) {
                const sp<IBase> remove = hidlService->getService();

                if (remove != nullptr) {
                    const std::string instanceName = name;
                    removeService(remove, &instanceName /* restrictToInstanceName */);
                }
            }
        }

        for(size_t i = 0; i < interfaceChain.size(); i++) {
            const std::string fqName = interfaceChain[i];

            PackageInterfaceMap &ifaceMap = mServiceMap[fqName];
            HidlService *hidlService = ifaceMap.lookup(name);

            if (hidlService == nullptr) {
                ifaceMap.insertService(
                    std::make_unique<HidlService>(fqName, name, service, callingContext.pid));
            } else {
                hidlService->setService(service, callingContext.pid);
            }

            ifaceMap.sendPackageRegistrationNotification(fqName, name);
        }

        bool linkRet = service->linkToDeath(this, kServiceDiedCookie).withDefault(false);
        if (!linkRet) {
            LOG(ERROR) << "Could not link to death for " << interfaceChain[0] << "/" << name;
        }

        isValidService = true;
    });

    if (!ret.isOk()) {
        LOG(ERROR) << "Failed to retrieve interface chain.";
        return false;
    }

    return isValidService;
}

2.6 joinRpcThreadpool

void joinRpcThreadpool() {
    // TODO(b/32756130) this should be transport-dependent
    joinBinderRpcThreadpool();
}

void joinBinderRpcThreadpool() {
    IPCThreadState::self()->joinThreadPool();
}

void IPCThreadState::joinThreadPool(bool isMain)
{
    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());

    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);

    status_t result;
    mIsLooper = true;
    do { // 只要结果result != -ECONNREFUSED && result != -EBADF
    	 // 一直循环调用 getAndExecuteCommand
        processPendingDerefs();
        // now get the next command to be processed, waiting if necessary
        result = getAndExecuteCommand();

        if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
            ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
                  mProcess->mDriverFD, result);
            abort();
        }

        // Let this thread exit the thread pool if it is no longer
        // needed and it is not the main process thread.
        if(result == TIMED_OUT && !isMain) {
            break;
        }
    } while (result != -ECONNREFUSED && result != -EBADF);

    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
        (void*)pthread_self(), getpid(), result);

    mOut.writeInt32(BC_EXIT_LOOPER);
    mIsLooper = false;
    talkWithDriver(false);
}

status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;
	// 从 binder 读数据
    result = talkWithDriver();
    if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        cmd = mIn.readInt32();
        IF_LOG_COMMANDS() {
            alog << "Processing top-level Command: "
                 << getReturnString(cmd) << endl;
        }

        pthread_mutex_lock(&mProcess->mThreadCountLock);
        mProcess->mExecutingThreadsCount++;
        if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&
            mProcess->mMaxThreads > 1 && mProcess->mStarvationStartTimeMs == 0) {
            mProcess->mStarvationStartTimeMs = uptimeMillis();
        }
        pthread_mutex_unlock(&mProcess->mThreadCountLock);

		// 顾名思义,执行读到的cmd
        result = executeCommand(cmd);

        pthread_mutex_lock(&mProcess->mThreadCountLock);
        mProcess->mExecutingThreadsCount--;
        if (mProcess->mExecutingThreadsCount < mProcess->mMaxThreads &&
            mProcess->mStarvationStartTimeMs != 0) {
            int64_t starvationTimeMs = uptimeMillis() - mProcess->mStarvationStartTimeMs;
            if (starvationTimeMs > 100) {
                // If there is only a single-threaded client, nobody would be blocked
                // on this, and it's not really starvation. (see b/37647467)
                ALOGW("All binder threads in pool (%zu threads) busy for %" PRId64 " ms%s",
                      mProcess->mMaxThreads, starvationTimeMs,
                      mProcess->mMaxThreads > 1 ? "" : " (may be a false alarm)");
            }
            mProcess->mStarvationStartTimeMs = 0;
        }
        pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
        pthread_mutex_unlock(&mProcess->mThreadCountLock);
    }

    return result;
}

status_t IPCThreadState::executeCommand(int32_t cmd)
{
    BHwBinder* obj;
    RefBase::weakref_type* refs;
    status_t result = NO_ERROR;
    switch ((uint32_t)cmd) {
.......
    case BR_TRANSACTION_SEC_CTX:
    case BR_TRANSACTION:
        {
            binder_transaction_data_secctx tr_secctx;
            binder_transaction_data& tr = tr_secctx.transaction_data;

            if (cmd == (int) BR_TRANSACTION_SEC_CTX) {
                result = mIn.read(&tr_secctx, sizeof(tr_secctx));
            } else {
                result = mIn.read(&tr, sizeof(tr));
                tr_secctx.secctx = 0;
            }

            ALOG_ASSERT(result == NO_ERROR,
                "Not enough command data for brTRANSACTION");
            if (result != NO_ERROR) break;

            Parcel buffer;
            buffer.ipcSetDataReference(
                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                tr.data_size,
                reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);

            const pid_t origPid = mCallingPid;
            const char* origSid = mCallingSid;
            const uid_t origUid = mCallingUid;
            const int32_t origStrictModePolicy = mStrictModePolicy;
            const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;

            mCallingPid = tr.sender_pid;
            mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
            mCallingUid = tr.sender_euid;
            mLastTransactionBinderFlags = tr.flags;

            // ALOGI(">>>> TRANSACT from pid %d sid %s uid %d\n", mCallingPid,
            // (mCallingSid ? mCallingSid : "<N/A>"), mCallingUid);

            Parcel reply;
            status_t error;
            bool reply_sent = false;
            IF_LOG_TRANSACTIONS() {
                alog << "BR_TRANSACTION thr " << (void*)pthread_self()
                    << " / obj " << tr.target.ptr << " / code "
                    << TypeCode(tr.code) << ": " << indent << buffer
                    << dedent << endl
                    << "Data addr = "
                    << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
                    << ", offsets addr="
                    << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
            }

            auto reply_callback = [&] (auto &replyParcel) {
                if (reply_sent) {
                    // Reply was sent earlier, ignore it.
                    ALOGE("Dropping binder reply, it was sent already.");
                    return;
                }
                reply_sent = true;
                if ((tr.flags & TF_ONE_WAY) == 0) {
                    replyParcel.setError(NO_ERROR);
                    sendReply(replyParcel, 0);
                } else {
                    ALOGE("Not sending reply in one-way transaction");
                }
            };

            if (tr.target.ptr) {
                // We only have a weak reference on the target object, so we must first try to
                // safely acquire a strong reference before doing anything else with it.
                if (reinterpret_cast<RefBase::weakref_type*>(
                        tr.target.ptr)->attemptIncStrong(this)) {
                    // 调用BnHwCameraProvider的transact函数
                    error = reinterpret_cast<BHwBinder*>(tr.cookie)->transact(tr.code, buffer,
                            &reply, tr.flags, reply_callback);
                    reinterpret_cast<BHwBinder*>(tr.cookie)->decStrong(this);
                } else {
                    error = UNKNOWN_TRANSACTION;
                }

            } else {
            	// HwServiceManager 调用
                error = mContextObject->transact(tr.code, buffer, &reply, tr.flags, reply_callback);
            }

            if ((tr.flags & TF_ONE_WAY) == 0) {
                if (!reply_sent) {
                    // Should have been a reply but there wasn't, so there
                    // must have been an error instead.
                    reply.setError(error);
                    sendReply(reply, 0);
                } else {
                    if (error != NO_ERROR) {
                        ALOGE("transact() returned error after sending reply.");
                    } else {
                        // Ok, reply sent and transact didn't return an error.
                    }
                }
            } else {
                // One-way transaction, don't care about return value or reply.
            }

            //ALOGI("<<<< TRANSACT from pid %d restore pid %d sid %s uid %d\n",
            // mCallingPid, origPid, (origSid ? origSid : "<N/A>"), origUid);

            mCallingPid = origPid;
            mCallingSid = origSid;
            mCallingUid = origUid;
            mStrictModePolicy = origStrictModePolicy;
            mLastTransactionBinderFlags = origTransactionBinderFlags;

            IF_LOG_TRANSACTIONS() {
                alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
                    << tr.target.ptr << ": " << indent << reply << dedent << endl;
            }

        }
        break;

........

    default:
        printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
        result = UNKNOWN_ERROR;
        break;
    }

    if (result != NO_ERROR) {
        mLastError = result;
    }

    return result;
}

// CameraProvider 没有实现 transact
// 调用父类的 transact
// binder.cpp
status_t BHwBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback callback)
{
    data.setDataPosition(0);

    status_t err = NO_ERROR;
    switch (code) {
        default:
        	// 此函数在BnHwCameraProvider中有实现
            err = onTransact(code, data, reply, flags,
                    [&](auto &replyParcel) {
                        replyParcel.setDataPosition(0);
                        if (callback != NULL) {
                            callback(replyParcel);
                        }
                    });
            break;
    }

    return err;
}

// BnHwCameraProvider 
::android::status_t BnHwCameraProvider::onTransact(
        uint32_t _hidl_code,
        const ::android::hardware::Parcel &_hidl_data,
        ::android::hardware::Parcel *_hidl_reply,
        uint32_t _hidl_flags,
        TransactCallback _hidl_cb) {
    ::android::status_t _hidl_err = ::android::OK;

	// 不一样的_hidl_code对应不一样的操做
    switch (_hidl_code) {
        case 1 /* setCallback */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }

            _hidl_err = ::android::hardware::camera::provider::V2_4::BnHwCameraProvider::_hidl_setCallback(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }

        case 2 /* getVendorTags */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }

            _hidl_err = ::android::hardware::camera::provider::V2_4::BnHwCameraProvider::_hidl_getVendorTags(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }

        case 3 /* getCameraIdList */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }

            _hidl_err = ::android::hardware::camera::provider::V2_4::BnHwCameraProvider::_hidl_getCameraIdList(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }

        case 4 /* isSetTorchModeSupported */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }

            _hidl_err = ::android::hardware::camera::provider::V2_4::BnHwCameraProvider::_hidl_isSetTorchModeSupported(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }

        case 5 /* getCameraDeviceInterface_V1_x */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }

            _hidl_err = ::android::hardware::camera::provider::V2_4::BnHwCameraProvider::_hidl_getCameraDeviceInterface_V1_x(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }

        case 6 /* getCameraDeviceInterface_V3_x */:
        {
            bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
            if (_hidl_is_oneway != false) {
                return ::android::UNKNOWN_ERROR;
            }

            _hidl_err = ::android::hardware::camera::provider::V2_4::BnHwCameraProvider::_hidl_getCameraDeviceInterface_V3_x(this, _hidl_data, _hidl_reply, _hidl_cb);
            break;
        }

        default:
        {
            return ::android::hidl::base::V1_0::BnHwBase::onTransact(
                    _hidl_code, _hidl_data, _hidl_reply, _hidl_flags, _hidl_cb);
        }
    }

    if (_hidl_err == ::android::UNEXPECTED_NULL) {
        _hidl_err = ::android::hardware::writeToParcel(
                ::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),
                _hidl_reply);
    }return _hidl_err;
}

3. 总结

Binder 分为 Bp 以及 Bn,Bp 对应 client , Bn 对应 server。ide

CameraProvider 服务,经过 ICameraProvider::getService 实例化 CameraProvider,而后经过toBinder函数转换为BnHwCameraProvider,注册到HwServiceManager中。svg

CameraService 服务,经过 ICameraProvider::getService 拿到 BpHwCameraProvider,而后经过binder通讯调用到CameraProvider,进而调用Camera HAL。函数

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Q中引入了HIDL(HAL Interface Definition Language)作为一种新的硬件抽象层接口定义语言,用于定义跨进程的硬件访问接口。HIDL的实操主要包括以下几个方面: 1. HIDL的使用:HIDL提供了一套接口定义语言和代码生成工具,我们可以通过编写HIDL文件来定义硬件接口,并使用代码生成工具生成对应的客户端和服务器端的代码。我们可以通过HIDL接口访问相应的硬件功能,比如传感器、音频设备等。 2. HIDL Client的编写:HIDL Client是客户端的实现代码,它通过HIDL接口与相应的硬件模块进行通信。我们可以通过调用HIDL接口提供的方法来使用硬件功能,比如打开、关闭传感器、读取传感器数据等。 3. HIDL Server的编写:HIDL Server是服务器端的实现代码,它通过HIDL接口与客户端进行通信并提供相应的硬件功能。在HIDL Server中,我们需要实现HIDL接口定义的方法,并在方法中实现相应的硬件操作逻辑。 4. HIDL的跨进程通信:HIDL使用Binder机制实现跨进程通信。客户端通过Binder机制将请求发送到服务器端,服务器端接收到请求后执行相应的操作,并将结果返回给客户端。这样,我们就可以通过HIDL实现跨进程的硬件访问。 5. HIDL的注册和调用:在使用HIDL时,我们需要将HIDL实例注册到系统服务中,以便在需要时能够使用相应的硬件功能。我们可以使用ServiceManager类的add/get方法进行注册和调用。 总之,HIDL实操主要涉及HIDL文件的编写、HIDL Client和Server的实现、跨进程通信的处理以及HIDL的注册和调用。通过掌握这些内容,我们可以使用HIDL来访问Android Q中的硬件功能,并实现跨进程的硬件交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值