参考:
http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html
基于Binder通信的C/S架构体系中,除了C/S架构所包括的Client端和Server端外,Android还有一个全局的ServiceManager端,它的作用是管理系统中的各种服务(Service)。这三者的关系如下:
注意:一个Server进程可以注册多个Service.
选择MediaServer做为切入点,因为这个Server是很多重要的Service的栖息地。包括:
AudioFlinger :音频系统的核心服务
AudioPolicyService:音频系统中关于音频策略的重要服务
MediaPlayerService: 多媒体系统的重要服务(本节以这个为例)
CameraService: 有关摄像 / 照相的重要服务
这里以MediaPlayerService 为切入点,先分析MediaServer本身。
MediaServer(MS)是一个可执行程序,入口函数是main,代码如下:
上面代码有5个关键点。下面一一分析。
一、ProcessState
每个进程只有一个ProcessState,它是独一无二的。
sp<ProcessState> proc(ProcessState::self());
关于sp<> ,wp<>的用法可以参考:
http://blog.csdn.net/lksodit_yiyi/article/details/8086059
定义了一个ProcessState sp指针proc,并为proc赋值为ProcessState::self()。下面看下其实现:
ProcessState的构造:
这个构造函数很重要,它悄悄地打开了Binder设备。代码如下:
打开binder设备:
open_driver的作用就是打开/dev/binder这个设备。它是Android在内核中为完成进程间通信而专门设置的一个虚拟设备。实现如下:
到这里ProcessState::self函数分析完成,总结:
1. 打开/dev/binder设备,这就相当与与内核的Binder驱动有了交互的通道
2. 对返回的fd使用mmap,这样Binder驱动就会分配一块内存来接收数据。
3. 由于ProcessState具有唯一性,因此一个进程只打开设备一次。
二、defaultServiceManager
defaultServiceManager函数的实现在IServiceManager.cpp中完成,它会返回一个IServiceManager对象,通过这个对象,就可以与ServiceManager进行交互了
下面看看这个函数的实现:
interface_case相关可以参考:http://blog.csdn.net/myarrow/article/details/7054589
我了解的意思是创建一个IServiceManager对象。
调用了ProcessState的getContextObject函数。
getStrongProxyForHandle 这个函数的调用参数名叫handle。它是对资源的一种标识。说白了,其实就是有一个资源项,保存在一个资源数组中,handle的值正式该资源项在数组中的索引。
上面的BpBinder是什么?
BpBinder和BBinder都是Android中与Binder通信相关的代表它们都是从IBinder类中派生而来。
1. BpBinder是客户端与Server交互的代理类,p即Proxy的意思
2. BBinder是与proxy相对的一端,它是proxy交互的目的端。如果说Proxy代表客户端,那么BBinder则代表服务端,这里的BpBinder和BBinder是一一对应的,即某个BpBinder只能和对应的BBinder交互。我们当然不希望通过BpBinderA发送的请求,却由BBinderB来处理。
刚才在defaultServiceManager中创建了这个BpBinder。这里有两个问题:
1. 为什么创建的不是BBinder?
因为我们是SeviceManager的客户端,档案使用代理端和ServiceManger进行交互。
2. BpBinder和BBinder是一一对应的,那么BpBinder如何标识它所对应的BBinder端呢?
答案: Binder系统通过handler来标识对应的BBinder。以后我再确认这个Handle值的作用。
注意: 这里我们给BpBinder构造函数传的参数handle的值是0.这个0在整个Binder系统中有重要含义:0代表的就是ServiceManager所对应的BBinder。
BpBinder是如此重要,必须对它进行深入分析,代码如下所示:
仔细查看,发现BpBinder,BBinder这两个类没有任何地方操作ProcessState打开的那个/dev/binder设备,换言之,这两个Binder类没有和binder设备直接交互。
为什么说BpBinder与通信相关呢?
BpBinde只是个道具,它的后面一定另有机关
下面看下道具的出场过程:
现在这个函数调用将变成如下所示的样子:
这里的interface_cast是一个障眼法,下面进行分析。
interface_case的具体实现:
下面看看IServiceManager
(1) 定义业务逻辑
IServiceManager定义在IServiceManager.h中,代码如下:
(2)业务与通信的挂钩:
Android巧妙地通过DECLARE_META_INTERFACE和IMPLENT宏,将业务和通信牢牢地钩在了一起。他俩都定义在IInterface.h中。先看DECLARE_META_INTERFACE这个宏,如下所示:
将IServiceManager的DECLARE宏进行相应的替换后得到的代码如下所示:
DECLARE宏声明了一些函数和一个变量,那么IMPLEMENT宏的作用肯定就是定义它们了。IMPLEMENT的定义在IInterface.h 中,IServiceManager是如何使用这个宏的呢?只有一行代码,在IServiceManager.cpp中。如下所示:
将这个宏展开,如下所示:
之前疑问:interface_case是如何把BpBinder指针转换为一个IServiceManager指针的。答案就在asInterface函数的这一行代码中,如下所示:
interface_cast不是指针的转换,而是利用BpBinder对象作为参数新建了一个BpServiceManager对象。我们已经直到BpBinder和BBinder与通信有关系,这里怎么突然冒出来一个BpServiceManager?他们有什么关系?
IServiceManager家族
要搞清楚上面问题,必须先了解IServiceManager家族之间的关系。下图展示了IServiceManager的家族图谱:
1. IServiceManager,BpServiceManager和BnServiceManager都与业务逻辑相关
2. BnServiceManager同时从IServiceManager BBinder派生,表示它可以直接参与Binder通信
3. BpServiceManager虽然从BpInterface中派生,但是这条分支似乎与BpBinder没有关系
4. BnServiceManager是一个虚类,它的业务函数最终需要子类来实现。
在上图中的BpServiceManager,既然不像BnServicemanager哪样与Binder有直接的血缘关系,那么它是如何与Binder交互的呢?简言之,BpRefBase中的mRemote值就是BpBinder。
BpInterface的实现代码如下所示:
BpRefBse()的实现如下所示:
原来,是BpServiceManager的一个变量mRemote指向了BpBinder。至此,我们的魔术结束。回想defaultServiceManager函数,可以得到一下两个关键对象:
1. 有一个BpBinder对象,它的handle值是0
2. 有一个BpServiceManager对象,它的mRemote值是BpBinder。
BpServiceManager对象实现了IServiceManager的业务函数,现在又有BpBinder作为通信的代表,接下来的工作就简单了。