• 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走完。

  • 相关阅读:
    Node实践之二
    Node实践之一
    总结的JS数据类型判定(非常全面)
    利用chorme调试手机网页
    设计模式总结综述
    Python3标准库使用样例
    systemd 文档教程
    编写Postgres扩展之五:代码组织和版本控制
    编写Postgres扩展之三:调试
    编写Postgres扩展之四:测试
  • 原文地址:https://www.cnblogs.com/aspirs/p/11558580.html
Copyright © 2020-2023  润新知