第一范文网 - 专业文章范例文档资料分享平台

android - IPC及原理简介

来源:用户分享 时间:2025/5/22 12:50:35 本文由loading 分享 下载这篇文档手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

size_t IN = mIn.dataAvail(); if (IN < sizeof(int32_t)) continue; cmd = mIn.readInt32(); IF_LOG_COMMANDS() {

alog << \ << getReturnString(cmd) << endl; }

result = executeCommand(cmd); } ... while(...);

这个函数在循环中重复执行下列动作:

talkWithDriver 通过ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)读取请求和写回结果。

executeCommand 执行相应的请求

在IPCThreadState::executeCommand(int32_t cmd)函数中:

对于控制对象生命周期的请求,像BR_ACQUIRE/BR_RELEASE直接做了处理。 对于BR_TRANSACTION请求,它调用被请求对象的transact函数。 按下列方式调用实际的对象: if (tr.target.ptr) {

sp b((BBinder*)tr.cookie);

const status_t error = b->transact(tr.code, buffer, &reply, 0); if (error < NO_ERROR) reply.setError(error); } else {

const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0); if (error < NO_ERROR) reply.setError(error);

}

如果tr.target.ptr不为空,就把tr.cookie转换成一个Binder对象,并调用它的transact函数。如果没有目标对象,就调用 the_context_object对象的transact函数。奇怪的是,根本没有谁对the_context_object进行初始化,the_context_object是空指针。原因是context_mgr的请求发给了ServiceManager,所以根本不会走到else语句里来。

o 内核模块

android使用了一个内核模块binder来中转各个进程之间的消息。模块源代码放在binder.c里,它是一个字符驱动程序,主要通过binder_ioctl与用户空间的进程交换数据。其中BINDER_WRITE_READ用来读写数据,数据包中有一个cmd域用于区分不同的请求:

binder_thread_write用于发送请求或返回结果。 binder_thread_read用于读取结果。

从binder_thread_write中调用binder_transaction中转请求和返回结果,binder_transaction的实现如下:

对请求的处理:

通过对象的handle找到对象所在的进程,如果handle为空就认为对象是context_mgr,把请求发给context_mgr所在的进程。

把请求中所有的binder对象全部放到一个RB树中。 把请求放到目标进程的队列中,等待目标进程读取。

如何成为context_mgr呢?内核模块提供了BINDER_SET_CONTEXT_MGR调用: static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { ...

case BINDER_SET_CONTEXT_MGR: if (binder_context_mgr_node != NULL) {

printk(KERN_ERR \set\\n\

ret = -EBUSY; goto err; }

if (binder_context_mgr_uid != -1) {

if (binder_context_mgr_uid != current->euid) { printk(KERN_ERR \ \ current->euid,

binder_context_mgr_uid); ret = -EPERM; goto err; } } else

binder_context_mgr_uid = current->euid;

binder_context_mgr_node = binder_new_node(proc, NULL, NULL); if (binder_context_mgr_node == NULL) { ret = -ENOMEM; goto err; }

binder_context_mgr_node->local_weak_refs++; binder_context_mgr_node->local_strong_refs++; binder_context_mgr_node->has_strong_ref = 1; binder_context_mgr_node->has_weak_ref = 1; break;

ServiceManager(frameworks/base/cmds/servicemanager)通过下列方式成为了context_mgr进程:

int binder_become_context_manager(struct binder_state *bs) {

return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); }

int main(int argc, char **argv) {

struct binder_state *bs;

void *svcmgr = BINDER_SERVICE_MANAGER;

bs = binder_open(128*1024);

if (binder_become_context_manager(bs)) {

LOGE(\ return -1; }

svcmgr_handle = svcmgr; binder_loop(bs, svcmgr_handler); return 0; }

o 如何得到服务对象的handle

服务提供者通过defaultServiceManager得到ServiceManager对象,然后调用addService向服务管理器注册。

服务使用者通过defaultServiceManager得到ServiceManager对象,然后调用getService通过服务名称查找到服务对象的handle。

o 如何通过服务对象的handle找到服务所在的进程

0表示服务管理器的handle,getService可以查找到系统服务的handle。这个handle只是代表了服务对象,内核模块是如何通过handle找到服务所在的进程的呢?

对于ServiceManager: ServiceManager调用了binder_become_context_manager使用自己成为context_mgr,所有handle为0的请求都会被转发给ServiceManager。

搜索更多关于: android - IPC及原理简介 的文档
android - IPC及原理简介.doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/c1uwhi1x56001k8300sr4_5.html(转载请注明文章来源)
热门推荐
Copyright © 2012-2023 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top