Service代理对象的获取过程

Service代理对象的获取过程

Service组件将自己注册到ServiceManager中后,它就在server进程中等待client进程将进程间通信请求发送过来。client进程为了和service组件通信,首先需要通过ServiceManager的service组件查询服务,得到service组件的一个代理对象。

为了创建一个FregService代理对象,即BpFregService对象,首先要通过binder驱动程序来获得一个引用了运行在FregServer进程中的FregService组件的binder引用对象的句柄值,然后在通过这个句柄值创建一个binder代理对象,即一个BpBinder对象,最后将这个binder代理对象封装成一个FregService(BpFregService)代理对象。

	int main(){
		sp<IBinder> binder = defaultServiceManager()->getService(String16(FREG_SERVICE));
		if(binder == NULL){
			LOGE("Failed to get freg service %s.\n", FREG_SERVICE);
			return -1;
		}
		sp<IFregService> service = IFregService::asInterface(binder);
		if(service == NULL){
			LOGE("Failed to get freg service interface\n");
			return -2;
		}
		int32_t val = service->getVal();
		printf("val = %d\n", val);
		val+=1;
		service->setVal(val);
		val = service->getVal();
		printf("val = %d\n", val);
	}

IServiceManager.cpp

    virtual sp<IBinder> getService(const String16& name) const
    {
        unsigned n;
        for (n = 0; n < 5; n++){//最多尝试5次获取名称为name的Service组件代理对象
            sp<IBinder> svc = checkService(name);
            if (svc != NULL) return svc;
            LOGI("Waiting for service %s...\n", String8(name).string());
            sleep(1);//获取失败,睡1毫秒,重试
        }
        return NULL;
    }
1、getService

尝试获取Service组件代理对象。

/*ServiceManager代理对象的成员函数checkService实现的是一个标准的binder进程间通信过程,它可以划分为五步
	1.FregClient进程将进程间通信数据,即Service组件FregService的代理对象的名称,封装到Parcel对象中;
	2.FregClient进程向binder驱动程序发送BC_TRANSACTION命令,binder驱动程序根据协议内容找到ServiceManager进程后,
	就会向FregClient进程发送一个BR_TRANSACTION_COMPLETE返回协议,表示它的进程间通信请求已被binder驱动程序接受。
	FregClient进程在接受到BR_TRANSACTION_COMPLETE返回协议,并且对它进行处理后,就会再次进入binder驱动程序中去等待
	ServiceManager进程将它要获取的binder代理对象的句柄值返回回来。
	3.binder驱动程序在向FregClient进程发送BR_TRANSACTION_COMPLETE返回协议的同时,也会向ServiceManager进程发送BR_TRANSACTION
	返回协议,请求ServiceManager进程执行一个CHECK_SERVICE_TRANSACTION操作。
	4.ServiceManager进程在执行完FregClient进程请求的CHECK_SERVICE_TRANSACTION操作后,就会向binder驱动程序发送一个BC_REPLY命令协议,
	协议包含Service组件FregService的信息。binder驱动程序就会根据FregService的信息为FregClient进程创建一个binder引用对象,
	接着就会向ServiceManager进程发送一个BR_TRANSACTION_COMPLETE返回协议,表示它返回的FregService信息已经收到。ServiceManager进程
	收到BR_TRANSACTION_COMPLETE返回协议,并对它处理后,一次进程间通信过程就结束了,接着它再次进入binder驱动程序,等待下一次进程间通信请求。
	5.binder驱动程序在向ServiceManager进程发送BR_TRANSACTION_COMPLETE返回协议的同时,也向FregClient进程发送一个BR_REPLY返回协议,
	协议中包含了前面创建的一个binder引用对象的句柄值,这时候FregClient进程就可以通过这个句柄值来创建一个binder代理对象。*/
    virtual sp<IBinder> checkService( const String16& name) const
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);//通过句柄值为0的binder代理对象与ServiceManager进行通信
        return reply.readStrongBinder();
    }
2、checkService

BpBinder

//transact函数将mHandler,以及进程间通信数据发送给Binder驱动程序,这样Binder驱动程序就能通过这个句柄值找到对应的Binder引用对象,
//进而找到Binder实体对象,最后就可以将进程间通信数据发送给service组件
status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)//data进程间通信数据,falg默认为0,表示这是一个同步请求
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}
3、transact
status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    status_t err = data.errorCheck();//进程间通信数据data是否有问题

    flags |= TF_ACCEPT_FDS;//表示server进程在返回结果携带文件描述符
    if (err == NO_ERROR) {//没有问题
        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);//将data写入到binder_transaction_data结构体中,还没发送到binder驱动程序
    }
    if (err != NO_ERROR) {
        if (reply) reply->setError(err);
        return (mLastError = err);
    }
    if ((flags & TF_ONE_WAY) == 0) {//判断是不是同步请求
        if (reply) {//是否有数据返回
            err = waitForResponse(reply);//向驱动程序发送一个BC_TRANSACTION命令协议
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
    } else {
        err = waitForResponse(NULL, NULL);
    }
    
    return err;
}
4、transact
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    int32_t cmd;
    int32_t err;

    while (1) {
        if ((err=talkWithDriver()) < NO_ERROR) break;
        err = mIn.errorCheck();
        if (err < NO_ERROR) break;
        if (mIn.dataAvail() == 0) continue;
        
        cmd = mIn.readInt32();//读出返回协议代码

        switch (cmd) {
        case BR_TRANSACTION_COMPLETE:
            if (!reply && !acquireResult) goto finish;//跳出switch语句,再次进入外层循环执行talkWithDriver()来与binder驱动程序交互
            break;
        
        case BR_REPLY:
            {
                binder_transaction_data tr;
                err = mIn.read(&tr, sizeof(tr));
                LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
                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 size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(size_t),
                            freeBuffer, this);
                    } else {
                        err = *static_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 size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(size_t), this);
                    }
                } else {
                    freeBuffer(NULL,
                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                        tr.data_size,
                        reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
                        tr.offsets_size/sizeof(size_t), this);
                    continue;
                }
            }
            goto finish;
        }
    }

