深入浅出Android底层(一)-Android中的IPC-Binder机制

328 阅读14分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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传统的进程间通信

image.png

2.2 进程隔离

由于进程A和进程B内存是不共享的,A进程和B进程进行数据交互就需要采用进程间通信.

进程空间又可以划分为

  • 用户空间(User Space)
  • 内核空间(Kernel Space)

2.3 传统的IPC通信原理

image.png 通常的做法是

  • 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到内核缓存区时,由于内核缓存区和接收数据的用户空间存在映射关系,所以就直接把数据发送到了接收进程的用户空间,完成了一次进程间的通信.

image.png

4.3 Binder架构

image.png 在上述的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函数

本系列的源码均来自AndroidXRef

/system/core/init/init.cpp

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/

image.png

包含了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出来的,后续会持续更新~