zoukankan      html  css  js  c++  java
  • register hidl service(omx)

    frameworks/av/services/mediacodec/main_codecservice.cpp

            // Default codec services
            using namespace ::android::hardware::media::omx::V1_0;
            sp<IOmxStore> omxStore = new implementation::OmxStore();
            if (omxStore == nullptr) {
                LOG(ERROR) << "Cannot create IOmxStore HAL service.";
            } else if (omxStore->registerAsService() != OK) {
                LOG(ERROR) << "Cannot register IOmxStore HAL service.";
            }
            sp<IOmx> omx = new implementation::Omx();
            if (omx == nullptr) {
                LOG(ERROR) << "Cannot create IOmx HAL service.";
            } else if (omx->registerAsService() != OK) {
                LOG(ERROR) << "Cannot register IOmx HAL service.";

    omxall.cpp

    registerAsService()

    -->

    servicemanagerall.cpp

    BpHwServiceManager::_hidl_add()

    if (service == nullptr) {
    _hidl_err = _hidl_data.writeStrongBinder(nullptr);
    
    } else {
    
    ::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::toBinder<
    
    ::android::hidl::base::V1_0::IBase>(service);
    
    if (_hidl_binder.get() != nullptr) {
    
    _hidl_err = _hidl_data.writeStrongBinder(_hidl_binder);
    
    } else {
    
    _hidl_err = ::android::UNKNOWN_ERROR;
    
    }
    
    }

    关键是上面的toBinder(),它是定义在hidlbindersupport.h中的宏:

    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));
        } else {
            std::string myDescriptor = details::getDescriptor(ifacePtr);
            if (myDescriptor.empty()) {
                // interfaceDescriptor fails
                return nullptr;
            }
    
            // for get + set
            std::unique_lock<std::mutex> _lock = details::gBnMap.lock();
    
            wp<BHwBinder> wBnObj = details::gBnMap.getLocked(ifacePtr, nullptr);
            sp<IBinder> sBnObj = wBnObj.promote();
    
            if (sBnObj == nullptr) {
                auto func = details::getBnConstructorMap().get(myDescriptor, nullptr);
                if (!func) {
                    func = details::gBnConstructorMap.get(myDescriptor, nullptr);
                    if (!func) {
                        return nullptr;
                    }
                }
    
                sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr)));
    
                if (sBnObj != nullptr) {
                    details::gBnMap.setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get()));
                }
            }
    
            return sBnObj;
        }
    }

    对于implementation::Omx,对应在omxall.cpp里,isRemote()会返回false,所以上面ifacePtr->isRemote()条件不成立,所以会跑else cae。

    所以然后是details::gBnMap.getLocked(ifacePtr, nullptr)

    这里是拿到一个BnHwOmx对象,然后将其转化为一个sp<IBinder>

    __attribute__((constructor)) static void static_constructor() {
    ::android::hardware::details::getBnConstructorMap().set(IOmx::descriptor,
    
    [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {
    
    return new BnHwOmx(static_cast<IOmx *>(iIntf));
    
    });
    
    ::android::hardware::details::getBsConstructorMap().set(IOmx::descriptor,
    
    [](void *iIntf) -> ::android::sp<::android::hidl::base::V1_0::IBase> {
    
    return new BsOmx(static_cast<IOmx *>(iIntf));
    
    });
    
    };

    所以上面toBinder拿到的是一个BnHwOmx sp

    然后是call writeStrongBinder()将这个BnHwOmx sp写到Parcel中,这个函数会call到flatten_binder(),在这个函数中,这时binder->localBinder()为非null,所以type为被设置为BINDER_TYPE_BINDER

    system/libhwbinder/Parcel.cpp

    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;
            } else {
                // Get policy and convert it
                int policy = local->getMinSchedulingPolicy();
                int priority = local->getMinSchedulingPriority();
    
                obj.flags = priority & FLAT_BINDER_FLAG_PRIORITY_MASK;
                obj.flags |= FLAT_BINDER_FLAG_ACCEPTS_FDS | FLAT_BINDER_FLAG_INHERIT_RT;
                obj.flags |= (policy & 3) << FLAT_BINDER_FLAG_SCHEDPOLICY_SHIFT;
                obj.hdr.type = BINDER_TYPE_BINDER;
                obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
                obj.cookie = reinterpret_cast<uintptr_t>(local);
            }
        } else {
            obj.hdr.type = BINDER_TYPE_BINDER;
            obj.binder = 0;
            obj.cookie = 0;
        }
    
        return finish_flatten_binder(binder, obj, out);
    }

    之后就是由hwservciemanager来处理这个add的请求,在BnHwServiceManager::_hidl_add()中。

    在这个函数中,会call readNullableStrongBinder(),这个函数会call到unflatten_binder()

    status_t unflatten_binder(const sp<ProcessState>& proc,
        const Parcel& in, sp<IBinder>* out)
    {
        const flat_binder_object* flat = in.readObject<flat_binder_object>();
    
        if (flat) {
            switch (flat->hdr.type) {
                case BINDER_TYPE_BINDER:
                    *out = reinterpret_cast<IBinder*>(flat->cookie);
                    return finish_unflatten_binder(NULL, *flat, in);
                case BINDER_TYPE_HANDLE:
                    *out = proc->getStrongProxyForHandle(flat->handle);
                    return finish_unflatten_binder(
                        static_cast<BpHwBinder*>(out->get()), *flat, in);
            }
        }
        return BAD_TYPE;
    }

    注意这时type是BINDER_TYPE_HANDLE。那为什么之前flatten_binder时,设置的type为BINDER_TYPE_BINDER,而这里却变成了BINDER_TYPE_HANDLE?这是因为在binder driver里将这个type改为了BINDER_TYPE_HANDLE:

    drivers/staging/android/binder.c

    static void binder_transaction(struct binder_proc *proc,
                       struct binder_thread *thread,
                       struct binder_transaction_data *tr, int reply)
    {
                if (fp->type == BINDER_TYPE_BINDER)
                    fp->type = BINDER_TYPE_HANDLE;
                else
                    fp->type = BINDER_TYPE_WEAK_HANDLE;
                fp->handle = ref->desc;

    上面的ref->desc被设置的地方如下,这个desc看起来是依次加1的:

    static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
                              struct binder_node *node)
    {
        new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1;
        for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
            ref = rb_entry(n, struct binder_ref, rb_node_desc);
            if (ref->desc > new_ref->desc)
                break;
            new_ref->desc = ref->desc + 1;
        }

    getStrongProxyForHandle(),这个函数的参数handle在binder driver里被赋值为desc。然后会根据handle创建一个BpHwBinder对象。

    system/libhwbinder/ProcessState.cpp

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

    BnHwServcieManager::_hidl_add()函数接下来会call fromBinder(),在这个函数中,binderIface->localBinder()会return false,原因是binderIface是BpHwBinder,而BpHwBinder没有override IBinder的localBinder(),而IBinder的localBinder()会返回null。

    所以这里会new一个ProxyType对象,即new一个BpHwBase对象

    system/libhidl/transport/include/hidl/HidlBinderSupport.h

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

    BnHwServcieManager::_hidl_add()函数接下来就是call add(),即为Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service),它定义在如下文件里:

    system/hwservicemanager/ServiceManger.cpp

    至此,registerAsService() flow走完。

  • 相关阅读:
    pat00-自测5. Shuffling Machine (20)
    Spiral Matrix
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Best Time to Buy and Sell Stock II
    4Sum
    3Sum Closest
    3Sum
    MySQL存储过程、函数和游标
    Word Ladder
  • 原文地址:https://www.cnblogs.com/aspirs/p/11558580.html
Copyright © 2011-2022 走看看