finish:
    if (err != NO_ERROR) {
        if (acquireResult) *acquireResult = err;
        if (reply) reply->setError(err);
        mLastError = err;
    }
    
    return err;
}
5、waitForResponse
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
    
    binder_write_read bwr;//使用BINDER_WRITE_READ IO控制命令,定义binder_write_read结构体来指定读端和写端
    
    // Is the read buffer empty?
    const bool needRead = mIn.dataPosition() >= mIn.dataSize();//返回协议缓冲区mIn的返回协议已经处理完成
    
    // We don't want to write anything if we are still reading
    // from data left in the input buffer and the caller
    // has requested to read the next data.
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;//doReceive表示是否想要接收binder驱动程序发送给进程的返回协议,needRead如果为false表示mIn中的返回协议还没处理完,这是再往写端写数据,也没用,读端mIn处理不了
    
    bwr.write_size = outAvail;//写端缓冲区和读端缓冲区的大小分别为0和大于0,binder驱动程序不会处理进程发送给他的命令协议,只会向该进程发送返回协议,这样进程就达到了只接受返回协议的结果
    bwr.write_buffer = (long unsigned int)mOut.data();

    // This is what we'll read.
    //doReceive如果为true表示想要接收binder的返回协议,
    //当然要能处理读端数据,返回协议缓冲区mIn中的数据也要处理完,否则往读端缓冲区写数据也处理不了,
    //所以如果mIn中的返回协议处理完了needRead为true,这时就可以设置读端缓冲区大小了
    if (doReceive && needRead) {
        bwr.read_size = mIn.dataCapacity();
        bwr.read_buffer = (long unsigned int)mIn.data();
    } else {
        bwr.read_size = 0;//
    }
    
    // Return immediately if there is nothing to do.
    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;//判断写端和读端的缓冲区大小是否都为0,如果是就不用进入binder驱动程序了,因为没有数据传入binder程序,也不需要binder程序返回结果
    
    bwr.write_consumed = 0;
    bwr.read_consumed = 0;
    status_t err;
    do {
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)//while循环使用IO控制命令BINDER_WRITE_READ与binder驱动程序交互
            err = NO_ERROR;
        else
            err = -errno;

    } while (err == -EINTR);

    if (err >= NO_ERROR) {
        if (bwr.write_consumed > 0) {//将binder驱动程序已经处理命令协议从mOut中移除
            if (bwr.write_consumed < (ssize_t)mOut.dataSize())
                mOut.remove(0, bwr.write_consumed);
            else
                mOut.setDataSize(0);
        }
        if (bwr.read_consumed > 0) {//将冲binder驱动程序中读取出来的返回协议保存在mIn中
            mIn.setDataSize(bwr.read_consumed);
            mIn.setDataPosition(0);
        }
        return NO_ERROR;
    }
    
    return err;
}
6、talkWithDriver

binder.c

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int ret;
	struct binder_proc *proc = filp->private_data;//获取驱动程序创建的一个binder_proc结构体
	struct binder_thread *thread;
	unsigned int size = _IOC_SIZE(cmd);
	void __user *ubuf = (void __user *)arg;//用户空间缓冲区地址

	/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/

	ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
	if (ret)
		return ret;

	mutex_lock(&binder_lock);
	thread = binder_get_thread(proc);//为当前线程创建一个binder_thread结构体
	if (thread == NULL) {
		ret = -ENOMEM;
		goto err;
	}

	switch (cmd) {
	case BINDER_WRITE_READ: {
		struct binder_write_read bwr;
		if (size != sizeof(struct binder_write_read)) {
			ret = -EINVAL;
			goto err;
		}
		if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {//将用户空间传进来的一个binder_write_read结构体复制出来
			ret = -EFAULT;
			goto err;
		}
		if (bwr.write_size > 0) {//传入的bwr写端有数据,有传入到binder驱动程序的数据
			ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);//client进程的proc和thread,现在还处于client进程
			if (ret < 0) {
				bwr.read_consumed = 0;
				if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
					ret = -EFAULT;
				goto err;
			}
		}
		if (bwr.read_size > 0) {//传入的bwr读端有缓冲区,需要将binder驱动程序中数据写入读端缓冲区
			ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
			if (!list_empty(&proc->todo))
				wake_up_interruptible(&proc->wait);
			if (ret < 0) {
				if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
					ret = -EFAULT;
				goto err;
			}
		}
		if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
			ret = -EFAULT;
			goto err;
		}
		break;
	}
	}
	ret = 0;
