`

Android Binder设计(三)

 
阅读更多
5.Binder 的表述
考察一次Binder通信的全过程会发现,Binder存在于系统以下几个部分中:
应用程序进程:又分为Server进程和Client进程
Binder驱动:Server和Client有不同表述形式
传输数据:由于Binder可以跨进程传递,需要在传输数据中予以表述

在系统不同部分,Binder实现的功能不同,表现形式也不一样的。接下来逐一探讨Binder在各部分所扮演的角色和使用的数据结构。

5.1 Binder 在应用程序中的表述
虽然Binder用到了面向对象的思想,但并不限制应用程序一定要使用面向对象的语言,无论是C语言还是C++语言都可以很容易的使用Binder 来通信。例如尽管Android主要使用java或C++,象SMgr这么重要的进程就是用C语言实现的。不过面向对象的方式表述起来更方便,所以本文假 设应用程序是用面向对象语言实现的。

Binder本质上只是一种底层通信方式,和具体服务没有关系。为了提供具体服务,Server必须提供一套接口函数以便Client通过远程访问 使用各种服务。这时通常采用Proxy设计模式:将接口函数定义在一个抽象类中,Server和Client都会以该抽象类为基类实现所有接口函数,所不 同的是Server端是真正的功能实现,而Client端是对这些函数远程调用请求的包装。如何将Binder和Proxy设计模式结合起来是应用程序实 现面向对象Binder通信的根本问题。

5.1.1 Binder 在Server端的表述 – Binder实体
做为Proxy设计模式的基础,首先定义一个抽象接口类封装Server所有功能,其中包含一系列纯虚函数留待Server和Proxy各自实现。 由于这些函数需要跨进程调用,须为其一一编号,从而Server可以根据收到的编号决定调用哪个函数。其次就要引入Binder了。Server端定义另 一个Binder抽象类处理来自Client的Binder请求数据包,其中最重要的成员是虚函数onTransact()。该函数分析收到的数据包,调 用相应的接口函数处理请求。

接下来采用继承方式以接口类和Binder抽象类为基类构建Binder在Server中的实体,实现基类里所有的虚函数,包括公共接口函数以及数 据包处理函数:onTransact()。这个函数的输入是来自Client的binder_transaction_data结构的数据包。前面提到, 该结构里有个成员code,包含这次请求的接口函数编号。onTransact()将case-by-case地解析code值,从数据包里取出函数参 数,调用接口类中相应的,已经实现的公共接口函数。函数执行完毕,如果需要返回数据就再构建一个binder_transaction_data包将返回 数据包填入其中。

那么各个Binder实体的onTransact()又是什么时候调用呢?这就需要驱动参与了。前面说过,Binder实体须要以Binde传输结 构flat_binder_object形式发送给其它进程才能建立Binder通信,而Binder实体指针就存放在该结构的handle域中。驱动根 据Binder位置数组从传输数据中获取该Binder的传输结构,为它创建位于内核中的Binder节点,将Binder实体指针记录在该节点中。如果 接下来有其它进程向该Binder发送数据,驱动会根据节点中记录的信息将Binder实体指针填入binder_transaction_data的 target.ptr中返回给接收线程。接收线程从数据包中取出该指针,reinterpret_cast成Binder抽象类并调用 onTransact()函数。由于这是个虚函数,不同的Binder实体中有各自的实现,从而可以调用到不同Binder实体提供的 onTransact()。

5.1.2 Binder 在Client端的表述 – Binder引用
做为Proxy设计模式的一部分,Client端的Binder同样要继承Server提供的公共接口类并实现公共函数。但这不是真正的实现,而是 对远程函数调用的包装:将函数参数打包,通过Binder向Server发送申请并等待返回值。为此Client端的Binder还要知道Binder实 体的相关信息,即对Binder实体的引用。该引用或是由SMgr转发过来的,对实名Binder的引用或是由另一个进程直接发送过来的,匿名 Binder的引用。

由于继承了同样的公共接口类,Client Binder提供了与Server Binder一样的函数原型,使用户感觉不出Server是运行在本地还是远端。Client Binder中,公共接口函数的实现方式是:创建一个binder_transaction_data数据包,将其对应的编码填入code域,将调用该函 数所需的参数填入data.buffer指向的缓存中,并指明数据包的目的地,那就是已经获得的对Binder实体的引用,填入数据包的 target.handle中。注意这里和Server的区别:实际上target域是个联合体,包括ptr和handle两个成员,前者用于作为响应方 的Server,指向 Binder实体对应的内存空间;后者用于作为请求方的Client,存放Binder实体的引用,告知驱动数据包将路由给哪个实体。数据包准备好后,通过驱动接口发送出去。经过BC_TRANSACTION/BC_REPLY回合完成函数的远程调用并得到返回值。

5.2 Binder 在传输数据中的表述
Binder可以塞在数据包的有效数据中越进程边界从一个进程传递给另一个进程,这些传输中的Binder用结构 flat_binder_object表示,如下表所示:

Binder传输结构:flat_binder_object
成员 含义
unsigned long type 表明该Binder的类型,包括以下几种: BINDER_TYPE_BINDER:表示传递的是Binder实体,并且指向该实体的引用都是强类型;BINDER_TYPE_WEAK_BINDER:表示传递的是Binder实体,并且指向该实体的引用都是弱类型;BINDER_TYPE_HANDLE:表示传递的是Binder强类型的引用BINDER_TYPE_WEAK_HANDLE:表示传递的是Binder弱类型的引用BINDER_TYPE_FD:表示传递的是文件形式的Binder,详见下节
unsigned long flags 该域只对第一次传递Binder实体时有效,因为此刻驱动需要在内核中创建相应的实体节点,有些参数需要从该域取出: 第0-7位:代码中用FLAT_BINDER_FLAG_PRIORITY_MASK取得,表示处理本实体请求数据包的线程的最低优先级。当一个应 用程序提供多个实体时,可以通过该参数调整分配给各个实体的处理能力。第8位:代码中用FLAT_BINDER_FLAG_ACCEPTS_FDS取得,置1表示该实体可以接收其它进程发过来的文件形式的 Binder。由于接收文件形式的Binder会在本进程中自动打开文件,有些Server可以用该标志禁止该功能,以防打开过多文件。
union { void *binder;signed long handle;}; 当传递的是Binder实体时使用binder域,指向Binder实体在应用程序中的地址。 当传递的是Binder引用时使用handle域,存放Binder在进程中的引用号。
void *cookie; 该域只对Binder实体有效,存放与该Binder有关的附加信息。


无论是Binder实体还是对实体的引用都从属与某个进程,所以该结构不能透明地在进程之间传输,必须有驱动的参与。例如当Server把 Binder实体传递给Client时,在发送数据中,flat_binder_object中的type是 BINDER_TYPE_BINDER,binder指向Server进程用户空间地址。如果透传给接收端将毫无用处,驱动必须对数据流中的这个 Binder做修改:将type该成BINDER_TYPE_HANDLE;为这个Binder在接收进程中创建位于内核中的引用并将引用号填入 handle中。对于发生数据流中引用类型的Binder也要做同样转换。经过处理后接收进程从数据流中取得的Binder引用才是有效的,才可以将其填 入数据包binder_transaction_data的target.handle域,向Binder实体发送请求。

这样做也是出于安全性考虑:应用程序不能随便猜测一个引用号填入target.handle中就可以向Server请求服务了,因为驱动并没有为你 在内核中创建该引用,必定会驱动被拒绝。唯有经过身份认证确认合法后,由‘权威机构’通过数据流授予你的Binder才能使用,因为这时驱动已经在内核中 为你建立了引用,交给你的引用号是合法的。
分享到:
评论

相关推荐

    Android Binder设计与实现——设计篇

    罗升阳在介绍和学习Binder的Blog中推荐:《Android Binder设计与实现》一文,详细地介绍了内核空间的Binder驱动程序的数据结构和设计原理

    Android Binder设计与实现

    详细分析了android binder的设计与实现。

    Android_Binder设计与实现_-_设计篇

    Android_Binder设计与实现_-_设计篇

    Android Binder设计与实现.docx

    Android Binder设计与实现.docxAndroid Binder设计与实现.docxAndroid Binder设计与实现.docxAndroid Binder设计与实现.docxAndroid Binder设计与实现.docxAndroid Binder设计与实现.docxAndroid Binder设计与实现....

    Android Binder设计之道.pptx

    Android Binder设计之道.pptx

    AndroidBinder设计与实现-设计篇

    Binder是Android系统进程间通信(IPC)方式之一。Linux已经拥有管道,systemVIPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具有无可比拟的优势。深入了解Binder并将之与传统IPC做对比有助于...

    android中binder设计与实现

    android中binder设计与实现 与深入浅出结合,非常好的诠释了android 中的binder机制的实现,各有所长,希望对您有帮助 个人也是网络上找的

    Android Binder 实现原理

    很详细讲解了Binder实现原理,细节,设计思想

    Binder设计与实现

    Binder是Android系统进程间通信(IPC)方式之一。Linux已经拥有管道,system V IPC,socket等IPC手段,却还要倚赖Binder来实现进程间通信,说明Binder具有无可比拟的优势。深入了解Binder并将之与传统 IPC做对比有助...

    Android Binder通信案例

    AIDL实现IPC,手写Binder实现IPC,Binder连接池的设计

    Android10.0 Binder通信原理(九)-AIDL Binder示例

    摘要:本节主要来讲解Android10.0 Binder中如何使用AIDL 阅读本文大约需要花费20分钟。 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设计,欢迎关注我,谢谢! [Android取经之路] 的...

    Android Binder

    本文将对Binder的设计细节做一个全面的阐述,首先通过介绍Binder通信 模型和 Binder通信协议了解Binder的设计需求;然后分别阐述Binder在系统不同部分的表述方式和起的作用;最后还 会解释Binder在数据接收端的设计...

    Android代码-Android

    对于Binder机制的介绍可以看universus写的《Android Binder设计与实现》。另外还两个老外介绍Binder的PPT也不错。 Android Binder设计与实现 - 设计篇 inter-process method invocation in Android (相对入门一点...

    android native层 binder通信机制演示源码

    该压缩包的内容主要是基于android系统演示native层进行binder通信的源码,里面分为bp和bn直接如何设计,可以给那些需要再native层进行binder通信的开发提供一个参考

    Android的设计与实现(卷1)

    android的设计与实现:卷i》是android应用开发工程师和android系统工程师进阶修炼的必读之作。它由资深android内核专家亲自执笔,从源代码角度,系统、深入、透彻剖析android系统框架层(framework)的设计思想和...

    基于Android的家庭理财系统的设计与实现.rar(毕业论文设计+程序源码) android studio导入可直接打开

    2.4.4 Binder 机制 15 2.5本章小结 16 第3章 需求分析与数据库设计 16 3.1需求分析 16 3.1.1功能性需求分析 16 3.12非功能性需求分析 17 3.2系统数据库设计 17 3.2.1数据库概念结构设计 17 3.2.2数据库逻辑结构设计 ...

    Android进程间通信Binder扩展模型的设计与实现.pdf

    Android进程间通信Binder扩展模型的设计与实现.pdf

    Android Binder入门学习笔记

    理解Binder能帮助我们更好的理解Android的系统设计,比如说四大组件,AMS,WMS等系统服务的底层通信机制就都是基于Binder机制的。当然了,Binder机制的底层驱动实现很复杂,本文的目的只是为了理清Binder的使用和在...

Global site tag (gtag.js) - Google Analytics