Binder 浅析 —— AMS 注册流程

899 阅读11分钟

Binder 浅析 —— 整体概览

经过上一篇博客的介绍,相信大家已经对于 binder 机制有了一定的了解,这篇博客将会解读 AMS 注册的代码流程,篇幅会很长,请大家耐心看完!

(以下分析的是 Android 6.0 的源码)

ServiceManager 是如何启动的?

AMS 在启动后会注册到 ServiceManager(之后简称为SM)中

那么 SM 是如何启动的?

SM 是由 init 进程通过解析 init.rc 文件而创建的,其所对应的可执行程序 servicemanager, 所对应的源文件是 service_manager.c,进程名为 servicemanager

启动 SM 的入口函数是 service_manager.c 中的 main 函数

int main(int argc, char **argv)
{
    struct binder_state *bs;
    // 打开binder驱动,映射 128K 大小的内存空间
    bs = binder_open(128*1024);
    ......
    // 把当前进程注册成为 SM
    if (binder_become_context_manager(bs))
    {
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
    ......
    // 进入 loop 无限循环,监听处理 AMS 端发来的请求
    binder_loop(bs, svcmgr_handler);
    return 0;
}

binder_open()

// frameworks/native/cmds/servicemanager/binder.c
struct binder_state *binder_open(size_t mapsize)
{
    struct binder_state *bs;
    struct binder_version vers;
    ......
    // 打开binder驱动,得到文件描述符,通过系统调用到 binder 驱动中的 binder_open 函数
    bs->fd = open("/dev/binder", O_RDWR);
    ......
    // 映射内存大小:128K
    bs->mapsize = mapsize;
    // 通过系统调用到 binder 驱动中的 binder_mmap 函数,
    // 在当前进程的用户空间和内核空间之间映射 128K 大小的内存空间
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    ......
    return bs;
    ......
}

这里有个知识点,SM 的跨进程通信数据大小不能超过 128K

因为 SM 中记录的只是所注册服务在 binder 驱动中实体节点的引用(这个后面会介绍到),所以 128K 的大小足够了

binder_become_context_manager()

// frameworks/native/cmds/servicemanager/binder.c
int binder_become_context_manager(struct binder_state *bs)
{
    // 通过系统调用到 binder 驱动中的 binder_ioctl 函数,指令为 BINDER_SET_CONTEXT_MGR
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

binder_ioctl()

// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp, 
                        unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
                        unsigned long arg // arg 就是我们传入的 bwr
){
    // 获取 binder 驱动的设备节点
    struct binder_proc *proc = filp->private_data;
    struct binder_thread *thread;
    ......
    // 获取 binder 线程
    // (当前 pid 此时没有创建过 binder 线程,则创建一个 binder 线程并返回)
    // thread->looper = BINDER_LOOPER_STATE_NEED_RETURN
    // thread->return_error = BR_OK
    // thread->return_error2 = BR_OK
    thread = binder_get_thread(proc);
    ......
    switch (cmd)
    {
        ......
        case BINDER_SET_CONTEXT_MGR:
            ret = binder_ioctl_set_ctx_mgr(filp);
            ......
            break;
        ......
    }
    ......
    return ret;
}

binder_ioctl_set_ctx_mgr()

// kernel/drivers/staging/android/binder.c
static int binder_ioctl_set_ctx_mgr(struct file *filp)
{
    // 获取 binder 驱动的设备节点实体,可以通过 filp->private_data 获取
    struct binder_proc *proc = filp->private_data;
    ......
    // 保证只创建一次 binder_context_mgr_node,不为null就直接返回
    if (context->binder_context_mgr_node)
    {
        ......
        goto out;
    }
    ......
    // uid 是否有效,当前是无效的
    if (uid_valid(context->binder_context_mgr_uid))
    {
        if (!uid_eq(context->binder_context_mgr_uid, curr_euid))
        {
            ......
            goto out;
        }
    }
    else
    {
        // 设置当前线程的 euid 作为 SM 的 uid
        context->binder_context_mgr_uid = curr_euid;
    }
    // 创建 SM 在 binder 驱动中的 binder 节点实体
    context->binder_context_mgr_node = binder_new_node(proc, 0, 0);
    ......
out:
    return ret;
}
binder_new_node()
// kernel/drivers/staging/android/binder.c
static struct binder_node *binder_new_node(
            struct binder_proc *proc, // binder 驱动的设备节点实体
            binder_uintptr_t ptr,
            binder_uintptr_t cookie
){
    struct rb_node **p = &proc->nodes.rb_node;
    struct rb_node *parent = NULL;
    struct binder_node *node;
    ......
    // 给新创建的 binder_node 分配内核空间的内存
    node = kzalloc(sizeof(*node), GFP_KERNEL);
    ......
    // 将新创建的 binder_node 添加到设备节点的 binder_node 红黑树中
    rb_link_node(&node->rb_node, parent, p);
    rb_insert_color(&node->rb_node, &proc->nodes);
    ......
    // 初始化新创建的 binder_node
    node->proc = proc;
    node->ptr = ptr;
    node->cookie = cookie;
    node->work.type = BINDER_WORK_NODE;
    // 初始化 todo 和 wait 队列
    INIT_LIST_HEAD(&node->work.entry);
    INIT_LIST_HEAD(&node->async_todo);
    ......
    return node;
}

binder_become_context_manager 函数中主要是创建了 SM 在 binder 驱动中的节点实体

binder_loop()

// frameworks/native/cmds/servicemanager/binder.c
void binder_loop(struct binder_state *bs, binder_handler func)
{
    int res;
    struct binder_write_read bwr;
    uint32_t readbuf[32];

    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;

    readbuf[0] = BC_ENTER_LOOPER;
    // 发送指令 BC_ENTER_LOOPER 给 binder 驱动
    binder_write(bs, readbuf, sizeof(uint32_t));

    ......
}

binder_write()

// frameworks/native/cmds/servicemanager/binder.c
int binder_write(struct binder_state *bs, 
                 void *data, // readbuf 的起始地址
                 size_t len // readbuf 的长度
){
    struct binder_write_read bwr;
    int res;
    bwr.write_size = len;
    bwr.write_consumed = 0;
    bwr.write_buffer = (uintptr_t) data;
    bwr.read_size = 0;
    bwr.read_consumed = 0;
    bwr.read_buffer = 0;
    // 通过系统调用到 binder 驱动中的 binder_ioctl 函数,指令为 BINDER_WRITE_READ
    res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    if (res < 0) {
        fprintf(stderr,"binder_write: ioctl failed (%s)\n",
                strerror(errno));
    }
    return res;
}

binder_ioctl()

// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp, 
                        unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
                        unsigned long arg // arg 就是我们传入的 bwr
){
    // 获取 binder 驱动的设备节点
    struct binder_proc *proc = filp->private_data;
    struct binder_thread *thread;
    ......
    // 获取 binder 线程
    // (当前 pid 此时已经创建过 binder 线程,则返回对应的 binder 线程)
    // thread->looper = BINDER_LOOPER_STATE_NEED_RETURN
    // thread->return_error = BR_OK
    // thread->return_error2 = BR_OK
    thread = binder_get_thread(proc);
    ......
    switch (cmd)
    {
        case BINDER_WRITE_READ:
            ret = binder_ioctl_write_read(filp, cmd, arg, thread);
            ......
            break;
        ......
    }
    ......
    return ret;
}
binder_get_thread()
static struct binder_thread *binder_get_thread(struct binder_proc *proc)
{
    struct binder_thread *thread = NULL;
    struct rb_node *parent = NULL;
    // binder 线程池的根节点指针
    struct rb_node **p = &proc->threads.rb_node;
    
    // 遍历 binder 线程池,查找和当前线程匹配(pid相同)的 binder 线程
    while (*p)
    {
        parent = *p;
        // 类型转换(rb_node -> binder_thread)
        thread = rb_entry(parent, struct binder_thread, rb_node);
        
        if (current->pid < thread->pid)
            p = &(*p)->rb_left;
        else if (current->pid > thread->pid)
            p = &(*p)->rb_right;
        else
            // 如果找到了就 break 跳出循环,停止遍历
            break;
    }
    
    // 如果 binder 线程池中没有记录,就创建新的 binder 线程
    if (*p == NULL)
    {
        thread = kzalloc(sizeof(*thread), GFP_KERNEL);
        if (thread == NULL)
            return NULL;
        binder_stats_created(BINDER_STAT_THREAD);
        // 记录 binder 线程所属进程
        thread->proc = proc;
        // 记录 binder 线程的 pid
        thread->pid = current->pid;
        // 初始化 binder 线程的 wait 队列
        init_waitqueue_head(&thread->wait);
        // 初始化 binder 线程的 todo 队列
        INIT_LIST_HEAD(&thread->todo);
        // 将 binder 线程放入 binder 线程池中
        rb_link_node(&thread->rb_node, parent, p);
        rb_insert_color(&thread->rb_node, &proc->threads);
        thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN;
        thread->return_error = BR_OK;
        thread->return_error2 = BR_OK;
    }
    return thread;
}

binder 线程池本质上是一个红黑树的数据结构,binder 线程被转换成 rb_node 类型进行存储

