Binder 浅析 —— AIDL 调用流程

Binder 浅析 —— 整体概览

Binder 浅析 —— AMS 注册流程

Binder 浅析 —— AMS 获取流程

Binder 机制是 Android 系统实现 IPC 的底层原理,通常只在系统源码中进行使用

而我们 Android 开发者通常做的都是应用层开发,当我们想要进行 IPC 时,想要使用 Binder 机制时,直接使用未免太繁琐了

因此谷歌为我们设计出了 AIDL

AIDL,全称是 Android Interface Definition Language(接口定义语言),相当于 Binder 机制在应用层的封装,我们可以通过使用 AIDL 实现 IPC 通信

这篇博客将解读 AIDL 的调用流程

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

APP 进程是如何发送数据给 AMS 的?

紧接上一篇博客,就以 APP 进程 AIDL 调用 AMS 服务绑定 Service 为例进行分析

// frameworks/base/core/java/android/app/ContextImpl.java
private boolean bindServiceCommon(Intent service, ServiceConnection conn, 
                                  int flags, UserHandle user
){
    ......
    int res = ActivityManagerNative.getDefault().bindService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, getOpPackageName(), user.getIdentifier());
    if (res < 0)
    {
        throw new SecurityException(
                "Not allowed to bind to service " + service);
    }
    return res != 0;
    ......
}
复制代码

通过上一篇博客我们得知,最终 ActivityManagerNative.getDefault() 函数会返回一个 ActivityManagerProxy 对象

// frameworks/base/core/java/android/app/ActivityManagerNative$ActivityManagerProxy.java
public int bindService(IApplicationThread caller, IBinder token,
            Intent service, String resolvedType, IServiceConnection connection,
            int flags, String callingPackage, int userId
){
    // 创建 data
    Parcel data = Parcel.obtain();
    // 创建 reply
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    // 将 APP 进程的 ApplicationThread 写入 data
    data.writeStrongBinder(caller != null ? caller.asBinder() : null);
    data.writeStrongBinder(token);
    service.writeToParcel(data, 0);
    data.writeString(resolvedType);
    // 将 ServiceConnection 写入 data
    data.writeStrongBinder(connection.asBinder());
    data.writeInt(flags);
    data.writeString(callingPackage);
    data.writeInt(userId);
    // mRemote = BinderProxy,相当于调用到 BinderProxy.transact
    mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
    reply.readException();
    int res = reply.readInt();
    data.recycle();
    reply.recycle();
    return res;
}
复制代码

之后的调用栈如下:

BinderProxy.transact()

--> BpBinder::transact()

--> IPCThreadState::transact()

--> IPCThreadState::waitForResponse()

--> IPCThreadState::talkWithDriver()

--> binder_ioctl_write_read()

--> binder_thread_write()

--> binder_transaction()

--> binder_thread_read()

其中的大部分在第二篇博客中就已经介绍了,这里就不再重复阐述了

传送门

除了 mOut 中的数据不同之外,调用流程都是相同的

最终 APP 线程会被挂起了,等待 AMS 进程返回数据后唤醒

AMS 进程是如何启动的?

AMS 服务运行在 system_server 进程中,system_server 进程属于 Java 层进程,都是通过 Process.start() 函数创建的

通过 Process.start() 函数,向 Zygote 进程发出创建进程的 socket 消息

Zygote 收到消息后会调用 Zygote.forkAndSpecialize() 函数来 fork 出新进程

通过 Process.start() 函数创建的新进程,在初始化的时候会调用 RuntimeInit.nativeZygoteInit() 函数,该函数经过 JNI 映射,最终会调用到 app_main.cpp 中的 onZygoteInit 函数

onZygoteInit()

// frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool();
}
复制代码

ProcessState::self() 函数之前的博客已经介绍过了,其主要是创建 ProcessState 对象 (单例),打开 Binder 驱动设备,并通过 mmap 映射内核的一部分地址空间作为缓冲区

ProcessState::startThreadPool()

// frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock); // 并发锁,多线程同步
    if (!mThreadPoolStarted)
    {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}
复制代码

Binder 设备启动后,会启动 Binder 线程池,并设置 mThreadPoolStarted = true

通过变量 mThreadPoolStarted 来保证每个应用进程只启动一个 Binder 线程池

ProcessState::spawnPooledThread()

// frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted)
    {
        // 获取 Binder 线程名,格式为 Binder_x,其中x为整数;
        // 每个进程中的x从1开始,依次递增,因此 Binder_1 代表的就是主线程
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());

        // 创建 Binder 线程
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}
复制代码

ProcessState::spawnPooledThread 用于创建 Binder 线程,通过参数 isMain 来区分创建的是主线程还是普通线程

此时创建的是 Binder 主线程 (isMain = true),Binder 普通线程都是由 Binder 驱动控制创建的

