Jimmy Chen

A Programmer

(原创)BpBinder、BBinder和IInterface的关系

  本来想一篇文章就把BpBinder、BBinder、IBinder和IInterface的关系弄清楚的,但是感觉脱离Binder实际的使用流程来看这几个类,总觉得抓不到重点,所以感觉也还是和前面的文章一样,只是直接看里面的几个重要的函数调用,先不管实际Binder实际调用流程是怎么样的

IBinder

  BpBinder和BBinder都是Android中与Binder通信相关的代表,他们都是从IBinder中继承而来的。其中BpBinder是客户端用来与Server交互的代理类,BBinder则是和proxy相对的一端,它是proxy交互的目的端。如果说Proxy代表客户端,那么BBinder就代表这服务端。这里BpBinder和BBinder是一一对应的,即某个BpBinder只能和对应的BBinder交互。

IBinder.h

  对于IBinder中的方法,基本都是没有实现的,这些方法的实现都交给继承它的子类来实现,那下面直接看BpBinder的内容。

BpBinder

BpBinder.h

BpBinder的构造函数

  首先调用extendObjectLifetime将对象改为弱引用控制,通过IPCThreadState的incWeakHandle增加Binder Service的如引用计数值。IncWeakHandle如下:

  这一步只是将BC_INCREFS请求写到mOut中,还没有发送出去。

  除了incWeakHandle函数外还有decWeakHandle,incStrongHandle和decStrongHandle与Binder协议中的其他命令对应起来。

getInterfaceDescriptor函数

  这里是通过BpBinder的transact函数将请求发送出去,transact函数相当重要,下面我们就看看这个函数。

transact函数

  这么看,BpBinder这个代理端的数据发送其实也不是自己执行数据传输的操作,而是调用IPCThreadState的transact函数进行数据传输。

IPCThreadState::transact函数

  IPCThreadState的transact函数主要的步骤是两个,首先调用writeTransactionData,在这个函数里面主要工作是将Parcel类变量data打包成一个binder_transaction_data,然后将其写到mOut中,方法比较简单,代码就不贴出来了。然后调用waitForResponse,等待binder驱动处理数据。

waitForResponse函数

  waitForResponse函数里面,首先调用talkWithDriver和Binder驱动进行交互,talkWithDrive里面通过ioctl系统调用,调用到binder驱动的binder_ioctl,然后根据binder驱动处理后的结果switch操作。除去一些BR_返回操作特殊处理外,default状态是调用executeCommand对返回值进行处理的。getInterfaceDescriptor和transact的内容就看到这里。

linkToDeath函数

  首先判断是否已经发送过死亡通知,如果没有发送过那么就分配内存,然后调用IPCThreadState的requestDeathNotification,将自己注册到binder驱动里面去,然后将Obituary添加到vector里。

requestDeathNotification && flushCommands

  所以也是将数据写到mOut中,然后调用IPCThreadState的flushCommands,然后再主动调用talkWithDriver和binder驱动进行交互。前面讲到talkWithDriver就是通过ioctl系统调用,进入到binder驱动,这里最后会调用到binder驱动中的binder_thread_write函数。

binder_thread_write的BC_REQUEST_DEATH_NOTIFICATION部分

  到这里死亡通知的注册工作就做完了,其实看这部分的时候一直有个疑问,就是在linkToDeath中用的是Vector类,表明可以有多个Obituary,但是在binder驱动里面有if (ref->death)判断之前是否已经注册过死亡通知了,那么不就代表只能注册一个死亡通知吗,哪位什么还要用Vector来保存,这里实在想不明白。

unlinkToDeath函数

  clearDeathNotification函数的内容和requestDeathNotification函数的内容基本类似,只是填充的command改成BC_CLEAR_DEATH_NOTIFICATION了而已,然后flushCommands前面已经看多,接下来看看binder驱动如何处理BC_CLEAR_DEATH_NOTIFICATION的。

BC_CLEAR_DEATH_NOTIFICATION的处理

  这里改变command为BINDER_WORK_CLEAR_DEATH_NOTIFICATION了,要等到下一个binder_thread_read就会处理这个command

BINDER_WORK_CLEAR_DEATH_NOTIFICATION

  上面直接将注册时传给binder驱动的BpBinder给传回给用户空间,其command为BR_CLEAR_DEATH_NOTIFICATION_DONE。

BR_CLEAR_DEATH_NOTIFICATION_DONE

这里只是做最后的清理工作。OK,unlinkToDeath就完成所有工作了。

attachObject、findObject、detachObject

attachObject

  从代码中可以知道,attachObject的工作是通过mObjects的attach来完成的,查看BpBinder.h的代码可以知道mObject的类型是ObjectManager,所以BpBinder的attachObjec的工作是交个BpBinder的内部类ObjectManager的attach来完成的。

findObject && detachObject && kill

  findObject、detachObject和函数的内容和attachObject基本一样,所以这里只贴出代码好了,分析相对简单,请大家自行查看。

sendObituary函数

  这里首先要判断之前是否已经发送过死亡通知,如果已经发送过了,那当然就不用再次发送了。如果没有发送过死亡通知的话,那么首先需要调用IPCThreadState的clearDeathNotification,来清除注册到binder驱动中的死亡通知,这两个函数在unlinkToDeath中已经有介绍了,这里就略过。最后会调用保存到mObituaries这个vector里面的死亡通知函数来通知相应的BpBinder实例。

BBinder

BBinder类

  其中,isBinderAlive函数只是返回true,这很好理解,因为BBinder代表的是Binder通信中的服务端,服务端是否存活,服务端自己当然是知道的。同时linkToDeath和unlinkToDeath这两个函数都只是返回INVALID_OPERATION,表明这两个函数在服务端是不需要做什么的,毕竟这两个函数是用来注册死亡通知用的。

transact函数

  那么接下来直接看onTransact函数好了。

  没有什么实际的内容,看样子,在编写实际的Binder服务端程序的时候应该是会重载这个函数,以提供实际的功能。

attachObject、detachObject、findObject

这三个函数的功能也是通过BpBinder中的ObjectManager来实现的。

  BBinder的代码不多s,看样子主要还是依靠具体服务端的特性来添加相应的功能的。

IInterface

IInterface.h

  除了构造函数和析构函数外,IInterface类里面只带有一个实现了的类方法,两个不同的重载,就是将IInterface参数转换成IBinder对象,然后返回给调用者,这样子调用者就可以使用IBinder提供的transact、onTransact等函数进行Binder数据传输了。

DECLARE_META_INTERFACE

  首先看看DECLARE_META_INTERFACE宏,我们直接将一个具体参数代替INTERFACE好了,这里假定适应CameraService来代替INTERFACE,得到如下的内容

  替换之后的内容就很容易理解了,无非就是定义了一些方法,那么IMPLEMENT_META_INTERFACE应该就是实现这些方法的宏了,下面看看替换后的IMPLEMENT_META_INTERFACE的内容是什么。

IMPLEMENT_META_INTERFACE

  其中依旧用CameraService来代替INTERFACE,然后用android.os.ICameraService来代替NAME,所以得到的代码如下:

  其实将descriptor定义为android.os.ICameraService,然后getInterfaceDescriptor函数可以获取到这个descriptor。然后在asInterface函数中,将一个IBinder对象转换为一个BpInterface类对象。

  这篇大概就看到这里好了,IInterface里面还有一些其他的函数,暂时也没办法彻底说清楚他们的作用,所以就先留着吧,到后面有机会看到再说好了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注