binder_ioctl_write_read()
// kernel/drivers/staging/android/binder.c
static int binder_ioctl_write_read(struct file *filp,
				unsigned int cmd, unsigned long arg,
				struct binder_thread *thread
){
    struct binder_proc *proc = filp->private_data;
    ......
    void __user *ubuf = (void __user *)arg;
    struct binder_write_read bwr;
    
    // 将描述数据的 binder_write_read 结构体(ubuf)从用户空间拷贝到内核空间(bwr)中去
    if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
    ......
    // 此时 bwr.write_size > 0,if 命中
    if (bwr.write_size > 0)
    {
        // 发送指令给 binder 驱动
        ret = binder_thread_write(proc, thread,
                        bwr.write_buffer,
                        bwr.write_size,
                        &bwr.write_consumed);
        ......
    }
    // 此时 bwr.read_size = 0,if 不命中
    if (bwr.read_size > 0)
    {
        ......
    }
    ......
    return ret;
}
binder_thread_write()
// kernel/drivers/staging/android/binder.c
static int binder_thread_write(struct binder_proc *proc,
			struct binder_thread *thread,
			binder_uintptr_t binder_buffer, // readbuf 的起始地址
			size_t size, // readbuf 的长度
			binder_size_t *consumed
){
    uint32_t cmd;
    struct binder_context *context = proc->context;
    void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
    // 指向 readbuf 内存起始地址的指针
    void __user *ptr = buffer + *consumed;
    // 指向 readbuf 内存结束地址的指针
    void __user *end = buffer + size;
    
    // 遍历 readbuf 的内存指针,取出指令
    while (ptr < end && thread->return_error == BR_OK)
    {
        // 从 readbuf 中读取指令,此时读取到的指令是 BC_ENTER_LOOPER
        if (get_user(cmd, (uint32_t __user *)ptr))
            return -EFAULT;
        // 指针后移
        ptr += sizeof(uint32_t);
        switch (cmd)
        {
            ......
            case BC_ENTER_LOOPER:
                ......
                // 给 binder 线程的 looper 标志位添加 BINDER_LOOPER_STATE_ENTERED
                thread->looper |= BINDER_LOOPER_STATE_ENTERED;
                break;
            ......
        }
        ......
    }
    return 0;
}

binder_thread_write 函数执行完成后,一直返回到 binder_loop 函数,继续执行,陷入死循环

// frameworks/native/cmds/servicemanager/binder.c
void binder_loop(struct binder_state *bs, binder_handler func)
{
    int res;
    struct binder_write_read bwr;
    uint32_t readbuf[32];

    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;

    ......

    for (;;)
    {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;
        // 通过系统调用到 binder 驱动中的 binder_ioctl 函数,指令为 BINDER_WRITE_READ
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
        ......
    }
}

binder_ioctl()

// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp, 
                        unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
                        unsigned long arg // arg 就是我们传入的 bwr
){
    // 获取 binder 驱动的设备节点
    struct binder_proc *proc = filp->private_data;
    struct binder_thread *thread;
    ......
    // 获取 binder 线程
    // (当前 pid 此时已经创建过 binder 线程,则返回对应的 binder 线程)
    // thread->looper = BINDER_LOOPER_STATE_NEED_RETURN + BINDER_LOOPER_STATE_ENTERED
    // thread->return_error = BR_OK
    // thread->return_error2 = BR_OK
    thread = binder_get_thread(proc);
    ......
    switch (cmd)
    {
        case BINDER_WRITE_READ:
            ret = binder_ioctl_write_read(filp, cmd, arg, thread);
            ......
            break;
        ......
    }
    ......
    return ret;
}

binder_ioctl_write_read()

// kernel/drivers/staging/android/binder.c
static int binder_ioctl_write_read(struct file *filp,
				unsigned int cmd, unsigned long arg,
				struct binder_thread *thread
){
    struct binder_proc *proc = filp->private_data;
    ......
    void __user *ubuf = (void __user *)arg;
    struct binder_write_read bwr;
    
    // 将描述数据的 binder_write_read 结构体(ubuf)从用户空间拷贝到内核空间(bwr)中去
    if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
    ......
    // 此时 bwr.write_size = 0,if 不命中
    if (bwr.write_size > 0)
    {
        ......
    }
    // 此时 bwr.read_size > 0,if 命中
    if (bwr.read_size > 0)
    {
        // 读取 binder 驱动返回的指令
        ret = binder_thread_read(proc, thread, bwr.read_buffer,
                        bwr.read_size,
                        &bwr.read_consumed,
                        filp->f_flags & O_NONBLOCK);
        ......
    }
    ......
    return ret;
}
binder_thread_read()
static int binder_thread_read(struct binder_proc *proc,
			      struct binder_thread *thread,
			      binder_uintptr_t binder_buffer, size_t size,
			      binder_size_t *consumed, int non_block
){
    void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
    // 指向 readbuf 内存起始地址的指针
    void __user *ptr = buffer + *consumed;
    // 指向 readbuf 内存结束地址的指针
    void __user *end = buffer + size;
    
    int ret = 0;
    int wait_for_proc_work;

    // 此时 consumed = 0,if命中
    if (*consumed == 0)
    {
        // 将指令 BR_NOOP 添加到 readbuf 中
        if (put_user(BR_NOOP, (uint32_t __user *)ptr))
            return -EFAULT;
        // 指针后移
        ptr += sizeof(uint32_t);
    }

    // 此时 thread->todo = NULL,thread->transaction_stack = NULL,
    // wait_for_proc_work = true
    wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);
    
    ......

    thread->looper |= BINDER_LOOPER_STATE_WAITING;
    if (wait_for_proc_work)
        // 当前进程可用的 binder 线程数 +1
        proc->ready_threads++;
    
    ......

    if (wait_for_proc_work)
    {
        ......
        // 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
        // 此时 non_block > 0,执行else
        if (non_block)
        {
            ......
        }
        else
            // 此时 thread->todo = NULL,binder_has_proc_work 返回 false,
            // 将 binder 线程挂起
            ret = wait_event_freezable_exclusive(proc->wait, 
                                                 binder_has_proc_work(proc, thread));
    }
    else
    {
        ......
    }
    ......
}

执行到这后 SM 线程就会被挂起,等待别的进程与之通信将其唤醒

被唤醒后的 SM 线程会继续执行此处未完成的 binder_thread_read 函数

此时 readbuf 的结构如下

AMS 是如何注册的?

将 AMS 注册到 SM 中的过程也是 AMS 与 SM 通信的过程

AMS 的注册是在 SystemServer#main 中执行的

// frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args)
{
    new SystemServer().run();
}

private void run()
{
    ......
    // 创建 SystemServiceManager
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    ......
    startBootstrapServices();
}

private void startBootstrapServices()
{
    ......
    // 通过反射创建 ActivityManagerService.Lifecycle 并获取 AMS 对象
    mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
    ......
    // 为 AMS 启动系统进程
    mActivityManagerService.setSystemProcess();
}

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void setSystemProcess()
{
    ......
    // 将 AMS 注册到 SM 中
    ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
    ......
}

// frameworks/base/core/java/android/os/ServiceManager.java
public static void addService(String name, IBinder service, boolean allowIsolated)
{
    ......
    getIServiceManager().addService(name, service, allowIsolated);
    ......
}

ServiceManager.getIServiceManager()

// frameworks/base/core/java/android/os/ServiceManager.java
private static IServiceManager getIServiceManager()
{
    if (sServiceManager != null)
    {
        return sServiceManager;
    }
    // 返回 ServiceManagerProxy
    sServiceManager = 
        	ServiceManagerNative.asInterface(BinderInternal.getContextObject());
    return sServiceManager;
}

BinderInternal.getContextObject()

// frameworks/base/core/java/com/android/internal/os/BinderInternal.java
public static final native IBinder getContextObject();

// frameworks/base/core/jni/android_util_Binder.cpp
static const JNINativeMethod gBinderInternalMethods[] = {
    ......
    { "getContextObject", "()Landroid/os/IBinder;", 
			(void*)android_os_BinderInternal_getContextObject },
    ......
};

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    // ProcessState::self() --> 打开 binder驱动并创建 ProcessState(ProcessState是单例的)
    // ProcessState::getContextObject(NULL) --> 创建 BpBinder 对象并返回
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    // 创建 BinderProxy 对象并返回
    return javaObjectForIBinder(env, b);
}

ProcessState::self()

// frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    // 单例模式
    if (gProcess != NULL)
    {
        return gProcess;
    }
    // 创建 ProcessState
    gProcess = new ProcessState;
    return gProcess;
}

// BINDER_VM_SIZE 的大小为 1M-8K
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))

ProcessState::ProcessState()
    : mDriverFD(open_driver()) // 开启 binder 驱动
    ......
{
    // 如果开启 binder 驱动成功,得到了 binder 驱动设备节点
    if (mDriverFD >= 0)
    {
        // 通过系统调用到 binder 驱动中的 binder_mmap 函数,
        // 在当前进程的用户空间和内核空间之间映射 BINDER_VM_SIZE (1M-8K)大小的内存空间
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        ......
    }
    ......
}

这里又有个知识点,AMS 的跨进程通信数据大小不能超过 1M-8K

这是一个面试常问的点,通常面试是这么问的:Intent 传输数据有大小限制吗?大小限制是多大?

答案就是 1M-8K

因为 Intent 是四大组件之间通信的方式,而 AMS 管理着四大组件,所以使用 Intent 就需要与 AMS 进行通信,由于 binder 机制的限制,与 AMS 的通信数据大小不能超过 1M-8K

ProcessState::getContextObject()

// frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    ......
    // 当前 handle 为 0,if 命中
    if (handle == 0)
    {
        Parcel data;
        // 通过 ping 操作测试 SM 是否准备就绪
        status_t status = IPCThreadState::self()->transact(0, IBinder::PING_TRANSACTION, 
                                                           data, NULL, 0);
        if (status == DEAD_OBJECT)
            return NULL;
    }
    // 创建 BpBinder 对象,handle 为 0
    b = new BpBinder(handle); 
    ......
    result = b;
    ......
    return result;
}

javaObjectForIBinder()