关于 Binder 线程名,只有通过 ProcessState::spawnPooledThread() 函数创建的线程才符合这个格式,对于直接将当前线程通过 IPCThreadState::joinThreadPool() 函数加入线程池的线程名则不符合这个命名格式

从 Android 7.0 开始格式已更改为 Binder:<pid>_x ,这样对于分析问题很有帮忙,我们可以通过 Binder 线程名中 pid 字段可以快速定位该 Binder 线程所属进程

PoolThread::run()
// frameworks/native/libs/binder/ProcessState.cpp
class PoolThread : public Thread
{
public:
    PoolThread(bool isMain)
        : mIsMain(isMain)
    {
    }
    
protected:
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }
    
    const bool mIsMain;
};

// system/core/include/utils/Thread.h
class Thread : virtual public RefBase
{
public:
    ......
    virtual status_t run(const char* name = 0, 
                         int32_t priority = PRIORITY_DEFAULT, 
                         size_t stack = 0);
    ......
}
复制代码

PoolThread 继承了 Thread 类,其本质上就是一个线程,t->run(name.string()); 这行代码会调用 PoolThread 中的 threadLoop() 函数

IPCThreadState::joinThreadPool()
// frameworks/native/libs/binder/IPCThreadState.cpp
void IPCThreadState::joinThreadPool(bool isMain)
{
    ......

    // 此时 isMain = true,写入 mOut 的命令为 BC_ENTER_LOOPER
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
    
    // 将当前 Binder 线程设置为前台线程
    set_sched_policy(mMyThreadId, SP_FOREGROUND);
        
    status_t result;
    do {
        ......
        // 处理 Binder 驱动所给的指令
        result = getAndExecuteCommand();

        ......
        
        // 如果不再需要该线程,并且它不是主进程线程,则让该线程退出线程池
        if(result == TIMED_OUT && !isMain)
        {
            break;
        }
    } while (result != -ECONNREFUSED && result != -EBADF);

    ......
}
复制代码
IPCThreadState::getAndExecuteCommand()
// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;

    // 与 Binder 驱动通信
    result = talkWithDriver();

    ......
}
复制代码

IPCThreadState::talkWithDriver() 函数之前的博客已经介绍过了,其主要是构建 binder_write_read 结构体,通过系统调用到 Binder 驱动的 binder_ioctl() 函数,进入内核态

值得注意的是,IPCThreadState::talkWithDriver() 函数参数的默认值为 true,也就是说通过该函数调用 Binder 驱动默认会同时触发 binder_thread_write()binder_thread_read() 函数

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, // mOut 的起始地址
			size_t size, // mOut 的长度
			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 中读取指令,此时读取到的指令是 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_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;
    // 指向 mIn 内存起始地址的指针
    void __user *ptr = buffer + *consumed;
    // 指向 mIn 内存结束地址的指针
    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
    {
        ......
    }
    ......
}
复制代码

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

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

此时 mIn 的结构如下

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

当 APP 进程发送数据给 AMS 后,AMS 进程中的 Binder 主线程被唤醒,继续执行未完成的 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 = AMS,不为空,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 = BIND_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;
            // 获取 APP 线程的 pid 并记录
            tr.sender_pid = task_tgid_nr_ns(sender, task_active_pid_ns(current));
        }
        else
        {
            ......
        }
        // 记录 APP 进程所发送数据的内存地址、大小等信息
        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 拷贝到用户空间(mIn)
        if (put_user(cmd, (uint32_t __user *)ptr))
            return -EFAULT;
        // 指针后移
        ptr += sizeof(uint32_t);
        
        // 将 mOut 数据部分的信息拷贝到用户空间(mIn)
        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 保存在 AMS 主线程的 transaction_stack 中
            thread->transaction_stack = t;
        }
        else
        {
            ......
        }
        // 跳出循环
        break;
        ......
    }

done:
    *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 拷贝到用户空间(mIn)
        if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
            return -EFAULT;
        ......
    }
    return 0;
}
复制代码

binder_thread_read() 函数执行完成后,binder_ioctl_write_read() 函数也执行完成,返回到 IPCThreadState::getAndExecuteCommand() 函数,继续执行

此时 mIn 的结构如下

IPCThreadState::getAndExecuteCommand()

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;

    // 执行返回处
    result = talkWithDriver();

    if (result >= NO_ERROR)
    {
        // mIn 中的数据长度
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        // 读取 mIn 中的指令
        cmd = mIn.readInt32();

        ......

        // 执行 Binder 驱动所给的指令
        result = executeCommand(cmd);

        ......

        // 将当前 Binder 线程设置为前台线程
        set_sched_policy(mMyThreadId, SP_FOREGROUND);
    }

    return result;
}
复制代码

