基于Android 6.0,从源码角度来理解Binder机制
Binder
正如前面说的,进程间通信的本质就是进程A拿到了进程B中Binder的对象的代理,通过这个代理Binder来向进程B发送请求进行通信。而Android系统有各种各样的系统服务,除了上一节提到的系统电量PowerManagerService,还有网络相关的、输入法、音频视频、剪切板和USB等等,想都不用向,这些服务肯定是共同持有一个Binder的抽象类,再具体扩展的。
BnInterface和BpInterface
先介绍2个来自IInterface.h的重要接口BnInterface和BpInterface,分别对应Binder实体即响应方持有的Binder和Binder代理即调用方持有。
1 | 49 template<typename INTERFACE> |
BnInterface和BpInterface又分别继承自Binder.h中定义的2个类BBinder和BpRefBase(实际上是和BpRefBase中的mRemote对象BpBinder有关),BBinder和BpBinder都继承自IBinder。
关系比较乱,上一个红茶大佬的图:
BBinder
在Binder.cpp中对BBinder的各个方法都进行了实现,主要关注transact这个方法中调用的onTransact,onTransact是会被子类重写来实现自己的业务的
1 | 97 status_t BBinder::transact( |
BpBinder
BpBinder的transact的内部实际调用的是IPCThreadState::transact,再跟进就是IPCThreadState::writeTransactionData
1 | 159 status_t BpBinder::transact( |
宏
再介绍IInterface.h头文件下的几个重要的宏。
DECLARE_META_INTERFACE
按字面意思直译的话就是声明interface,实际上下面的宏也确实是起到了声明的作用1
2
3
4
5
6
774
75 static const android::String16 descriptor; \
76 static android::sp<I##INTERFACE> asInterface( \
77 const android::sp<android::IBinder>& obj); \
78 virtual const android::String16& getInterfaceDescriptor() const; \
79 I##INTERFACE(); \
80 virtual ~I##INTERFACE();
IMPLEMENT_META_INTERFACE
对应上面的声明,这里就是实现interface了。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2283
84 const android::String16 I##INTERFACE::descriptor(NAME); \
85 const android::String16& \
86 I##INTERFACE::getInterfaceDescriptor() const { \
87 return I##INTERFACE::descriptor; \
88 } \
89 android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
90 const android::sp<android::IBinder>& obj) \
91 { \
92 android::sp<I##INTERFACE> intr; \
93 if (obj != NULL) { \
94 intr = static_cast<I##INTERFACE*>( \
95 obj->queryLocalInterface( \
96 I##INTERFACE::descriptor).get()); \
97 if (intr == NULL) { \
98 intr = new Bp##INTERFACE(obj); \
99 } \
100 } \
101 return intr; \
102 } \
103 I##INTERFACE::I##INTERFACE() { } \
104 I##INTERFACE::~I##INTERFACE() { }
实例分析
下面就以Camera服务来实际理一遍Bn和Bp是如何工作的。
在Camera.cpp中各个方法内部实际调用ICamera.cpp来实现
BnCamera在ICamera.h中定义了
1 | 118class BnCamera: public BnInterface<ICamera> |
而BpCamera是ICamera.cpp中定义的类
1 | 54 class BpCamera: public BpInterface<ICamera> |
其他进程请求Camera服务的时候,就需要通过BpCamera来了。下面从BpCamera中一次实际的请求takePicture切入分析:1
2
3
4
5
6
7
8
9
10
11
12
13206 // take a picture - returns an IMemory (ref-counted mmap)
207 status_t takePicture(int msgType)
208 {
209 ALOGV("takePicture: 0x%x", msgType);
210 Parcel data, reply;
211 data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
212 data.writeInt32(msgType);
213 remote()->transact(TAKE_PICTURE, data, &reply);
214 status_t ret = reply.readInt32();
215 return ret;
216 }
...
}
1 | 373 case TAKE_PICTURE: { |
通过请求码TAKE_PICTURE来最后调用到(takePicture(msgType));
BpCamera继承BpInterface,是代理Binder。takePicture这个方法中data根据一些传输协议来写入数据,通过remote来transact,同时还有reply作为响应。
ServiceManager
通过0号Binder来获取SM的代理
JAVA层
在ServiceManager.java中通过ServiceManagerNative来获取ServiceManager
1 | 33 private static IServiceManager getIServiceManager() { |
在ServiceManagerNative中,返回IServiceManager的实现类ServiceManagerProxy实例,来获取0号Binder
1 | static public IServiceManager asInterface(IBinder obj) |
引用红茶话Binder中2句话
1) ServiceManagerProxy就是IServiceManager代理接口;
2) ServiceManagerNative显得很鸡肋;
C层
在IServiceManager.cpp中line40提供了获取0号Binder的方法
1 | 33sp<IServiceManager> defaultServiceManager() |
再进入到ProcessState中查看相关代码,getContextObject中调用getStrongProxyForHandle(0)方法。
1 | 85sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/) |
getContextObject(NULL)实际上相当于返回了一个 new BpBinder(0)
再来看看模板方法interface_cast
1 | template<typename INTERFACE> |
实际上是调用IServiceManager的asInterface方法
通过SM代理来向SM注册其他系统服务
1 | power = new PowerManagerService(); |
SystemServer向SM注册PowerManagerService
通过SM代理向SM获得其他系统服务
IServiceManager的实现类ServiceManagerProxy实例中提供了add、get等方法
1 | public IBinder getService(String name) throws RemoteException |
