android binder机制,注册系统服务---结果返回

5结果返回

用户态的Servicemanager进程发送的是BINDER_WRITE_READ命令,需要处理返回的BC_REPLY命令。

并且只有写操作,没有读操作,即read_size0

5.1 servicemanager进程binder驱动

1,首先binder驱动的binder_ioctl方法处理BINDER_WRITE_READ命令,前面已经论述了,在此就不赘述。

2, binder_ioctl方法调用binder_thread_write方法处理BC_REPLY命令

当然是和BC_TRANSACTION命令一起处理的,只是调用binder_transaction时最后一个参数不一样,

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;
}

binder_transaction以及以后的方法上面都论述过,在此不再论述了。关键代码如下,

tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
	list_add_tail(&tcomplete->entry, &thread->todo);
	if (target_wait)
		wake_up_interruptible(target_wait);
	return;

此时发送的命令是BINDER_WORK_TRANSACTION_COMPLETE,

然后唤醒客户端的等待线程,执行binder_thread_read方法。

通俗的讲,原理如下,

1,顾客告诉厨师需要的菜之后就去睡觉了。

2,厨师做好菜之后就将客户叫醒,该吃饭了。

这样, servicemanager进程一个周期的消息就处理完了,返回到binder_loop方法

for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;
         // 读取驱动的命令
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

        if (res < 0) {
            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }
         // 解析命令
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
        if (res == 0) {
            ALOGE("binder_loop: unexpected reply?!\n");
            break;
        }

接着调用ioctl方法进入内核态,调用binder_thread_read方法,进入等待状态,等待下一个客户进程的请求,

如此这样循环往复,生生不息。

好了, 对于注册消息,servicemanager进程到此就分析完了。

5.2 客户进程binder驱动

绕了这么一大圈,又回到了客户端进程, binder驱动的binder_thread_read方法对

BINDER_WORK_TRANSACTION_COMPLETE消息处理如下,

case BINDER_WORK_TRANSACTION_COMPLETE: {
			cmd = BR_TRANSACTION_COMPLETE;
			if (put_user(cmd, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);

			binder_stat_br(proc, thread, cmd);
			binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE,
				     "%d:%d BR_TRANSACTION_COMPLETE\n",
				     proc->pid, thread->pid);

			list_del(&w->entry);
			kfree(w);
			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
		} break;
•••
tr.target.ptr = 0;
tr.cookie = 0;
cmd = BR_REPLY;

这样,内核态返回给servicemanager进程用户态的命令是BR_TRANSACTION_COMPLETE

发送给客户端用户态的命令是BR_REPLY

 

用户态将数据从内核态复制到用户态,其他的处理就不多说了。

binder_thread_read方法处理完成之后,返回到binder_ioctl方法,然后返回到用户态的talkWithDriver方法, 

最后返回到waitForResponse方法。

5.3 客户进程

waitForResponse方法对BR_REPLY命令处理如下,

case BR_REPLY:
            {
                binder_transaction_data tr;
                err = mIn.read(&tr, sizeof(tr));
                ALOG_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 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;

这样客户进程就得到了目标进程ServiceManager发送过来的服务注册结果了,结果保存在reply中。

这样,客户端整个周期也处理完了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值