// frameworks/base/core/jni/android_util_Binder.cpp
jobject javaObjectForIBinder(JNIEnv* env, 
                            const sp<IBinder>& val // val = BpBinder
){
    ......
    
    // 从 gBinderProxyOffsets 中查找 BinderProxy 对象
    // 因为此时 BinderProxy 没有创建过,此时 object 为 null
    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
    if (object != NULL)
    {
        // 通过查找 BinderProxy 对象的引用链,判断其是否正在被引用,返回其引用对象
        jobject res = jniGetReferent(env, object);
        // 如果 BinderProxy 对象正在被引用
        if (res != NULL)
        {
            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
            // 返回引用对象
            return res;
        }
        ......
        // 移除与当前 BinderProxy 对象的所有引用
        android_atomic_dec(&gNumProxyRefs);
        val->detachObject(&gBinderProxyOffsets);
        env->DeleteGlobalRef(object);
    }
    
    // 创建一个新的 BinderProxy 对象
    object = env->NewObject(gBinderProxyOffsets.mClass, 
                            gBinderProxyOffsets.mConstructor);
    if (object != NULL)
    {
        // 将 gBinderProxyOffsets 结构体中的成员变量 mObject 赋值(BpBinder),
        // 记录 BpBinder 对象
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        
        // 创建智能指针,相当于当前函数把 BpBinder 强引用了
        val->incStrong((void*)javaObjectForIBinder);
        
        // jni 环境变量(env)生成一个对于 BinderProxy 对象的弱引用,用于检索
        jobject refObject = env->NewGlobalRef(
                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        
        // 将 BinderProxy 对象信息添加到 BpBinder 的成员变量 mObjects 中,
        // 将 BinderProxy 与 BpBinder 互相绑定
        val->attachObject(&gBinderProxyOffsets, refObject, 
                          jnienv_to_javavm(env), proxy_cleanup);
        ......
        // BinderProxy.mOrgue 成员变量记录死亡通知对象
        env->SetLongField(object, gBinderProxyOffsets.mOrgue, 
                          reinterpret_cast<jlong>(drl.get()));
        ......
        // BinderProxy 对象引用计数加一,标志 BinderProxy 对象已被引用
        android_atomic_inc(&gNumProxyRefs);
        ......
    }
    
    return object;
}

每个 BinderProxy 对象都会绑定一个 BpBinder 对象,每次调用 javaObjectForIBinder() 函数时都会重新生成一个 BinderProxy 对象,并重新绑定一个 BpBinder 对象

此时 BinderProxy 对象绑定的 BpBinder 对象对应的是 SM(handle 为 0)

BinderInternal.getContextObject() 函数会返回一个 BinderProxy 对象,其在 Native 层绑定了一个 BpBinder 对象(对应 SM)

ServiceManagerNative.asInterface()

// frameworks/base/core/java/android/os/ServiceManagerNative.java
static public IServiceManager asInterface(
    IBinder obj // obj = BinderProxy
){
    if (obj == null)
    {
        return null;
    }
    IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
    if (in != null)
    {
        return in;
    }
    return new ServiceManagerProxy(obj);
}

// frameworks/base/core/java/android/os/BinderProxy.java
public IInterface queryLocalInterface(String descriptor)
{
    return null;
}

getIServiceManager() 函数会返回一个 ServiceManagerProxy 对象,其内部持有了一个 BinderProxy 对象

ServiceManagerProxy.addService()

// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public void addService(String name, IBinder service, boolean allowIsolated)
{
    // 创建 data
    Parcel data = Parcel.obtain();
    // 创建 reply
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    // 将 AMS 名称写入 data
    data.writeString(name);
    // 将 AMS 写入 data
    data.writeStrongBinder(service);
    data.writeInt(allowIsolated ? 1 : 0);
    // mRemote = BinderProxy,相当于调用到 BinderProxy.transact
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    reply.recycle();
    data.recycle();
}

AMS 是如何将自己打包的?

// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public void addService(String name, IBinder service, boolean allowIsolated)
{
    // 创建 data
    Parcel data = Parcel.obtain();
    ......
    // 将 AMS 写入 data
    data.writeStrongBinder(service);
    ......
}

Parcel.writeStrongBinder()

// frameworks/base/core/java/android/os/Parcel.java
public final void writeStrongBinder(IBinder val)
{
    nativeWriteStrongBinder(mNativePtr, val);
}

// frameworks/base/core/jni/android_os_Parcel.cpp
static const JNINativeMethod gParcelMethods[] = {
    ......
    {"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
    ......
}

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, 
                                                jclass clazz, jlong nativePtr, 
                                                jobject object // object = AMS
){
    // 将 Java 层的 Parcel 类型(Java的Parcel)对象强制类型转换成 Native 层的 Parcel 类型对象(Native的Parcel)
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL)
    {
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
        ......
    }
}

ibinderForJavaObject()

// frameworks/base/core/jni/android_util_Binder.cpp
sp<IBinder> ibinderForJavaObject(JNIEnv* env,
                                jobject obj // object = AMS
){
    if (obj == NULL)
        return NULL;
    // 如果 obj 的类型是 Binder,此时 obj = AMS,AMS 继承自 Binder.java,if 命中
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass))
    {
        // 从 gBinderOffsets.mObject 成员属性获取 JavaBBinderHolder 对象
        JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
        // 通过 JavaBBinderHolder#get 函数创建 JavaBBinder
        return jbh != NULL ? jbh->get(env, obj) : NULL;
    }
    ......
    return NULL;
}

JavaBBinderHolder 在 AMS 创建时一同被创建了,保存在 gBinderOffsets.mObject 中

通过调用 JavaBBinderHolder#get 函数可以创建 JavaBBinder 对象

此时创建的 JavaBBinder 对象的 mObject 字段持有了 AMS

ibinderForJavaObject 函数会返回一个 JavaBBinder 对象,其持有了 AMS

Parcel::writeStrongBinder()

// frameworks/native/libs/binder/Parcel.cpp
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
    return flatten_binder(ProcessState::self(), val, this);
}

status_t flatten_binder(const sp<ProcessState>& /*proc*/,
    const sp<IBinder>& binder, // binder = JavaBBinder
    Parcel* out // out = ServiceManagerProxy.addSevice 函数中定义的 data
){
    // 用于封装 JavaBBinder
    flat_binder_object obj;
    ......
    if (binder != NULL)
    {
        // 判断 binder 对象是 BpBinder 还是 BBinder,
        // JavaBBinder 是 BBinder,local 不为 NULL,执行 else
        IBinder *local = binder->localBinder();
        if (!local)
        {
            ......
        }
        else
        {
            obj.type = BINDER_TYPE_BINDER;
            // local->getWeakRefs() = JavaBBinder = AMS
            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
            obj.cookie = reinterpret_cast<uintptr_t>(local);
        }
    }
    else
    {
        ......
    }
    return finish_flatten_binder(binder, obj, out);
}

inline static status_t finish_flatten_binder(
            const sp<IBinder>& binder, // binder = JavaBBinder
            const flat_binder_object& flat, 
            Parcel* out // out = ServiceManagerProxy.addSevice 函数中定义的 data
){
    // 将 flat_binder_object 对象写入 data
    return out->writeObject(flat, false);
}

flat_binder_object 在之后的流程中还会出现,需要对其留个印象;当数据传输到 binder 驱动时,就会转变成 flat_binder_object 结构体进行处理

flat_binder_object 是对于 JavaBBinder 的封装,而 JavaBBinder 又持有了 AMS,可以理解为 flat_binder_object 就是对于 AMS 的封装

同时我们还需要留意此时 flat_binder_object.type = BINDER_TYPE_BINDER

AMS 最终是被封装成 flat_binder_object 写入 data 中的

AMS 是如何将自己发送给 SM 的?

// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public void addService(String name, IBinder service, boolean allowIsolated)
{
    // 创建 data
    Parcel data = Parcel.obtain();
    ......
    // mRemote = BinderProxy,相当于调用到 BinderProxy.transact
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    ......
}

BinderProxy.transact()

// android\frameworks\base\core\java\android\os\Binder.java
public boolean transact(int code, Parcel data, Parcel reply, int flags)
{
    ......
    return transactNative(code, data, reply, flags);
}

public native boolean transactNative(int code, Parcel data, Parcel reply, int flags);
            
// android\frameworks\base\core\jni\android_util_Binder.cpp
static const JNINativeMethod gBinderProxyMethods[] = {
    ......
    {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", 
            (void*)android_os_BinderProxy_transact},
    ......
};

// android\frameworks\base\core\jni\android_util_Binder.cpp
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
                    jint code, // code = ADD_SERVICE_TRANSACTION
                    jobject dataObj,
                    jobject replyObj,
                    jint flags
){
    ......
    // 将 dataObj 的类型转成 Parcel
    Parcel* data = parcelForJavaObject(env, dataObj);
    ......
    // 将 replyObj 的类型转成 Parcel
    Parcel* reply = parcelForJavaObject(env, replyObj);
    ......
    // 获取 gBinderProxyOffsets.mObject 中保存的 BpBinder 对象
    IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
    ......
    // 调用到 BpBinder 对象的 transact 函数
    status_t err = target->transact(code, *data, reply, flags);
    ......
}

// android\frameworks\native\libs\binder\BpBinder.cpp
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    ......
    // mHandle = 0
    status_t status = IPCThreadState::self()->transact(mHandle, code, data, 
                                                       reply, flags);
    ......
}

IPCThreadState::self()

// android\frameworks\native\libs\binder\IPCThreadState.cpp

static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; // 并发锁对象
static bool gHaveTLS = false; // 标识TLS是否已经创建
static pthread_key_t gTLS = 0; // TLS存储的key

