zoukankan      html  css  js  c++  java
  • get hidl service

    1. BpHwServiceManager::_hidl_get()

    transact(/*get*/)

    2. BnHwServiceManager::_hidl_get()

    上面transact()会call到hwservicemanager的BnHwServiceManager::_hidl_get(),在这个函数中,首先call hwservicemanager/ServiceManager.cpp的get()拿到一个BpHwBase对象,然后call toBinder()将其转化为BpHwBinder对象,详细分析如下:

    因为iface为BpHwBase,在BpHwBase.h里,isRemote()被override里,会return true,所以ifacePtr->isRemote()条件成立。

    sp<IBinder> toBinder(sp<IType> iface) {
        IType *ifacePtr = iface.get();
        if (ifacePtr == nullptr) {
            return nullptr;
        }
        if (ifacePtr->isRemote()) {
            return ::android::hardware::IInterface::asBinder(
                static_cast<BpInterface<IType>*>(ifacePtr));

    然后call writeStrongBinder()将上面的BpHwBinder写到Parcel reply里。在flatten_binder()里,因为参数binder为BpHwBinder,所以binder->localBinder()会return false,而binder->remoteBinder()会return this,即BpHwBinder this指针。

    proxy->handle()即在registerAsService时在hwservicemanager的BnHwServiceManager::_hidl_add函数里call的readNullableStrongBinder()时创建BpHwBinder时作为BpHwBinder构造函数的参数的handle。

    status_t flatten_binder(const sp<ProcessState>& /*proc*/,
        const sp<IBinder>& binder, Parcel* out)
    {
        flat_binder_object obj;
    
        if (binder != NULL) {
            BHwBinder *local = binder->localBinder();
            if (!local) {
                BpHwBinder *proxy = binder->remoteBinder();
                if (proxy == NULL) {
                    ALOGE("null proxy");
                }
                const int32_t handle = proxy ? proxy->handle() : 0;
                obj.hdr.type = BINDER_TYPE_HANDLE;
                obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
                obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
                obj.handle = handle;
                obj.cookie = 0;

    3. 从hwservicemanager返回,回到BpHwServiceManager::_hidl_get()

    call readNullableStrongBinder(),这个函数call到getStrongProxyForHandle(),在这个函数里,根据handle拿到对应的handle_entry,这时e->binder不是null了,所以这个函数就是return一个BpHwBinder对象。

    sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
    {
        sp<IBinder> result;
    
        AutoMutex _l(mLock);
    
        handle_entry* e = lookupHandleLocked(handle);
    
        if (e != NULL) {
            // We need to create a new BpHwBinder if there isn't currently one, OR we
            // are unable to acquire a weak reference on this current one.  See comment
            // in getWeakProxyForHandle() for more info about this.
            IBinder* b = e->binder;
            if (b == NULL || !e->refs->attemptIncWeak(this)) {
                b = new BpHwBinder(handle);
                e->binder = b;
                if (b) e->refs = b->getWeakRefs();
                result = b;
            } else {
                // This little bit of nastyness is to allow us to add a primary
                // reference to the remote proxy when this team doesn't have one
                // but another team is sending the handle to us.
                result.force_set(b);
                e->refs->decWeak(this);
            }
        }
    
        return result;
    }

    然后根据上面得到的BpHwBinder call fromBinder(),在fromBinder里,因为参数binderIface为BpHwBinder,所以,binderIface->localBinder()会return null,所以这里会new一个ProxyType,即new一个BpHwBase

    template <typename IType, typename ProxyType, typename StubType>
    sp<IType> fromBinder(const sp<IBinder>& binderIface) {
        using ::android::hidl::base::V1_0::IBase;
        using ::android::hidl::base::V1_0::BnHwBase;
    
        if (binderIface.get() == nullptr) {
            return nullptr;
        }
        if (binderIface->localBinder() == nullptr) {
            return new ProxyType(binderIface);
        } 

    所以sm->get()会返回一个BpHwBase,然后call details::canCastInterface(),这个函数在system/libhidl/transport/hidltransportutils.cpp里。这里的castTo是omall.cpp里call getServiceInternal<BpHwOmx>()的BpHwOmx的pure成员,pure成员即是IOmx,注意这里的IOmx是out/soong下的IOmx,所以这里的castTo即是IOmx::descriptor,即在omxall.cpp中的:

    const char* IOmx::descriptor("android.hardware.media.omx@1.0::IOmx");

     而IBase::descriptor是const char* IBase::descriptor("android.hidl.base@1.0::IBase"),所以会call到下面的interface->interfaceChain()

    Return<bool> canCastInterface(IBase* interface, const char* castTo, bool emitError) {
        if (interface == nullptr) {
            return false;
        }
    
        // b/68217907
        // Every HIDL interface is a base interface.
        if (std::string(IBase::descriptor) == castTo) {
            return true;
        }
    
        bool canCast = false;
        auto chainRet = interface->interfaceChain([&](const hidl_vec<hidl_string> &types) {
            for (size_t i = 0; i < types.size(); i++) {
                if (types[i] == castTo) {
                    canCast = true;
                    break;
                }
            }
        });
    
        if (!chainRet.isOk()) {
            // call fails, propagate the error if emitError
            return emitError
                    ? details::StatusOf<void, bool>(chainRet)
                    : Return<bool>(false);
        }
    
        return canCast;
    }

    下面说下interface->interfaceChain()的call flow,这个interface是一个BpHwBase,所以是call的BpHwBase的interfaceChain(),而这个函数会call到BnHwBase::_hidl_interfaceChain()。这个函数会call static_cast<IBase*>(_hidl_this->getImpl().get())->interfaceChain(),而这个interfaceChain()是IOmx::interfaceChain(),所以写到_hidl_reply里的_hidl_out_descriptors是:

    ::android::hardware::media::omx::V1_0::IOmx::descriptor
    ::android::hidl::base::V1_0::IBase::descriptor

    BnHwBase::_hidl_interfaceChain()

    static_cast<IBase*>(_hidl_this->getImpl().get())->interfaceChain([&](const auto &_hidl_out_descriptors) {
    if (_hidl_callbackCalled) {
    
    LOG_ALWAYS_FATAL("interfaceChain: _hidl_cb called a second time, but must be called once.");
    
    }
    
    _hidl_callbackCalled = true;
    
    ::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);
    
    size_t _hidl__hidl_out_descriptors_parent;
    
    _hidl_err = _hidl_reply->writeBuffer(&_hidl_out_descriptors, sizeof(_hidl_out_descriptors), &_hidl__hidl_out_descriptors_parent);
    ::android::hardware::Return<void> IOmx::interfaceChain(interfaceChain_cb _hidl_cb){
    _hidl_cb({
    
    ::android::hardware::media::omx::V1_0::IOmx::descriptor,
    
    ::android::hidl::base::V1_0::IBase::descriptor,
    
    });
    
    return ::android::hardware::Void();}

    然后在返回到BpHwBase::_hidl_interfaceChain(),完成了这个函数里的transact()后,call Parcel::readBuffer从Parcel reply中读取descriptors,然后再将这个descriptors作为参数call canCastInterface中的匿名函数,在这个匿名函数中,将descriptors中的descriptor和castTo比较,如上面分析,castTo是::android::hardware::media::omx::V1_0::IOmx::descriptor,而descriptors中其中一个就是它,所以canCast会被赋值为true。所以canCastInterface()会return true。

    所以getRawServiceInternal()会返回一个BpHwBase。

    回到getServiceInternal(),因为getRawServiceInternal()return的是一个BpHwBase,即base是一个BpHwBase,所以base->isRemote()会return true,所以这时会new一个BpHwOmx对象。

    所以IOmx::getService()拿到的是一个BpHwOmx对象。

  • 相关阅读:
    简单计算器
    dfs(通过控制点的编号来得出每个点的坐标)
    dfs(通过控制点的编号来得出每个点的坐标)
    神奇的 组合数
    神奇的 组合数
    B. Light It Up
    B. Light It Up
    Python 字符串
    Python radians() 函数
    Python degrees() 函数
  • 原文地址:https://www.cnblogs.com/aspirs/p/11569751.html
Copyright © 2011-2022 走看看