02.HIDL绑定式和直通式区别

Android P HIDL服务绑定模式与直通模式的分析

HIDL绑定式和直通式区别

以前Adnroid版本的hal和framwork的代码紧密联系起来的,Google为了framework升级的方便在Android 8.0 上对 Android 操作系统底层进行了重新架构。

新的架构已经了解一部分,但仍需要不断学习,加上最近需要将一些项目升级到Android O,所以决定该好好看看了,阅读代码过程中发现存在一种后缀为.hal的文件,该文件改变了我的一些久的思想。

该文件具体的作用和语法后续博文再介绍。

目前HAL分为下面4类,具体可以参考下面链接提供,那里写的最详细,这里只记录下我自己的理解。

客户端通过 getService() 来获取服务端,而 getService() 是每个 .hal 文件在自动生成源码时,都会自动添加的函数

getService 主要是根据参数 getStub 的值来决定采用哪种方式获取服务端:

/system/libhidl/transport/ServiceManagement.cpp

getRawServiceInternal(const std::string& descriptor, const std::string& instance, bool retry, bool getStub) {

 ->sp<IServiceManager1_1> sm;

 ->sm = defaultServiceManager1_1();  // 获取绑定式 IServiceManager

 ->for (int tries = 0; !getStub && (vintfHwbinder || vintfLegacy); tries++) {  //getStub为false时,通过defaultServiceManager1_1获取服务端,即绑定式

  ->Return<sp<IBase>> ret = sm->get(descriptor, instance);  // 通过绑定式 IServiceManager 获取服务端

  ->sp<IBase> base = ret;

  ->if (base != nullptr) {

   return base; // still needs to be wrapped by Bp class.

 ->if (getStub || vintfPassthru || vintfLegacy) {  //getStub为true时,通过getPassthroughServiceManager获取服务端,即直通式

  ->const sp<IServiceManager1_0> pm = getPassthroughServiceManager(); // 获取直通式 IServiceManager

        if (pm != nullptr) {

            sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr); // 通过直通式 IServiceManager 获取服务端

            if (!getStub || trebleTestingOverride) {  // 直通模式中如果 getStub 为 false,返回的是 wrapPassthrough

                base = wrapPassthrough(base);

            }

            return base;

1.绑定式 HAL:这个完全由hidl语言描述,由hidl-gen工具自动生成的hal。此模式下framwework和hal通过进程间binder通信。(camera相关的是/dev/hwbinder节点)。

Android 8.0 或后续版本的设备都必须只支持绑定式 HAL。

2.直通式HAL:这个是由hidl 封装的hal,具体是在hidl封装处dlopen传统的hal(目前8.0上Camera是这种形式)大概形如如下面这个。

下面右侧三个子部分都是在同一个进程中。封装层dlopen传统的hal(在同一个进程),这样就不用更改太多代码。 

直通模式与绑定模式最大的区别就是直通模式没有一个独立运行的服务进程,而绑定模式是作为一个独立运行的服务相当于Deamon进程在运行。

直通模式是将android 8.0之前的版本的module 封装起来,供System以上的服务进行调用, 上层直接调用 HIDL_FETCH_XXX 来调用此接口的。

/system/libhidl/transport/include/hidl/LegacySupport.h

defaultPassthroughServiceImplementation

 ->registerPassthroughServiceImplementation<Interface, ExpectInterface>(name);  /system/libhidl/transport/LegacySupport.cpp

  ->details::registerPassthroughServiceImplementation(interfaceName, expectInterfaceName,[](const sp<IBase>& service, const std::string& name) {...}

   ->sp<IBase> service = getRawServiceInternal(interfaceName, serviceName, true /*retry*/, true /*getStub*/);  // 直通式加载服务端

  ->details::registerAsServiceInternal(service, name);  // 向 hwservicemanager 注册服务

 ->joinRpcThreadpool();  //该函数实际上等同于thread->join(),并且binder线程是在死循环中轮询client是否发送消息过来的,所以并不会返回,正常情况下server也就不会退出。

3.Same-Process HAL:如它名字所示,是在使用它们的进程中打开的HAL,同一进程这里就不需要binder通信了。

4.传统 HAL 和旧版 HAL:目前我的理解是实现HAL_MODULE_INFO_SYM的hal,google给出下面的解释.

传统 HAL(在 Android 8.0 中已弃用)是指与具有特定名称及版本号的应用二进制接口 (ABI) 标准相符的接口。

大部分 Android 系统接口(相机、音频和传感器等)都采用传统 HAL 形式(已在 hardware/libhardware/include/hardware 下进行定义)。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值