IPCThreadState* IPCThreadState::self()
{
    if (gHaveTLS)
    {
restart:
        const pthread_key_t k = gTLS;
        // 调用pthread_getspecific,通过gTLS获取存储的数据
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        if (st) return st;
        return new IPCThreadState;
    }
    ......
    pthread_mutex_lock(&gTLSMutex); // 加锁,防止线程并发访问
    // gHaveTLS初始值为false,表示TLS未创建
    if (!gHaveTLS)
    {
        // 调用pthread_key_create创建TLS,并对gTLS赋值
        // (pthread_key_create创建成功返回0,反之返回错误码)
        if (pthread_key_create(&gTLS, threadDestructor) != 0)
        {
            pthread_mutex_unlock(&gTLSMutex); // 释放锁
            return NULL; // 创建TLS错误就返回null
        }
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex); // 释放锁
    goto restart;
}

IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()), // 调用 ProcessState::self 函数
      ......
{
    // 调用pthread_setspecific,将IPCThreadState对象保存到TLS中
    pthread_setspecific(gTLS, this);
    ......
    mIn.setDataCapacity(256); // 设置 mIn 的大小
    mOut.setDataCapacity(256); // 设置 mOut 的大小
}

IPCThreadState::self() 函数完成了对于 IPCThreadState 对象的创建

为了做到让 IPCThreadState 对象对应每一个线程独一份,系统使用了 Linux 中的 TLS 技术

TLS 是指 Thread local storage(线程本地储存空间),每个线程都拥有自己的 TLS,并且是私有空间,线程之间不会共享,可以近似理解为 Java 中的 ThreadLocal

可以通过 pthread_getspecific / pthread_setspecific 函数获取 / 设置 TLS 空间中的内容

IPCThreadState::self() 函数中,将 IPCThreadState 对象使用 TLS 进行存储,使得 IPCThreadState 对象对于每个线程来说是唯一的

IPCThreadState::transact()

// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::transact(int32_t handle, // handle = 0
                        uint32_t code, // code = ADD_SERVICE_TRANSACTION
                        const Parcel& data,
                        Parcel* reply,
                        uint32_t flags
){
    // 数据错误检查
    status_t err = data.errorCheck();

    // TF_ACCEPT_FDS = 0x10:允许回复中包含文件描述符 
    // TF_ONE_WAY:当前业务是异步的,不需要等待 
    // TF_ROOT_OBJECT:所包含的内容是根对象 
    // TF_STATUS_CODE:所包含的内容是 32-bit 的状态值
    flags |= TF_ACCEPT_FDS;
    ......
    // 整理数据,将 flat_binder_object(data)写入 mOut 中
    err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
    ......
    // 判断当前业务是否为异步操作。
    // AIDL 默认是同步操作,除非定义 AIDL 接口时使用了 oneway 关键字。
    if ((flags & TF_ONE_WAY) == 0)
    {
        ......
        // reply 不为空
        if (reply)
        {
            // 等待 binder 驱动回应事件
            err = waitForResponse(reply);
        }
        else
        {
            Parcel fakeReply;
            // 等待 binder 驱动回应事件
            err = waitForResponse(&fakeReply);
        }
        ......
    }
    else
    {
        // 不等待 binder 驱动回应事件
        err = waitForResponse(NULL, NULL);
    }
    ......
}

mOut 中分为两部分:

  • 命令部分(在 mOut 中的地址高位)

  • 数据部分,封装好的 flat_binder_object 位于这部分(在 mOut 中的地址低位)

结构如下图所示

IPCThreadState::waitForResponse()

// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::waitForResponse(
                    Parcel *reply,
                    status_t *acquireResult
){
    uint32_t cmd;
    int32_t err;
    // 循环等待结果
    while (1)
    {
        // 调用 talkWithDriver 函数发送指令给 binder 驱动
        if ((err=talkWithDriver()) < NO_ERROR) break;
        ......
        // 如果 mIn 中没有数据,就 continue
        if (mIn.dataAvail() == 0) continue;
        ......
    }
    ......
}
IPCThreadState::talkWithDriver()
// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    ......
    // mIn 是宏定义的 Parcel 变量,此时 mIn 未进行赋值
    // mIn.dataPosition() = mIn.dataSize() = 0,needRead为true
    const bool needRead = mIn.dataPosition() >= mIn.dataSize();
    ......
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
    
    bwr.write_size = outAvail;
    // 此时 bwr.write_buffer 指向 mOut 的起始地址
    bwr.write_buffer = (uintptr_t)mOut.data();

    // 如果需要读数据
    if (doReceive && needRead)
    {
        // dataCapacity = 256
        bwr.read_size = mIn.dataCapacity();
        // 此时的 mIn.data() = 0
        bwr.read_buffer = (uintptr_t)mIn.data();
    }
    else // 不需要读数据就设置 bwr.read_size 为零
         // 这样在 binder_ioctl_write_read 函数中就不会执行 binder_thread_read
    {
        bwr.read_size = 0;
        bwr.read_buffer = 0;
    }
    ......
    bwr.write_consumed = 0;
    bwr.read_consumed = 0;
    // 循环发送指令给 binder 驱动直至成功
    do {
        ......
        // 通过系统调用到 binder 驱动的 binder_ioctl 方法,进入内核态
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
        ......
    } while (err == -EINTR); // 只有当 ioctl 发生错误后 while 循环条件才会成立,
                             // 因此如果发送成功就只执行一次
    ......

    return err;
}
binder_ioctl()
// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp, 
                        unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
                        unsigned long arg // arg 就是我们传入的 bwr
){
    // 获取 binder 驱动的设备节点
    struct binder_proc *proc = filp->private_data;
    struct binder_thread *thread;
    ......
    // 获取 binder 线程
    // (当前 pid 此时没有创建过 binder 线程,则创建一个 binder 线程并返回)
    // thread->looper = BINDER_LOOPER_STATE_NEED_RETURN
    // thread->return_error = BR_OK
    // thread->return_error2 = BR_OK
    thread = binder_get_thread(proc);
    ......
    switch (cmd)
    {
        case BINDER_WRITE_READ:
            ret = binder_ioctl_write_read(filp, cmd, arg, thread);
            ......
            break;
        ......
    }
    ......
    return ret;
}
binder_ioctl_write_read()
// kernel\drivers\staging\android\binder.c
static int binder_ioctl_write_read(struct file *filp,
				unsigned int cmd, unsigned long arg,
				struct binder_thread *thread)
{
    struct binder_proc *proc = filp->private_data;
    ......
    void __user *ubuf = (void __user *)arg;
    struct binder_write_read bwr;

    // 将 mOut 的起始地址从用户空间拷贝到内核空间(bwr)
    if (copy_from_user(&bwr, ubuf, sizeof(bwr)))
    {
        ret = -EFAULT;
        goto out;
    }
    ......
    // 此时 bwr.write_size > 0,if命中
    if (bwr.write_size > 0)
    {
        // 发送指令给 binder 驱动
        ret = binder_thread_write(proc, thread,
                        bwr.write_buffer,
                        bwr.write_size,
                        &bwr.write_consumed);
        ......
    }
    // 此时 bwr.read_size > 0,if命中
    if (bwr.read_size > 0)
    {
        // 读取 binder 驱动返回的指令
        ret = binder_thread_read(proc, thread, bwr.read_buffer,
                        bwr.read_size,
                        &bwr.read_consumed,
                        filp->f_flags & O_NONBLOCK);
        ......
    }
    ......
out:
    return ret;
}
binder_thread_write()
// kernel\drivers\staging\android\binder.c
static int binder_thread_write(struct binder_proc *proc,
			struct binder_thread *thread,
			binder_uintptr_t binder_buffer, size_t size,
			binder_size_t *consumed)
{
    uint32_t cmd;
    struct binder_context *context = proc->context;
    void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
    // 指向 mOut 起始地址的指针
    void __user *ptr = buffer + *consumed;
    // 指向 mOut 结束地址的指针
    void __user *end = buffer + size;
    
    // 遍历 mOut 的内存指针,取出指令
    while (ptr < end && thread->return_error == BR_OK)
    {
        // 将 mOut 命令部分中的命令从用户空间拷贝到内核空间(cmd),
        // 此时 cmd = BC_TRANSACTION
        if (get_user(cmd, (uint32_t __user *)ptr))
            return -EFAULT;
        // 指针后移
        ptr += sizeof(uint32_t);
        ......
        switch (cmd)
        {
            ......
            case BC_TRANSACTION:
            case BC_REPLY:
            {
                struct binder_transaction_data tr;
                // 将 mOut 数据部分中的 binder_transaction_data 从用户空间拷贝到内核空间
                if (copy_from_user(&tr, ptr, sizeof(tr)))
                    return -EFAULT;
                // 指针后移
                ptr += sizeof(tr);
                // 调用 binder_transaction 函数
                binder_transaction(proc, thread, &tr, cmd == BC_REPLY, 0);
                break;
            }
            ......
        }
        ......
    }
    ......
}

这里还不是真正意义上的一次拷贝