err:
	if (thread)
		thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
	mutex_unlock(&binder_lock);
	wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
	if (ret && ret != -ERESTARTSYS)
		printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
	return ret;
}
7、binder_ioctl
int
binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
		    void __user *buffer, int size, signed long *consumed)//buffer执行进程传递给binder驱动程序的一个binder_write_read结构体的写缓冲区
{
	uint32_t cmd;
	void __user *ptr = buffer + *consumed;
	void __user *end = buffer + size;

	while (ptr < end && thread->return_error == BR_OK) {
		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;

			if (copy_from_user(&tr, ptr, sizeof(tr)))//读出进程间通信数据,如果数据中有指针,只拷贝指针指向的地址,还没拷贝指针指向的内容
				return -EFAULT;
			ptr += sizeof(tr);
			binder_transaction(proc, thread, &tr, cmd == BC_REPLY);
			break;
		}

		default:
			printk(KERN_ERR "binder: %d:%d unknown command %d\n", proc->pid, thread->pid, cmd);
			return -EINVAL;
		}
		*consumed = ptr - buffer;
	}
	return 0;
}
8、binder_thread_write
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_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;
	struct binder_transaction *in_reply_to = NULL;
	struct binder_transaction_log_entry *e;
	uint32_t return_error;

	if (reply) {//要处理的是BC_REPLY命令还是BC_TRANSACTION
	} else {//BC_TRANSACTION
		if (tr->target.handle) {
		} else {//句柄值为0,找到ServiceManager的实体对象
			target_node = binder_context_mgr_node;
			if (target_node == NULL) {
				return_error = BR_DEAD_REPLY;
				goto err_no_context_mgr_node;
			}
		}
		e->to_node = target_node->debug_id;
		target_proc = target_node->proc;//找到目标进程
		if (target_proc == NULL) {
			return_error = BR_DEAD_REPLY;
			goto err_dead_binder;
		}
		if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {//判断是不是同步进程间通信
			struct binder_transaction *tmp;
			tmp = thread->transaction_stack;
			if (tmp->to_thread != thread) {
				return_error = BR_FAILED_REPLY;
				goto err_bad_call_stack;
			}
			while (tmp) {//找到最优目标线程
				if (tmp->from && tmp->from->proc == target_proc)
					target_thread = tmp->from;
				tmp = tmp->from_parent;
			}
		}
	}
	if (target_thread) {//有目标线程,指向目标线程
		e->to_thread = target_thread->pid;
		target_list = &target_thread->todo;
		target_wait = &target_thread->wait;
	} else {//指向目标进程
		target_list = &target_proc->todo;
		target_wait = &target_proc->wait;
	}
	e->to_proc = target_proc->pid;

	/* TODO: reuse incoming transaction for reply */
	t = kzalloc(sizeof(*t), GFP_KERNEL);//分配一个binder_transaction结构体
	if (t == NULL) {
		return_error = BR_FAILED_REPLY;
		goto err_alloc_t_failed;
	}
	binder_stats.obj_created[BINDER_STAT_TRANSACTION]++;

	tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);//binder_work
	if (tcomplete == NULL) {
		return_error = BR_FAILED_REPLY;
		goto err_alloc_tcomplete_failed;
	}
	binder_stats.obj_created[BINDER_STAT_TRANSACTION_COMPLETE]++;

	t->debug_id = ++binder_last_id;
	e->debug_id = t->debug_id;


	if (!reply && !(tr->flags & TF_ONE_WAY))//初始化binder_transaction
		t->from = thread;//from指向源线程,client线程以便以便目标线程或进程处理完该进程间通信请求后,能够找回发出该请求的线程
	else
		t->from = NULL;
	t->sender_euid = proc->tsk->cred->euid;
	t->to_proc = target_proc;
	t->to_thread = target_thread;
	t->code = tr->code;
	t->flags = tr->flags;
	t->priority = task_nice(current);
	t->buffer = binder_alloc_buf(target_proc, tr->data_size,
		tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));//分配内核缓冲区,以便可以将进程间通信数据复制到里面
	if (t->buffer == NULL) {
		return_error = BR_FAILED_REPLY;
		goto err_binder_alloc_buf_failed;
	}
	t->buffer->allow_user_free = 0;
	t->buffer->debug_id = t->debug_id;
	t->buffer->transaction = t;
	t->buffer->target_node = target_node;
	if (target_node)
		binder_inc_node(target_node, 1, 0, NULL);//增加目标实体对象的强引用

	offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));//偏移数组起始位置

	if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {//将client数据缓冲区的数据复制到binder_transaction的内核缓冲区中
		binder_user_error("binder: %d:%d got transaction with invalid "
			"data ptr\n", proc->pid, thread->pid);
		return_error = BR_FAILED_REPLY;
		goto err_copy_data_failed;
	}
	if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {//将client偏移数组内容复制到binder_transaction内核缓冲区中
		binder_user_error("binder: %d:%d got transaction with invalid "
			"offsets ptr\n", proc->pid, thread->pid);
		return_error = BR_FAILED_REPLY;
		goto err_copy_data_failed;
	}

	off_end = (void *)offp + tr->offsets_size;
	for (; offp < off_end; offp++) {//遍历进程间通信数据中的binder对象
		
	}
	if (reply) {

	} else if (!(t->flags & TF_ONE_WAY)) {//如果源线程正在处理的是一个同步的进程间通信请求
		BUG_ON(t->buffer->async_transaction != 0);
		t->need_reply = 1;
		t->from_parent = thread->transaction_stack;//将事务t压入源线程的事务栈中
		thread->transaction_stack = t;
	} else {
	}
	t->work.type = BINDER_WORK_TRANSACTION;//将事务中的工作项设置为BINDER_WORK_TRANSACTION类型
	list_add_tail(&t->work.entry, target_list);//添加到目标进程或线程的todo队列
	tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;//将工作项tcomplete设置为BINDER_WORK_TRANSACTION_COMPLETE类型
	list_add_tail(&tcomplete->entry, &thread->todo);//添加到源线程的todo队列,表示transaction已完成
	if (target_wait)
		wake_up_interruptible(target_wait);
	return;

	if (in_reply_to) {
		thread->return_error = BR_TRANSACTION_COMPLETE;
		binder_send_failed_reply(in_reply_to, return_error);
	} else
		thread->return_error = return_error;
}
9、binder_transaction
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;

	int ret = 0;
	int wait_for_proc_work;

	if (*consumed == 0) {
		if (put_user(BR_NOOP, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
	}
//如果一个线程的事务栈transaction_stack不为NULL,就表示它正在等待其他线程完成另一个事务;
//如果线程的todo队列不为空,说明该线程有待处理的工作项;
//一个线程只有在线程事务栈为NULL和todo队列为空的情况下才会去处理所属进程todo队列中的工作项
retry:
	wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);//判断当前线程事务栈和工作项队列todo是否需要处理


	thread->looper |= BINDER_LOOPER_STATE_WAITING;//设置当前线程为BINDER_LOOPER_STATE_WAITING,表示当前线程正处于空闲状态
	if (wait_for_proc_work)
		proc->ready_threads++;//当前线程所属的进程多了一个空闲的binder线程
	mutex_unlock(&binder_lock);
	if (wait_for_proc_work) {
		if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
					BINDER_LOOPER_STATE_ENTERED))) {
			wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
		}
		binder_set_nice(proc->default_priority);//将当前线程的优先级设置为所属进程的优先级
		//non_block表示当前线程是否以非阻塞的形式打开设备文件/dev/binder,如果是就不能在binder驱动程序中睡眠,
		//即,线程todo队列为空时,线程不可以进入睡眠状态去等待新的工作项
		if (non_block) {//不可阻塞
			if (!binder_has_proc_work(proc, thread))//判断一个进程是否有未处理的工作项,没有,直接返回
				ret = -EAGAIN;
		} else//可阻塞,当前线程没有新的工作项,就会睡在proc->wait(进程的等待队列)中,或自己的一个等待队列wait中
			ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));//等到所属进程有新的工作项
	} else {
		if (non_block) {
			if (!binder_has_thread_work(thread))
				ret = -EAGAIN;
		} else
			ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
	}
	mutex_lock(&binder_lock);//被唤醒
	if (wait_for_proc_work)
		proc->ready_threads--;//空闲线程-1
	thread->looper &= ~BINDER_LOOPER_STATE_WAITING;//当前线程取消空闲状态

	if (ret)
		return ret;

	while (1) {
		uint32_t cmd;
		struct binder_transaction_data tr;
		struct binder_work *w;
		struct binder_transaction *t = NULL;

		if (!list_empty(&thread->todo))//当前线程检查自己的todo队列有没有新的工作项
			w = list_first_entry(&thread->todo, struct binder_work, entry);
		else if (!list_empty(&proc->todo) && wait_for_proc_work)//线程所在的宿主进程有没有新的工作项
			w = list_first_entry(&proc->todo, struct binder_work, entry);
		else {
			if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */
				goto retry;
			break;
		}

		if (end - ptr < sizeof(tr) + 4)
			break;

		switch (w->type) {
		case BINDER_WORK_TRANSACTION: {
			t = container_of(w, struct binder_transaction, work);
		} break;
		case BINDER_WORK_TRANSACTION_COMPLETE: {
			cmd = BR_TRANSACTION_COMPLETE;
			if (put_user(cmd, (uint32_t __user *)ptr))//将BR_TRANSACTION_COMPLETE写入用户空间提供的缓冲区中
				return -EFAULT;
			ptr += sizeof(uint32_t);

			binder_stat_br(proc, thread, cmd);
			if (binder_debug_mask & BINDER_DEBUG_TRANSACTION_COMPLETE)
				printk(KERN_INFO "binder: %d:%d BR_TRANSACTION_COMPLETE\n",
				       proc->pid, thread->pid);

			list_del(&w->entry);//移除当前工作项
			kfree(w);
			binder_stats.obj_deleted[BINDER_STAT_TRANSACTION_COMPLETE]++;
		} break;
		}

		if (!t)
			continue;

		if (t->buffer->target_node) {//设置binder_transaction_data 进程间通信数据
			struct binder_node *target_node = t->buffer->target_node;
			tr.target.ptr = target_node->ptr;
			tr.cookie =  target_node->cookie;
			t->saved_priority = task_nice(current);
			if (t->priority < target_node->min_priority &&
			    !(t->flags & TF_ONE_WAY))
				binder_set_nice(t->priority);
			else if (!(t->flags & TF_ONE_WAY) ||
				 t->saved_priority > target_node->min_priority)
				binder_set_nice(target_node->min_priority);
			cmd = BR_TRANSACTION;
		} else {//当一个server线程将一个进程间通信数据返回给client线程时,是不需要在进程间通信数据中指定一个目标binder实体对象的
			tr.target.ptr = NULL;
			tr.cookie = NULL;
			cmd = BR_REPLY;
		}
		tr.code = t->code;
		tr.flags = t->flags;
		tr.sender_euid = t->sender_euid;

		if (t->from) {
			struct task_struct *sender = t->from->proc->tsk;
			tr.sender_pid = task_tgid_nr_ns(sender, current->nsproxy->pid_ns);
		} else {
			tr.sender_pid = 0;
		}

		tr.data_size = t->buffer->data_size;
		tr.offsets_size = t->buffer->offsets_size;
		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 *));

		if (put_user(cmd, (uint32_t __user *)ptr))//将binder_transaction_data所对应的返回协议BR_TRANSACTION及它复制到目标线程提供的一个用户缓冲区中
			return -EFAULT;
		ptr += sizeof(uint32_t);
		if (copy_to_user(ptr, &tr, sizeof(tr)))//复制的只是地址值
			return -EFAULT;
		ptr += sizeof(tr);

		binder_stat_br(proc, thread, cmd);
		list_del(&t->work.entry);//将binder_work结构体w,从目标线程的todo队列中删除,因为他描述的工作项已经完成
		t->buffer->allow_user_free = 1;//表示binder驱动程序分配的内核缓冲区允许目标线程在用户空间发出BC_FREE_BUFFER命令协议来释放
		if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) {//binder向目标线程发送的是一个BR_TRANSACTION返回协议binder_transaction.falg的TF_ONE_WAY位为0
			t->to_parent = thread->transaction_stack;//说明binder正在执行一个进程间通信请求,将binder_transaction结构体t压入目标线程thread的事务堆栈
			t->to_thread = thread;
			thread->transaction_stack = t;
		} else {//处理的不是进程间同步请求,释放binder_transaction结构体t的内核空间
			t->buffer->transaction = NULL;
			kfree(t);
			binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++;
		}
		break;
	}

