bindService() 跨进程调用流程的请求流程

看这个也行:bindService() 调用流程

API 26

## ContextImpl#bindService()

[–>ContextImpl.java, bindService()]

public boolean bindService(Intent service, ServiceConnection conn, int flags) {
	return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), Process.myUserHandle());
}

[–>ContextImpl.java, bindServiceCommon()]

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) {
	IServiceConnection sd;
	if (mPackageInfo != null) {
        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
    }
    ...
    // Binder 跨进程调用获取 AMS 代理对象,然后调用 AMS 代理对象的 bindService(),即 ActivityManagerProxy##bindService()(在 ActivityManagerNative.java 中)
    int res = ActivityManager.getService().bindService(
		        mMainThread.getApplicationThread(), getActivityToken(), service,
		        service.resolveTypeIfNeeded(getContentResolver()),
		        sd, flags, getOpPackageName(), user.getIdentifier());
    ...
}

[–>ActivityManagerNative.java, ActivityManagerProxy#bindService()]

// connection:实际类型为 InnerConnection
ActivityManagerNative#bindService(..., IServiceConnection connection, ...)
	// connection 继承 Binder,asBinder() 返回 this
	data.writeStrongBinder(connection.asBinder());
	// mRemote:AMS 对应的 BinderProxy 对象
	// int BIND_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+35 = 36(IActivityManager.java)
	mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);

### Parcel#writeStrongBinder()

[–>Parcel.java, writeStrongBinder()]

writeStrongBinder()
	// native 方法,方法实现在 android_os_parcel.cpp
	nativeWriteStrongBinder(mNativePtr, val);

[–>android_os_parcel.cpp, writeStrongBinder()]

// writeStrongBinder() -> android_os_Parcel_writeStrongBinder()
android_os_Parcel_writeStrongBinder()
	// Native 层 Parcel
	Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
	// ibinderForJavaObject():返回的是 Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder
	const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));

[–>Parcel.cpp, writeStrongBinder()]

writeStrongBinder()
	// val:Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder
	flatten_binder(ProcessState::self(), val, this);

[–>Parcel.cpp, flatten_binder()]

flatten_binder(const sp<ProcessState>& /*proc*/, const sp<IBinder>& binder, Parcel* out)
	flat_binder_object obj;

    obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    if (binder != NULL) {
    	// binder:Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder
    	// JavaBBinder 的父类 BBinder#localBinder() 返回 this(class JavaBBinder : public BBinder)
        IBinder *local = binder->localBinder();
        if (!local) {
            ...
        } else { // 走这个
        	// Binder 本地对象
            obj.type = BINDER_TYPE_BINDER;
            // binder、cookie 记录的是 Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder 这个 BBinder(实际为 JavaBBinder)的信息
            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
            obj.cookie = reinterpret_cast<uintptr_t>(local);
        }
    } else {
        ...
    }

    return finish_flatten_binder(binder, obj, out);

// 上面把 Java 层 connection 这个 Binder 通过 Parcel 转换后写到 flat_binder_object 结构体中

### BinderProxy#transact()

[–>Binder.java, transact()]

BinderProxy#transact()
	// native 方法,方法实现在 android_util_binder.cpp
	transactNative(code, data, reply, flags);

// transactNative() -> android_os_BinderProxy_transact()
[–>android_util_binder.cpp]

android_os_BinderProxy_transact()
	// 根据 Java 层 BinderProxy 获取 Native 层 BpBinder
	IBinder* target = (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
	// BpBinder#transact()
		// code = BIND_SERVICE_TRANSACTION
	status_t err = target->transact(code, *data, reply, flags);

[–>BpBinder.cpp, transact()]

BpBinder#transact()
	// mHandle:AMS 服务对应的 BpBinder 的 handle 值
	// code = BIND_SERVICE_TRANSACTION
	status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);

[–>IPCThreadState.cpp, transact()]

IPCThreadState#transact()
	// handle:AMS 服务对应的 BpBinder 的 handle 值
	// code = BIND_SERVICE_TRANSACTION
	err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
	err = waitForResponse(reply);

[–>IPCThreadState.cpp, writeTransactionData()]

writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
	binder_transaction_data tr;

	tr.target.ptr = 0;
	tr.target.handle = handle; // AMS 服务对应的 BpBinder 的 handle 值
	tr.code = code; // BIND_SERVICE_TRANSACTION
	tr.flags = binderFlags;
	tr.cookie = 0;
	tr.sender_pid = 0;
	tr.sender_euid = 0;

	const status_t err = data.errorCheck();
	if (err == NO_ERROR) {
	    tr.data_size = data.ipcDataSize();
	    tr.data.ptr.buffer = data.ipcData();
	    tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
	    tr.data.ptr.offsets = data.ipcObjects();
	} else if (statusBuffer) {
	    ...
	} else {
	    return (mLastError = err);
	}

	// mOut(Parcel)中的数据格式:cmd = BC_TRANSACTION + binder_transaction_data
		// binder_transaction_data 主要数据:
			// handle:AMS 服务对应的 BpBinder 的 handle 值
			// code:BIND_SERVICE_TRANSACTION
			// Binder 对象:在 flat_binder_object 结构体中(Java 层 connection 这个 Binder 通过 Parcel 转换后写到了 flat_binder_object 结构体中)
	mOut.writeInt32(cmd); // BC_TRANSACTION
	mOut.write(&tr, sizeof(tr));

	return NO_ERROR;

[–>IPCThreadState.cpp, waitForResponse()]

waitForResponse()
	while (1) {
		// 往 Binder 驱动写东西
        if ((err=talkWithDriver()) < NO_ERROR) break;
        
        cmd = mIn.readInt32();

        switch (cmd) {
        ...
        case BR_REPLY:
            {
                binder_transaction_data tr;
                err = mIn.read(&tr, sizeof(tr));
                if (err != NO_ERROR) goto finish;

                if (reply) {
                    if ((tr.flags & TF_STATUS_CODE) == 0) {
                        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 {
                        err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
                        freeBuffer(NULL,
                            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), this);
                    }
                } else {
                    freeBuffer(NULL,
                        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), this);
                    continue;
                }
            }
            goto finish;

        default:
            err = executeCommand(cmd);
            if (err != NO_ERROR) goto finish;
            break;
        }
    }

[–>IPCThreadState.cpp, talkWithDriver()]

talkWithDriver()
	binder_write_read bwr;

	bwr.write_size = outAvail;
	// mOut 就是 Parcel,上面 writeTransactionData() 中 mOut(Parcel)中的数据,数据格式:cmd = BC_TRANSACTION + binder_transaction_data
		// binder_transaction_data 主要数据:
			// handle:AMS 服务对应的 BpBinder 的 handle 值
			// code:BIND_SERVICE_TRANSACTION
			// Binder 对象:在 flat_binder_object 结构体中(Java 层 connection 这个 Binder 通过 Parcel 转换后写到了 flat_binder_object 结构体中)
	// 把 mOut(Parcel)中的数据赋给 binder_write_read 的 write_buffer,准备写到 Binder 驱动中
    bwr.write_buffer = (uintptr_t)mOut.data();

    bwr.write_consumed = 0;

	do {
        ...
        ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)
        ...
	} while (err == -EINTR);

[–>IPCThreadState.cpp, executeCommand()]

executeCommand()
	... // 等待 Binder 驱动处理后返回结果

########################### Binder 驱动 ###########################
// ioctl() -> binder_ioctl()
[–>binder.c, binder_ioctl()]

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
	// 当前 proc 进程对应的是 Java 层 connection 这个 Binder 所在的进程,即应用的进程
	struct binder_proc *proc = filp->private_data;
	// arg 对应用户空间 ioctl() 第三个参数 bwr(binder_write_read)
	void __user *ubuf = (void __user *)arg;

	// ioctl 传入的是 BINDER_WRITE_READ
	switch (cmd) {
	case BINDER_WRITE_READ: {
		struct binder_write_read bwr;
		// 从应用空间拷贝 ubuf(binder_write_read)数据到内核空间 Binder 驱动层的 bwr(binder_write_read)
		if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
			ret = -EFAULT;
			goto err;
		}

		if (bwr.write_size > 0) {
			// binder_write_read 的 write_buffer 中保存的是 cmd = BC_TRANSACTION + binder_transaction_data
			// binder_transaction_data 主要数据:
				// handle:AMS 服务对应的 BpBinder 的 handle 值
				// code:BIND_SERVICE_TRANSACTION
				// Binder 对象:在 flat_binder_object 结构体中(Java 层 connection 这个 Binder 通过 Parcel 转换后写到了 flat_binder_object 结构体中)
			ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
			...
		}
		... // 省略 binder_thread_read(),只关注 binder_thread_write()
		break;
	}
	}

[–>binder.c, binder_thread_write()]

