摘要:本节主要来讲解Android10.0 Native层HIDL服务的获取原理

阅读本文大约需要花费23分钟。

文章首发微信公众号:IngresGe

专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢!

欢迎关注我的公众号!

[Android取经之路] 的源码都基于Android-Q(10.0) 进行分析

[Android取经之路] 系列文章:

《系统启动篇》

  1. Android系统架构
  2. Android是怎么启动的
  3. Android 10.0系统启动之init进程
  4. Android10.0系统启动之Zygote进程
  5. Android 10.0 系统启动之SystemServer进程
  6. Android 10.0 系统服务之ActivityMnagerService
  7. Android10.0系统启动之Launcher(桌面)启动流程
  8. Android10.0应用进程创建过程以及Zygote的fork流程
  9. Android 10.0 PackageManagerService(一)工作原理及启动流程
  10. Android 10.0 PackageManagerService(二)权限扫描
  11. Android 10.0 PackageManagerService(三)APK扫描
  12. Android 10.0 PackageManagerService(四)APK安装流程

《日志系统篇》

  1. Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性
  2. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化
  3. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析
  4. Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​

《Binder通信原理》

  1. Android10.0 Binder通信原理(一)Binder、HwBinder、VndBinder概要
  2. Android10.0 Binder通信原理(二)-Binder入门篇
  3. Android10.0 Binder通信原理(三)-ServiceManager篇
  4. Android10.0 Binder通信原理(四)-Native-C\C++实例分析
  5. Android10.0 Binder通信原理(五)-Binder驱动分析
  6. Android10.0 Binder通信原理(六)-Binder数据如何完成定向打击
  7. Android10.0 Binder通信原理(七)-Framework binder示例
  8. Android10.0 Binder通信原理(八)-Framework层分析
  9. Android10.0 Binder通信原理(九)-AIDL Binder示例
  10. Android10.0 Binder通信原理(十)-AIDL原理分析-Proxy-Stub设计模式
  11. Android10.0 Binder通信原理(十一)-Binder总结

  《HwBinder通信原理》

  1. HwBinder入门篇-Android10.0 HwBinder通信原理(一)
  2. HIDL详解-Android10.0 HwBinder通信原理(二)
  3. HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)
  4. HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)
  5. HwServiceManager篇-Android10.0 HwBinder通信原理(五)
  6. Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)
  7. Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)
  8. JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)
  9. JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)
  10. HwBinder驱动篇-Android10.0 HwBinder通信原理(十)
  11. HwBinder原理总结-Android10.0 HwBinder通信原理(十一)

《编译原理》

  1. 编译系统入门篇-Android10.0编译系统(一)
  2. 编译环境初始化-Android10.0编译系统(二)
  3. make编译过程-Android10.0编译系统(三)
  4. Image打包流程-Android10.0编译系统(四)
  5. Kati详解-Android10.0编译系统(五)

上一节,我们学习了Native层 HIDL服务的注册原理,这一节我们来看看Native层HIDL服务的获取流程。

5.IDemo的服务获取

IDemo的HIDL服务获取流程如下图所示:

5.1调用栈如下

5.2 main

[\vendor\ingres\hal_demo\cpp\hal_demo_test.cpp]
int main() {//1.获取IDemo这个HIDL服务的代理对象android::sp<IDemo> service = IDemo::getService();if(service == nullptr) {printf("Failed to get service\n");return -1;}//2.调用服务的HIDL接口 getHelloString()service->getHelloString("IngresGe", [&](hidl_string result) {printf("%s\n", result.c_str());});return 0;
}

主要分两步:

1.获取IDemo这个HIDL服务的代理对象

2.调用服务的HIDL接口 getHelloString()

5.3 getService()