binder_transaction()
// kernel\drivers\staging\android\binder.c
static void binder_transaction(struct binder_proc *proc,
			       struct binder_thread *thread,
			       struct binder_transaction_data *tr, // mOut 数据部分
				   int reply, // 此时 reply = false
			       binder_size_t extra_buffers_size)
{
    ......
    struct binder_transaction *t;
    struct binder_work *tcomplete;
    binder_size_t *offp, *off_end, *off_start;
    ......
    struct binder_proc *target_proc;
    struct binder_thread *target_thread = NULL;
    struct binder_node *target_node = NULL;
    struct list_head *target_list;
    wait_queue_head_t *target_wait;
    ......
    // 此处 reply 为 false(cmd == BC_TRANSACTION)
    if (reply)
    {
        ......
    }
    else
    {
        // tr->target.handle = 0,执行 else
        if (tr->target.handle)
        {
            ......
        }
        else
        {
            // 获取 SM 的 binder_node 节点
            target_node = context->binder_context_mgr_node;
            ......
        }
        ......
        // 获取 SM 的 binder_proc
        target_proc = target_node->proc;
        ......
    }
    // 获取 SM 的 todo 队列和 wait 队列
    target_list = &target_proc->todo;
    target_wait = &target_proc->wait;
    ......
    // 生成一个 binder_transaction 变量(即变量 t),
    // 用于描述本次要进行的 transaction(最后将其加入 target_thread->todo)。
    // 这样当目标对象被唤醒时,它就可以从这个队列中取出需要做的工作。
    t = kzalloc(sizeof(*t), GFP_KERNEL);
    ......
    // 生成一个 binder_work 变量(即变量 tcomplete),用于说明 AMS 有一个未完成的工作
    tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
    ......
    // 此时 if 命中
    if (!reply && !(tr->flags & TF_ONE_WAY))
        // 非 oneway(同步)的通信方式,把当前 thread 保存到 transaction 的 from 字段
        t->from = thread;
    else
        t->from = NULL;
    ......
    // 记录此次通信的目标进程
    t->to_proc = target_proc;
    ......
    // 此次通信 code = ADD_SERVICE_TRANSACTION
    t->code = tr->code;
    // 此次通信 flags = 0
    t->flags = tr->flags;
    ......
    // 从 SM 进程中分配 buffer
    // (为完成本条 transaction 申请内存,从 binder_mmap 开辟的空间中申请内存)
    t->buffer = binder_alloc_buf(target_proc, tr->data_size,
            tr->offsets_size, extra_buffers_size,
            !reply && (t->flags & TF_ONE_WAY));
    ......
    // 记录 SM 的 binder_node
    t->buffer->target_node = target_node;
    ......
    // 记录 mOut 数据部分的起始地址
    off_start = (binder_size_t *)(t->buffer->data +
            ALIGN(tr->data_size, sizeof(void *)));
    offp = off_start;
    ......
    // 将 mOut 数据部分从用户空间拷贝到内核空间(t->buffer->data)(一次拷贝)
    if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
                    tr->data.ptr.buffer, tr->data_size))
    ......
    // 记录 mOut 数据部分的结束地址
    off_end = (void *)off_start + tr->offsets_size;
    ......
    // 遍历 mOut 数据部分的内存指针
    for (; offp < off_end; offp++)
    {
        struct binder_object_header *hdr;
        ......
        // 将 mOut 的数据部分转型成 binder_object_header
        hdr = (struct binder_object_header *)(t->buffer->data + *offp);
        ......
        switch (hdr->type) // 此时 hdr->type = flat_binder_object.type = BINDER_TYPE_BINDER
        {
            case BINDER_TYPE_BINDER:
            case BINDER_TYPE_WEAK_BINDER:
            {
                struct flat_binder_object *fp;
                // 将数据转型成 flat_binder_object 结构体
                fp = to_flat_binder_object(hdr);
                // 创建 AMS 在 binder 驱动中的实体节点,并创建对该节点的引用(handle)
                ret = binder_translate_binder(fp, t, thread);
                ......
            } break;
            ......
        }
    }
    ......
    // 此时 cmd = BC_TRANSACTION,cmd != BC_REPLY,reply = false
    if (reply)
    {
        ......
    }
    else if(!(t->flags & TF_ONE_WAY)) // 操作是同步的,命中
    {
        ......
        // 记录本次的 transaction,以备后期查询
        // (SM 通过这个知道是谁调用的,从而返回数据)
        thread->transaction_stack = t;
    }
    else
    {
        ......
    }
    // 设置 t 的类型为 BINDER_WORK_TRANSACTION
    t->work.type = BINDER_WORK_TRANSACTION;
    // 将 t 加入 SM 进程的 todo 队列
    list_add_tail(&t->work.entry, target_list);
    // 设置 binder_work 的类型为 BINDER_WORK_TRANSACTION_COMPLETE
    tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
    // 将 tcomplete 加入 AMS 线程的 todo 队列
    list_add_tail(&tcomplete->entry, &thread->todo);
    // 此时 SM 被挂起,target_wait != NULL,if命中
    if (target_wait)
        // 唤醒 SM 进程
        wake_up_interruptible(target_wait);
    return;
    ......
}

binder_transaction 函数主要做了几件事:

  1. 获取到 SM 进程的 binder_proc 结构体
  2. 生成一个 binder_transaction 变量(给 SM 的)和一个 binder_work 变量(给 AMS 的)来保存信息
  3. 将封装好的 flat_binder_object 拷贝到 binder_mmap 开辟的共享内存中(重点,一次拷贝)
  4. 创建 AMS 在 binder 驱动中的实体节点,并创建对该节点的引用(handle)
  5. 将 binder_transaction 变量添加到 SM 进程的 todo 队列,唤醒 SM 进程
  6. 将 binder_work 变量添加到 AMS 调用线程的 todo 队列,将 AMS 挂起等待

binder_transaction 函数中才真正的做到了 IPC 通信传输

binder_thread_read()
// kernel\drivers\staging\android\binder.c
static int binder_thread_read(struct binder_proc *proc,
			      struct binder_thread *thread,
			      binder_uintptr_t binder_buffer, size_t size,
			      binder_size_t *consumed, int non_block)
{
    void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
    // 指向 mIn 内存起始地址的指针
    void __user *ptr = buffer + *consumed;
    // 指向 mIn 内存结束地址的指针
    void __user *end = buffer + size;

    int ret = 0;
    int wait_for_proc_work;
    ......
retry:
    // 1. thread->todo 不为空,wait_for_proc_work 为 false
    // 2. thread->todo 为空,wait_for_proc_work 为 true
    wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);
    // 1. 执行 else
    // 2. 执行 if
    if (wait_for_proc_work)
    {
        ......
        if (non_block) // 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
                       // 此时 non_block > 0,执行else
        {
            ......
        }
        else
            // 2. thread->todo 为空,binder_has_thread_work 返回 false,将 AMS 线程挂起
            ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
    }
    else
    {
        if (non_block) // 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
                       // 此时 non_block > 0,执行else
        {
            ......
        }
        else
            // 1. thread->todo 不为空,binder_has_thread_work 返回 true,不会将 AMS 线程挂起
            ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread));
    }
    ......
    // 1. 线程没有挂起,继续执行 while 循环
    while (1)
    {
        uint32_t cmd;
        struct binder_transaction_data tr;
        struct binder_work *w;
        struct binder_transaction *t = NULL;
        
        // 1. 在 binder_transaction 函数中添加了一个 binder_work,此时 thread->todo 不为空,if 命中
        // 2. 在执行 BINDER_WORK_TRANSACTION_COMPLETE 指令的时候将 binder_work 删除了,
        // 此时 thread->todo 为空,执行else
        if (!list_empty(&thread->todo))
        {
            // 1. 取出 binder_work
            w = list_first_entry(&thread->todo, struct binder_work, entry);
        }
        else
        {
            // 2. 此时 if 命中
            if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN))
                // 2. 返回 retry 处执行代码
                goto retry;
            break;
        }
        ......
        // 1. 此时 w->type 为 BINDER_WORK_TRANSACTION_COMPLETE
        switch (w->type)
        {
            ......
            case BINDER_WORK_TRANSACTION_COMPLETE:
            {
                // 1. 更改指令 BR_TRANSACTION_COMPLETE
                cmd = BR_TRANSACTION_COMPLETE;
                // 1. 将指令拷贝到 mIn 中
                if (put_user(cmd, (uint32_t __user *)ptr))
                    return -EFAULT;
                // 1. 指针后移
                ptr += sizeof(uint32_t);
                ......
                // 1. 将当前的 binder_work 从 thread->todo 中删除
                list_del(&w->entry);
                // 1. 释放 binder_work 的内存
                kfree(w);
                ......
            } break;
            ......
        }
        // 1. 此时 t = null,if 命中
        if (!t)
            continue;
        ......
    }
    *consumed = ptr - buffer;
    ......
    return 0;
}

binder_thread_read 函数中的 while 循环会执行两次,所以代码中的注释写了序号,序号对应着第几次 while 循环

此时 AMS 就被挂起了,等待 SM 进程返回数据后唤醒

当 AMS 被唤醒后就从此处的 binder_thread_read 函数开始继续执行

SM 进程被唤醒后做了什么?

binder_transaction 函数执行完成后,SM 线程被唤醒,继续执行未完成的 binder_thread_read 函数

binder_thread_read()

