ssc

HIDL模型分析

2018-05-23  本文已影响0人  Little熊猫

一 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;
}
上一篇下一篇

猜你喜欢

热点阅读