持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情
本篇将以IPC下的通信机制,作为Android底层源码解读的第一篇,理解Android下的跨进程通信.
一、IPC
IPC是Inter-Proces Communication的缩写,含义就是跨进程通信.
1.1 进程 vs 线程
首先我们需要区分一下进程和线程
进程是资源分配的最小单位,而线程是CPU调度的最小单位.
一个进程可以包含多个线程(主线程、子线程)
1.2 Android中的多进程
我们可以通过在四大组件中指定android:process 开启多进程,以下两种方式都可以开启一个进程
<activity android:name=".FirstActivity"
android:process=":remote"/>
<activity android:name=".SecondActivity"
android:process="com.zchhh.LaunchMode:remote"/>
1.3 开启多进程
- 1、当某些模块由于特殊原因需要运行在独立进程时
- 2、加大一个应用可使用的内存
二、进程间通信
进程获取的内存空间是一块抽象的内存,会映射到实际的某一块物理内存.因此,进程间也是数据隔离的.
不同进程之间的通信,是在不同的物理内存之间传递数据
2.1 Linux传统的进程间通信
2.2 进程隔离
由于进程A和进程B内存是不共享的,A进程和B进程进行数据交互就需要采用进程间通信.
进程空间又可以划分为
- 用户空间(User Space)
- 内核空间(Kernel Space)
2.3 传统的IPC通信原理
通常的做法是
- 1、消息发送方将要发送的数据存放在内存缓存区中
- 2、通过系统调用进入内核态
- 3、内核程序在内核空间分配内存,开辟一块内核缓存区
- 4、调用copy_from_user()函数将数据从用户空间的内存缓冲区拷贝到内核空间的内核缓冲区中
- 5、接收方进程在接收数据时在自己的用户空间开辟一块内存缓冲区
- 6、接收方进程接收数据
2.4 存在问题
我们可以看到
- 1、这样的数据传递经历了:内存缓存区->内核缓冲区->内存缓存区,经历了两次数据拷贝
- 2、由于接收数据的缓存区是由数据接收进程提供,但是接收进程并不知道需要具体需要多大的空间,所以只能尽可能开辟大空间或者提前获取消息体的大小,比较浪费时间和性能
四、Binder跨进程通信
4.1 内存映射
Binder IPC机制中涉及到的内存映射通过mmap()来实现
内存映射:将用户空间的一块内存区域映射到内核空间.映射关系建立后,用户对这块内存区域的修改可以直接反应在映射的内核空间.
反之内核空间对这段区域的修改也能直接反应到用户空间
可以看到,内存映射有效地减少了拷贝次数,实现了用户空间和内核空间的高效率互动.
内存映射中的关键函数就是mmap,将文件的内容的全部或者一部分直接映射到进程的地址空间,映射完成后,进程可以像访问普通内存一样做其他的操作,比如memcpy等.mmap并不分配具体的物理地址空间,它只是占有进程的虚拟地址空间
4.2 Binder IPC
- 1、首先Binder驱动在内核空间创建一个数据接收的缓存区
- 2、在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系
- 3、当发送方进程通过系统调用copy_from_user()将数据copy到内核缓存区时,由于内核缓存区和接收数据的用户空间存在映射关系,所以就直接把数据发送到了接收进程的用户空间,完成了一次进程间的通信.
4.3 Binder架构
在上述的Binder架构中,有三个主要的部分:服务端,Binder驱动和客户端
客户端和服务端都处在用户空间,而Binder驱动处在内核空间
- 服务器端
一个Binder服务器端就是一个Binder类的对象。当创建一个Binder对象时,内部就会开启一个线程,这个线程用于接收binder驱动发送的消息,收到消息后,会执行相关的代码
- Binder驱动
当服务器端创建一个Binder对象后,Binder驱动也会相应创建一个mRemote对象,该对象的类型也是一个Binder类.客户端可以借助这个mRemote对象来访问远程服务
- 客户端
当客户端想要访问Binder的远程服务时,获取服务器端在binder驱动层的mRemote引用,获取到引用后,就可以调用相应的服务了.
4.4 Android Binder框架
在Android的Binder框架中,定义了四个角色:Service服务器端,Client客户端,ServiceManager(SMgr)以及Binder驱动
其中Server,Client,SMgr运行于用户空间,Binder驱动运行于内核区间.
值得注意的是,SMgr和Service服务器端不在同一个线程中,看到一个比较靠谱的分析是,可能ServiceManager中保存的系统服务不单单是只有system_server进程中的系统服务,还有别的进程中的系统服务.
它作为一个单独的进程存在需要与其他的系统服务实现解耦,因为它是系统服务提供的代理者,只需要保证SMgr在系统启动时最先启动就可以了,后续的系统服务启动后去创建相应的映射关系即可,后续客户端去找代理获取相应的服务者
五、Binder源码分析
由于之后的SystemServer以及一些系统服务例如AMS,PMS这些涉及的底层源码会比较多,所以这一篇我们先深入了解一下Binder的实现原理和几个关键函数.
5.1 Android 系统启动流程
系统第一个启动的是init进程,然后init进程会再启动Zygote,SMgr等这些比较关键的服务进程.
系统首先启动init进程,然后init进程会通过init.rc脚本做一些初始化工作,启动一些比较重要的服务进程.
我们先来看一下init进程init.cpp中的main函数
Binder驱动的源码位于drivers/android目录下,我们从binder.c文件着手
5.1.1 main函数
int main(int argc, char** argv) {
...
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
//BootLoader内核引导程序的装载
LoadBootScripts(am, sm);
..
return 0;
}
5.1.2 LoadBootScripts函数
//LoadBootScripts函数
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/init.rc");
if (!parser.ParseConfig("/system/etc/init")) {
late_import_paths.emplace_back("/system/etc/init");
}
if (!parser.ParseConfig("/product/etc/init")) {
late_import_paths.emplace_back("/product/etc/init");
}
if (!parser.ParseConfig("/odm/etc/init")) {
late_import_paths.emplace_back("/odm/etc/init");
}
if (!parser.ParseConfig("/vendor/etc/init")) {
late_import_paths.emplace_back("/vendor/etc/init");
}
} else {
parser.ParseConfig(bootscript);
}
}
5.1.3 CreateParser函数
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
Parser parser;
parser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, subcontexts));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, subcontexts));
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
return parser;
}
可以看到通过Parser方法解析了一个重要的文件 init.rc文件
5.2 init_rc文件
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc
可以看到init进程启动后会解析zygote.rc
在rootdir文件夹中 可以看到 system/core/rootdir/
包含了zygote32以及zygote64等,{ro.zygote}就是平台相关的参数,对应到init.zygote32.rc,init.zygote64.rc,init.zygote64_32.rc,init.zygote32_64.rc。
前两个只会启动单一的一个app_process进程,而后两个则会启动两个app_process进程:第二个app_process进程成为secondary(有相应secondary socket的创建过程)
这里以/system/core/rootdir/init.zygote32.rc为例
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
init.rc首先创建了名为zygote的进程,这个进程是通过app_process的main函数启动并且下面定义了main函数的若干参数.
5.3 app_process函数
/frameworks/base/cmds/app_process/app_main.cpp
//Zygote进程由init进程通过fork而来,init.rc中设置的启动参数:
///system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
374int main(int argc, char** argv)
375{
376 struct binder_state *bs;
377 union selinux_callback cb;
378 char *driver;
379
//定义driver路径
380 if (argc > 1) {
381 driver = argv[1];
382 } else {
383 driver = "/dev/binder";
384 }
385
//调用binder_open函数
386 bs = binder_open(driver, 128*1024);
387 if (!bs) {
388#ifdef VENDORSERVICEMANAGER
389 ALOGW("failed to open binder driver %s\n", driver);
390 while (true) {
391 sleep(UINT_MAX);
392 }
393#else
394 ALOGE("failed to open binder driver %s\n", driver);
395#endif
396 return -1;
397 }
//binder_become_context_manager函数
399 if (binder_become_context_manager(bs)) {
400 ALOGE("cannot become context manager (%s)\n", strerror(errno));
401 return -1;
402 }
403
404 cb.func_audit = audit_callback;
405 selinux_set_callback(SELINUX_CB_AUDIT, cb);
406 cb.func_log = selinux_log_callback;
407 selinux_set_callback(SELINUX_CB_LOG, cb);
408
409#ifdef VENDORSERVICEMANAGER
410 sehandle = selinux_android_vendor_service_context_handle();
411#else
412 sehandle = selinux_android_service_context_handle();
413#endif
414 selinux_status_open(true);
415
416 if (sehandle == NULL) {
417 ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
418 abort();
419 }
420
421 if (getcon(&service_manager_context) != 0) {
422 ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
423 abort();
424 }
425
//binder_loop函数
427 binder_loop(bs, svcmgr_handler);
428
429 return 0;
430}
431
5.4.2 binder_open()函数
xref: /frameworks/native/cmds/servicemanager/binder.c
struct binder_state *binder_open(const char* driver, size_t mapsize)
98{
99 struct binder_state *bs;
100 struct binder_version vers;
101
102 bs = malloc(sizeof(*bs));
103 if (!bs) {
104 errno = ENOMEM;
105 return NULL;
106 }
107
//打开binder设备驱动
108 bs->fd = open(driver, O_RDWR | O_CLOEXEC);
109 if (bs->fd < 0) {
110 fprintf(stderr,"binder: cannot open %s (%s)\n",
111 driver, strerror(errno));
112 goto fail_open;
113 }
114
115 if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
116 (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
117 fprintf(stderr,
118 "binder: kernel driver version (%d) differs from user space version (%d)\n",
119 vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);
120 goto fail_open;
121 }
122
123 bs->mapsize = mapsize;
//2.建立内存映射
124 bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
125 if (bs->mapped == MAP_FAILED) {
126 fprintf(stderr,"binder: cannot map device (%s)\n",
127 strerror(errno));
128 goto fail_map;
129 }
130
131 return bs;
132
133fail_map:
134 close(bs->fd);
135fail_open:
136 free(bs);
137 return NULL;
138}
139
binder_open最终会调用linux内核的binder_open函数
5.4.3 binder_become_context_manager
147int binder_become_context_manager(struct binder_state *bs)
148{
149 return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
150}
该函数内部通过ioctl函数向binder驱动发送一个BINDER_SET_CONTEXT_MGR的命令,使当前进程成为系统的ServiceManger
5.4.4 binder_loop 函数
389void binder_loop(struct binder_state *bs, binder_handler func)
390{
391 int res;
392 struct binder_write_read bwr;
393 uint32_t readbuf[32];
394
395 bwr.write_size = 0;
396 bwr.write_consumed = 0;
397 bwr.write_buffer = 0;
398
399 readbuf[0] = BC_ENTER_LOOPER;
400 binder_write(bs, readbuf, sizeof(uint32_t));
401
402 for (;;) {
403 bwr.read_size = sizeof(readbuf);
404 bwr.read_consumed = 0;
405 bwr.read_buffer = (uintptr_t) readbuf;
406
407 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
408
409 if (res < 0) {
410 ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
411 break;
412 }
413
414 res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
415 if (res == 0) {
416 ALOGE("binder_loop: unexpected reply?!\n");
417 break;
418 }
419 if (res < 0) {
420 ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
421 break;
422 }
423 }
424}
5.4.5 binder_write函数
152int binder_write(struct binder_state *bs, void *data, size_t len)
153{
154 struct binder_write_read bwr;
155 int res;
156
157 ...
163 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
164 if (res < 0) {
165 fprintf(stderr,"binder_write: ioctl failed (%s)\n",
166 strerror(errno));
167 }
168 return res;
169}
binder_write函数会调用ioctl函数发送BINDER_WRITE_READ命令将消息拷贝到&bwr binder_parse函数
217int binder_parse(struct binder_state *bs, struct binder_io *bio,
218 uintptr_t ptr, size_t size, binder_handler func)
219{
220 int r = 1;
221 uintptr_t end = ptr + (uintptr_t) size;
222
223 while (ptr < end) {
224 uint32_t cmd = *(uint32_t *) ptr;
225 ptr += sizeof(uint32_t);
226#if TRACE
227 fprintf(stderr,"%s:\n", cmd_name(cmd));
228#endif
229 switch(cmd) {
230 case BR_NOOP:
231 break;
232 case BR_TRANSACTION_COMPLETE:
233 break;
234 case BR_INCREFS:
235 case BR_ACQUIRE:
236 case BR_RELEASE:
237 case BR_DECREFS:
238#if TRACE
239 fprintf(stderr," %p, %p\n", (void *)ptr, (void *)(ptr + sizeof(void *)));
240#endif
241 ptr += sizeof(struct binder_ptr_cookie);
242 break;
243 case BR_TRANSACTION: {
244 struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
245 if ((end - ptr) < sizeof(*txn)) {
246 ALOGE("parse: txn too small!\n");
247 return -1;
248 }
249 binder_dump_txn(txn);
250 if (func) {
251 unsigned rdata[256/4];
252 struct binder_io msg;
253 struct binder_io reply;
254 int res;
255
256 bio_init(&reply, rdata, sizeof(rdata), 4);
257 bio_init_from_txn(&msg, txn);
258 res = func(bs, txn, &msg, &reply);
259 if (txn->flags & TF_ONE_WAY) {
260 binder_free_buffer(bs, txn->data.ptr.buffer);
261 } else {
262 binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
263 }
264 }
265 ptr += sizeof(*txn);
266 break;
267 }
268 case BR_REPLY: {
269 struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
270 if ((end - ptr) < sizeof(*txn)) {
271 ALOGE("parse: reply too small!\n");
272 return -1;
273 }
274 binder_dump_txn(txn);
275 if (bio) {
276 bio_init_from_txn(bio, txn);
277 bio = 0;
278 } else {
279 /* todo FREE BUFFER */
280 }
281 ptr += sizeof(*txn);
282 r = 0;
283 break;
284 }
285 case BR_DEAD_BINDER: {
286 struct binder_death *death = (struct binder_death *)(uintptr_t) *(binder_uintptr_t *)ptr;
287 ptr += sizeof(binder_uintptr_t);
288 death->func(bs, death->ptr);
289 break;
290 }
291 case BR_FAILED_REPLY:
292 r = -1;
293 break;
294 case BR_DEAD_REPLY:
295 r = -1;
296 break;
297 default:
298 ALOGE("parse: OOPS %d\n", cmd);
299 return -1;
300 }
301 }
302
303 return r;
304}
5.5 客户端获取ServiceManager
客户端想要获取系统服务,首先就要像ServiceManager请求服务端的代理对象.
而各类系统服务也要在系统启动时先注册到ServiceManager,
所以如何获取到ServiceManager也成为了第一个要解决的问题.
/frameworks/native/libs/binder/IServiceManager.cpp
38sp<IServiceManager> defaultServiceManager()
39{
40 if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
41
42 {
43 AutoMutex _l(gDefaultServiceManagerLock);
44 while (gDefaultServiceManager == NULL) {
45 gDefaultServiceManager = interface_cast<IServiceManager>(
46 ProcessState::self()->getContextObject(NULL));
47 if (gDefaultServiceManager == NULL)
48 sleep(1);
49 }
50 }
51
52 return gDefaultServiceManager;
53}
这是非常典型的一个单例加载模式
5.6 ProcessState::self()
68sp<ProcessState> ProcessState::self()
69{
70 Mutex::Autolock _l(gProcessMutex);
71 if (gProcess != NULL) {
72 return gProcess;
73 }
74 gProcess = new ProcessState("/dev/binder");
75 return gProcess;
76}
77
409ProcessState::ProcessState(const char *driver)
410 : mDriverName(String8(driver))
411 , mDriverFD(open_driver(driver))
412 , mVMStart(MAP_FAILED)
413 , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
414 , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
415 , mExecutingThreadsCount(0)
416 , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
417 , mStarvationStartTimeMs(0)
418 , mManagesContexts(false)
419 , mBinderContextCheckFunc(NULL)
420 , mBinderContextUserData(NULL)
421 , mThreadPoolStarted(false)
422 , mThreadPoolSeq(1)
423{
424 if (mDriverFD >= 0) {
425 // mmap the binder, providing a chunk of virtual address space to receive transactions.
426 mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
427 if (mVMStart == MAP_FAILED) {
428 // *sigh*
429 ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
430 close(mDriverFD);
431 mDriverFD = -1;
432 mDriverName.clear();
433 }
434 }
435
436 LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
437}
可以看到ProcessState通过一个单例模式,在构造函数中,打开了/dev/binder设备,保存了文件句柄,然后调用mmap()映射内存到当前进程的虚拟地址空间.
5.7 getContextObject()
110sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
111{
112 return getStrongProxyForHandle(0);
113}
114
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
245{
246 sp<IBinder> result;
247
248 AutoMutex _l(mLock);
249
250 handle_entry* e = lookupHandleLocked(handle);
251
252 if (e != NULL) {
253 // We need to create a new BpBinder if there isn't currently one, OR we
254 // are unable to acquire a weak reference on this current one. See comment
255 // in getWeakProxyForHandle() for more info about this.
256 IBinder* b = e->binder;
257 if (b == NULL || !e->refs->attemptIncWeak(this)) {
258 if (handle == 0) {
259 // Special case for context manager...
260 // The context manager is the only object for which we create
261 // a BpBinder proxy without already holding a reference.
262 // Perform a dummy transaction to ensure the context manager
263 // is registered before we create the first local reference
264 // to it (which will occur when creating the BpBinder).
265 // If a local reference is created for the BpBinder when the
266 // context manager is not present, the driver will fail to
267 // provide a reference to the context manager, but the
268 // driver API does not return status.
269 //
270 // Note that this is not race-free if the context manager
271 // dies while this code runs.
272 //
273 // TODO: add a driver API to wait for context manager, or
274 // stop special casing handle 0 for context manager and add
275 // a driver API to get a handle to the context manager with
276 // proper reference counting.
277
278 Parcel data;
279 status_t status = IPCThreadState::self()->transact(
280 0, IBinder::PING_TRANSACTION, data, NULL, 0);
281 if (status == DEAD_OBJECT)
282 return NULL;
283 }
284
285 b = BpBinder::create(handle);
286 e->binder = b;
287 if (b) e->refs = b->getWeakRefs();
288 result = b;
289 } else {
290 // This little bit of nastyness is to allow us to add a primary
291 // reference to the remote proxy when this team doesn't have one
292 // but another team is sending the handle to us.
293 result.force_set(b);
294 e->refs->decWeak(this);
295 }
296 }
297
298 return result;
299}
可以看到,getContextObject返回了一个BpBinder::create(handle),这里的入参handle是0
5.8 interface_cast
41template<typename INTERFACE>
42inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
43{
44 return INTERFACE::asInterface(obj);
45}
前面我们已经获得了一个BpBinder对象,而最终是要得到一个 IServiceManager对象,然而这两者并没有任何的继承关系,所以并不是简单的强转,看下上面模板函数的定义
把INTERFACE替换成IServiceManager,然而IServiceManager中并没有asInterface这个方法
注意到IServiceManager.h中有一句宏调用. /frameworks/native/include/binder/IServiceManager.h
DECLARE_META_INTERFACE(ServiceManager)
而IServiceManager.cpp中也有一句宏调用:
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
这里的声明和实现里有包含了 asInterface方法,这两个宏定义在IInterface.h中 /frameworks/native/include/binder/IInterface.h
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const ::android::String16 I##INTERFACE::descriptor(NAME); \
const ::android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
::android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const ::android::sp<::android::IBinder>& obj) \
{ \
::android::sp<I##INTERFACE> intr; \
if (obj != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
#define DECLARE_META_INTERFACE(INTERFACE) \
static const ::android::String16 descriptor; \
static ::android::sp<I##INTERFACE> asInterface( \
const ::android::sp<::android::IBinder>& obj); \
virtual const ::android::String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
把两个宏展开之后就变成了
#define DECLARE_META_INTERFACE(IServiceManager) \
static const ::android::String16 descriptor; \
static ::android::sp<IServiceManager> asInterface( \
const ::android::sp<::android::IBinder>& obj); \
virtual const ::android::String16& getInterfaceDescriptor() const; \
IServiceManager(); \
virtual ~IServiceManager(); \
#define IMPLEMENT_META_INTERFACE(IServiceManager, "android.os.IServiceManager") \
const ::android::String16 IServiceManager::descriptor("android.os.IServiceManager"); \
const ::android::String16& \
IServiceManager::getInterfaceDescriptor() const { \
return IServiceManager::descriptor; \
} \
::android::sp<IServiceManager> IServiceManager::asInterface( \
const ::android::sp<::android::IBinder>& obj) \
{ \
::android::sp<IServiceManager> intr; \
if (obj != NULL) { \
intr = static_cast<IServiceManager*>( \
obj->queryLocalInterface( \
IServiceManager::descriptor).get()); \
if (intr == NULL) { \
intr = new BpServiceManager(obj); \
} \
} \
return intr; \
} \
IServiceManager::I##INTERFACE() { } \
IServiceManager::~I##INTERFACE() { } \
重点关注asInterface方法,这里传入的obj参数就是前面得到的BpBinder(0)对象,queryLocalInterface的默认实现在IBinder.cpp中,它返回null,所以intr==null,最终就构造了BpServiceManager(obj)返回,而BpServiceManager正是IServiceManager的一个实现类,它也是ServiceManager在客户端的代理对象
六、总结
通过上述分析,我们大致知道了SMgr是如何通过Binder驱动提供自己的代理对象的.
-
1.服务接口定义服务提供的业务逻辑,比如IServiceManager,定义了getService,addService等
-
2.本地服务,也即服务端,是真正实现业务逻辑的对象
-
3.远程服务,也即客户端,或者代理端,比如BpServiceManager,里面保存了一个BpBinder(实际在构造函数时保存在父类BpRefBase.mRemote中,通过remote()方法获得),作为服务端的代理,主要职责是封装请求,并向Binder驱动发起请求,Binder驱动会负责把请求发送到对应的服务端
由于字数限制,SMgr中各种服务是如何注册以及Zygote进程中其他子进程是如何fork出来的,后续会持续更新~