从Android 8.0之后,Android 引入Treble机制,主要是为了解决目前Android 版本之间升级麻烦的问题,将OEM适配的部分vendor与google 对android  大框架升级的部分system部分做了分离,一旦适配了一个版本的vendor信息之后,之后的版本再进行升级时,直接升级system即可,这个就不会给OEM厂商升级带来太大的工作量,直接升级最新功能,可以解决目前市面上Android版本过来凌乱的问题。

首先Treble机制在Vendor分区中有两种模式,一个编译成so库,供System分区的进程和应用直接加载调用,两者在同一个进程中,这种叫直通式 HAL(passthrough)模式, 另外一种是直接编译成一个daemon可运行的服务,然后System分区的进程通过HwBinder的IPC通信方式来调用,两者在二个独立的进程中,这种称为绑定式HAL(Binderized)模式。

HIDL 初始化

Passthrough

extern "C" IMapper* HIDL_FETCH_IMapper(const char*name){returnCrallocLoader::load();

}

class GrallocLoader : public V2.0::passthrough::GrallocLoader {public:static IMapper*load(){const hw_module_t* module =loadModule();

auto hal=createHal(module);returncreateMapper(std::move(hal));

}

static const hw_module_t loadModule(){

const hw_module_t* module;

int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);

return module;

}

static std::unique_prt<:mapperhal> createHal(const hw_module_t* module){

auto hal = std::make_unique();

return hal->initWithModule(module) ? std::move(hal) : nullptr;

}

}

直通模式与 绑定模式最大的区别就是直通模式没有一个独立运行的服务进程,而绑定模式是作为一个独立运行的服务相当于Deamon进程在运行。直通模式是将android 8.0之前的版本的module 封装起来,供System以上的服务进行调用, 上层直接调用 HIDL_FETCH_XXX 来调用此接口的。

Binderized

绑定式可以用两种方式来绑定服务,第一种通过defaultPassthroughServiceImplementation 的调用来注册服务,另外一种是直接调用RegisterAsService来注册服务。

1. defaultPassthroughServiceImplementation

intmain{return defaultPassthroughServiceImplementation(4); //4表示与/dev/hwbinder通信的最大的线程数

}

这个函数的功能是创建默认的IDemo直通服务的实现方式。

1 status_t defaultPassthroughServiceImplementation(size_t maxThreads = 1){

2 configureRpcThreadpool(maxThreads, true);

3 status_t result = registerPassthroughServiceImplementation("default");

joinRpcThreadpool();

return UNKOWN_ERROR;

4 }

status_t registerPassthroughServiceImplementation(String name = "default"){

sp service = Interface::getService(name, true);

....

status_t status = service->registerAsService(name);

return status;

}

将IDemo 实例化一个对象出来, 然后将其与“default”为名称注册到一个服务上。那我们来看RegisterAsService,这个函数是使用hidl的工具生成的:

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){

::android::hardware::details::onRegistration("android.hardware.demo@1.0", "IDemo", serviceName);

const ::android::sp<::android::hidl::manager::v1_0::iservicemanager> sm = ::android::hardware::defaultServiceManager();

::android::hardware::Return ret = sm->add(serviceName.c_str(), this);

return ret.isOk() && ret ? ::android::OK :: android::UNKNOWN_ERROR;

}

这里就是将IDemo这个实例 通过IServicemanager的add 接口,添加到服务列表中, 到目前前止,就将defaultPassthroughServiceImplementation的服务注册过程完成了。

2. RegisterAsService

intmain(){

configureRpcThreadpool(4, true);

Demo mDemo= newDemo();

mDemo.registerAsService();

joinRpcThreadpool();return 1;

}

这里核心的也是registerAsService(), 此函数之前已经分析过了,就不重复解释了,就是注册一个服务到Service列表中。

HIDL的调用

上面已经说明了直通模式与绑定模式的初始化,现在我们来介绍下如何调用直通模式和绑定模式,两者调用的函数有没有什么区别呢? 答案是两者使用的调用接口是一样的,都是通过getService 来调用的。

IMapper mMapper = mapper::V2_0::IMapper::getService()

同样getService 也是HIDL的工具生成的函数执行的:

out/soong/.intermediates/hardware/interfaces/graphics/mapper/2.1/android.hardware.graphics.mapper@2.1_genc++/gen/android/hardware/graphics/mapper/2.1/MapperAll.cpp

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

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

}

sp getServiceInternal(const std::string & instance, bool retry, boolgetStub){

sp base = getRawServiceInternal(IType::descriptor, inst/ance, retyr, getStub);

.....

}