int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, void __user *buffer, int size, signed long *consumed)
	uint32_t cmd;
	// buffer 中保存的数据:cmd = BC_TRANSACTION + binder_transaction_data
	void __user *ptr = buffer + *consumed;
	void __user *end = buffer + size;

	while (ptr < end && thread->return_error == BR_OK) {
		// 读数据,读到 cmd = BC_TRANSACTION
		if (get_user(cmd, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
		
		// cmd = BC_TRANSACTION
		switch (cmd) {
		...
		case BC_TRANSACTION:
		case BC_REPLY: {
			struct binder_transaction_data tr;

			// 从应用空间拷贝 ptr(binder_transaction_data)数据到内核空间 Binder 驱动层的 tr(binder_transaction_data)
			if (copy_from_user(&tr, ptr, sizeof(tr)))
				return -EFAULT;
			ptr += sizeof(tr);
			binder_transaction(proc, thread, &tr, cmd == BC_REPLY);
			break;
		}
		...
		}
		*consumed = ptr - buffer;
	}

[–>binder.c, binder_transaction()]

static void binder_transaction(struct binder_proc *proc, struct binder_thread *thread, struct binder_transaction_data *tr, int reply)
	struct binder_transaction *t;
	struct binder_work *tcomplete;
	size_t *offp, *off_end;
	struct binder_node *target_node = NULL;
	...
	if (reply) {
		...
	} else {
		// binder_transaction_data 主要数据:
			// handle:AMS 服务对应的 BpBinder 的 handle 值
			// code:BIND_SERVICE_TRANSACTION
			// Binder 对象:在 flat_binder_object 结构体中(Java 层 connection 这个 Binder 通过 Parcel 转换后写到了 flat_binder_object 结构体中)
		// t(binder_transaction_data)中 handle 是 AMS 服务对应的 BpBinder 的 handle 值,所以不为 0
		if (tr->target.handle) { // 走这个
			struct binder_ref *ref;
			// Binder 驱动根据 handle 值(这个 handle 值和 AMS 服务有关,由 Binder 驱动创建并返回给应用进程的)获取 AMS 服务的 Binder 引用对象(binder_ref)
				// proc 进程:Java 层 connection 这个 Binder 所在的进程,即应用进程
			ref = binder_get_ref(proc, tr->target.handle);
			// 根据 Binder 引用对象(binder_ref)获取 Binder 实体对象(binder_node)
			target_node = ref->node;
		} else {
			...
		}
		// target_proc 指的是 AMS 进程
		target_proc = target_node->proc;
	}

	// target_thread 在 reply 阶段才有值
	if (target_thread) {
		e->to_thread = target_thread->pid;
		target_list = &target_thread->todo;
		target_wait = &target_thread->wait;
	} else { // 走这个
		// target_proc(AMS 进程)的 todo 队列
		target_list = &target_proc->todo;
		// target_proc(AMS 进程)的 wait 等待队列
		target_wait = &target_proc->wait;
	}

	t = kzalloc(sizeof(*t), GFP_KERNEL);

	tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
	// binder_transaction_data 主要数据:
		// handle:AMS 服务对应的 BpBinder 的 handle 值
		// code:BIND_SERVICE_TRANSACTION
		// Binder 对象:在 flat_binder_object 结构体中(Java 层 connection 这个 Binder 通过 Parcel 转换后写到了 flat_binder_object 结构体中)
			// obj.type = BINDER_TYPE_BINDER;
        	// obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); // binder、cookie 记录的是 Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder 这个 BBinder(实际为 JavaBBinder)的信息
        	// obj.cookie = reinterpret_cast<uintptr_t>(local);
	// binder_transaction_data 的 BIND_SERVICE_TRANSACTION 赋给 t->code
	t->code = tr->code;
	// 内核空间申请内存,用于保存 binder_transaction_data 的 data 数据(包含 Binder 对象),保存到 target_proc(AMS 进程)的内核空间
		// target_proc 指的是 AMS 进程
	t->buffer = binder_alloc_buf(target_proc, tr->data_size, tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));
	t->buffer->target_node = target_node;

	offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));
	// 从应用空间拷贝 tr->data.ptr.buffer(包含 Binder 对象)到内核空间 Binder 驱动层的 tr(binder_transaction_data)(注意注意注意:Binder 对象此时就从应用空间拷到了内核空间,保存到 target_proc(AMS 进程)的内核空间)
	if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {
		... // 不出错不会进来
	}
	// 从应用空间拷贝 offsets 偏移数组到内核空间 Binder 驱动层的 offp(size_t)
		// offsets 偏移数组:Binder 对象在 tr->data.ptr.buffer 中的位置
	if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {
		... // 不出错不会进来
	}
	off_end = (void *)offp + tr->offsets_size;
	off_min = 0;
	// for 循环遍历 offsets 偏移数组
		// offsets 偏移数组:Binder 对象在 tr->data.ptr.buffer 中的位置
	for (; offp < off_end; offp++) {
		struct flat_binder_object *fp;

		// binder_transaction_data 主要数据:
			// handle:AMS 服务对应的 BpBinder 的 handle 值
			// code:BIND_SERVICE_TRANSACTION
			// Binder 对象:在 flat_binder_object 结构体中(Java 层 connection 这个 Binder 通过 Parcel 转换后写到了 flat_binder_object 结构体中)
				// obj.type = BINDER_TYPE_BINDER;
        		// obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); // binder、cookie 记录的是 Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder 这个 BBinder(实际为 JavaBBinder)的信息
        		// obj.cookie = reinterpret_cast<uintptr_t>(local);

		// fp(flat_binder_object)保存的是 Binder 对象
			// Binder 对象(保存在 flat_binder_object 结构体中):保存在 target_proc(AMS 进程)的内核空间 t->buffer 中
		fp = (struct flat_binder_object *)(t->buffer->data + *offp);
		off_min = *offp + sizeof(struct flat_binder_object);
		// BINDER_TYPE_BINDER
		switch (fp->type) {
		case BINDER_TYPE_BINDER: // 走这个
		case BINDER_TYPE_WEAK_BINDER: {
			struct binder_ref *ref;
			// Binder 驱动层获取 Binder 驱动层给应用进程创建的关于 Java 层 connection 这个 Binder 的 Binder 实体对象,第一次来肯定为 NULL
				// proc 进程:Java 层 connection 这个 Binder 所在的进程,即应用进程
				// fp->binder 记录的是 Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder 这个 BBinder(实际为 JavaBBinder)的信息
			struct binder_node *node = binder_get_node(proc, fp->binder);
			if (node == NULL) {
				// Binder 驱动在 Binder 驱动层为应用进程创建属于应用进程的关于 Java 层 connection 这个 Binder 的 Binder 实体对象(binder_node)
					// 把 binder、cookie 赋给 binder 的 ptr、cookie
						// binder、cookie 记录的是 Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder 这个 BBinder(实际为 JavaBBinder)的信息
				node = binder_new_node(proc, fp->binder, fp->cookie);
				...
			}
			// Binder 驱动在 Binder 驱动层为 target_proc(AMS 进程)创建属于应用进程的关于 Java 层 connection 这个 Binder 的 Binder 实体对象(binder_node)的 Binder 引用对象(binder_ref)
				// target_proc 指的是 AMS 进程
			ref = binder_get_ref_for_node(target_proc, node);
			// 修改 fp(flat_binder_object)保存的 Binder 对象的类型 BINDER_TYPE_BINDER 为 BINDER_TYPE_HANDLE
	            // Binder 对象:在 flat_binder_object 结构体中(Java 层 connection 这个 Binder 通过 Parcel 转换后写到了 flat_binder_object 结构体中)
					// obj.type = BINDER_TYPE_BINDER;
	        		// obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); // binder、cookie 记录的是 Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder 这个 BBinder(实际为 JavaBBinder)的信息
	        		// obj.cookie = reinterpret_cast<uintptr_t>(local);
			if (fp->type == BINDER_TYPE_BINDER)
				fp->type = BINDER_TYPE_HANDLE;
			else
				fp->type = BINDER_TYPE_WEAK_HANDLE;
			// 给 fp(flat_binder_object)保存的 Binder 对象设置 handle 值
				// fp:target_proc(AMS 进程)的内核空间 t->buffer 中保存的 Binder 对象
				// ref->desc:Binder 驱动为 target_proc(AMS 进程)创建 Binder 引用对象(binder_ref)时生成的 handle 值
			fp->handle = ref->desc;
			binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, &thread->todo);
		} break;
		case BINDER_TYPE_HANDLE:
		case BINDER_TYPE_WEAK_HANDLE: {
			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
			if (ref == NULL) {
				return_error = BR_FAILED_REPLY;
				goto err_binder_get_ref_failed;
			}
			if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
				return_error = BR_FAILED_REPLY;
				goto err_binder_get_ref_failed;
			}
			if (ref->node->proc == target_proc) {
				if (fp->type == BINDER_TYPE_HANDLE)
					fp->type = BINDER_TYPE_BINDER;
				else
					fp->type = BINDER_TYPE_WEAK_BINDER;
				fp->binder = ref->node->ptr;
				fp->cookie = ref->node->cookie;
				binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
			} else {
				struct binder_ref *new_ref;
				new_ref = binder_get_ref_for_node(target_proc, ref->node);
				if (new_ref == NULL) {
					return_error = BR_FAILED_REPLY;
					goto err_binder_get_ref_for_node_failed;
				}
				fp->handle = new_ref->desc;
				binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
			}
		} break;

		...
	}
	if (reply) {
		binder_pop_transaction(target_thread, in_reply_to);
	} else if (!(t->flags & TF_ONE_WAY)) {
		t->need_reply = 1;
		// 当前事务堆栈的上一个设置为当前线程处理的事务堆栈
		t->from_parent = thread->transaction_stack;
		// 当前线程处理的事务堆栈设置为当前事务堆栈
		thread->transaction_stack = t;
	} else {
		if (target_node->has_async_transaction) {
			target_list = &target_node->async_todo;
			target_wait = NULL;
		} else
			target_node->has_async_transaction = 1;
	}
	// 下面两行代码将 t(binder_transaction 结构体)封装成一个类型为 BINDER_WORK_TRANSACTION 的工作项,然后把工作项添加到 target_list(目标进程或线程 todo 队列)
		// target_list:target_proc(AMS 进程)的 todo 队列
	t->work.type = BINDER_WORK_TRANSACTION;
	list_add_tail(&t->work.entry, target_list);
	// 下面两行代码将 tcomplete(binder_work 结构体)封装成一个类型为 BINDER_WORK_TRANSACTION_COMPLETE 的工作项,然后把工作项添加到 thread(应用进程)todo 队列
	tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
	list_add_tail(&tcomplete->entry, &thread->todo);
	// 上面刚刚添加了一个类型为 BINDER_WORK_TRANSACTION 的工作项,target_list:target_proc(AMS 进程)的 todo 队列此时不为空,可以换新等待队列上的线程去处理
	if (target_wait)
		// 唤醒 target_proc(AMS 进程)的 wait 等待队列
		wake_up_interruptible(target_wait);
	return;

