Fork me on GitHub

浅析Android进程间通信(三)

基于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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
49  template<typename INTERFACE>
50 class BnInterface : public INTERFACE, public BBinder
51 {
52 public:
53 virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
54 virtual const String16& getInterfaceDescriptor() const;
55
56 protected:
57 virtual IBinder* onAsBinder();
58 };
59
60 // ----------------------------------------------------------------------
61
62 template<typename INTERFACE>
63 class BpInterface : public INTERFACE, public BpRefBase
64 {
65 public:
66 BpInterface(const sp<IBinder>& remote);
67
68 protected:
69 virtual IBinder* onAsBinder();
70 };

BnInterface和BpInterface又分别继承自Binder.h中定义的2个类BBinderBpRefBase(实际上是和BpRefBase中的mRemote对象BpBinder有关),BBinder和BpBinder都继承自IBinder

关系比较乱,上一个红茶大佬的图:

BBinder

Binder.cpp中对BBinder的各个方法都进行了实现,主要关注transact这个方法中调用的onTransactonTransact是会被子类重写来实现自己的业务的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
97 status_t BBinder::transact(
98 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
99 {
100 data.setDataPosition(0);
101
102 status_t err = NO_ERROR;
103 switch (code) {
104 case PING_TRANSACTION:
105 reply->writeInt32(pingBinder());
106 break;
107 default:
108 err = onTransact(code, data, reply, flags);
109 break;
110 }
111
112 if (reply != NULL) {
113 reply->setDataPosition(0);
114 }
115
116 return err;
117 }

BpBinder

BpBinder的transact的内部实际调用的是IPCThreadState::transact,再跟进就是IPCThreadState::writeTransactionData

1
2
3
4
5
6
7
8
9
10
11
12
13
159 status_t BpBinder::transact(
160 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
161{
162 // Once a binder has died, it will never come back to life.
163 if (mAlive) {
164 status_t status = IPCThreadState::self()->transact(
165 mHandle, code, data, reply, flags);
166 if (status == DEAD_OBJECT) mAlive = 0;
167 return status;
168 }
169
170 return DEAD_OBJECT;
171}

再介绍IInterface.h头文件下的几个重要的宏。

DECLARE_META_INTERFACE

按字面意思直译的话就是声明interface,实际上下面的宏也确实是起到了声明的作用

1
2
3
4
5
6
7
74#define DECLARE_META_INTERFACE(INTERFACE)                               \
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
22
83#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
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来实现

BnCameraICamera.h中定义了

1
2
3
4
5
6
7
8
118class BnCamera: public BnInterface<ICamera>
119{
120public:
121 virtual status_t onTransact( uint32_t code,
122 const Parcel& data,
123 Parcel* reply,
124 uint32_t flags = 0);
125};

BpCamera是ICamera.cpp中定义的类

1
2
3
4
5
6
7
8
9
54 class BpCamera: public BpInterface<ICamera>
55 {
56 public:
57 BpCamera(const sp<IBinder>& impl)
58 : BpInterface<ICamera>(impl)
59 {
60 }
...
}

其他进程请求Camera服务的时候,就需要通过BpCamera来了。下面从BpCamera中一次实际的请求takePicture切入分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
206    // 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
2
3
4
5
6
7
373        case TAKE_PICTURE: {
374 ALOGV("TAKE_PICTURE");
375 CHECK_INTERFACE(ICamera, data, reply);
376 int msgType = data.readInt32();
377 reply->writeInt32(takePicture(msgType));
378 return NO_ERROR;
379 } break;

通过请求码TAKE_PICTURE来最后调用到(takePicture(msgType));

BpCamera继承BpInterface,是代理Binder。takePicture这个方法中data根据一些传输协议来写入数据,通过remote来transact,同时还有reply作为响应。

ServiceManager

通过0号Binder来获取SM的代理

JAVA层

ServiceManager.java中通过ServiceManagerNative来获取ServiceManager

1
2
3
4
5
6
7
8
9
33    private static IServiceManager getIServiceManager() {
34 if (sServiceManager != null) {
35 return sServiceManager;
36 }
37
38 // Find the service manager
39 sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
40 return sServiceManager;
41 }

ServiceManagerNative中,返回IServiceManager的实现类ServiceManagerProxy实例,来获取0号Binder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}

return new ServiceManagerProxy(obj);
}
public ServiceManagerProxy(IBinder remote)
{
mRemote = remote;//
}

引用红茶话Binder中2句话

1) ServiceManagerProxy就是IServiceManager代理接口;

2) ServiceManagerNative显得很鸡肋;

C层

IServiceManager.cpp中line40提供了获取0号Binder的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
33sp<IServiceManager> defaultServiceManager()
34{
35 if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
36
37 {
38 AutoMutex _l(gDefaultServiceManagerLock);
39 while (gDefaultServiceManager == NULL) {
40 gDefaultServiceManager = interface_cast<IServiceManager>(
41 ProcessState::self()->getContextObject(NULL));
42 if (gDefaultServiceManager == NULL)
43 sleep(1);
44 }
45 }
46
47 return gDefaultServiceManager;
48}

再进入到ProcessState中查看相关代码,getContextObject中调用getStrongProxyForHandle(0)方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
85sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
86{
87 return getStrongProxyForHandle(0);
88}

179sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
180{
181 sp<IBinder> result;
182
183 AutoMutex _l(mLock);
184
185 handle_entry* e = lookupHandleLocked(handle);
186
187 if (e != NULL) {
191 IBinder* b = e->binder;
192 if (b == NULL || !e->refs->attemptIncWeak(this)) {
193 if (handle == 0) {
212
213 Parcel data;
214 status_t status = IPCThreadState::self()->transact(
215 0, IBinder::PING_TRANSACTION, data, NULL, 0);
216 if (status == DEAD_OBJECT)
217 return NULL;
218 }
220 b = new BpBinder(handle);
221 e->binder = b;
222 if (b) e->refs = b->getWeakRefs();
223 result = b;
224 } else {
225 // This little bit of nastyness is to allow us to add a primary
226 // reference to the remote proxy when this team doesn't have one
227 // but another team is sending the handle to us.
228 result.force_set(b);
229 e->refs->decWeak(this);
230 }
231 }
232
233 return result;
234}

getContextObject(NULL)实际上相当于返回了一个 new BpBinder(0)

再来看看模板方法interface_cast

1
2
3
4
5
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}

实际上是调用IServiceManager的asInterface方法

通过SM代理来向SM注册其他系统服务

1
2
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);

SystemServer向SM注册PowerManagerService

通过SM代理向SM获得其他系统服务

IServiceManager的实现类ServiceManagerProxy实例中提供了addget等方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public IBinder getService(String name) throws RemoteException 
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);

mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);

IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}

参考

红茶话Binder-1

Android系统服务