摘要:本节主要来讲解Android10.0 Native层HIDL服务的获取原理
阅读本文大约需要花费23分钟。
文章首发微信公众号:IngresGe
专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!
[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析
[Android取经之路] 系列文章:
《系统启动篇》
- Android系统架构
- Android是怎么启动的
- Android 10.0系统启动之init进程
- Android10.0系统启动之Zygote进程
- Android 10.0 系统启动之SystemServer进程
- Android 10.0 系统服务之ActivityMnagerService
- Android10.0系统启动之Launcher(桌面)启动流程
- Android10.0应用进程创建过程以及Zygote的fork流程
- Android 10.0 PackageManagerService(一)工作原理及启动流程
- Android 10.0 PackageManagerService(二)权限扫描
- Android 10.0 PackageManagerService(三)APK扫描
- Android 10.0 PackageManagerService(四)APK安装流程
《日志系统篇》
- Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
- Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
- Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
- Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现
《Binder通信原理》****:
- Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
- Android10.0 Binder通信原理(二)-Binder入门篇
- Android10.0 Binder通信原理(三)-ServiceManager篇
- Android10.0 Binder通信原理(四)-Native-C\C++实例分析
- Android10.0 Binder通信原理(五)-Binder驱动分析
- Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
- Android10.0 Binder通信原理(七)-Framework binder示例
- Android10.0 Binder通信原理(八)-Framework层分析
- Android10.0 Binder通信原理(九)-AIDL Binder示例
- Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
- Android10.0 Binder通信原理(十一)-Binder总结
《HwBinder通信原理》
- HwBinder入门篇-Android10.0 HwBinder通信原理(一)
- HIDL详解-Android10.0 HwBinder通信原理(二)
- HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
- HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
- HwServiceManager篇-Android10.0 HwBinder通信原理(五)
- Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
- Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
- JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
上一节,我们学习了Native层 HIDL服务的注册原理,这一节我们来看看Native层HIDL服务的获取流程。
5.IDemo的服务获取
IDemo的HIDL服务获取流程如下图所示:

5.1调用栈如下

5.2 main
1[\vendor\ingres\hal_demo\cpp\hal_demo_test.cpp] 2int main() { 3 //1.获取IDemo这个HIDL服务的代理对象 4 android::sp<IDemo> service = IDemo::getService(); 5 6 if(service == nullptr) { 7 printf("Failed to get service\n"); 8 return -1; 9 } 10 //2.调用服务的HIDL接口 getHelloString() 11 service->getHelloString("IngresGe", [&](hidl_string result) { 12 printf("%s\n", result.c_str()); 13 }); 14 15 return 0; 16}
主要分两步:
1.获取IDemo这个HIDL服务的代理对象
2.调用服务的HIDL接口 getHelloString()
5.3 getService()
1[/out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo@1.0_genc++/gen/vendor/ingres/demo/1.0/DemoAll.cpp] 2::android::sp<IDemo> IDemo::getService(const std::string &serviceName, const bool getStub) { 3 return ::android::hardware::details::getServiceInternal<BpHwDemo>(serviceName, true, getStub); 4}
getService的调用栈如下:

根据上面的调用栈,最终进入getRawServiceInternal()
1[/system/libhidl/transport/ServiceManagement.cpp] 2sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor, 3 const std::string& instance, 4 bool retry, bool getStub) { 5 using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport; 6 using ::android::hidl::manager::V1_0::IServiceManager; 7 sp<Waiter> waiter; 8 9 sp<IServiceManager1_1> sm; 10 Transport transport = Transport::EMPTY; 11 if (kIsRecovery) { 12 transport = Transport::PASSTHROUGH; 13 } else { 14 //拿到HwServiceManager的对象,参考[5.4] 15 sm = defaultServiceManager1_1(); 16 if (sm == nullptr) { 17 ALOGE("getService: defaultServiceManager() is null"); 18 return nullptr; 19 } 20 //获取IDemo服务的transport,确认是直通式PASSTHROUGH,还是绑定式:HWBINDER 21 //transport可以在/vendor/etc/vintf/manifest.xml中查看<transport>hwbinder</transport> 22 Return<Transport> transportRet = sm->getTransport(descriptor, instance); 23 24 if (!transportRet.isOk()) { 25 ALOGE("getService: defaultServiceManager()->getTransport returns %s", 26 transportRet.description().c_str()); 27 return nullptr; 28 } 29 transport = transportRet; 30 } 31 32 const bool vintfHwbinder = (transport == Transport::HWBINDER); //绑定式服务 33 const bool vintfPassthru = (transport == Transport::PASSTHROUGH); //直通式服务 34 ... 35 36 for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) { 37 if (waiter == nullptr && tries > 0) { 38 waiter = new Waiter(descriptor, instance, sm); 39 } 40 if (waiter != nullptr) { 41 waiter->reset(); // don't reorder this -- see comments on reset() 42 } 43 //如果是绑定式的服务,调用 BpHwServiceManager::get() 44 Return<sp<IBase>> ret = sm->get(descriptor, instance); 45 if (!ret.isOk()) { 46 ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.", 47 ret.description().c_str(), descriptor.c_str(), instance.c_str()); 48 break; 49 } 50 sp<IBase> base = ret; 51 if (base != nullptr) { 52 Return<bool> canCastRet = 53 details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */); 54 55 if (canCastRet.isOk() && canCastRet) { 56 if (waiter != nullptr) { 57 waiter->done(); 58 } 59 return base; // still needs to be wrapped by Bp class. 60 } 61 62 if (!handleCastError(canCastRet, descriptor, instance)) break; 63 } 64 65 // In case of legacy or we were not asked to retry, don't. 66 if (vintfLegacy || !retry) break; 67 68 if (waiter != nullptr) { 69 ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str()); 70 waiter->wait(true /* timeout */); 71 } 72 } 73 74 if (waiter != nullptr) { 75 waiter->done(); 76 } 77 78 if (getStub || vintfPassthru || vintfLegacy) { 79 //如果是直通式的hidl服务,获取直通式的HwServiceManager对象来获取服务 80 const sp<IServiceManager> pm = getPassthroughServiceManager(); 81 if (pm != nullptr) { 82 sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr); 83 if (!getStub || trebleTestingOverride) { 84 base = wrapPassthrough(base); 85 } 86 return base; 87 } 88 } 89 return nullptr; 90}
getRawServiceInternal()步骤如下:
1.获取HwServiceManager的代理对象
2.获取IDemo 这个hidl服务的transport,来确认是绑定式服务,还是直通式服务
3.根据transport类型,调用不同的接口来获取服务对象 (我们设计的IDemo是绑定式hidl服务)
5.4 defaultServiceManager1_1
1[/system/libhidl/transport/ServiceManagement.cpp] 2sp<IServiceManager1_1> defaultServiceManager1_1() { 3 return defaultServiceManager1_2(); 4} 5 6[/system/libhidl/transport/ServiceManagement.cpp] 7defaultServiceManager1_2()是用来拿到HwServiceManager的代理对象--BpHwServiceManager 8sp<IServiceManager1_2> defaultServiceManager1_2() { 9 using android::hidl::manager::V1_2::BnHwServiceManager; 10 using android::hidl::manager::V1_2::BpHwServiceManager; 11 12 static std::mutex gDefaultServiceManagerLock; 13 static sp<IServiceManager1_2> gDefaultServiceManager; 14 15 { 16 std::lock_guard<std::mutex> _l(gDefaultServiceManagerLock); 17 if (gDefaultServiceManager != nullptr) { 18 return gDefaultServiceManager; 19 } 20 //1.检查hwbinder的节点是否存在,如果不存在说明不支持hwbinder 21 if (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) { 22 // HwBinder not available on this device or not accessible to 23 // this process. 24 return nullptr; 25 } 26 //2.等待属性"hwservicemanager.ready" 变为true,表明hwservicemanager已经启动好 27 waitForHwServiceManager(); 28 29 while (gDefaultServiceManager == nullptr) { 30 //3.拿到HwServiceManager的代理对象 31 gDefaultServiceManager = 32 fromBinder<IServiceManager1_2, BpHwServiceManager, BnHwServiceManager>( 33 ProcessState::self()->getContextObject(nullptr)); 34 if (gDefaultServiceManager == nullptr) { 35 LOG(ERROR) << "Waited for hwservicemanager, but got nullptr."; 36 sleep(1); 37 } 38 } 39 } 40 return gDefaultServiceManager; 41}
5.4.1 BpHwBinder::transact()
1[/system/libhwbinder/BpHwBinder.cpp] 2status_t BpHwBinder::transact( 3 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback /*callback*/) 4{ 5 // Once a binder has died, it will never come back to life. 6 if (mAlive) { 7 //拿到IPCThreadState的对象,调用transact()执行 8 status_t status = IPCThreadState::self()->transact( 9 mHandle, code, data, reply, flags); 10 if (status == DEAD_OBJECT) mAlive = 0; 11 return status; 12 } 13 14 return DEAD_OBJECT; 15}
BpBinder::transact()就是调用IPCThreadState::self()->transact() 进行处理
根据如下调用栈所示,BpHwBinder::transact()最终会转到BnHwServiceManager::_hidl_get(),实现流程和注册服务类似,相关源码分析参考上一节《Native层HIDL服务的注册原理》的[4.7.1] - [4.8]

5.5 BnHwServiceManager::_hidl_get()
1[/out/soong/.intermediates/system/libhidl/transport/manager/1.2/android.hidl.manager@1.2_genc++/gen/android/hidl/manager/1.2/ServiceManagerAll.cpp] 2::android::status_t BnHwServiceManager::_hidl_get( 3 ::android::hidl::base::V1_0::BnHwBase* _hidl_this, 4 const ::android::hardware::Parcel &_hidl_data, 5 ::android::hardware::Parcel *_hidl_reply, 6 TransactCallback _hidl_cb) { 7 8 ... 9 ::android::status_t _hidl_err = ::android::OK; 10 if (!_hidl_data.enforceInterface(BnHwServiceManager::Pure::descriptor)) { 11 _hidl_err = ::android::BAD_TYPE; 12 return _hidl_err; 13 } 14 15 const ::android::hardware::hidl_string* fqName; 16 const ::android::hardware::hidl_string* name; 17 18 size_t _hidl_fqName_parent; 19 20 //1.获取hidl服务的fqName 21 _hidl_err = _hidl_data.readBuffer(sizeof(*fqName), &_hidl_fqName_parent, reinterpret_cast<const void **>(&fqName)); 22 23 if (_hidl_err != ::android::OK) { return _hidl_err; } 24 25 _hidl_err = ::android::hardware::readEmbeddedFromParcel( 26 const_cast<::android::hardware::hidl_string &>(*fqName), 27 _hidl_data, 28 _hidl_fqName_parent, 29 0 /* parentOffset */); 30 31 if (_hidl_err != ::android::OK) { return _hidl_err; } 32 33 size_t _hidl_name_parent; 34 35 //2.获取hidl服务的name 36 _hidl_err = _hidl_data.readBuffer(sizeof(*name), &_hidl_name_parent, reinterpret_cast<const void **>(&name)); 37 38 if (_hidl_err != ::android::OK) { return _hidl_err; } 39 40 _hidl_err = ::android::hardware::readEmbeddedFromParcel( 41 const_cast<::android::hardware::hidl_string &>(*name), 42 _hidl_data, 43 _hidl_name_parent, 44 0 /* parentOffset */); 45 46 if (_hidl_err != ::android::OK) { return _hidl_err; } 47 48 atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::get::server"); 49 ... 50 //3.根据hidl服务的fqName和name,从HwServiceManager的hidl service的map中拿到服务对象 51 ::android::sp<::android::hidl::base::V1_0::IBase> _hidl_out_service = static_cast<IServiceManager*>(_hidl_this->getImpl().get())->get(*fqName, *name); 52 53 //4.把reply信息写入Parcel 54 ::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply); 55 56 if (_hidl_out_service == nullptr) { 57 _hidl_err = _hidl_reply->writeStrongBinder(nullptr); 58 } else { 59 //5.把获取的hidl服务转成IBinder对象 60 ::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::getOrCreateCachedBinder(_hidl_out_service.get()); 61 if (_hidl_binder.get() != nullptr) { 62 //6.把转换后的IBinder对象,写入reply的Parcel数据中 63 _hidl_err = _hidl_reply->writeStrongBinder(_hidl_binder); 64 } else { 65 _hidl_err = ::android::UNKNOWN_ERROR; 66 } 67 } 68 /* _hidl_err ignored! */ 69 70 atrace_end(ATRACE_TAG_HAL); 71 .. 72 //7.通过回调,把reply的Parcel数据给发给client 73 _hidl_cb(*_hidl_reply); 74 return _hidl_err; 75}
_hidl_get流程如下:
1.获取hidl服务的fqName
2.获取hidl服务的name
3.根据hidl服务的fqName和name,从HwServiceManager的hidl service的map中拿到服务对象
4.把reply信息写入Parcel
5.把获取的hidl服务转成IBinder对象
6.把转换后的IBinder对象,写入reply的Parcel数据中
7.通过回调,把reply的Parcel数据给发给client
5.5.1 ServiceManager::get()
1[/system/hwservicemanager/ServiceManager.cpp] 2Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName, 3 const hidl_string& hidlName) { 4 const std::string fqName = hidlFqName; 5 const std::string name = hidlName; 6 7 if (!mAcl.canGet(fqName, getBinderCallingContext())) { 8 return nullptr; 9 } 10 11 //1.根据fqName和name找到对应的hidlService 12 HidlService* hidlService = lookup(fqName, name); 13 if (hidlService == nullptr) { 14 tryStartService(fqName, name); 15 return nullptr; 16 } 17 18 //2.根据hidlService 拿到IBase的对象 19 sp<IBase> service = hidlService->getService(); 20 if (service == nullptr) { 21 tryStartService(fqName, name); 22 return nullptr; 23 } 24 25 hidlService->guaranteeClient(); 26 27 hardware::addPostCommandTask([hidlService] { 28 hidlService->handleClientCallbacks(false /* isCalledOnInterval */); 29 }); 30 return service; 31}
5.7.3 ServiceManager::lookup()
主要是根据fqName和name从 HwServiceManager的服务map:mServiceMap 中找到对应的hidlservice。
1[/system/hwservicemanager/ServiceManager.cpp] 2HidlService* ServiceManager::lookup(const std::string& fqName, const std::string& name) { 3 //1.根据fqName从 mServiceMap 中 找到一个节点 4 auto ifaceIt = mServiceMap.find(fqName); 5 if (ifaceIt == mServiceMap.end()) { 6 return nullptr; 7 } 8 //2.从找到的map节点中,拿到PackageInterfaceMap的内容 9 PackageInterfaceMap &ifaceMap = ifaceIt->second; 10 //3.从PackageInterfaceMap中根据name找到hidlService 11 HidlService *hidlService = ifaceMap.lookup(name); 12 return hidlService; 13}
5.5.2 HidlService::getService()
获取HidlService对象的mService

1[/system/hwservicemanager/HidlService.cpp] 2sp<IBase> HidlService::getService() const { 3 return mService; 4}
6. 协议码的转换流程
Binder通信协议是基于Command-Reply的方式的。

7.IDemo Client\Server交互流程
在IDemo的服务注册和获取的过程中,IDemo的服务和Client都是作为Client端,HwServiceManager作为Server端。
在IDemo的服务和client调用过程中,IDemo的服务为Server端,Client为客户端。

8.代码路径
1/system/libhwbinder/BpHwBinder.cpp 2/system/libhwbinder/IPCThreadState.cpp 3/system/libhidl/transport/ServiceManagement.cpp 4/system/libhidl/transport/include/hidl/HidlTransportSupport.h 5/vendor/ingres/hal_demo/cpp/hal_demo_test.cpp 6/out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo@1.0_genc++/gen/vendor/ingres/demo/1.0/DemoAll.cpp 7/out/soong/.intermediates/system/libhidl/transport/manager/1.2/android.hidl.manager@1.2_genc++/gen/android/hidl/manager/1.2/ServiceManagerAll.cpp
9. 总结
至此,Native层的HIDL服务注册和获取就梳理完了,主要就是进程和HwBinder驱动、HwServiceManager的交互流程,下一节我们再一起看看JAVA层的hidl服务注册和获取流程。
我的微信公众号:IngresGe
