HwBinder与普通Binder是一样的,区别是前者是专门给硬件使用,后者是给一般的应用程序使用,为了不影响现有的binder,单独增加硬件的HwBinder来实现硬件相关进程的通信。
HwBinder也是有四部分组成:hwservermanager、server、client,driver,其中Driver部分与普通Binder是一样的,《Android图形显示系统》对Binder的原理进行过详细的介绍,这里主要介绍HwBinder与Binder不一样的地方。
服务管理进程
首先是服务管理进程由HwServiceManager服务,主要流程如下:
/* system/hwservicemanager/service.cpp */ int main() { ServiceManager *manager = new ServiceManager(); if (!manager->add(serviceName, manager)) {} TokenManager *tokenManager = new TokenManager(); if (!manager->add(serviceName, tokenManager)) {} sp<BnHwServiceManager> service = new BnHwServiceManager(manager); IPCThreadState::self()->setTheContextObject(service); ProcessState::self()->becomeContextManager(nullptr, nullptr); joinRpcThreadpool(); } |
HwServiceManager与ServiceManager不一样的地方是hwservicemanager有Binder节点,并把Binder节点通过setTheContextObject传给了驱动,并且使用IPCThreadState把主线程加入到线程池来循环处理请求。意味着HwServiceManager是支持并发访问的,可以同时处理多个请求,
服务进程
Server的开发比较简单,service.cpp的实现比较简单,如下所示。
int main() { return defaultPassthroughServiceImplementation<IDemo>(); } |
defaultPassthroughServiceImplementation的实现流程如下。
/* system\libhidl\transport\include\hidl\LegacySupport.h*/ template<class Interface> __attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation(size_t maxThreads = 1) { return defaultPassthroughServiceImplementation<Interface>("default", maxThreads); } 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); joinRpcThreadpool(); return UNKNOWN_ERROR; } template<class Interface> __attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation( std::string name = "default") { sp<Interface> service = Interface::getService(name, true /* getStub */); status_t status = service->registerAsService(name); return status; } |
最后调registerPassthroughServiceImplementation来注册服务,把Interface替换成IDemo得到以下。
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation( std::string name = "default") { sp<IDemo> service = IDemo::getService(name, true /* getStub */); status_t status = service->registerAsService(name); return status; } |
调用的是IDemo的接口getService得到IDemo节点,通过registerAsServie来添加到服务管理HwServiceManager。
IDemo::getService在DemoAll.cpp实现,该文件是自动生成的,路径如下
out/soong/.intermediates/hardware/interfaces/demo/1.0/android.hardware.demo@1.0_genc++/gen/android/hardware/demo/1.0/DemoAll.cpp ::android::sp<IDemo> IDemo::getService(const std::string &serviceName, const bool getStub) { return ::android::hardware::details::getServiceInternal<BpHwDemo>( serviceName, true, getStub); } |
getService主要通过getServiceInternal来实现,继续往下:
system\libhidl\transport\include\hidl\HidlTransportSupport.h template <typename BpType, typename IType = typename BpType::Pure, typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>, typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>> sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) { using ::android::hidl::base::V1_0::IBase; 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))); } return IType::castFrom(base); } |
system\libhidl\transport\ServiceManagement.cpp sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor, const std::string& instance, bool retry, bool getStub) { const sp<IServiceManager> pm = getPassthroughServiceManager(); sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr); return base; } sp<IServiceManager1_0> getPassthroughServiceManager() { return getPassthroughServiceManager1_1(); } sp<IServiceManager1_1> getPassthroughServiceManager1_1() { static sp<PassthroughServiceManager> manager(new PassthroughServiceManager()); return manager; } struct PassthroughServiceManager : IServiceManager1_1 { static void openLibs( const std::string& fqName, const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */, const std::string& /* sym */)>& eachLib) { const std::string sym = "HIDL_FETCH_" + ifaceName;/ } Return<sp<IBase>> get(const hidl_string& fqName, const hidl_string& name) override { sp<IBase> ret = nullptr; openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) { IBase* (*generator)(const char* name); *(void **)(&generator) = dlsym(handle, sym.c_str()); ret = (*generator)(name.c_str()); using ::android::hardware::details::getDescriptor; std::string actualFqName = getDescriptor(ret.get()); registerReference(actualFqName, name); }); return ret; } } |
最终通过遍历so加载得到符号HIDL_FETCH_IDemo,并调用得到Demo的对象,在Demo.h已经定义 extern "C" IDemo* HIDL_FETCH_IDemo(const char* name); 在函数前加extern “C”才能使用dlsym 加载到该方法的地址。
下一步Server通过registerAsService把Binder注册到ServiceManager的流程,实现还是在DemoAll.cpp里。
out/soong/.intermediates/hardware/interfaces/demo/1.0/android.hardware.demo@1.0_genc++/gen/android/hardware/demo/1.0/DemoAll.cpp ::android::status_t IDemo::registerAsService(const std::string &serviceName) { const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm = ::android::hardware::defaultServiceManager(); ::android::hardware::Return<bool> ret = sm->add(serviceName.c_str(), this); } |
这里也是通过defaultServiceManager找到ServiceManager的索引对象,然后调add接口来添加Demo的对象。
system/hwservicemanager/ServieManager.cpp Return<bool> ServiceManager::add(const hidl_string& name, const sp<IBase>& service) { auto ret = service->interfaceChain([&](const auto &interfaceChain) { for(size_t i = 0; i < interfaceChain.size(); i++) { const std::string fqName = interfaceChain[i]; PackageInterfaceMap &ifaceMap = mServiceMap[fqName]; HidlService *hidlService = ifaceMap.lookup(name); if (hidlService == nullptr) { ifaceMap.insertService( std::make_unique<HidlService>(fqName, name, service, pid)); } else { hidlService->setService(service, pid); } ifaceMap.sendPackageRegistrationNotification(fqName, name); } }); } |
在HwServiceManager注册Binder的时候,也是需要name的,不过是通过interfaceChain来获取Demo Binder对象的name。最后把结果保存到ifaceMap里,这里跟ServiceManager只保存Binder的handle也是不一样的。
Server注册服务后,Client进程可以查找到Server的binder对象,并调用相关的接口来向Server请求服务了
客户进程
接下来是客户进程的流程,
int main() { android::sp<IDemo> service = IDemo::getService(); service->sayHello("HIDL !!!", [&](hidl_string result) { printf("get from server %s\n", result.c_str()); }); return 0; } |
Client进程主要先调IDemo::getService来得到binder对象,并调其方法sayHello,把请求发给Server。
Client进程也通过getService获取Demo索引对象,跟Server进程获取到的Demo节点对象是不太一样的。
out/soong/.intermediates/hardware/interfaces/demo/1.0/android.hardware.demo@1.0_genc++_headers/gen/android/hardware/demo/1.0/IDemo.h struct IDemo : public ::android::hidl::base::V1_0::IBase { static ::android::sp<IDemo> getService(const std::string &serviceName="default", bool getStub=false); } |
Server进程的registerPassthroughServiceImplementation也使用过getService,只不过getStub为true,这里使用默认参数为false,主要是getRawServiceInternal有区别。
system\libhidl\transport\ServiceManagement.cpp sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor, const std::string& instance, bool retry, bool getStub) { const sp<IServiceManager1_1> sm = defaultServiceManager1_1(); for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) { Return<sp<IBase>> ret = sm->get(descriptor, instance); sp<IBase> base = ret; return base; } } |
getStub为false,会从ServiceManager来查找服务。
system/hwservicemanager/ServieManager.cpp Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName, const hidl_string& hidlName) { const std::string fqName = hidlFqName; const std::string name = hidlName; auto ifaceIt = mServiceMap.find(fqName); const PackageInterfaceMap &ifaceMap = ifaceIt->second; const HidlService *hidlService = ifaceMap.lookup(name); sp<IBase> service = hidlService->getService(); return service; } |
Client进程是从HwManager查询回来的索引对象。原理跟普通的binder一样。只不过这里封装的比普通的Binder要复杂。
上面结合一个简单的例子介绍了HIDL的用法,并解析了相关的代码,HIDL基于hwbinder进行进程间通信。