done:

	*consumed = ptr - buffer;
	//检查当线程所属的进程是否需要请求增加一个新的binder线程来处理进程间通信请求
	if (proc->requested_threads + proc->ready_threads == 0 &&//空闲线程数(ready_threads)为0,binder驱动程序中正在处理请求的binder进程数(proc->requested_threads)之和为0,其实他们两个都为0,和才为0,空闲线程数为0
	    proc->requested_threads_started < proc->max_threads &&//binder驱动程序请求增加的binder线程数requested_threads_started 小于 预设的最大线程数
	    (thread->looper & (BINDER_LOOPER_STATE_REGISTERED |//当前线程已经注册成了binder线程
	     BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */
	     /*spawn a new thread if we leave this out */) {
		proc->requested_threads++;
		if (binder_debug_mask & BINDER_DEBUG_THREADS)
			printk(KERN_INFO "binder: %d:%d BR_SPAWN_LOOPER\n",
			       proc->pid, thread->pid);
		if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))//将一个返回协议代码BR_SPAWN_LOOPER,写入到用户空间缓冲区buffer中,以便进程可以创建一个新的线程加入到binder线程池中。
			return -EFAULT;
	}
	return 0;
}
10、binder_thread_read

处理BINDER_WORK_TRANSACTION和BINDER_WORK_TRANSACTION_COMPLETE类型的工作项

service_manager.c

//等待和处理service组件的注册请求,以及其代理对象的获取请求
void binder_loop(struct binder_state *bs, binder_handler func)
{
    int res;
    struct binder_write_read bwr;
    unsigned readbuf[32];//32*4=128字节,ServiceManager一次最多能接收128字节大小的请求

    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;
    //一个线程需要通过协议BC_ENTER_LOOPER或者BC_REGISTER_LOOPER将自己注册成binder线程
    //以便binder驱动程序可以将进程间通信请求发给他处理。
    readbuf[0] = BC_ENTER_LOOPER;//ServiceManager主线程是主动成为一个binder线程的,因此他使用BC_ENTER_LOOPER协议将自己注册到binder驱动程序中
    binder_write(bs, readbuf, sizeof(unsigned));

    for (;;) {//循环不断使用IO控制命令BINDER_WRITE_READ来检查binder驱动程序是否有新的进程间通信请求需要它去处理
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (unsigned) readbuf;

        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

        if (res < 0) {
            LOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }

        res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);//如果有就交给binder_parse函数处理,否则当前线程就会在binder驱动程序中睡眠直到有新的请求到达
        if (res == 0) {
            LOGE("binder_loop: unexpected reply?!\n");
            break;
        }
        if (res < 0) {
            LOGE("binder_loop: io error %d %s\n", res, strerror(errno));
            break;
        }
    }
}
11、binder_loop
int binder_parse(struct binder_state *bs, struct binder_io *bio,
                 uint32_t *ptr, uint32_t size, binder_handler func)
{
    int r = 1;
    uint32_t *end = ptr + (size / 4);

    while (ptr < end) {
        uint32_t cmd = *ptr++;
        switch(cmd) {
        case BR_TRANSACTION: {
            struct binder_txn *txn = (void *) ptr;
            if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
                LOGE("parse: txn too small!\n");
                return -1;
            }
            binder_dump_txn(txn);
            if (func) {
                unsigned rdata[256/4];//4*256/4 = 256 bit
                struct binder_io msg;//读取从binder驱动程序传递过来的数据
                struct binder_io reply;//将将进程间通信结果保存到缓冲区rdata中,以便后面可以将它返回给binder驱动程序
                int res;

                bio_init(&reply, rdata, sizeof(rdata), 4);//初始化
                bio_init_from_txn(&msg, txn);
                res = func(bs, txn, &msg, &reply);//处理保存在msg中的BR_TRANSACTION返回协议
                binder_send_reply(bs, &reply, txn->data, res);//将注册结果返回给binder驱动程序
            }
            ptr += sizeof(*txn) / sizeof(uint32_t);
            break;
        }
        }
    }

    return r;
}
12、binder_parse
int svcmgr_handler(struct binder_state *bs,
                   struct binder_txn *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
    struct svcinfo *si;
    uint16_t *s;
    unsigned len;
    void *ptr;
    uint32_t strict_policy;

//    LOGI("target=%p code=%d pid=%d uid=%d\n",
//         txn->target, txn->code, txn->sender_pid, txn->sender_euid);

    if (txn->target != svcmgr_handle)//检查binder驱动程序传进来的目标binder本地对象是否等于ServiceManager中定义的虚拟binder本地对象scvmgr_handle
        return -1;

    // Equivalent to Parcel::enforceInterface(), reading the RPC
    // header with the strict mode policy mask and the interface name.
    // Note that we ignore the strict_policy and don't propagate it
    // further (since we do no outbound RPCs anyway).
    strict_policy = bio_get_uint32(msg);//检查进程间通信请求头是否合法
    s = bio_get_string16(msg, &len);
    if ((len != (sizeof(svcmgr_id) / 2)) ||
        memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
        fprintf(stderr,"invalid id %s\n", str8(s));
        return -1;
    }

    switch(txn->code) {
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
        s = bio_get_string16(msg, &len);
        ptr = do_find_service(bs, s, len);
        if (!ptr)
            break;
        bio_put_ref(reply, ptr);
        return 0;
    }

    bio_put_uint32(reply, 0);//成功,将代码0写入到binder_io结构体reply中
    return 0;
}
13、svcmgr_handler
int binder_parse(struct binder_state *bs, struct binder_io *bio,
                 uint32_t *ptr, uint32_t size, binder_handler func)
{
    int r = 1;
    uint32_t *end = ptr + (size / 4);

    while (ptr < end) {
        uint32_t cmd = *ptr++;
        switch(cmd) {
        case BR_TRANSACTION: {
            struct binder_txn *txn = (void *) ptr;
            if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
                LOGE("parse: txn too small!\n");
                return -1;
            }
            binder_dump_txn(txn);
            if (func) {
                unsigned rdata[256/4];//4*256/4 = 256 bit
                struct binder_io msg;//读取从binder驱动程序传递过来的数据
                struct binder_io reply;//将将进程间通信结果保存到缓冲区rdata中,以便后面可以将它返回给binder驱动程序
                int res;

                bio_init(&reply, rdata, sizeof(rdata), 4);//初始化
                bio_init_from_txn(&msg, txn);
                res = func(bs, txn, &msg, &reply);//处理保存在msg中的BR_TRANSACTION返回协议
                binder_send_reply(bs, &reply, txn->data, res);//将注册结果返回给binder驱动程序
            }
            ptr += sizeof(*txn) / sizeof(uint32_t);
            break;
        }
        }
    }

    return r;
}
14、binder_parse
//reply包含了进程间通信结果数据 buffer_to_free用户地址空间,指向一块用于进程间通信数据的内核缓冲区
//status 是否成功处理了进程间通信请求
void binder_send_reply(struct binder_state *bs,
                       struct binder_io *reply,
                       void *buffer_to_free,
                       int status)
{
    struct {//用来描述一个BC_FREE_BUFFER和BC_REPLY命令协议
        uint32_t cmd_free;
        void *buffer;//指向内核缓冲区的用户空间地址
        uint32_t cmd_reply;
        struct binder_txn txn;//对应于一个binder_transaction_data结构体地址
    } __attribute__((packed)) data;

    data.cmd_free = BC_FREE_BUFFER;//设置BC_FREE_BUFFER协议的内容
    data.buffer = buffer_to_free;//进程间通信完成,返回到内核,需要释放的与用户缓冲区地址对应的内核空间地址
    data.cmd_reply = BC_REPLY;//设置BC_REPLY协议的内容
    data.txn.target = 0;
    data.txn.cookie = 0;
    data.txn.code = 0;
    if (status) {//处理进程间通信请求发生错误
        data.txn.flags = TF_STATUS_CODE;
        data.txn.data_size = sizeof(int);
        data.txn.offs_size = 0;
        data.txn.data = &status;//错误代码写入内核缓冲区
        data.txn.offs = 0;
    } else {//成功
        data.txn.flags = 0;
        data.txn.data_size = reply->data - reply->data0;
        data.txn.offs_size = ((char*) reply->offs) - ((char*) reply->offs0);
        data.txn.data = reply->data0;//数据缓冲区
        data.txn.offs = reply->offs0;//偏移数组
    }
    binder_write(bs, &data, sizeof(data));//发送给binder驱动程序
}
15、binder_send_reply
int binder_write(struct binder_state *bs, void *data, unsigned len)
{
    struct binder_write_read bwr;
    int res;
    bwr.write_size = len;
    bwr.write_consumed = 0;
    bwr.write_buffer = (unsigned) data;//将data作为bwr的一块写缓冲区
    bwr.read_size = 0;
    bwr.read_consumed = 0;
    bwr.read_buffer = 0;//读缓冲区设置为NULL,这样当前线程将自己注册到binder驱动程序后,就会马上返回用户空间,而不会在binder驱动程序中等待client进程的通信请求。
    res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//IO控制命令后面跟着struct binder_write_read结构体
    if (res < 0) {
        fprintf(stderr,"binder_write: ioctl failed (%s)\n",
                strerror(errno));
    }
    return res;
}
16、binder_write
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int ret;
	struct binder_proc *proc = filp->private_data;//获取驱动程序创建的一个binder_proc结构体
	struct binder_thread *thread;
	unsigned int size = _IOC_SIZE(cmd);
	void __user *ubuf = (void __user *)arg;//用户空间缓冲区地址

	/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/

	ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
	if (ret)
		return ret;

	mutex_lock(&binder_lock);
	thread = binder_get_thread(proc);//为当前线程创建一个binder_thread结构体
	if (thread == NULL) {
		ret = -ENOMEM;
		goto err;
	}

	switch (cmd) {
	case BINDER_WRITE_READ: {
		struct binder_write_read bwr;
		if (size != sizeof(struct binder_write_read)) {
			ret = -EINVAL;
			goto err;
		}
		if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {//将用户空间传进来的一个binder_write_read结构体复制出来
			ret = -EFAULT;
			goto err;
		}
		if (bwr.write_size > 0) {//传入的bwr写端有数据,有传入到binder驱动程序的数据
			ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);//client进程的proc和thread,现在还处于client进程
			if (ret < 0) {
				bwr.read_consumed = 0;
				if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
					ret = -EFAULT;
				goto err;
			}
		}
		if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
			ret = -EFAULT;
			goto err;
		}
		break;
	}
	}
	ret = 0;