########################### AMS 进程在 Binder 驱动层被唤醒 ###########################
// 之前 AMS 进程在 Binder 驱动层的 binder_thread_read() 中阻塞
[–>binder.c, binder_thread_read()]

static int binder_thread_read(struct binder_proc *proc, struct binder_thread *thread, void  __user *buffer, int size, signed long *consumed, int non_block) {
	void __user *ptr = buffer + *consumed;
	void __user *end = buffer + size;

	// 线程事务堆栈为空(没有等待其他线程完成事务) && 线程 todo 队列为空,此时可以去等待处理进程 todo 队列中的待处理项
	wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);

	if (wait_for_proc_work)
		proc->ready_threads++;

	// 进程等待处理工作项
	if (wait_for_proc_work) {
		...
		if (non_block) {
			// 当前进程 todo 队列没有未处理的工作项
			if (!binder_has_proc_work(proc, thread))
                ret = -EAGAIN;
		} else
			// 当前线程睡眠等待,直到所属进程 proc->wait 队列上有新的未处理工作项为止
			ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));
	}
	// 线程等待处理工作项
	else {
		if (non_block) {
			// 当前线程 todo 队列没有未处理的工作项
			if (!binder_has_thread_work(thread))
				ret = -EAGAIN;
		} else
			// 当前线程睡眠等待,直到当前线程 thread->wait 队列上有新的未处理工作项为止
			ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
	}
	// 能走到这,说明 AMS 进程被唤醒了,此时进程 proc->wait 队列或线程 thread->wait 上有新的未处理工作项

	if (wait_for_proc_work)
		proc->ready_threads--;

	// while 循环处理工作项
	while (1) {
		struct binder_transaction_data tr;
		struct binder_transaction *t = NULL;
		...
		// 线程 todo 队列不为空
        if (!list_empty(&thread->todo))
            w = list_first_entry(&thread->todo, struct binder_work, entry);
        // 进程 todo 队列有一个类型为 BINDER_WORK_TRANSACTION 的工作项 && 进程 todo 队列中的未处理工作项
        else if (!list_empty(&proc->todo) && wait_for_proc_work)
            // 取出工作项(类型为 BINDER_WORK_TRANSACTION)
            w = list_first_entry(&proc->todo, struct binder_work, entry);

        // 根据工作项类型,获取对应工作项
		switch (w->type) { // 在上面 binder_transaction() 的最后,唤醒 AMS 进程时,添加的工作类型是 BINDER_WORK_TRANSACTION
		case BINDER_WORK_TRANSACTION: {
			t = container_of(w, struct binder_transaction, work);
		} break;
		...
		}

		// binder_transaction():请求阶段会给 target_node 赋值,reply 阶段 target_node 为空
        if (t->buffer->target_node) { // target_node:Java 层 connection 这个 Binder 本地对象对应在 Binder 驱动层的 Binder 实体对象(binder_node)
        	struct binder_node *target_node = t->buffer->target_node;
        	// 把 target_node 对应 Binder 实体对象(binder_node)信息设置到 binder_transaction_data 中
        		// ptr、cookie 记录的是 Java 层 connection 这个 Binder 在 Native 层的 JavaBBinder 这个 BBinder(实际为 JavaBBinder)的信息
			tr.target.ptr = target_node->ptr;
			tr.cookie =  target_node->cookie;
			// 修改 cmd 为 BR_TRANSACTION
			cmd = BR_TRANSACTION;
		} else {
			...
        }
        // 把 binder_transaction 结构体对应的进程间通信数据设置到 binder_transaction_data 中
        tr.code = t->code; // BIND_SERVICE_TRANSACTION
        ...

        tr.data_size = t->buffer->data_size;
		tr.offsets_size = t->buffer->offsets_size;
		// 当前并不是真的把 t(binder_transaction)中的数据缓冲区和偏移数组的内容复制到 tr(binder_transaction_data)中
        // 而只是修改 tr(binder_transaction_data)中的数据缓冲区和偏移数组的地址值,从而指向 t(binder_transaction)中的数据缓冲区和偏移数组
		tr.data.ptr.buffer = (void *)t->buffer->data + proc->user_buffer_offset;
		tr.data.ptr.offsets = tr.data.ptr.buffer + ALIGN(t->buffer->data_size, sizeof(void *));

		// cmd 在上面已设置为 BR_TRANSACTION
        // 通过 put_user 复制 cmd(BR_TRANSACTION)返回协议到目标线程提供的用户空间缓冲区
		if (put_user(cmd, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
		if (copy_to_user(ptr, &tr, sizeof(tr)))
			return -EFAULT;
		ptr += sizeof(tr);

		// 工作项已得到处理(交给了目标线程处理),从目标进程或线程 todo 队列中移除工作项,对应上面获取的 w(binder_work)
		list_del(&t->work.entry);
		// allow_user_free = 1:表示 Binder 驱动程序为目标线程分配的内核缓冲区允许目标线程在用户空间通过 BC_FREE_BUFFER 命令协议来释放
		t->buffer->allow_user_free = 1;
		// cmd 是 BR_TRANSACTION && 不是异步
		if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) {
			// 当前处理的事务堆栈的下一个设置为当前线程处理的事务堆栈
			t->to_parent = thread->transaction_stack;
			// 事务堆栈目标线程设置为处理事务线程
			t->to_thread = thread;
			// 当前线程处理的事务堆栈设置为当前要处理的事务堆栈
			thread->transaction_stack = t;
		} else {
			...
		}
		break;
	}

	*consumed = ptr - buffer;
	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)) {
		proc->requested_threads++;
		// 将返回协议代码 BR_SPAWN_LOOPER 写入到用户空间缓冲区 buffer 中,通知进程 proc 创建新的进程加入到 Binder 线程池中
		if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
			return -EFAULT;
	}
}