IPCThreadState::getAndExecuteCommand() 函数执行在 IPCThreadState::joinThreadPool() 函数的 do-while 循环中,只有当 Binder 线程不再被需要,才会退出循环将 Binder 线程从 Binder 线程池中移除

每次循环,都会调用 IPCThreadState::talkWithDriver() 函数与 Binder 驱动通信,IPCThreadState::talkWithDriver() 函数每次都会将 mIn 中的全部数据返回

Parcel::readInt32() 函数内部,会通过 mDataPos 字段记录下一条指令的位置,每次被调用会返回当前读取到的指令,并对 mDataPos 字段进行自增操作

// frameworks/native/libs/binder/Parcel.cpp
int32_t Parcel::readInt32() const
{
    return readAligned<int32_t>();
}

template<class T>
T Parcel::readAligned() const
{
    T result;
    if (readAligned(&result) != NO_ERROR)
    {
        result = 0;
    }
    return result;
}

template<class T>
status_t Parcel::readAligned(T *pArg) const
{
    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));

    if ((mDataPos+sizeof(T)) <= mDataSize)
    {
        const void* data = mData+mDataPos;
        mDataPos += sizeof(T);
        *pArg =  *reinterpret_cast<const T*>(data);
        return NO_ERROR;
    }
    else
    {
        return NOT_ENOUGH_DATA;
    }
}
复制代码

IPCThreadState::executeCommand()

mIn 中指令被处理次序:

  1. BR_SPAWN_LOOPER
  2. BR_NOOP
  3. BR_TRANSACTION
// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::executeCommand(int32_t cmd)
{
    BBinder* obj;
    RefBase::weakref_type* refs;
    status_t result = NO_ERROR;

    switch ((uint32_t)cmd)
    {
        ......

        case BR_TRANSACTION: // 3
        {
            binder_transaction_data tr;
            // 读取 mIn 中 APP 进程发来的数据
            result = mIn.read(&tr, sizeof(tr));

            ......

            Parcel buffer;
            // 将数据写入 buffer
            buffer.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);

            ......

            Parcel reply;
            status_t error;

            ......

            // tr.target.ptr = AMS 内核节点的弱引用
            if (tr.target.ptr)
            {
                // 获取对 AMS 内核节点的强引用
                if (reinterpret_cast<RefBase::weakref_type*>(tr.target.ptr)->
                    attemptIncStrong(this))
                {
                    // tr.cookie = JavaBBinder(AMS)
                    // 调用 JavaBBinder 的 transact 函数
                    error = reinterpret_cast<BBinder*>(tr.cookie)->
                            transact(tr.code, buffer, &reply, tr.flags);
                    // 移除对 AMS 内核节点的强引用
                    reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
                }
                else
                {
                    error = UNKNOWN_TRANSACTION;
                }

            }
            else
            {
                ......
            }

            // 如果是 oneway(异步)的通信方式,此时 if 命中
            if ((tr.flags & TF_ONE_WAY) == 0)
            {
                LOG_ONEWAY("Sending reply to %d!", mCallingPid);
                if (error < NO_ERROR)
                    reply.setError(error);
                // 立刻发送 reply 给 APP 进程,唤醒 APP 进程
                sendReply(reply, 0);
            }
            else
            {
                LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
            }

            ......

        }
        break;

        ......

        case BR_NOOP: // 2
            break;
        case BR_SPAWN_LOOPER: // 1
            // 创建新的 Binder 线程
            mProcess->spawnPooledThread(false);
            break;

        ......
    }
    
    ......
    
    return result;
}
复制代码
  1. 主线程处理该指令(BR_SPAWN_LOOPER)

    通过 ProcessState::spawnPooledThread() 函数创建一个新的 Binder 线程

    新线程启动后,就会执行 IPCThreadState::joinThreadPool() 函数将新线程加入 Binder 线程池中

    IPCThreadState::joinThreadPool() 函数中,会将新线程设置为前台线程

    由于 Android 系统采用的是抢占式多任务 CPU 调度,就会使得新线程抢占主线程的 CPU 时间片来执行

  2. 新线程处理该指令(BR_NOOP)

    不做处理,直接返回

  3. 新线程处理该指令(BR_TRANSACTION)

    接收 APP 进程发来的数据

    JavaBBinder 继承自 BBinder,相当于调用父类的 BBinder::transact() 函数

BBinder::transact()

// frameworks/native/libs/binder/Binder.cpp
status_t BBinder::transact(
	uint32_t code, // code = BIND_SERVICE_TRANSACTION
        const Parcel& data, // data = APP 进程发来的数据
        Parcel* reply, 
        uint32_t flags
){
    data.setDataPosition(0);

    status_t err = NO_ERROR;

    // code = BIND_SERVICE_TRANSACTION
    switch (code)
    {
        case PING_TRANSACTION:
            reply->writeInt32(pingBinder());
            break;
        default:
            // 调用 JavaBBinder 的 onTransact 函数
            err = onTransact(code, data, reply, flags);
            break;
    }

    if (reply != NULL)
    {
        reply->setDataPosition(0);
    }

    return err;
}
复制代码
JavaBBinder::onTransact()
// frameworks/base/core/jni/android_util_Binder.cpp

