美文网首页ssc
HIDL模型分析

HIDL模型分析

作者: Little熊猫 | 来源:发表于2018-05-23 10:27 被阅读0次

    一 HIDL的结构体关系

    以 Light的HIDL为例,class之间的关系如下


    HIDL_0525.png

    二 client端

         if ((sLight == nullptr && !sLightInit) ||
                    (sLight != nullptr && !sLight->ping().isOk())) {
                // will return the hal if it exists the first time.
                sLight = ILight::getService();
                sLightInit = true;
    
                if (sLight == nullptr) {
                    ALOGE("Unable to get ILight interface.");
                }
            }
    
            return sLight;
        }
           sp<ILight> hal = LightHal::associate();
            Return<Status> ret = hal->setLight(type, state);
    
    
    // static
    ::android::sp<ILight> ILight::getService(const std::string &serviceName, const bool getStub) {
        return ::android::hardware::details::getServiceInternal<BpHwLight>(serviceName, true, getStub);
    }
    getRawServiceInternal {
        const sp<IServiceManager1_1> sm = defaultServiceManager1_1();
        if (sm == nullptr) {
            ALOGE("getService: defaultServiceManager() is null");
            return nullptr;
        }
    }
    
    

    sm 通过defaultServiceManager1_1 得到的是BpHwServiceManager,调用get得到ILight的server

    sp<IServiceManager1_1> defaultServiceManager1_1() {
        {
            AutoMutex _l(details::gDefaultServiceManagerLock);
            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;
            }
    
            waitForHwServiceManager();
    
            while (details::gDefaultServiceManager == nullptr) {
                details::gDefaultServiceManager =
                        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;
    
    

    在get Light的server中,如果server还未启动的话,调用tryStartService启动light server

    // 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;
    
        pid_t pid = IPCThreadState::self()->getCallingPid();
        if (!mAcl.canGet(fqName, pid)) {
            return nullptr;
        }
    
        auto ifaceIt = mServiceMap.find(fqName);
        if (ifaceIt == mServiceMap.end()) {
            tryStartService(fqName, hidlName);
            return nullptr;
        }
    
        const PackageInterfaceMap &ifaceMap = ifaceIt->second;
        const HidlService *hidlService = ifaceMap.lookup(name);
    
        if (hidlService == nullptr) {
            tryStartService(fqName, hidlName);
            return nullptr;
        }
    
        sp<IBase> service = hidlService->getService();
        if (service == nullptr) {
            tryStartService(fqName, hidlName);
            return nullptr;
        }
    
        return service;
    }
    

    通过getServiceInternal得到的是ILigt注意一点同server端的getService不同的是client端的getStub:false,而在server端是true,这样在 getRawServiceInternal处理流程就不一样,client端是通过hwservice拿到ILitht,而server端是使用openLibs打开-impl.so,得到ILight。client在getServiceInternal完成后拿到ILight,再new出一个BpHwLight

     return sp<IType>(new BpType(toBinder<IBase>(base)));
    

    client调用server的接口,比如light的setLight操作,通过HIDL传到server操作

    // Methods from ::android::hardware::light::V2_0::ILight follow.
    ::android::hardware::Return<::android::hardware::light::V2_0::Status> BpHwLight::setLight(::android::hardware::light::V2_0::Type type, const ::android::hardware::light::V2_0::LightState& state){
        ::android::hardware::Return<::android::hardware::light::V2_0::Status>  _hidl_out = ::android::hardware::light::V2_0::BpHwLight::_hidl_setLight(this, this, type, state);
    
        return _hidl_out;
    }
    ::android::hardware::Return<::android::hardware::light::V2_0::Status> BpHwLight::_hidl_setLight(::android::hardware::IInterface *_hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, ::android::hardware::light::V2_0::Type type, const ::android::hardware::light::V2_0::LightState& state) {
    
         _hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(1 /* setLight */, _hidl_data, &_hidl_reply);
        if (_hidl_err != ::android::OK) { goto _hidl_error; }
    
    }
    

    asBinder最后得到的是IBiner *remote
    sp<IBinder> IInterface::asBinder(const sp<IInterface>& iface)
    {
    if (iface == NULL) return NULL;
    return iface->onAsBinder();
    }
    frombinder是在client get service过程中由

        {
            ::android::sp<::android::hardware::IBinder> _hidl_binder;
            _hidl_err = _hidl_reply.readNullableStrongBinder(&_hidl_binder);
            if (_hidl_err != ::android::OK) { goto _hidl_error; }
    
            _hidl_out_service = ::android::hardware::fromBinder<::android::hidl::base::V1_0::IBase,::android::hidl::base::V1_0::BpHwBase,::android::hidl::base::V1_0::BnHwBase>(_hidl_binder);
        }
    

    readNullableStrongBinder 通过handle创建 BpHwBinder
    sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)

    b = new BpHwBinder(handle);

    最后通过 fromBinder创建BpHwBase(BpHwBinder),bpHwBase同BpHwLight一样继承同一父类

       _hidl_out_service = ::android::hardware::fromBinder<::android::hidl::base::V1_0::IBase,::android::hidl::base::V1_0::BpHwBase,::android::hidl::base::V1_0::BnHwBase>(_hidl_binder);
    
    struct BpHwBase : public ::android::hardware::BpInterface<IBase>, public ::android::hardware::details::HidlInstrumentor {
    
    struct BpHwLight : public ::android::hardware::BpInterface<ILight>, public ::android::hardware::details::HidlInstrumentor {
    IBase是ILight的基类
    
    

    在getServiceInternal内部得到Ibase也就是BpHwBase之后,在getServiceInternal经过转换

    sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
        if (base->isRemote()) {
            // getRawServiceInternal guarantees we get the proper class
            return sp<IType>(new BpType(toBinder<IBase>(base)));
        }
    

    这个过程中还有一个toBinder也就是将BpHwBinder

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

    asBinder其实就是调用remoteBinder,而remotebinder其实就是BpHwBinder

    BpHwBinder* BpHwBinder::remoteBinder()
    {
        return this;
    }
    

    return sp<IType>(new BpType(toBinder<IBase>(base))); == new BpHwLight(BpHwBinder)
    当bpHwLight调用HIDL通信是,通过asBinder将hidl_this(指向bpHwBinder)转换成对bpHwBinder->remote的调用,调用bpHwBinder->tranct
    _hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact(1 /* setLight */, _hidl_data, &_hidl_reply);
    client过程中有
    先fromBinder则是new出一个bpHwbase(bpHwBinder)
    通过toBinder 通过bpHwbase得到bpHwBinder给Iligt
    在ILigt调用hidl时asBinder 得到bpHwBinder对于client端toBinder是asBinder的封装

    三 server端

    server端开始的Interface::getService(name, true /* getStub */); ,只不过这里的getStub为true,加载ILight

    hardware/interfaces/light/2.0/default/service.cpp
    int main() {
        return defaultPassthroughServiceImplementation<ILight>();
    }
    
    template<class Interface>
    __attribute__((warn_unused_result))
    status_t defaultPassthroughServiceImplementation(std::string name,
                                                size_t maxThreads = 1) {
        configureRpcThreadpool(maxThreads, true);
        status_t result = registerPassthroughServiceImplementation<Interface>(name);
    
        if (result != OK) {
            return result;
        }
    
        joinRpcThreadpool();
        return 0;
    }
    template<class Interface>
    __attribute__((warn_unused_result))
    status_t registerPassthroughServiceImplementation(
            std::string name = "default") {
        sp<Interface> service = Interface::getService(name, true /* getStub */); //这部分同client相同,得到的是ILight
    
        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());
    
        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;
    }
    // static
    ::android::sp<ILight> ILight::getService(const std::string &serviceName, const bool getStub) {
        return ::android::hardware::details::getServiceInternal<BpHwLight>(serviceName, true, getStub);
    }
    

    拿到的这个service就是Light(Light继承ILight),这个ILight也被BnHwLight的hidl_impl所指向。当调用setLight时其实就转到Light的setLight
    service->registerAsService(name); 其实调用的是ILight::registerAsService,通过BpHwServiceManager::add 经HIDL到hwservice,在这个过程中ILigt的this被作为输入参数经toBinder转换成BnHwLight

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

    在ILight中有descriptor和getBnConstructorMap,这个就是在add service中的BpHwServiceManager::_hidl_add 中通过ILight new一个BnHwLight,在service->add时其实添加的是BnHwLight

    const char* ILight::descriptor("android.hardware.light@2.0::ILight");
    
    __attribute__((constructor)) static void static_constructor() {
        ::android::hardware::details::getBnConstructorMap().set(ILight::descriptor,
                [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {
                    return new BnHwLight(static_cast<ILight *>(iIntf));
                });
        
    

    在HIDL调用hwservice后,BnHwServiceManager::_hidl_add添加service的接口被调用,读出BnHwLight,转变成IBase作为service添加进去

    _hidl_err = _hidl_data.readNullableStrongBinder(&_hidl_binder); 
    
    ::android::hardware::fromBinder<::android::hidl::base::V1_0::IBase,::android::hidl::base::V1_0::BpHwBase,::android::hidl::base::V1_0::BnHwBase>(_hidl_binder);
    
    

    add调用最后就执行servicemanager的add接口

    下面是BnHwLight 操作setLight接口,其实调用的是impl中的HAL实现接口。

    ::android::status_t BnHwLight::_hidl_setLight(
            ::android::hidl::base::V1_0::BnHwBase* _hidl_this,
            const ::android::hardware::Parcel &_hidl_data,
            ::android::hardware::Parcel *_hidl_reply,
            TransactCallback _hidl_cb) {
    
    ::android::hardware::light::V2_0::Status _hidl_out_status = static_cast<ILight*>(_hidl_this->getImpl().get())->setLight(type, *state);
    
    
    HIDL_getservice.png
    ::android::status_t ILight::registerAsService(const std::string &serviceName) {
        ::android::hardware::details::onRegistration("android.hardware.light@2.0", "ILight", serviceName);
    
        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;
    }
    
    joinRpcThreadpool(); 流程如下:
    void IPCThreadState::joinThreadPool(bool isMain)
    {
            result = getAndExecuteCommand();
    
    status_t IPCThreadState::executeCommand(int32_t cmd)
    {
                        error = reinterpret_cast<BHwBinder*>(tr.cookie)->transact(tr.code, buffer,
                                &reply, tr.flags, reply_callback);
    

    三 hwserice

    hwservice负责管理hidl clinet与server之间的管理。
    system/hwservicemanager/service.cpp中

    int main() {
        configureRpcThreadpool(1, true /* callerWillJoin */);
    
        ServiceManager *manager = new ServiceManager();
    
        if (!manager->add(serviceName, manager)) {
            ALOGE("Failed to register hwservicemanager with itself.");
        }
    
        TokenManager *tokenManager = new TokenManager();
    
        if (!manager->add(serviceName, tokenManager)) {
            ALOGE("Failed to register ITokenManager with hwservicemanager.");
        }
    
        // Tell IPCThreadState we're the service manager
        sp<BnHwServiceManager> service = new BnHwServiceManager(manager);
        IPCThreadState::self()->setTheContextObject(service);
        // Then tell the kernel
        ProcessState::self()->becomeContextManager(nullptr, nullptr);
    
        int rc = property_set("hwservicemanager.ready", "true");
        if (rc) {
            ALOGE("Failed to set \"hwservicemanager.ready\" (error %d). "\
                  "HAL services will not start!\n", rc);
        }
    
        joinRpcThreadpool();
    
        return 0;
    }
    
    

    当client或者server需要使用hwservice时,主要有以下get add

    ::android::status_t BnHwServiceManager::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;
    
        switch (_hidl_code) {
            case 1 /* get */:
            {
                bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
                if (_hidl_is_oneway != false) {
                    return ::android::UNKNOWN_ERROR;
                }
    
                _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_get(this, _hidl_data, _hidl_reply, _hidl_cb);
                break;
            }
    
            case 2 /* add */:
            {
                bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
                if (_hidl_is_oneway != false) {
                    return ::android::UNKNOWN_ERROR;
                }
    
                _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_add(this, _hidl_data, _hidl_reply, _hidl_cb);
                break;
            }
    
            case 3 /* getTransport */:
            {
                bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
                if (_hidl_is_oneway != false) {
                    return ::android::UNKNOWN_ERROR;
                }
    
                _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_getTransport(this, _hidl_data, _hidl_reply, _hidl_cb);
                break;
            }
    
            case 4 /* list */:
            {
                bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
                if (_hidl_is_oneway != false) {
                    return ::android::UNKNOWN_ERROR;
                }
    
                _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_list(this, _hidl_data, _hidl_reply, _hidl_cb);
                break;
            }
    
            case 5 /* listByInterface */:
            {
                bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
                if (_hidl_is_oneway != false) {
                    return ::android::UNKNOWN_ERROR;
                }
    
                _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_listByInterface(this, _hidl_data, _hidl_reply, _hidl_cb);
                break;
            }
    
            case 6 /* registerForNotifications */:
            {
                bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
                if (_hidl_is_oneway != false) {
                    return ::android::UNKNOWN_ERROR;
                }
    
                _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_registerForNotifications(this, _hidl_data, _hidl_reply, _hidl_cb);
                break;
            }
    
            case 7 /* debugDump */:
            {
                bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
                if (_hidl_is_oneway != false) {
                    return ::android::UNKNOWN_ERROR;
                }
    
                _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_debugDump(this, _hidl_data, _hidl_reply, _hidl_cb);
                break;
            }
    
            case 8 /* registerPassthroughClient */:
            {
                bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
                if (_hidl_is_oneway != false) {
                    return ::android::UNKNOWN_ERROR;
                }
    
                _hidl_err = ::android::hidl::manager::V1_0::BnHwServiceManager::_hidl_registerPassthroughClient(this, _hidl_data, _hidl_reply, _hidl_cb);
                break;
            }
    
            case 9 /* unregisterForNotifications */:
            {
                bool _hidl_is_oneway = _hidl_flags & 1 /* oneway */;
                if (_hidl_is_oneway != false) {
                    return ::android::UNKNOWN_ERROR;
                }
    
                _hidl_err = ::android::hidl::manager::V1_1::BnHwServiceManager::_hidl_unregisterForNotifications(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;
    }
    

    相关文章

      网友评论

        本文标题:HIDL模型分析

        本文链接:https://www.haomeiwen.com/subject/zkaljftx.html