########################### AMS 进程回到用户空间 ###########################
// binder_thread_read() 执行完后,返回到 binder_loop,当前也就返回到了用户空间,接着调用 binder_parse() 来处理 Binder 驱动程序发来的返回协议和相应进程间通信数据
[–>frameworks/native/cmds/servicemanager/binder.c, binder_parse()]

int binder_parse(struct binder_state *bs, struct binder_io *bio, uintptr_t ptr, size_t size, binder_handler func)
{
    int r = 1;
    uintptr_t end = ptr + (uintptr_t) size;

    while (ptr < end) {
        uint32_t cmd = *(uint32_t *) ptr;
        ptr += sizeof(uint32_t);
        switch(cmd) {
        ...
        case BR_TRANSACTION: { // 走这个
            struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
            ...
            if (func) {
                unsigned rdata[256/4];
                struct binder_io msg;
                struct binder_io reply;
                int res;

                bio_init(&reply, rdata, sizeof(rdata), 4);
				// 解析从 Binder 驱动程序中获取的 txn(struct binder_transaction_data),保存到 msg(struct binder_io)
                bio_init_from_txn(&msg, txn);
				// 处理保存在 msg(binder_io)中的 BR_TRANSACTION 返回协议,处理结果保存在 reply(binder_io)
                res = func(bs, txn, &msg, &reply); // 正常情况下,返回 0
				// 处理后,发送 reply 给 Client 进程,表示处理完了
                binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
            }
            ptr += sizeof(*txn);
            break;
        }
        ...
        }
    }

    return r;
}

