get hidl service

Posted aspirs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
    

 

以上是关于get hidl service的主要内容,如果未能解决你的问题,请参考以下文章

Android HIDL概述(一)

android treble项目&&HIDL学习总结

HIDL(HAL interface definition langguage)

Android HIDL 详解

Android P HIDL demo代码编写

Android HIDL 介绍学习之客户端调用