err:
	if (thread)
		thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
	mutex_unlock(&binder_lock);
	wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
	return ret;
}
17、binder_ioctl
int
binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
		    void __user *buffer, int size, signed long *consumed)//buffer执行进程传递给binder驱动程序的一个binder_write_read结构体的写缓冲区
{
	uint32_t cmd;
	void __user *ptr = buffer + *consumed;
	void __user *end = buffer + size;

	while (ptr < end && thread->return_error == BR_OK) {
		if (get_user(cmd, (uint32_t __user *)ptr))//读出传入的协议命令
			return -EFAULT;
		ptr += sizeof(uint32_t);
		if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {
			binder_stats.bc[_IOC_NR(cmd)]++;
			proc->stats.bc[_IOC_NR(cmd)]++;
			thread->stats.bc[_IOC_NR(cmd)]++;
		}
		switch (cmd) {
		case BC_FREE_BUFFER: {
			void __user *data_ptr;
			struct binder_buffer *buffer;

			if (get_user(data_ptr, (void * __user *)ptr))//得到要释放的内核缓冲区用户空间地址
				return -EFAULT;
			ptr += sizeof(void *);

			buffer = binder_buffer_lookup(proc, data_ptr);//根据内核缓冲区用户空间地址得到对应的内核空间地址
			if (buffer == NULL) {
				binder_user_error("binder: %d:%d "
					"BC_FREE_BUFFER u%p no match\n",
					proc->pid, thread->pid, data_ptr);
				break;
			}
			if (!buffer->allow_user_free) {
				binder_user_error("binder: %d:%d "
					"BC_FREE_BUFFER u%p matched "
					"unreturned buffer\n",
					proc->pid, thread->pid, data_ptr);
				break;
			}

			if (buffer->transaction) {
				buffer->transaction->buffer = NULL;
				buffer->transaction = NULL;
			}
			if (buffer->async_transaction && buffer->target_node) {
				BUG_ON(!buffer->target_node->has_async_transaction);
				if (list_empty(&buffer->target_node->async_todo))
					buffer->target_node->has_async_transaction = 0;
				else
					list_move_tail(buffer->target_node->async_todo.next, &thread->todo);
			}
			binder_transaction_buffer_release(proc, buffer, NULL);//减少binder实体对象或引用对象的引用计数
			binder_free_buf(proc, buffer);//释放内核缓冲区
			break;
		}
		case BC_TRANSACTION:
		case BC_REPLY: {
			struct binder_transaction_data tr;

			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;
	}
	return 0;
}
18、binder_thread_write
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_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;
	struct binder_transaction *in_reply_to = NULL;
	struct binder_transaction_log_entry *e;
	uint32_t return_error;

	if (reply) {//要处理的是BC_REPLY命令还是BC_TRANSACTION
		in_reply_to = thread->transaction_stack;//binder驱动程序分发一个进程间通信请求给一个线程处理时,会将一个binder_transaction结构体压入它的事务栈
		if (in_reply_to == NULL) {
			return_error = BR_FAILED_REPLY;
			goto err_empty_call_stack;
		}
		binder_set_nice(in_reply_to->saved_priority);//恢复原来线程的优先级
		if (in_reply_to->to_thread != thread) {
			return_error = BR_FAILED_REPLY;
			in_reply_to = NULL;
			goto err_bad_call_stack;
		}
		thread->transaction_stack = in_reply_to->to_parent;//下一个需要处理的事务
		target_thread = in_reply_to->from;//获得目标线程
		if (target_thread == NULL) {
			return_error = BR_DEAD_REPLY;
			goto err_dead_binder;
		}
		if (target_thread->transaction_stack != in_reply_to) {
			return_error = BR_FAILED_REPLY;
			in_reply_to = NULL;
			target_thread = NULL;
			goto err_dead_binder;
		}
		target_proc = target_thread->proc;
	} else {//BC_TRANSACTION
	}
	if (target_thread) {//有目标线程,指向目标线程
		e->to_thread = target_thread->pid;
		target_list = &target_thread->todo;
		target_wait = &target_thread->wait;
	} else {//指向目标进程
		target_list = &target_proc->todo;
		target_wait = &target_proc->wait;
	}
	e->to_proc = target_proc->pid;

	/* TODO: reuse incoming transaction for reply */
	t = kzalloc(sizeof(*t), GFP_KERNEL);//分配一个binder_transaction结构体
	if (t == NULL) {
		return_error = BR_FAILED_REPLY;
		goto err_alloc_t_failed;
	}
	binder_stats.obj_created[BINDER_STAT_TRANSACTION]++;

	tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);//binder_work
	if (tcomplete == NULL) {
		return_error = BR_FAILED_REPLY;
		goto err_alloc_tcomplete_failed;
	}
	binder_stats.obj_created[BINDER_STAT_TRANSACTION_COMPLETE]++;

	t->debug_id = ++binder_last_id;
	e->debug_id = t->debug_id;

	if (!reply && !(tr->flags & TF_ONE_WAY))//初始化binder_transaction
		t->from = thread;//from指向源线程,client线程以便以便目标线程或进程处理完该进程间通信请求后,能够找回发出该请求的线程
	else
		t->from = NULL;
	t->sender_euid = proc->tsk->cred->euid;
	t->to_proc = target_proc;
	t->to_thread = target_thread;
	t->code = tr->code;
	t->flags = tr->flags;
	t->priority = task_nice(current);
	t->buffer = binder_alloc_buf(target_proc, tr->data_size,
		tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));//分配内核缓冲区,以便可以将进程间通信数据复制到里面
	if (t->buffer == NULL) {
		return_error = BR_FAILED_REPLY;
		goto err_binder_alloc_buf_failed;
	}
	t->buffer->allow_user_free = 0;
	t->buffer->debug_id = t->debug_id;
	t->buffer->transaction = t;
	t->buffer->target_node = target_node;
	if (target_node)
		binder_inc_node(target_node, 1, 0, NULL);//增加目标实体对象的强引用