// 这里有个问题需要说明一下,上面的 fun 是一个回调函数,关于 Binder 的讲解一般都描述的是注册服务到 ServiceManager 进程或从 ServiceManager 进程获取服务,那么这里的 fun 就指的是 service_manager.c 中的 svcmgr_handler,但我们当前是 bindService() 流程,通信目标是 AMS 进程,没找到 AMS 的相关回调,所以我们参考 ServiceManager 的 svcmgr_handler

重要的事情说三遍,本来我们要看的是 AMS 进程的回调函数,但是没找到,我们参考一下 ServiceManager 进程的 svcmgr_handler
重要的事情说三遍,本来我们要看的是 AMS 进程的回调函数,但是没找到,我们参考一下 ServiceManager 进程的 svcmgr_handler
重要的事情说三遍,本来我们要看的是 AMS 进程的回调函数,但是没找到,我们参考一下 ServiceManager 进程的 svcmgr_handler
[–>service_manager.c, svcmgr_handler()]

int svcmgr_handler(struct binder_state *bs, struct binder_transaction_data *txn, struct binder_io *msg, struct binder_io *reply)
{
    struct svcinfo *si;
    uint16_t *s;
    size_t len;
    uint32_t handle;
    uint32_t strict_policy;
    int allow_isolated;

    if (txn->target.handle != svcmgr_handle)
        return -1;

    if (txn->code == PING_TRANSACTION)
        return 0;

    strict_policy = bio_get_uint32(msg);
    // 获取 svcmgr_publish 时设置的字符串 "android.os.IServiceManager"
    s = bio_get_string16(msg, &len);
    if (s == NULL) {
        return -1;
    }

    // 判断长度是否等于 svcmgr_id 的一半?数组元素类型是 uint16_t,所以在计算长度时需要除以 2
    // uint16_t svcmgr_id[] = {
    //     'a','n','d','r','o','i','d','.','o','s','.',
    //     'I','S','e','r','v','i','c','e','M','a','n','a','g','e','r'
    // };
    // 长度和内容若存在不一致的情况,则返回错误码 -1
    if ((len != (sizeof(svcmgr_id) / 2)) || memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
        return -1;
    }

    if (sehandle && selinux_status_updated() > 0) {
        struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
        if (tmp_sehandle) {
            selabel_close(sehandle);
            sehandle = tmp_sehandle;
        }
    }

    switch(txn->code) {
	// 获取服务
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
        if (!handle)
            break;
		// 把返回值 handle 封装成 binder_io 写回客户端
        bio_put_ref(reply, handle);
        return 0;
	
	// 注册服务
    case SVC_MGR_ADD_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid))
            return -1;
        break;

    case SVC_MGR_LIST_SERVICES: {
        uint32_t n = bio_get_uint32(msg);

        if (!svc_can_list(txn->sender_pid)) {
            return -1;
        }
        si = svclist;
        while ((n-- > 0) && si)
            si = si->next;
        if (si) {
            bio_put_string16(reply, si->name);
            return 0;
        }
        return -1;
    }
    ...
    }

    // 操作成功(把 00 00 00 00 作为 reply(binder_io)data,表示操作成功),之后会通过 Binder 驱动程序返回给 Client 进程
    bio_put_uint32(reply, 0);
    return 0;
}