// kernel\drivers\staging\android\binder.c
static int binder_thread_read(struct binder_proc *proc,
			      struct binder_thread *thread,
			      binder_uintptr_t binder_buffer, size_t size,
			      binder_size_t *consumed, int non_block)
{
    ......

    if (wait_for_proc_work)
        // 当前进程可用的 binder 线程数 -1
        proc->ready_threads--;
    thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
    
    ......
    
    while (1)
    {
        uint32_t cmd;
        struct binder_transaction_data tr;
        struct binder_work *w;
        struct binder_transaction *t = NULL;
        ......
        // 在 binder_transaction 函数中添加了一个 binder_transaction,此时 proc->todo 不为空
        else if (!list_empty(&proc->todo) && wait_for_proc_work)
        {
            // 取出 binder_transaction,但类型是 binder_work
            w = list_first_entry(&proc->todo, struct binder_work, entry);
        }
        ......
        // 此时 w->type 为 BINDER_WORK_TRANSACTION
        switch (w->type)
        {
            ......
            case BINDER_WORK_TRANSACTION:
            {
                // 类型转换(binder_work -> binder_transaction)
                t = container_of(w, struct binder_transaction, work);
            } break;
            ......
        }
        // 此时 t != null,if不命中
        if (!t)
            continue;
        ......
        // 此时 t->buffer->target_node = SM,不为空,if命中
        if (t->buffer->target_node)
        {
            struct binder_node *target_node = t->buffer->target_node;
            tr.target.ptr = target_node->ptr;
            tr.cookie =  target_node->cookie;
            ......
            // 指令更改为 BR_TRANSACTION
            cmd = BR_TRANSACTION;
        }
        else
        {
            ......
        }
        
        // t->code = ADD_SERVICE_TRANSACTION
        tr.code = t->code;
        // t->flags = 0
        tr.flags = t->flags;
        
        // 此时 t->from 不为 NULL,if 命中
        if (t->from)
        {
            struct task_struct *sender = t->from->proc->tsk;
            // 获取 AMS 线程的 pid 并记录
            tr.sender_pid = task_tgid_nr_ns(sender, task_active_pid_ns(current));
        }
        else
        {
            ......
        }
        // 记录 mOut 数据部分的内存地址、大小等信息
        tr.data_size = t->buffer->data_size;
        tr.offsets_size = t->buffer->offsets_size;
        tr.data.ptr.buffer = (binder_uintptr_t)((uintptr_t)t->buffer->data + 
                                                proc->user_buffer_offset);
        tr.data.ptr.offsets = tr.data.ptr.buffer + ALIGN(t->buffer->data_size, 
                                                         sizeof(void *));
        
        // 将指令 BR_TRANSACTION 拷贝到用户空间(binder_loop 中的 readbuf)
        if (put_user(cmd, (uint32_t __user *)ptr))
            return -EFAULT;
        // 指针后移
        ptr += sizeof(uint32_t);
        
        // 将 mOut 数据部分的信息拷贝到用户空间(binder_loop 中的 readbuf)
        if (copy_to_user(ptr, &tr, sizeof(tr)))
            return -EFAULT;
        // 指针后移
        ptr += sizeof(tr);
        ......
        // 此时 if 命中
        if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY))
        {
            t->to_parent = thread->transaction_stack;
            t->to_thread = thread;
            // 将 t 保存在 SM 线程的 transaction_stack 中
            thread->transaction_stack = t;
        }
        else
        {
            ......
        }
        // 跳出循环
        break;
        ......
    }

    *consumed = ptr - buffer;
    // 此时 proc->requested_threads = proc->ready_threads = 0,
    // proc->requested_threads_started = 0 < proc->max_threads(默认是15),
    // thread->looper = BINDER_LOOPER_STATE_NEED_RETURN + BINDER_LOOPER_STATE_ENTERED,
    // 条件满足,if 命中
    if (proc->requested_threads + proc->ready_threads == 0 && 
        proc->requested_threads_started < proc->max_threads && 
        (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | 
                           BINDER_LOOPER_STATE_ENTERED))
    {
        ......
        // 当前进程需要创建的 binder 线程数 +1
        proc->requested_threads++;
        // 将指令 BR_SPAWN_LOOPER 拷贝到用户空间(binder_loop 中的 readbuf)
        if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
            return -EFAULT;
        ......
    }
    return 0;
}

binder_thread_read 函数执行完成后,binder_ioctl_write_read 函数也执行完成,返回到 binder_loop 函数,继续执行

此时 readbuf 的结构如下

binder_loop()

// frameworks/native/cmds/servicemanager/binder.c
void binder_loop(struct binder_state *bs, binder_handler func)
{
    ......
    for (;;)
    {
        ......
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
        ......
    }
}

binder_parse()

readbuf 中别的指令处理流程都可以不用管,直接看最重要的 BR_TRANSACTION

// frameworks/native/cmds/servicemanager/binder.c
int binder_parse(struct binder_state *bs, 
                struct binder_io *bio,
                uintptr_t ptr, // ptr 指向 binder_loop 中 readbuf 的起始地址
                size_t size, // size = binder_loop 中 readbuf 的长度
                binder_handler func
){
    int r = 1;
    // 指向 binder_loop 中的 bwr.read_buffer 内存结束地址的指针
    uintptr_t end = ptr + (uintptr_t) size;

    while (ptr < end)
    {
        // 指令占用的内存大小是 uint32_t,取出 readbuf 中的指令(从头开始)
        uint32_t cmd = *(uint32_t *) ptr;
        // 指针后移
        ptr += sizeof(uint32_t);
        ......
        switch(cmd)
        {
            ......
            case BR_TRANSACTION:
            {
                // 将 mOut 数据部分转型为 binder_transaction_data
                struct binder_transaction_data *txn = 
                    	(struct binder_transaction_data *) ptr;
                ......
                // 函数指针引用,此时 func = service_manager.svcmgr_handler,if 命中
                if (func)
                {
                    unsigned rdata[256/4];
                    struct binder_io msg;
                    struct binder_io reply;
                    int res;
                    // 初始化 reply
                    bio_init(&reply, rdata, sizeof(rdata), 4);
                    // 初始化 msg,将 mOut 数据部分的信息拷贝到 msg 中
                    bio_init_from_txn(&msg, txn);
                    // 执行 service_manager.svcmgr_handler 函数
                    res = func(bs, txn, &msg, &reply);
                    // 将 reply 发送给 binder 驱动
                    binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
                }
                // 指针后移
                ptr += sizeof(*txn);
                break;
            }
            ......
        }
    }
    return r;
}

func 是一个函数指针,指向 service_manager.svcmgr_handler 函数,所以 res = func(bs, txn, &msg, &reply); 这行代码调用的就是 service_manager.svcmgr_handler 函数

service_manager.svcmgr_handler()

// frameworks/native/cmds/servicemanager/service_manager.c
int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn, // mOut 数据部分
                   struct binder_io *msg, // mOut 数据部分的信息
                   struct binder_io *reply
){
    struct svcinfo *si;
    uint16_t *s;
    size_t len;
    uint32_t handle;
    uint32_t strict_policy;
    int allow_isolated;
    ......
    // 此时 txn->code = ADD_SERVICE_TRANSACTION = 3 = SVC_MGR_ADD_SERVICE
    switch(txn->code)
    {
        ......
        case SVC_MGR_ADD_SERVICE:
            // 从 mOut 数据部分中获取 AMS 的名称
            s = bio_get_string16(msg, &len);
            ......
            // 从 mOut 数据部分中获取 AMS 的引用(handle)
            handle = bio_get_ref(msg);
            allow_isolated = bio_get_uint32(msg) ? 1 : 0;
            // 在 SM 中记录 AMS
            if (do_add_service(bs, s, len, handle, txn->sender_euid,
                allow_isolated, txn->sender_pid))
                return -1;
            break;
        ......
    }
    // 此时 reply 中没有数据
    bio_put_uint32(reply, 0);
    return 0;
}
do_add_service()
// frameworks/native/cmds/servicemanager/service_manager.c
int do_add_service(struct binder_state *bs,
                   const uint16_t *s, size_t len,
                   uint32_t handle, uid_t uid, int allow_isolated,
                   pid_t spid
){
    // 在 SM 中用 svcinfo 结构体保存注册过的 Service 信息
    struct svcinfo *si;
    ......
    // 查找 AMS 是否在 SM 注册过
    si = find_svc(s, len);
    // 如果 AMS 已经注册过了
    if (si)
    {
        if (si->handle)
        {
            ......
            // 将当前这个 svcinfo 中记录的引用(handle)清空
            svcinfo_death(bs, si);
        }
        // 对当前这个 svcinfo 中的引用(handle)重新赋值
        si->handle = handle;
    }
    else // 如果 AMS 没注册过
    {
        // 创建一个新的 svcinfo 结构体
        si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
        ......
        // 记录 AMS 的引用(handle)
        si->handle = handle;
        si->len = len;
        // 拷贝 AMS 信息
        memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
        si->name[len] = '\0';
        si->death.func = (void*) svcinfo_death;
        si->death.ptr = si;
        si->allow_isolated = allow_isolated;
        // 将创建的 svcinfo 结构体添加到 svclist 中
        si->next = svclist;
        svclist = si;
    }
    // 以 BC_ACQUIRE 命令,handle 为目标的信息,通过 ioctl 发送给 binder 驱动,
    // 使 binder_ref 强引用加1操作
    binder_acquire(bs, handle);
    // 以 BC_REQUEST_DEATH_NOTIFICATION 命令的信息,通过 ioctl 发送给 binder 驱动,
    // 主要进行清理内存等收尾工作
    binder_link_to_death(bs, handle, &si->death);
    return 0;
}

service_manager.do_add_service 函数将 AMS 记录到了 SM 中,完成了注册

在 SM 中保存是 AMS 的名称对于 AMS 在 binder 驱动中实体节点的引用(handle)

当之后有别的进程通过访问 SM 来请求 AMS 时,SM 就会返回这个引用给请求方

binder_send_reply()