//(((tr->data_size)+((typeof(tr->data_size))(sizeof(void *))-1))&~((typeof(tr->data_size))(sizeof(void *))-1))
	offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));//偏移数组起始位置

	if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {//将client数据缓冲区的数据复制到binder_transaction的内核缓冲区中
		return_error = BR_FAILED_REPLY;
		goto err_copy_data_failed;
	}
	if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {//将client偏移数组内容复制到binder_transaction内核缓冲区中
		return_error = BR_FAILED_REPLY;
		goto err_copy_data_failed;
	}
	if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
		return_error = BR_FAILED_REPLY;
		goto err_bad_offset;
	}
	off_end = (void *)offp + tr->offsets_size;
	for (; offp < off_end; offp++) {//遍历进程间通信数据中的binder对象
		struct flat_binder_object *fp;
		if (*offp > t->buffer->data_size - sizeof(*fp) ||
		    t->buffer->data_size < sizeof(*fp) ||
		    !IS_ALIGNED(*offp, sizeof(void *))) {
			return_error = BR_FAILED_REPLY;
			goto err_bad_offset;
		}
		fp = (struct flat_binder_object *)(t->buffer->data + *offp);
		switch (fp->type) {
		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 (ref->node->proc == target_proc) {
			} else {
				struct binder_ref *new_ref;
				new_ref = binder_get_ref_for_node(target_proc, ref->node);//查找FregClient进程中是否一个引用了FregService实体对象的binder引用对象
				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) {
		BUG_ON(t->buffer->async_transaction != 0);
		binder_pop_transaction(target_thread, in_reply_to);//从目标线程的事务堆栈中删除binder_transaction,因为in_reply_to描述的事务已经处理完
	} else if (!(t->flags & TF_ONE_WAY)) {//如果源线程正在处理的是一个同步的进程间通信请求
	} else {
	}
	t->work.type = BINDER_WORK_TRANSACTION;//将事务中的工作项设置为BINDER_WORK_TRANSACTION类型
	list_add_tail(&t->work.entry, target_list);//添加到目标进程或线程的todo队列
	tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;//将工作项tcomplete设置为BINDER_WORK_TRANSACTION_COMPLETE类型
	list_add_tail(&tcomplete->entry, &thread->todo);//添加到源线程的todo队列,表示transaction已完成
	if (target_wait)
		wake_up_interruptible(target_wait);
	return;
}
19、binder_transaction
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;

	int ret = 0;
	int wait_for_proc_work;

	if (*consumed == 0) {
		if (put_user(BR_NOOP, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
	}
//如果一个线程的事务栈transaction_stack不为NULL,就表示它正在等待其他线程完成另一个事务;
//如果线程的todo队列不为空,说明该线程有待处理的工作项;
//一个线程只有在线程事务栈为NULL和todo队列为空的情况下才会去处理所属进程todo队列中的工作项
retry:
	wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);//判断当前线程事务栈和工作项队列todo是否需要处理

	if (thread->return_error != BR_OK && ptr < end) {
		if (thread->return_error2 != BR_OK) {
			if (put_user(thread->return_error2, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);
			if (ptr == end)
				goto done;
			thread->return_error2 = BR_OK;
		}
		if (put_user(thread->return_error, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
		thread->return_error = BR_OK;
		goto done;
	}

	thread->looper |= BINDER_LOOPER_STATE_WAITING;//设置当前线程为BINDER_LOOPER_STATE_WAITING,表示当前线程正处于空闲状态
	if (wait_for_proc_work)
		proc->ready_threads++;//当前线程所属的进程多了一个空闲的binder线程
	mutex_unlock(&binder_lock);
	if (wait_for_proc_work) {
		if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
					BINDER_LOOPER_STATE_ENTERED))) {
			wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
		}
		binder_set_nice(proc->default_priority);//将当前线程的优先级设置为所属进程的优先级
		//non_block表示当前线程是否以非阻塞的形式打开设备文件/dev/binder,如果是就不能在binder驱动程序中睡眠,
		//即,线程todo队列为空时,线程不可以进入睡眠状态去等待新的工作项
		if (non_block) {//不可阻塞
			if (!binder_has_proc_work(proc, thread))//判断一个进程是否有未处理的工作项,没有,直接返回
				ret = -EAGAIN;
		} else//可阻塞,当前线程没有新的工作项,就会睡在proc->wait(进程的等待队列)中,或自己的一个等待队列wait中
			ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));//等到所属进程有新的工作项
	} else {
		if (non_block) {
			if (!binder_has_thread_work(thread))
				ret = -EAGAIN;
		} else
			ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
	}
	mutex_lock(&binder_lock);//被唤醒
	if (wait_for_proc_work)
		proc->ready_threads--;//空闲线程-1
	thread->looper &= ~BINDER_LOOPER_STATE_WAITING;//当前线程取消空闲状态

	if (ret)
		return ret;

	while (1) {
		uint32_t cmd;
		struct binder_transaction_data tr;
		struct binder_work *w;
		struct binder_transaction *t = NULL;

		if (!list_empty(&thread->todo))//当前线程检查自己的todo队列有没有新的工作项
			w = list_first_entry(&thread->todo, struct binder_work, entry);
		else if (!list_empty(&proc->todo) && wait_for_proc_work)//线程所在的宿主进程有没有新的工作项
			w = list_first_entry(&proc->todo, struct binder_work, entry);
		else {
			if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */
				goto retry;
			break;
		}

		if (end - ptr < sizeof(tr) + 4)
			break;

		switch (w->type) {
		case BINDER_WORK_TRANSACTION_COMPLETE: {
			cmd = BR_TRANSACTION_COMPLETE;
			if (put_user(cmd, (uint32_t __user *)ptr))//将BR_TRANSACTION_COMPLETE写入用户空间提供的缓冲区中
				return -EFAULT;
			ptr += sizeof(uint32_t);

			binder_stat_br(proc, thread, cmd);
			list_del(&w->entry);//移除当前工作项
			kfree(w);
			binder_stats.obj_deleted[BINDER_STAT_TRANSACTION_COMPLETE]++;
		} break;
		}

		if (!t)
			continue;
	}
	return 0;
}
20、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;

	int ret = 0;
	int wait_for_proc_work;

	if (*consumed == 0) {
		if (put_user(BR_NOOP, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
	}
//如果一个线程的事务栈transaction_stack不为NULL,就表示它正在等待其他线程完成另一个事务;
//如果线程的todo队列不为空,说明该线程有待处理的工作项;
//一个线程只有在线程事务栈为NULL和todo队列为空的情况下才会去处理所属进程todo队列中的工作项
retry:
	wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);//判断当前线程事务栈和工作项队列todo是否需要处理

	if (thread->return_error != BR_OK && ptr < end) {
		if (thread->return_error2 != BR_OK) {
			if (put_user(thread->return_error2, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);
			if (ptr == end)
				goto done;
			thread->return_error2 = BR_OK;
		}
		if (put_user(thread->return_error, (uint32_t __user *)ptr))
			return -EFAULT;
		ptr += sizeof(uint32_t);
		thread->return_error = BR_OK;
		goto done;
	}

	thread->looper |= BINDER_LOOPER_STATE_WAITING;//设置当前线程为BINDER_LOOPER_STATE_WAITING,表示当前线程正处于空闲状态
	if (wait_for_proc_work)
		proc->ready_threads++;//当前线程所属的进程多了一个空闲的binder线程
	mutex_unlock(&binder_lock);
	if (wait_for_proc_work) {
		if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
					BINDER_LOOPER_STATE_ENTERED))) {
			wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
		}
		binder_set_nice(proc->default_priority);//将当前线程的优先级设置为所属进程的优先级
		//non_block表示当前线程是否以非阻塞的形式打开设备文件/dev/binder,如果是就不能在binder驱动程序中睡眠,
		//即,线程todo队列为空时,线程不可以进入睡眠状态去等待新的工作项
		if (non_block) {//不可阻塞
			if (!binder_has_proc_work(proc, thread))//判断一个进程是否有未处理的工作项,没有,直接返回
				ret = -EAGAIN;
		} else//可阻塞,当前线程没有新的工作项,就会睡在proc->wait(进程的等待队列)中,或自己的一个等待队列wait中
			ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));//等到所属进程有新的工作项
	} else {
		if (non_block) {
			if (!binder_has_thread_work(thread))
				ret = -EAGAIN;
		} else
			ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
	}
	mutex_lock(&binder_lock);//被唤醒
	if (wait_for_proc_work)
		proc->ready_threads--;//空闲线程-1
	thread->looper &= ~BINDER_LOOPER_STATE_WAITING;//当前线程取消空闲状态

	if (ret)
		return ret;

	while (1) {
		uint32_t cmd;
		struct binder_transaction_data tr;
		struct binder_work *w;
		struct binder_transaction *t = NULL;

		if (!list_empty(&thread->todo))//当前线程检查自己的todo队列有没有新的工作项
			w = list_first_entry(&thread->todo, struct binder_work, entry);
		else if (!list_empty(&proc->todo) && wait_for_proc_work)//线程所在的宿主进程有没有新的工作项
			w = list_first_entry(&proc->todo, struct binder_work, entry);
		else {
			if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */
				goto retry;
			break;
		}

		if (end - ptr < sizeof(tr) + 4)
			break;

		switch (w->type) {
		case BINDER_WORK_TRANSACTION: {
			t = container_of(w, struct binder_transaction, work);
		} break;
		}

		if (!t)
			continue;

		BUG_ON(t->buffer == NULL);
		if (t->buffer->target_node) {//设置binder_transaction_data 进程间通信数据
		} else {//当一个server线程将一个进程间通信数据返回给client线程时,是不需要在进程间通信数据中指定一个目标binder实体对象的
			tr.target.ptr = NULL;
			tr.cookie = NULL;
			cmd = BR_REPLY;
		}
		tr.code = t->code;
		tr.flags = t->flags;
		tr.sender_euid = t->sender_euid;

		if (t->from) {
			struct task_struct *sender = t->from->proc->tsk;
			tr.sender_pid = task_tgid_nr_ns(sender, current->nsproxy->pid_ns);
		} else {
			tr.sender_pid = 0;
		}

		tr.data_size = t->buffer->data_size;
		tr.offsets_size = t->buffer->offsets_size;
		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 *));

		if (put_user(cmd, (uint32_t __user *)ptr))//将binder_transaction_data所对应的返回协议BR_TRANSACTION及它复制到目标线程提供的一个用户缓冲区中
			return -EFAULT;
		ptr += sizeof(uint32_t);
		if (copy_to_user(ptr, &tr, sizeof(tr)))//复制的只是地址值
			return -EFAULT;
		ptr += sizeof(tr);

		binder_stat_br(proc, thread, cmd);

		list_del(&t->work.entry);//将binder_work结构体w,从目标线程的todo队列中删除,因为他描述的工作项已经完成
		t->buffer->allow_user_free = 1;//表示binder驱动程序分配的内核缓冲区允许目标线程在用户空间发出BC_FREE_BUFFER命令协议来释放
		if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) {//binder向目标线程发送的是一个BR_TRANSACTION返回协议binder_transaction.falg的TF_ONE_WAY位为0
			t->to_parent = thread->transaction_stack;//说明binder正在执行一个进程间通信请求,将binder_transaction结构体t压入目标线程thread的事务堆栈
			t->to_thread = thread;
			thread->transaction_stack = t;
		} else {//处理的不是进程间同步请求,释放binder_transaction结构体t的内核空间
			t->buffer->transaction = NULL;
			kfree(t);
			binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++;
		}
		break;
	}

