hidl 原理分析_HIDL模型分析

本文详细剖析了HIDL(硬件接口描述语言)的工作原理,从client端的ILight服务获取,到server端的注册与服务调用。通过HIDL,client通过BpHwLight与远程服务进行交互,server端则通过BnHwLight实现接口。讲解了从getRawServiceInternal、defaultServiceManager1_1到BpHwBinder和BnHwLight的角色转换,揭示了Android系统中硬件服务的通信机制。
摘要由CSDN通过智能技术生成

一 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 hal = LightHal::associate();

Return ret = hal->setLight(type, state);

// static

::android::sp ILight::getService(const std::string &serviceName, const bool getStub) {

return ::android::hardware::details::getServiceInternal(serviceName, true, getStub);

}

getRawServiceInternal {

const sp sm = defaultServiceManager1_1();

if (sm == nullptr) {

ALOGE("getService: defaultServiceManager() is null");

return nullptr;

}

}

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

sp 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(

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> 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 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(new BpType(toBinder(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 IInterface::asBinder(const sp& 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>(_hidl_binder);

}

readNullableStrongBinder 通过handle创建 BpHwBinder

sp 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>(_hidl_binder);

struct BpHwBase : public ::android::hardware::BpInterface, public ::android::hardware::details::HidlInstrumentor {

struct BpHwLight : public ::android::hardware::BpInterface, public ::android::hardware::details::HidlInstrumentor {

IBase是ILight的基类

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

sp base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);

if (base->isRemote()) {

// getRawServiceInternal guarantees we get the proper class

return sp(new BpType(toBinder(base)));

}

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

sp toBinder(sp iface) {

IType *ifacePtr = iface.get();

if (ifacePtr == nullptr) {

return nullptr;

}

if (ifacePtr->isRemote()) {

return ::android::hardware::IInterface::asBinder(

static_cast*>(ifacePtr));

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

BpHwBinder* BpHwBinder::remoteBinder()

{

return this;

}

return sp(new BpType(toBinder(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();

}

template

__attribute__((warn_unused_result))

status_t defaultPassthroughServiceImplementation(std::string name,

size_t maxThreads = 1) {

configureRpcThreadpool(maxThreads, true);

status_t result = registerPassthroughServiceImplementation(name);

if (result != OK) {

return result;

}

joinRpcThreadpool();

return 0;

}

template

__attribute__((warn_unused_result))

status_t registerPassthroughServiceImplementation(

std::string name = "default") {

sp 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::getService(const std::string &serviceName, const bool getStub) {

return ::android::hardware::details::getServiceInternal(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(func(static_cast(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(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>(_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(_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 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(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 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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值