// frameworks/native/cmds/servicemanager/binder.c
void binder_send_reply(
    	struct binder_state *bs,
		struct binder_io *reply, // 此时 reply 中是空的
		binder_uintptr_t buffer_to_free, //  mOut 数据部分内存起始地址的指针
		int status // status = 0
){
    // 定义了一个结构体 data,用于封装命令和 reply
    struct {
        uint32_t cmd_free; // 占高位
        binder_uintptr_t buffer;
        uint32_t cmd_reply; // 占低位
        struct binder_transaction_data txn;
    } __attribute__((packed)) data;

    data.cmd_free = BC_FREE_BUFFER; // free buffer 命令
    data.buffer = buffer_to_free;
    data.cmd_reply = BC_REPLY; // reply 命令
    data.txn.target.ptr = 0;
    data.txn.cookie = 0;
    data.txn.code = 0;
    
    // status = 0,执行 else
    if (status)
    {
        ......
    }
    else
    {
        // 使用 data 中的 binder_transaction_data(txn)记录 reply 的地址信息
        data.txn.flags = 0;
        data.txn.data_size = reply->data - reply->data0;
        data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
        data.txn.data.ptr.buffer = (uintptr_t)reply->data0;
        data.txn.data.ptr.offsets = (uintptr_t)reply->offs0;
    }
    // 向 binder 驱动通信,执行指令
    binder_write(bs, &data, sizeof(data));
}
binder_write()
// frameworks/native/cmds/servicemanager/binder.c
int binder_write(struct binder_state *bs, void *data, size_t len)
{
    struct binder_write_read bwr;
    int res;

    bwr.write_size = len;
    bwr.write_consumed = 0;
    bwr.write_buffer = (uintptr_t) data;
    bwr.read_size = 0;
    bwr.read_consumed = 0;
    bwr.read_buffer = 0;
    
    // 通过系统调用到 binder 驱动中的 binder_ioctl 函数,指令为 BINDER_WRITE_READ
    res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    ......
    return res;
}
binder_ioctl()
// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp, 
                        unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
                        unsigned long arg // arg 就是我们传入的 bwr
){
    // 获取 binder 驱动的设备节点
    struct binder_proc *proc = filp->private_data;
    struct binder_thread *thread;
    ......
    // 获取 binder 线程
    // (当前 pid 此时已经创建过 binder 线程,则返回对应的 binder 线程)
    // thread->looper = BINDER_LOOPER_STATE_NEED_RETURN + BINDER_LOOPER_STATE_ENTERED
    // thread->return_error = BR_OK
    // thread->return_error2 = BR_OK
    thread = binder_get_thread(proc);
    ......
    switch (cmd)
    {
        case BINDER_WRITE_READ:
            ret = binder_ioctl_write_read(filp, cmd, arg, thread);
            ......
            break;
        ......
    }
    ......
    return ret;
}
binder_ioctl_write_read()
// kernel/drivers/staging/android/binder.c
static int binder_ioctl_write_read(struct file *filp,
				unsigned int cmd, unsigned long arg,
				struct binder_thread *thread)
{
    int ret = 0;
    struct binder_proc *proc = filp->private_data;
    ......
    void __user *ubuf = (void __user *)arg;
    struct binder_write_read bwr;
    ......
    // 将 data 的起始地址从用户空间拷贝到内核空间(bwr)
    if (copy_from_user(&bwr, ubuf, sizeof(bwr)))
    {
        ret = -EFAULT;
        goto out;
    }
    ......
    if (bwr.write_size > 0)
    {
        // 发送指令给 binder 驱动
        ret = binder_thread_write(proc, thread,
                                bwr.write_buffer,
                                bwr.write_size,
                                &bwr.write_consumed);
        ......
    }
    // 此时 bwr.read_size = 0,if 不命中
    if (bwr.read_size > 0)
    {
	......
    }
    ......
out:
    return ret;
}
binder_thread_write()
// kernel/drivers/staging/android/binder.c
static int binder_thread_write(struct binder_proc *proc,
			struct binder_thread *thread,
			binder_uintptr_t binder_buffer, // binder_buffer = data 的起始地址
			size_t size, // data 的大小
			binder_size_t *consumed
){
    uint32_t cmd;
    struct binder_context *context = proc->context;
    void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
    // 指向 data 内存起始地址的指针
    void __user *ptr = buffer + *consumed;
    // 指向 data 内存结束地址的指针
    void __user *end = buffer + size;
    
    while (ptr < end && thread->return_error == BR_OK)
    {
        // 从 data 中读取指令
        if (get_user(cmd, (uint32_t __user *)ptr))
            return -EFAULT;
        // 指针后移
        ptr += sizeof(uint32_t);
        // cmd 先是 BC_FREE_BUFFER,再是 BC_REPLY
        switch (cmd)
        {
            ......
            case BC_FREE_BUFFER:
            {
                // 在这里会将 data.buffer 所指向的内存区域中的数据清空,
                // 也就是拷贝到内核空间中的 mOut 数据部分的缓存,
                // 在这里就不过多分析了
                ......
                break;
            }
            ......
            case BC_TRANSACTION:
            case BC_REPLY:
            {
                struct binder_transaction_data tr;
                // 将 data 中记录的 reply 从用户空间拷贝到内核空间(binder_transaction_data)
                if (copy_from_user(&tr, ptr, sizeof(tr)))
                    return -EFAULT;
                // 指针后移
                ptr += sizeof(tr);
                // 调用 binder_transaction 函数
                binder_transaction(proc, thread, &tr, cmd == BC_REPLY, 0);
                break;
            }
            ......
        }
        ......
    }
    return 0;
}
binder_transaction()

再次调用 binder_transaction 函数与 AMS 进程进行通信,通知 AMS 注册成功

// kernel\drivers\staging\android\binder.c
static void binder_transaction(struct binder_proc *proc,
			       struct binder_thread *thread,
			       struct binder_transaction_data *tr, 
				   int reply, // 此时 reply = true
			       binder_size_t extra_buffers_size)
{
    ......
    struct binder_transaction *t;
    struct binder_work *tcomplete;
    ......
    struct binder_proc *target_proc;
    struct binder_thread *target_thread = NULL;
    struct binder_node *target_node = NULL;
    struct list_head *target_list;
    wait_queue_head_t *target_wait;
    ......
    // 此处 reply 为 true(cmd == BC_REPLY)
    if (reply)
    {
        // 获取记录在 thread->transaction_stack 中的 binder_transaction
        in_reply_to = thread->transaction_stack;
        ......
        thread->transaction_stack = in_reply_to->to_parent;
        // in_reply_to->from = AMS 线程
        target_thread = in_reply_to->from;
        ......
        target_proc = target_thread->proc;
    }
    else
    {
        ......
    }
    // 此时 target_thread != NULL,if 命中
    if (target_thread)
    {
        // 获取 AMS 线程的 pid 值
        e->to_thread = target_thread->pid;
        // 获取 AMS 线程的 todo 队列和 wait 队列
        target_list = &target_thread->todo;
        target_wait = &target_thread->wait;
    }
    else
    {
        ......
    }
    ......
    // 生成一个 binder_transaction 变量(即变量 t),
    // 用于描述本次要进行的 transaction(最后将其加入 target_thread->todo)。
    // 这样当目标对象被唤醒时,它就可以从这个队列中取出需要做的工作。
    t = kzalloc(sizeof(*t), GFP_KERNEL);
    ......
    // 生成一个 binder_work 变量(即变量 tcomplete),用于说明 AMS 有一个未完成的工作
    tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
    ......
    // 此时 if 不命中,执行 else
    if (!reply && !(tr->flags & TF_ONE_WAY))
        ......
    else
        t->from = NULL;
    ......
    // 记录此次通信的目标进程(AMS)
    t->to_proc = target_proc;
    ......
    // 此次通信 code = 0
    t->code = tr->code;
    // 此次通信 flags = 0
    t->flags = tr->flags;
    ......
    // 从 AMS 进程中分配 buffer
    // (为完成本条 transaction 申请内存,从 binder_mmap 开辟的空间中申请内存)
    t->buffer = binder_alloc_buf(target_proc, tr->data_size,
            tr->offsets_size, extra_buffers_size,
            !reply && (t->flags & TF_ONE_WAY));
    ......
    // 记录 AMS 的 binder_node,此时 target_node = NULL
    t->buffer->target_node = target_node;
    ......
    // 将 reply 从用户空间拷贝到内核空间(t->buffer->data)
    if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
                    tr->data.ptr.buffer, tr->data_size))
    ......
    // 此时 cmd = BC_REPLY,reply = true
    if (reply)
    {
        ......
        // 清空数据,释放缓存
        binder_pop_transaction(target_thread, in_reply_to);
    }
    else if(!(t->flags & TF_ONE_WAY))
    {
        ......
    }
    else
    {
        ......
    }
    // 设置 t 的类型为 BINDER_WORK_TRANSACTION
    t->work.type = BINDER_WORK_TRANSACTION;
    // 将 t 加入 AMS 线程的 todo 队列
    list_add_tail(&t->work.entry, target_list);
    // 设置 binder_work 的类型为 BINDER_WORK_TRANSACTION_COMPLETE
    tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
    // 将 tcomplete 加入 SM 进程的 todo 队列
    list_add_tail(&tcomplete->entry, &thread->todo);
    // 此时 AMS 被挂起,target_wait != NULL,if命中
    if (target_wait)
        // 唤醒 AMS 进程
        wake_up_interruptible(target_wait);
    return;
    ......
}

binder_transaction 函数执行完成后,会一直返回到 binder_loop 函数,经过循环再次调用 ioctl 函数读取 binder 驱动的指令

binder_ioctl_write_read()

// kernel/drivers/staging/android/binder.c
static int binder_ioctl_write_read(struct file *filp,
				unsigned int cmd, unsigned long arg,
				struct binder_thread *thread
){
    struct binder_proc *proc = filp->private_data;
    ......
    void __user *ubuf = (void __user *)arg;
    struct binder_write_read bwr;
    
    // 将描述数据的 binder_write_read 结构体(ubuf)从用户空间拷贝到内核空间(bwr)中去
    if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
    ......
    // 此时 bwr.write_size = 0,if 不命中
    if (bwr.write_size > 0)
    {
        ......
    }
    // 此时 bwr.read_size > 0,if 命中
    if (bwr.read_size > 0)
    {
        // 读取 binder 驱动返回的指令
        ret = binder_thread_read(proc, thread, bwr.read_buffer,
                        bwr.read_size,
                        &bwr.read_consumed,
                        filp->f_flags & O_NONBLOCK);
        ......
    }
    ......
    return ret;
}

binder_thread_read()