done:

	*consumed = ptr - buffer;
	//检查当线程所属的进程是否需要请求增加一个新的binder线程来处理进程间通信请求
	if (proc->requested_threads + proc->ready_threads == 0 &&//空闲线程数(ready_threads)为0,binder驱动程序中正在处理请求的binder进程数(proc->requested_threads)之和为0,其实他们两个都为0,和才为0,空闲线程数为0
	    proc->requested_threads_started < proc->max_threads &&//binder驱动程序请求增加的binder线程数requested_threads_started 小于 预设的最大线程数
	    (thread->looper & (BINDER_LOOPER_STATE_REGISTERED |//当前线程已经注册成了binder线程
	     BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */
	     /*spawn a new thread if we leave this out */) {
		proc->requested_threads++;
		if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))//将一个返回协议代码BR_SPAWN_LOOPER,写入到用户空间缓冲区buffer中,以便进程可以创建一个新的线程加入到binder线程池中。
			return -EFAULT;
	}
	return 0;
}
21、binder_thread_read
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
    
    binder_write_read bwr;//使用BINDER_WRITE_READ IO控制命令,定义binder_write_read结构体来指定读端和写端
    
    // Is the read buffer empty?
    const bool needRead = mIn.dataPosition() >= mIn.dataSize();//返回协议缓冲区mIn的返回协议已经处理完成
    
    // We don't want to write anything if we are still reading
    // from data left in the input buffer and the caller
    // has requested to read the next data.
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;//doReceive表示是否想要接收binder驱动程序发送给进程的返回协议,needRead如果为false表示mIn中的返回协议还没处理完,这是再往写端写数据,也没用,读端mIn处理不了
    
    bwr.write_size = outAvail;//写端缓冲区和读端缓冲区的大小分别为0和大于0,binder驱动程序不会处理进程发送给他的命令协议,只会向该进程发送返回协议,这样进程就达到了只接受返回协议的结果
    bwr.write_buffer = (long unsigned int)mOut.data();

    // This is what we'll read.
    //doReceive如果为true表示想要接收binder的返回协议,
    //当然要能处理读端数据,返回协议缓冲区mIn中的数据也要处理完,否则往读端缓冲区写数据也处理不了,
    //所以如果mIn中的返回协议处理完了needRead为true,这时就可以设置读端缓冲区大小了
    if (doReceive && needRead) {
        bwr.read_size = mIn.dataCapacity();
        bwr.read_buffer = (long unsigned int)mIn.data();
    } else {
        bwr.read_size = 0;//
    }
    
    // Return immediately if there is nothing to do.
    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;//判断写端和读端的缓冲区大小是否都为0,如果是就不用进入binder驱动程序了,因为没有数据传入binder程序,也不需要binder程序返回结果
    
    bwr.write_consumed = 0;
    bwr.read_consumed = 0;
    status_t err;
    do {
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)//while循环使用IO控制命令BINDER_WRITE_READ与binder驱动程序交互
            err = NO_ERROR;
        else
            err = -errno;
    } while (err == -EINTR);

    if (err >= NO_ERROR) {
        if (bwr.write_consumed > 0) {//将binder驱动程序已经处理命令协议从mOut中移除
            if (bwr.write_consumed < (ssize_t)mOut.dataSize())
                mOut.remove(0, bwr.write_consumed);
            else
                mOut.setDataSize(0);
        }
        if (bwr.read_consumed > 0) {//将冲binder驱动程序中读取出来的返回协议保存在mIn中
            mIn.setDataSize(bwr.read_consumed);
            mIn.setDataPosition(0);
        }
        return NO_ERROR;
    }
    
    return err;
}
22、talkWithDriver
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    int32_t cmd;
    int32_t err;

    while (1) {
        if ((err=talkWithDriver()) < NO_ERROR) break;
        err = mIn.errorCheck();
        if (err < NO_ERROR) break;
        if (mIn.dataAvail() == 0) continue;
        
        cmd = mIn.readInt32();//读出返回协议代码

        switch (cmd) {
        case BR_REPLY:
            {
                binder_transaction_data tr;
                err = mIn.read(&tr, sizeof(tr));
                LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
                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 size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(size_t),
                            freeBuffer, this);
                    } else {
                        err = *static_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 size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(size_t), this);
                    }
                } else {
                    freeBuffer(NULL,
                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                        tr.data_size,
                        reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
                        tr.offsets_size/sizeof(size_t), this);
                    continue;
                }
            }
            goto finish;
        }
    }

    return err;
}
23、waitForResponse
status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    status_t err = data.errorCheck();//进程间通信数据data是否有问题

    flags |= TF_ACCEPT_FDS;//表示server进程在返回结果携带文件描述符
    
    if (err == NO_ERROR) {//没有问题
        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);//将data写入到binder_transaction_data结构体中,还没发送到binder驱动程序
    }
    
    if (err != NO_ERROR) {
        if (reply) reply->setError(err);
        return (mLastError = err);
    }
    
    if ((flags & TF_ONE_WAY) == 0) {//判断是不是同步请求
        if (reply) {//是否有数据返回
            err = waitForResponse(reply);//向驱动程序发送一个BC_TRANSACTION命令协议
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
    } else {
        err = waitForResponse(NULL, NULL);
    }
    
    return err;
}
24、transact
//transact函数将mHandler,以及进程间通信数据发送给Binder驱动程序,这样Binder驱动程序就能通过这个句柄值找到对应的Binder引用对象,
//进而找到Binder实体对象,最后就可以将进程间通信数据发送给service组件
status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)//data进程间通信数据,falg默认为0,表示这是一个同步请求
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}
25、transact
/*ServiceManager代理对象的成员函数checkService实现的是一个标准的binder进程间通信过程,它可以划分为五步
	1.FregClient进程将进程间通信数据,即Service组件FregService的代理对象的名称,封装到Parcel对象中;
	2.FregClient进程向binder驱动程序发送BC_TRANSACTION命令,binder驱动程序根据协议内容找到ServiceManager进程后,
	就会向FregClient进程发送一个BR_TRANSACTION_COMPLETE返回协议,表示它的进程间通信请求已被binder驱动程序接受。
	FregClient进程在接受到BR_TRANSACTION_COMPLETE返回协议,并且对它进行处理后,就会再次进入binder驱动程序中去等待
	ServiceManager进程将它要获取的binder代理对象的句柄值返回回来。
	3.binder驱动程序在向FregClient进程发送BR_TRANSACTION_COMPLETE返回协议的同时,也会向ServiceManager进程发送BR_TRANSACTION
	返回协议,请求ServiceManager进程执行一个CHECK_SERVICE_TRANSACTION操作。
	4.ServiceManager进程在执行完FregClient进程请求的CHECK_SERVICE_TRANSACTION操作后,就会向binder驱动程序发送一个BC_REPLY命令协议,
	协议包含Service组件FregService的信息。binder驱动程序就会根据FregService的信息为FregClient进程创建一个binder引用对象,
	接着就会向ServiceManager进程发送一个BR_TRANSACTION_COMPLETE返回协议,表示它返回的FregService信息已经收到。ServiceManager进程
	收到BR_TRANSACTION_COMPLETE返回协议,并对它处理后,一次进程间通信过程就结束了,接着它再次进入binder驱动程序,等待下一次进程间通信请求。
	5.binder驱动程序在向ServiceManager进程发送BR_TRANSACTION_COMPLETE返回协议的同时,也向FregClient进程发送一个BR_REPLY返回协议,
	协议中包含了前面创建的一个binder引用对象的句柄值,这时候FregClient进程就可以通过这个句柄值来创建一个binder代理对象。*/
    virtual sp<IBinder> checkService( const String16& name) const
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);//通过句柄值为0的binder代理对象与ServiceManager进行通信
        return reply.readStrongBinder();
    }
26、checkService
    virtual sp<IBinder> getService(const String16& name) const
    {
        unsigned n;
        for (n = 0; n < 5; n++){//最多尝试5次获取名称为name的Service组件代理对象
            sp<IBinder> svc = checkService(name);
            if (svc != NULL) return svc;
            LOGI("Waiting for service %s...\n", String8(name).string());
            sleep(1);//获取失败,睡1毫秒,重试
        }
        return NULL;
    }
27、getService

版权声明:本文为qq_30874221原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。