// 上面参考的是 ServiceManager 进程的 svcmgr_handler,txn(binder_transaction_data)中的 code:
// code = SVC_MGR_ADD_SERVICE:注册服务
// code = SVC_MGR_GET_SERVICE:获取服务
// 本来我们要看的是 AMS 进程的回调函数,虽然没找到这个回调函数,但是通过参考 ServiceManager 进程的 svcmgr_handler 回调函数,我们知道接下来该处理 code = BIND_SERVICE_TRANSACTION 了

API 26
// ActivityManagerNative 就相当于 AIDL 的 Stub
    // AIDL 的 Stub 类的继承关系:abstract class Stub erxtends android.os.Binder implements IXxx
    // ActivityManagerNative 类的继承关系:abstract class ActivityManagerNative extends Binder implements IActivityManager
// 至于怎么调到 ActivityManagerNative#onTransact(),因为 ActivityManagerNative 相当于 AIDL 的 Stub,所以可以参考网上关于 AIDL 通信流程相关文章,着重看下 Prox 端的请求怎么发送到 Stub 端
[–>ActivityManagerNative.java, onTransact()]

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
	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);
        int res = bindService(app, token, service, resolvedType, conn, fl, callingPackage, userId);
        reply.writeNoException();
        reply.writeInt(res);
        return true;
    }
}