[/out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo@1.0_genc++/gen/vendor/ingres/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的调用栈如下:

根据上面的调用栈,最终进入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) {using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;using ::android::hidl::manager::V1_0::IServiceManager;sp<Waiter> waiter;sp<IServiceManager1_1> sm;Transport transport = Transport::EMPTY;if (kIsRecovery) {transport = Transport::PASSTHROUGH;} else {//拿到HwServiceManager的对象,参考[5.4]sm = defaultServiceManager1_1();if (sm == nullptr) {ALOGE("getService: defaultServiceManager() is null");return nullptr;}//获取IDemo服务的transport,确认是直通式PASSTHROUGH,还是绑定式:HWBINDER//transport可以在/vendor/etc/vintf/manifest.xml中查看<transport>hwbinder</transport>Return<Transport> transportRet = sm->getTransport(descriptor, instance);if (!transportRet.isOk()) {ALOGE("getService: defaultServiceManager()->getTransport returns %s",transportRet.description().c_str());return nullptr;}transport = transportRet;}const bool vintfHwbinder = (transport == Transport::HWBINDER); //绑定式服务const bool vintfPassthru = (transport == Transport::PASSTHROUGH); //直通式服务...for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {if (waiter == nullptr && tries > 0) {waiter = new Waiter(descriptor, instance, sm);}if (waiter != nullptr) {waiter->reset();  // don't reorder this -- see comments on reset()}//如果是绑定式的服务,调用 BpHwServiceManager::get()Return<sp<IBase>> ret = sm->get(descriptor, instance);if (!ret.isOk()) {ALOGE("getService: defaultServiceManager()->get returns %s for %s/%s.",ret.description().c_str(), descriptor.c_str(), instance.c_str());break;}sp<IBase> base = ret;if (base != nullptr) {Return<bool> canCastRet =details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);if (canCastRet.isOk() && canCastRet) {if (waiter != nullptr) {waiter->done();}return base; // still needs to be wrapped by Bp class.}if (!handleCastError(canCastRet, descriptor, instance)) break;}// In case of legacy or we were not asked to retry, don't.if (vintfLegacy || !retry) break;if (waiter != nullptr) {ALOGI("getService: Trying again for %s/%s...", descriptor.c_str(), instance.c_str());waiter->wait(true /* timeout */);}}if (waiter != nullptr) {waiter->done();}if (getStub || vintfPassthru || vintfLegacy) {//如果是直通式的hidl服务,获取直通式的HwServiceManager对象来获取服务const sp<IServiceManager> pm = getPassthroughServiceManager();if (pm != nullptr) {sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);if (!getStub || trebleTestingOverride) {base = wrapPassthrough(base);}return base;}}return nullptr;
}

getRawServiceInternal()步骤如下:

1.获取HwServiceManager的代理对象

2.获取IDemo 这个hidl服务的transport,来确认是绑定式服务,还是直通式服务

3.根据transport类型,调用不同的接口来获取服务对象 (我们设计的IDemo是绑定式hidl服务)

5.4 defaultServiceManager1_1

[/system/libhidl/transport/ServiceManagement.cpp]
sp<IServiceManager1_1> defaultServiceManager1_1() {return defaultServiceManager1_2();
}[/system/libhidl/transport/ServiceManagement.cpp]
defaultServiceManager1_2()是用来拿到HwServiceManager的代理对象--BpHwServiceManager
sp<IServiceManager1_2> defaultServiceManager1_2() {using android::hidl::manager::V1_2::BnHwServiceManager;using android::hidl::manager::V1_2::BpHwServiceManager;static std::mutex gDefaultServiceManagerLock;static sp<IServiceManager1_2> gDefaultServiceManager;{std::lock_guard<std::mutex> _l(gDefaultServiceManagerLock);if (gDefaultServiceManager != nullptr) {return gDefaultServiceManager;}//1.检查hwbinder的节点是否存在,如果不存在说明不支持hwbinderif (access("/dev/hwbinder", F_OK|R_OK|W_OK) != 0) {// HwBinder not available on this device or not accessible to// this process.return nullptr;}//2.等待属性"hwservicemanager.ready" 变为true,表明hwservicemanager已经启动好waitForHwServiceManager();while (gDefaultServiceManager == nullptr) {//3.拿到HwServiceManager的代理对象gDefaultServiceManager =fromBinder<IServiceManager1_2, BpHwServiceManager, BnHwServiceManager>(ProcessState::self()->getContextObject(nullptr));if (gDefaultServiceManager == nullptr) {LOG(ERROR) << "Waited for hwservicemanager, but got nullptr.";sleep(1);}}}return gDefaultServiceManager;
}

5.4.1 BpHwBinder::transact()

[/system/libhwbinder/BpHwBinder.cpp]
status_t BpHwBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags, TransactCallback /*callback*/)
{// Once a binder has died, it will never come back to life.if (mAlive) {//拿到IPCThreadState的对象,调用transact()执行status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);if (status == DEAD_OBJECT) mAlive = 0;return status;}return DEAD_OBJECT;
}

BpBinder::transact()就是调用IPCThreadState::self()->transact() 进行处理

根据如下调用栈所示,BpHwBinder::transact()最终会转到BnHwServiceManager::_hidl_get(),实现流程和注册服务类似,相关源码分析参考上一节《Native层HIDL服务的注册原理》的[4.7.1] - [4.8]

5.5 BnHwServiceManager::_hidl_get()

[/out/soong/.intermediates/system/libhidl/transport/manager/1.2/android.hidl.manager@1.2_genc++/gen/android/hidl/manager/1.2/ServiceManagerAll.cpp]
::android::status_t BnHwServiceManager::_hidl_get(::android::hidl::base::V1_0::BnHwBase* _hidl_this,const ::android::hardware::Parcel &_hidl_data,::android::hardware::Parcel *_hidl_reply,TransactCallback _hidl_cb) {...::android::status_t _hidl_err = ::android::OK;if (!_hidl_data.enforceInterface(BnHwServiceManager::Pure::descriptor)) {_hidl_err = ::android::BAD_TYPE;return _hidl_err;}const ::android::hardware::hidl_string* fqName;const ::android::hardware::hidl_string* name;size_t _hidl_fqName_parent;//1.获取hidl服务的fqName_hidl_err = _hidl_data.readBuffer(sizeof(*fqName), &_hidl_fqName_parent,  reinterpret_cast<const void **>(&fqName));if (_hidl_err != ::android::OK) { return _hidl_err; }_hidl_err = ::android::hardware::readEmbeddedFromParcel(const_cast<::android::hardware::hidl_string &>(*fqName),_hidl_data,_hidl_fqName_parent,0 /* parentOffset */);if (_hidl_err != ::android::OK) { return _hidl_err; }size_t _hidl_name_parent;//2.获取hidl服务的name_hidl_err = _hidl_data.readBuffer(sizeof(*name), &_hidl_name_parent,  reinterpret_cast<const void **>(&name));if (_hidl_err != ::android::OK) { return _hidl_err; }_hidl_err = ::android::hardware::readEmbeddedFromParcel(const_cast<::android::hardware::hidl_string &>(*name),_hidl_data,_hidl_name_parent,0 /* parentOffset */);if (_hidl_err != ::android::OK) { return _hidl_err; }atrace_begin(ATRACE_TAG_HAL, "HIDL::IServiceManager::get::server");...//3.根据hidl服务的fqName和name,从HwServiceManager的hidl service的map中拿到服务对象::android::sp<::android::hidl::base::V1_0::IBase> _hidl_out_service = static_cast<IServiceManager*>(_hidl_this->getImpl().get())->get(*fqName, *name);//4.把reply信息写入Parcel::android::hardware::writeToParcel(::android::hardware::Status::ok(), _hidl_reply);if (_hidl_out_service == nullptr) {_hidl_err = _hidl_reply->writeStrongBinder(nullptr);} else {//5.把获取的hidl服务转成IBinder对象::android::sp<::android::hardware::IBinder> _hidl_binder = ::android::hardware::getOrCreateCachedBinder(_hidl_out_service.get());if (_hidl_binder.get() != nullptr) {//6.把转换后的IBinder对象,写入reply的Parcel数据中_hidl_err = _hidl_reply->writeStrongBinder(_hidl_binder);} else {_hidl_err = ::android::UNKNOWN_ERROR;}}/* _hidl_err ignored! */atrace_end(ATRACE_TAG_HAL);..//7.通过回调,把reply的Parcel数据给发给client_hidl_cb(*_hidl_reply);return _hidl_err;
}

_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()

[/system/hwservicemanager/ServiceManager.cpp]
Return<sp<IBase>> ServiceManager::get(const hidl_string& hidlFqName,const hidl_string& hidlName) {const std::string fqName = hidlFqName;const std::string name = hidlName;if (!mAcl.canGet(fqName, getBinderCallingContext())) {return nullptr;}//1.根据fqName和name找到对应的hidlServiceHidlService* hidlService = lookup(fqName, name);if (hidlService == nullptr) {tryStartService(fqName, name);return nullptr;}//2.根据hidlService 拿到IBase的对象sp<IBase> service = hidlService->getService();if (service == nullptr) {tryStartService(fqName, name);return nullptr;}hidlService->guaranteeClient();hardware::addPostCommandTask([hidlService] {hidlService->handleClientCallbacks(false /* isCalledOnInterval */);});return service;
}

5.7.3 ServiceManager::lookup()

主要是根据fqName和name从 HwServiceManager的服务map:mServiceMap 中找到对应的hidlservice。

[/system/hwservicemanager/ServiceManager.cpp]
HidlService* ServiceManager::lookup(const std::string& fqName, const std::string& name) {//1.根据fqName从 mServiceMap 中 找到一个节点auto ifaceIt = mServiceMap.find(fqName);if (ifaceIt == mServiceMap.end()) {return nullptr;}//2.从找到的map节点中,拿到PackageInterfaceMap的内容PackageInterfaceMap &ifaceMap = ifaceIt->second;//3.从PackageInterfaceMap中根据name找到hidlServiceHidlService *hidlService = ifaceMap.lookup(name);return hidlService;
}

5.5.2 HidlService::getService()

获取HidlService对象的mService

[/system/hwservicemanager/HidlService.cpp]
sp<IBase> HidlService::getService() const {return mService;
}

6. 协议码的转换流程

Binder通信协议是基于Command-Reply的方式的。

7.IDemo Client\Server交互流程

在IDemo的服务注册和获取的过程中,IDemo的服务和Client都是作为Client端,HwServiceManager作为Server端。

在IDemo的服务和client调用过程中,IDemo的服务为Server端,Client为客户端。

8.代码路径

/system/libhwbinder/BpHwBinder.cpp
/system/libhwbinder/IPCThreadState.cpp
/system/libhidl/transport/ServiceManagement.cpp
/system/libhidl/transport/include/hidl/HidlTransportSupport.h
/vendor/ingres/hal_demo/cpp/hal_demo_test.cpp
/out/soong/.intermediates/vendor/ingres/interfaces/demo/1.0/vendor.ingres.demo@1.0_genc++/gen/vendor/ingres/demo/1.0/DemoAll.cpp
/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

Native层HIDL服务的获取原理-Android10.0 HwBinder通信原理(七)相关推荐

  1. JAVA层HIDL服务的获取原理-Android10.0 HwBinder通信原理(九)

    摘要:本节主要来讲解Android10.0 JAVA层HIDL服务的获取原理 阅读本文大约需要花费19分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的 ...

  2. Native层HIDL服务的注册原理-Android10.0 HwBinder通信原理(六)

    摘要:本节主要来讲解Android10.0 Native层HIDL服务的注册原理 阅读本文大约需要花费23分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Androi ...

  3. JAVA层HIDL服务的注册原理-Android10.0 HwBinder通信原理(八)

    摘要:本节主要来讲解Android10.0 JAVA层HIDL服务的注册原理 阅读本文大约需要花费22分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的 ...

  4. HIDL示例-JAVA服务创建-Client验证-Android10.0 HwBinder通信原理(四)

    摘要:本节主要来讲解Android10.0 JAVA层的HIDL服务创建和JAVA层的Client验证 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...

  5. HIDL示例-C++服务创建Client验证-Android10.0 HwBinder通信原理(三)

    摘要:本节主要来讲解Android10.0 Native层的HIDL服务创建和Native层的Client验证 阅读本文大约需要花费18分钟. 文章首发微信公众号:IngresGe 专注于Androi ...

  6. nacis服务注册原理_HwServiceManager篇Android10.0 HwBinder通信原理(五)

    阅读本文大约需要花费34分钟. 原创不易,如果您觉得有点用,希望可以随手转发或者点击右下角的 "在看".""分享"",拜谢! <And ...

  7. HwBinder原理总结-Android10.0 HwBinder通信原理(十一)

    摘要:本节主要来进行Android10.0 HwBinder的原理总结 阅读本文大约需要花费14分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...

  8. HwBinder驱动篇-Android10.0 HwBinder通信原理(十)

    摘要:本节主要来讲解Android10.0 HwBinder驱动的流程 阅读本文大约需要花费24分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...

  9. HwServiceManager篇-Android10.0 HwBinder通信原理(五)

    摘要:本节主要来讲解Android10.0 HwServiceManager的通信原理 阅读本文大约需要花费34分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,And ...

最新文章

  1. 表格布局实践中经验的一些总结
  2. java 子类重写父类的方法应注意的问题
  3. 重拾算法(3)——用458329个测试用例全面测试二叉树和线索二叉树的遍历算法
  4. 有关Location对象,及URL的解析
  5. go语言中变量的定义和使用
  6. 一站式金融云托管服务 都匀融通村镇银行系统成功上线运行
  7. P1541-乌龟棋【多维dp】
  8. cat命令详解_好程序员Python培训之详解eval好与坏
  9. 为什么开发移动端web不使用jQuery
  10. Java8 实战系列-05-lambda 类型推断
  11. excel熵值法计算权重_小技巧1:Excel进行熵值法计算权重,查收一下!
  12. java取拼音首字母_java取出汉字字符串的拼音首字母
  13. Sketch使用教程(四)
  14. [小技巧1]Word或WPS文献引用、交叉引用方括号编号
  15. 高防服务器的机房硬件防火墙类型和主要功能
  16. telnet登录交换机
  17. 中考体育项目满分标准(深圳、安徽、湖北)
  18. 已有一个排好序的数组,今输入一个数,要求按原来排序的规律将它插入数组中
  19. Android手写签名
  20. 表情识别(七)--面部表情识别阶段综述(2018.4)

热门文章

  1. E0144“const char *“ 类型的值不能用于初始化 “char *“ 类型的实体
  2. 「BATJ面试系列」并发编程
  3. Spring Boot 2.x整合Websocket(基于Spring Boot 2.x 前后端分离 iview admin vue 集成activiti工作流...
  4. nginx反向代理、负载均衡、动态请求
  5. 【源资讯 第37期】一个时代的终结 —— 再见, Flash !
  6. vmware克隆server2008R2造成SID冲突
  7. 硬链接和软链接使用,以及区别
  8. SAP 应用服务负载均衡的实现
  9. 类的内置方法__attr__介绍
  10. (转)linux基本变量学习:位置变量$0 、$1 shift轮替、本地变量、环境变量、特殊变量...