sp<::android::hidl::base::v1_0::ibase> getRawServiceInternal(const std::string&descriptor,const std::string&instance,bool retry, boolgetStub) {const sp sm =defaultServiceManager1_1();

....//绑定模式

const bool vintfHwbinder = (transport ==Transport::HWBINDER);//直通模式

const bool vintfPassthru = (transport ==Transport::PASSTHROUGH);

......//绑定模式

for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {

Return> ret = sm->get(descriptor, instance);

}//直通模式

if (getStub || vintfPassthru ||vintfLegacy) {const sp pm =getPassthroughServiceManager();

sp base = pm->get(descriptor, instance).withDefault(nullptr);

}

....

这里分成了二条路,绑定模式就直接通过IServiceManager->get的方法去获取,是不是觉得很熟悉,就和AIDL一个套路,通过BpBinder 和 BnBinder 直接对Binder驱动的操作来完成数据交换,但AIDL的binder驱动是/dev/binder, HIDL的hwbinder驱动是/dev/hwbinder,具体的我们就不去详细分析了。关于直通模式,先通过getPassthroughServiceManager ,获取IServiceManager的句柄,然后再get得到对应的服务。

spgetPassthroughServiceManager() {returngetPassthroughServiceManager1_1();

}

spgetPassthroughServiceManager1_1() {static sp manager(newPassthroughServiceManager());returnmanager;

}

这里相当于直接new了一个PassthroughServiceManager(), 之后再调用get 方法:

static voidopenLibs(const std::string&fqName,const std::function&eachLib) {

std::string packageAndVersion = fqName.substr(0, idx);

std::string ifaceName = fqName.substr(idx + strlen("::"));const std::string prefix = packageAndVersion + "-impl";

//HIDL_FETCH_XXX 出现了,就是passthrough模式下需要被调用的方法。const std::string sym = "HIDL_FETCH_" +ifaceName;

.....

std::vector<:string> paths ={HAL_LIBRARY_PATH_ODM, HAL_LIBRARY_PATH_VENDOR,

halLibPathVndkSp, HAL_LIBRARY_PATH_SYSTEM};

....for (const std::string&path : paths) {

std::vector<:string> libs = search(path, prefix, ".so");for (const std::string &lib : libs) {

//路径最后组装成/system 或者/vendor 下面的供调用的xxxxx-impl.soconst std::string fullPath = path +lib;if (path ==HAL_LIBRARY_PATH_SYSTEM) {

//这里就供dlopen了。

handle=dlopen(fullPath.c_str(), dlMode);

}else{

handle=android_load_sphal_library(fullPath.c_str(), dlMode);

}

.....

}

}

Return> get(const hidl_string&fqName,const hidl_string& name) override{

sp ret =nullptr;

openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {

IBase* (*generator)(const char*name);

//这里就会调用 到sym 也就是HIDL_FETCH_XXX ,然后通过dlsym 去链接调用了。*(void **)(&generator) =dlsym(handle, sym.c_str());

ret= (*generator)(name.c_str());

});returnret;

}

到这里就可以看到HIDL_FETCH_XXX的调用过程了。

Android属于绑定服务特点是,Android P HIDL服务绑定模式与直通模式的分析 (原创)相关推荐

  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. AndroidO Treble架构下HIDL服务查询过程

    通过前面的分析我们知道,Hal进程启动时,会向hwservicemanager进程注册hidl服务,那么当Framework Server需要通过hal访问硬件设备时,首先需要查询对应的hidl服务, ...

  5. android服务绑定音乐播放器,Android开发【04-21求助贴】使用后台服务的音乐播放器...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import android.Manifest; import android.content.pm.PackageManager; import and ...

  6. 如何检查服务是否在Android上运行?

    如何检查后台服务是否正在运行? 我想要一个可切换服务状态的Android活动-它可以让我在关闭状态下将其打开,在开启状态下将其关闭. #1楼 这更适用于Intent Service调试,因为它们会生成 ...

  7. Android绑定多个aidl,android aidl 多`module`版的实现

    多module版,pojo类型数据的双向传递 [service client] android中如何进行跨进程通信的? aidl是什么? android中如何通过aidl实现跨进程通信? 最简单的ai ...

  8. android 辅助服务 简书,Android AccessibilityService使用

    测试demo主要使用了Android 的无障碍辅助服务(AccessibilityService),主要注意是 1. 开启服务,绑定目标app的监听(demo中根据包命绑定了体积计算的app),需要在 ...

  9. android服务应用场景,Android Service的使用介绍

    简介 Service是Android应用程序中的一个组件,与用户不进行交互,可以长期的执行在后台.当新建一个服务的时候需要在AndroidManifest.xml文件中进行声明.服务可以通过Conte ...

最新文章

  1. Sublime Text 3 (含:配置 C# 编译环境)
  2. linux fedor 安装 gcc,fedora中如何安装gccsense
  3. 单系统站内信数据库设计思路
  4. 如何让hierarchyviewer调试查看商业版真机上的应用
  5. 工信部明确公共互联网网络安全突发事件分级预警、应急
  6. JAVA-初步认识-第三章-if语句练习-星期和季节
  7. WinCE6.0的批量编译
  8. centos使用git安装nvm
  9. Android应用开发——onStop的调用时机
  10. 红橙Darren视频笔记 面试题 为什么view获取宽高为0 onCreate onResume view.post源码浅析(继承activity api27)
  11. 【英语学习】【WOTD】grift 释义/词源/示例
  12. void符合c语言用户标识吗,1以下可用作C语言用户标识符的是()。void,define,.doc...
  13. C++基础——有关FILE的那些函数
  14. unity使用屏幕后处理实现闪烁特效,创建新的shader文件过程
  15. 制图利器—MapGIS10.5制图版体验
  16. STM32:FSMC驱动TFTLCD(ST7789)
  17. 谈医药行业网站的运营模式分析
  18. 在LR字符串中交换相邻字符
  19. TSP 问题的几种经典建模方式
  20. 如何在Windows 10中打印照片

热门文章

  1. 数据库中间件 MyCAT源码分析 —— XA分布式事务
  2. C/C++ 如何设计框架
  3. mysql之关联更新(update join,用b表更新a表记录)
  4. 一个游戏策划的八年回忆录
  5. 我读经典(5):读《大话重构》迷你书有感
  6. 花火之声不闻于耳 [线段树]
  7. 桃词典 Peach Dictionary 简易英语词典app开发 安卓软件开发 Part 5
  8. APP开发要么快要么死!
  9. Docker容器的数据卷(volumes)
  10. Kubernetes volumes简介