static int binder_thread_read(struct binder_proc *proc,
			      struct binder_thread *thread,
			      binder_uintptr_t binder_buffer, size_t size,
			      binder_size_t *consumed, int non_block
){
    void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
    // 指向 binder_loop 中的 bwr.read_buffer 内存起始地址的指针
    void __user *ptr = buffer + *consumed;
    // 指向 binder_loop 中的 bwr.read_buffer 内存结束地址的指针
    void __user *end = buffer + size;

    int ret = 0;
    int wait_for_proc_work;
    ......
retry:
    // 1. thread->todo 不为空,wait_for_proc_work 为 false
    // 2. thread->todo 为空,wait_for_proc_work 为 true
    wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);
    ......
    // 1. 执行 else
    // 2. 执行 if
    if (wait_for_proc_work)
    {
        ......
        if (non_block) // 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
                       // 此时 non_block > 0,执行else
        {
            ......
        }
        else
            // 2. thread->todo 为空,binder_has_thread_work 返回 false,将 SM 线程挂起
            ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
    }
    else
    {
        if (non_block) // 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
                       // 此时 non_block > 0,执行 else
        {
            ......
        }
        else
            // 1. thread->todo 不为空,binder_has_thread_work 返回 true,不会将 SM 线程挂起
            ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread));
    }
    ......
    // 1. 线程没有挂起,继续执行 while 循环
    while (1)
    {
        uint32_t cmd;
        struct binder_transaction_data tr;
        struct binder_work *w;
        struct binder_transaction *t = NULL;
        
        // 1. 在 binder_transaction 函数中添加了一个 binder_work,此时 thread->todo 不为空,if 命中
        // 2. 在执行 BINDER_WORK_TRANSACTION_COMPLETE 指令的时候将 binder_work 删除了,
        // 此时 thread->todo 为空,执行else
        if (!list_empty(&thread->todo))
        {
            // 1. 取出 binder_work
            w = list_first_entry(&thread->todo, struct binder_work, entry);
        }
        else
        {
            // 2. 此时 if 命中
            if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN))
                // 2. 返回 retry 处执行代码
                goto retry;
            break;
        }
        ......
        // 1. 此时 w->type 为 BINDER_WORK_TRANSACTION_COMPLETE
        switch (w->type)
        {
            ......
            case BINDER_WORK_TRANSACTION_COMPLETE:
            {
                // 1. 更改指令 BR_TRANSACTION_COMPLETE
                cmd = BR_TRANSACTION_COMPLETE;
                // 1. 将指令拷贝到 binder_loop 中的 bwr.read_buffer
                if (put_user(cmd, (uint32_t __user *)ptr))
                    return -EFAULT;
                // 1. 指针后移
                ptr += sizeof(uint32_t);
                ......
                // 1. 将当前的 binder_work 从 thread->todo 中删除
                list_del(&w->entry);
                // 1. 释放 binder_work 的内存
                kfree(w);
                ......
            } break;
            ......
        }
        // 1. 此时 t = null,if 命中
        if (!t)
            continue;
        ......
    }
    *consumed = ptr - buffer;
    ......
    return 0;
}

binder_thread_read 函数中 while 循环会执行两次,所以代码中的注释写了序号,序号对应着第几次 while 循环

此时 SM 就再次被挂起了,等待其他进程与之通信后被唤醒

当 SM 被唤醒后就从此处的 binder_thread_read 函数开始继续执行

AMS 进程被唤醒后做了什么?

binder_transaction 函数执行完成后,AMS 进程被唤醒,继续执行未完成的 binder_thread_read 函数

binder_thread_read()
// kernel\drivers\staging\android\binder.c
static int binder_thread_read(struct binder_proc *proc,
			      struct binder_thread *thread,
			      binder_uintptr_t binder_buffer, size_t size,
			      binder_size_t *consumed, int non_block)
{
    ......
    while (1)
    {
        uint32_t cmd;
        struct binder_transaction_data tr;
        struct binder_work *w;
        struct binder_transaction *t = NULL;
        ......
        // 在 binder_transaction 函数中添加了一个 binder_transaction,此时 proc->todo 不为空
        else if (!list_empty(&proc->todo) && wait_for_proc_work)
        {
            // 取出 binder_transaction,但类型是 binder_work
            w = list_first_entry(&proc->todo, struct binder_work, entry);
        }
        ......
        // 此时 w->type 为 BINDER_WORK_TRANSACTION
        switch (w->type)
        {
            ......
            case BINDER_WORK_TRANSACTION:
            {
                // 类型转换(binder_work -> binder_transaction)
                t = container_of(w, struct binder_transaction, work);
            } break;
            ......
        }
        // 此时 t != null,if不命中
        if (!t)
            continue;
        ......
        // 此时 t->buffer->target_node 为空,if 不命中
        if (t->buffer->target_node)
        {
            ......
        }
        else
        {
            tr.target.ptr = 0;
            tr.cookie = 0;
            // 指令更改为 BR_REPLY
            cmd = BR_REPLY;
        }
        
        // t->code = 0
        tr.code = t->code;
        // t->flags = 0
        tr.flags = t->flags;
        
        // 此时 t->from 为 NULL,if 不命中
        if (t->from)
        {
            ......
        }
        else
        {
            tr.sender_pid = 0;
        }
        // 记录 reply 的内存起始地址、大小等信息
        tr.data_size = t->buffer->data_size;
        tr.offsets_size = t->buffer->offsets_size;
        tr.data.ptr.buffer = (binder_uintptr_t)((uintptr_t)t->buffer->data + 
                                                proc->user_buffer_offset);
        tr.data.ptr.offsets = tr.data.ptr.buffer + 
            	ALIGN(t->buffer->data_size, sizeof(void *));
        
        // 将指令 BR_REPLY 拷贝到用户空间(mIn)
        if (put_user(cmd, (uint32_t __user *)ptr))
            return -EFAULT;
        // 指针后移
        ptr += sizeof(uint32_t);
        
        // 将 reply 的信息拷贝到用户空间(mIn)
        if (copy_to_user(ptr, &tr, sizeof(tr)))
            return -EFAULT;
        // 指针后移
        ptr += sizeof(tr);
        ......
        // 此时 if 不命中
        if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY))
        {
            ......
        }
        else
        {
            t->buffer->transaction = NULL;
            // 释放内存
            kfree(t);
        }
        // 跳出循环
        break;
        ......
    }
    *consumed = ptr - buffer;
    ......
    return 0;
}

binder_thread_read 函数执行完成后,一直返回到 IPCThreadState::talkWithDriver() 函数,继续执行

IPCThreadState::talkWithDriver()

// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    ......

    do {
        ......
        // 执行返回处
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
        ......
    } while (err == -EINTR); // 如果 ioctl 没有发生错误,退出循环

    ......

    // 如果 ioctl 没有发生错误,if 命中
    if (err >= NO_ERROR)
    {
        // 如果已经将 mOut 中的数据发送给了 Binder 驱动
        if (bwr.write_consumed > 0)
        {
            if (bwr.write_consumed < mOut.dataSize())
                // 将 mOut 中已经发送的数据删除
                mOut.remove(0, bwr.write_consumed);
            else
                mOut.setDataSize(0);
        }

        // 如果 mIn 中有数据,将 mIn 全部返回
        if (bwr.read_consumed > 0)
        {
            mIn.setDataSize(bwr.read_consumed);
            mIn.setDataPosition(0);
        }
        
        ......
        
        return NO_ERROR;
    }
    
    return err;
}

IPCThreadState::waitForResponse()

// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::waitForResponse(
                    Parcel *reply, // reply = ServiceManagerProxy.addSevice 中的 reply
                                   // 该 reply 位于用户空间
                    status_t *acquireResult
){
    uint32_t cmd;
    int32_t err;
    // 循环等待结果
    while (1)
    {
        ......
        // 读取 mIn 中的指令(BR_REPLY)
        cmd = (uint32_t)mIn.readInt32();
        ......
        switch(cmd)
        {
            ......
            case BR_REPLY:
            {
                binder_transaction_data tr;
                // 读取(位于内核空间的)reply 的信息
                err = mIn.read(&tr, sizeof(tr));
                ......
                //(位于用户空间的)reply 不为空,if 命中
                if (reply)
                {
                    // 此时 tr.flags = 0,if 命中
                    if ((tr.flags & TF_STATUS_CODE) == 0)
                    {
                        // 将(位于内核空间的)reply 写入(位于用户空间的)reply,
                        // 也就是写入 ServiceManagerProxy.addSevice 中的 reply
                        reply->ipcSetDataReference(
                                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                                tr.data_size,
                                reinterpret_cast<const binder_size_t*> 
                            			(tr.data.ptr.offsets),
                                tr.offsets_size/sizeof(binder_size_t),
                                freeBuffer, this);
                    }
                    else
                    {
                        ......
                    }
                }
                else
                {
                    ......
                }
            }
            // 跳出循环
            goto finish;
            ......
        }
    }
finish:
    if (err != NO_ERROR)
    {
        if (acquireResult) *acquireResult = err;
        if (reply) reply->setError(err);
        mLastError = err;
    }
    return err;
}

IPCThreadState::waitForResponse 函数执行完成后,一直返回到 ServiceManagerProxy.addSevice 函数,继续执行

ServiceManagerProxy.addSevice()

// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public void addService(String name, IBinder service, boolean allowIsolated) 
		throws RemoteException
{
    ......
    // 执行返回处
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    // 回收 data 和 reply
    reply.recycle();
    data.recycle();
}

至此,整个流程结束

总结

按照指令的顺序,AMS 的注册流程大致如下图

未命名文件.png

按照调用栈的顺序,AMS 的注册流程大致如下图

大家结合流程图再去看代码流程可能会更加清晰一些