一 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;
}
网友评论