// 既然有 Stub(ActivityManagerNative)#onTransact() 处理 BIND_SERVICE_TRANSACTION 请求,那么肯定有 Proxy()#transact() 发送 BIND_SERVICE_TRANSACTION 请求,实际上就是本文最开始的 [–>ActivityManagerNative.java, ActivityManagerProxy#bindService()]
// ActivityManagerProxy 就相当于 AIDL 的 Proxy
    // AIDL 的 Proxy 类的继承关系:class Proxy implements IXxx
    // ActivityManagerProxy 类的继承关系:class ActivityManagerProxy implements IActivityManager
[–>ActivityManagerNative.java, ActivityManagerProxy#bindService()]

class ActivityManagerProxy implements IActivityManager
{
    public ActivityManagerProxy(IBinder remote)
    {
        mRemote = remote;
    }

    public IBinder asBinder()
    {
        return mRemote;
    }
    ...
    public int bindService(IApplicationThread caller, IBinder token,
            Intent service, String resolvedType, IServiceConnection connection,
            int flags,  String callingPackage, int userId) throws RemoteException {
	    Parcel data = Parcel.obtain();
	    Parcel reply = Parcel.obtain();
	    data.writeInterfaceToken(IActivityManager.descriptor);
	    data.writeStrongBinder(caller != null ? caller.asBinder() : null);
	    data.writeStrongBinder(token);
	    service.writeToParcel(data, 0);
	    data.writeString(resolvedType);
	    data.writeStrongBinder(connection.asBinder());
	    data.writeInt(flags);
	    data.writeString(callingPackage);
	    data.writeInt(userId);
	    mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
	    reply.readException();
	    int res = reply.readInt();
	    data.recycle();
	    reply.recycle();
	    return res;
	}
    ...
}

// 回到上面的 ActivityManagerNative#onTransact()
// ActivityManagerNative 就相当于 AIDL 的 Stub
    // AIDL 的 Stub 类的继承关系:abstract class Stub erxtends android.os.Binder implements IXxx
    // ActivityManagerNative 类的继承关系:abstract class ActivityManagerNative extends Binder implements IActivityManager
[–>ActivityManagerNative.java, onTransact()]

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
	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);
        // 调用 Stub(ActivityManagerNative)实现类的 bindService(),即 ActivityManagerService#bindService()
        int res = bindService(app, token, service, resolvedType, conn, fl, callingPackage, userId);
        reply.writeNoException();
        reply.writeInt(res);
        return true;
    }
}

[–>ActivityManagerService.java, bindService()]

public int bindService(IApplicationThread caller, IBinder token, Intent service,
        String resolvedType, IServiceConnection connection, int flags, String callingPackage,
        int userId) throws TransactionTooLargeException {
    ...

    synchronized(this) {
        return mServices.bindServiceLocked(caller, token, service, resolvedType, connection, flags, callingPackage, userId);
    }
}

## 剩下的流程就概括一下

多次编写,欢迎交流,如有错误,感谢指正

后面就是 AMS 进程开始绑定服务了,涉及到 Binder 跨进程通信
Service#onBind(),也涉及到 Binder 跨进程通信
然后 AMS 进程发布服务,也涉及到 Binder 跨进程通信
最终 ServiceConnection#onServiceConnected(ComponentName name, IBinder service) 方法第二个参数拿到的是 Binder 本地对象 InnerConnection(ServiceDispatcher.Stub 的子类)对应的 BinderProxy 对象
bindService() 第二个参数 ServiceConnection 的 onServiceConnected 回调的第二个参数 service 实际类型是 BinderProxy

## 最后看下 InnerConnection 是个啥?

[–>LoadedApk.java, InnerConnection]

// InnerConnection 继承自 IServiceConnection.Stub,上面 [-->ContextImpl.java, bindService()] 中写到 ActivityManagerProxy#bindService() 中的就是 InnerConnection,因为这是个 Binder 对象可以跨进程传递
private static class InnerConnection extends IServiceConnection.Stub {
    ...

    public void connected(ComponentName name, IBinder service, boolean dead) throws RemoteException {
        LoadedApk.ServiceDispatcher sd = mDispatcher.get();
        if (sd != null) {
            sd.connected(name, service, dead);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值