const char* const kBinderPathName = "android/os/Binder";

static int int_register_android_os_Binder(JNIEnv* env)
{
    ......

    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", 
                                                    "(IJJI)Z");
    ......
}

virtual status_t onTransact(
        uint32_t code, // code = BIND_SERVICE_TRANSACTION
        const Parcel& data, // data = APP 进程发来的数据
    	Parcel* reply, 
    	uint32_t flags = 0
){
    ......

    // mObject = AMS 对象
    // gBinderOffsets.mExecTransact = android/os/Binder.execTransact 函数
    // code = BIND_SERVICE_TRANSACTION
    // 调用到 AMS 的 execTransact 函数
    jboolean res = env->CallBooleanMethod(mObject, 
                                          gBinderOffsets.mExecTransact, 
                                          code, reinterpret_cast<jlong>(&data), 
                                          reinterpret_cast<jlong>(reply), flags);

    ......

    return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
复制代码

AMS 继承自 ActivityManagerNative,ActivityManagerNative 继承自 Binder,相当于调用超父类的 Binder.execTransact() 函数

Binder.execTransact()
// frameworks/base/core/java/android/os/Binder.java
private boolean execTransact(int code, long dataObj, long replyObj, int flags)
{
    // 创建 data
    Parcel data = Parcel.obtain(dataObj);
    // 创建 reply
    Parcel reply = Parcel.obtain(replyObj);

    boolean res;

    ......

    // 调用 ActivityManagerNative 的 onTransact 函数
    res = onTransact(code, data, reply, flags);

    ......

    reply.recycle();
    data.recycle();

    ......

    return res;
}
复制代码
ActivityManagerNative.onTransact()
// frameworks/base/core/java/android/app/ActivityManagerNative.java
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
{
    // code = BIND_SERVICE_TRANSACTION
    switch (code)
    {
        ......

        case BIND_SERVICE_TRANSACTION:
            {
            	data.enforceInterface(IActivityManager.descriptor);
            	IBinder b = data.readStrongBinder();
            	IApplicationThread app = ApplicationThreadNative.asInterface(b);
            	IBinder token = data.readStrongBinder();
            	Intent service = Intent.CREATOR.createFromParcel(data);
            	String resolvedType = data.readString();
            	b = data.readStrongBinder();
            	int fl = data.readInt();
            	String callingPackage = data.readString();
            	int userId = data.readInt();
            	IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
                // 调用 AMS 的 bindService 函数
            	int res = bindService(app, token, service, resolvedType, conn, 
                                      fl, callingPackage, userId);
            	reply.writeNoException();
            	reply.writeInt(res);
            	return true;
            }

        ......
    }
    return super.onTransact(code, data, reply, flags);
}
复制代码

ActivityServiceManager.bindService() 函数之后就是绑定 Service 的流程,这里就不继续展开了

IPCThreadState::sendReply()

// frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
{
    status_t err;
    status_t statusBuffer;
    // 整理数据,将指令 BC_REPLY 和 reply 一起写入 mOut 中
    err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
    if (err < NO_ERROR) 
        return err;
    // 与 Binder 驱动通信
    return waitForResponse(NULL, NULL);
}
复制代码

IPCThreadState::waitForResponse() 函数之前的博客已经介绍过了,其主要是调用 IPCThreadState::talkWithDriver() 函数与 BInder 驱动进行通信

当指令 BC_REPLY 发送给 Binder 驱动后,就会调用 Binder 驱动的 binder_transaction() 函数唤醒 APP 进程,并发送 reply 给 APP 进程

这部分流程与第二篇博客中介绍的 binder_send_reply() 函数的执行流程类似,可以参考

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

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

其流程与第二篇博客中介绍的 AMS 进程被唤醒后做了什么? 这部分基本相同

因为我们分析的是 APP 进程 AIDL 调用 AMS 服务绑定 Service 流程,因此最后返回到 ContextImpl.bindServiceCommon() 函数

// frameworks/base/core/java/android/app/ContextImpl.java
private boolean bindServiceCommon(Intent service, ServiceConnection conn, 
                                  int flags, UserHandle user
){
    ......
    // 执行返回处
    int res = ActivityManagerNative.getDefault().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
    if (res < 0)
    {
        throw new SecurityException(
                "Not allowed to bind to service " + service);
    }
    return res != 0;
    ......
}
复制代码

至此,整个 AIDL 调用流程结束

总结

(之后会补上关于 AIDL 调用的整体流程图)

Guess you like

Origin juejin.im/post/7053109782030319653