9.7 Binder系统_c++实现_内部机制1

1. 内部机制_回顾binder框架关键点

binder进程通讯过程情景举例:

test_server通过addservice向service_manager注册服务

test_client通过getservice向service_manager获取服务

然后test_client使用服务和test_server通讯

在上述通讯过程中涉及的对驱动访问:

(1)注册服务过程add_service

a、test_server为每个服务构造一个flat_binder_object结构体,不同服务结构体的binder和cookie不同

b、调用ioctl发送数据(数据包括:flat_binder_object、服务名称、目的发给谁(handle = 0,表示发给service_manager))

c、驱动程序对每一个flat_binder_object为test_server进程新建binder_node节点,节点的ptr和cookie参数值来之flat_binder_object结构体的binder和cookie

d、驱动程序根据handle=0,找到service_manager,把数据发送给它,且为service_manager进程创建binder_ref结构体,并根据binder_ref创建的顺序设置其desc参数和node指向对应的binder_node

e、service_manager里,记录服务的名称和的desc值,在service_manager应用程序中有svclist链表,链表的每个节点保存有服务的名称和的handle值(其值等于desc)

(2)获取服务过程get_service

a、test_client构造数据(数据:服务的名称、目的(handle = 0))

b、调用ioctl发送数据

c、驱动程序根据handle=0,找到service_manager,把数据发送给它

d、service_manager从svclist根据服务的名字找到对应的项,取出对应节点的handle

e、service_manager通过ioctl返回数据(数据的格式:flat_binder_object(type是引用、handle、cookie))

f、驱动程序发现数据中含有flat_binder_object结构体,且type表示引用,从service_manager进程的binder_ref中找到desc等于handle的一项,找根据binder_node找到对应的服务,最后为test_client进程建立binder_ref,根据test_client获取服务的顺序设置test_client进程你binder_ref的desc值,并设置其node执行对应的服务binder_node

(3)test_client怎么使用helloservice

a、构造数据(数据包含:code(和服务端约定的代表函数的值)、参数、目的(根据服务确定handle值))

b、使用ioctl发数据

c、驱动程序从数据中取出handle,根据handle找到test_client进程里的binder_ref,根据其找到binder_node,在根据binder_node里面的proc找到服务进程,把数据给test_server,并且在数据中设置ptr和cookie,这两个变量等于binder_node的ptr和cookie

d、test_server根据ptr和cookie知道你想调用哪个服务,在根据数据里的code来调用哪个函数

server注册服务时, 对每个服务都提供不同的ptr/cookie,
在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie

client使用服务前要先getService:会在驱动程序里对该服务构造一个binder_ref,
binder_ref含有desc, node成员, desc是整数, node指向对应服务的binder_node

使用服务时, client构造数据,调用ioctl:数据里含有handle

驱动程序根据handle找到binder_ref(desc==handle), 找到binder_node, 再找到server,
从binder_node取出ptr/cookie连同那些数据发给server

server根据ptr/cookie知道要调用哪一个服务,....

最核心函数: ioctl
client的最核心数据是:handle
server的最核心数据是:ptr/cookie

4. 内部机制_代理类分析: BpServiceManager和BpHelloService

test_client与test_server之间通信在C++中是通过代理类BpHelloService来实现(这个时候test_client是client,test_server是server)

test_server向service_manager添加服务的过程是通过代理类BpServiceManager来实现的(这个时候test_server是client,service_manager是server)

test_client向service_manager获得服务的过程是通过代理类BpServiceManager来实现的(这个时候test_client是client,service_manager是server)

根据上面那节内容:client的最核心数据是:handle

那么对于类BpServiceManager:传给它的handle = 0;

那么对于类BpHelloService:传给它的handle = BpServiceManager->getservice("hello")返回的handle值

4.1 获得BpServiceManager对象的过程:
defaultServiceManager构造了一个BpServiceManager对象,
其中它的mRemote = new BpBinder(0); // mRemote->mHandle=0

defaultServiceManager(单例模式,一个进程中只有一个) // IServiceManager.cpp
              // 把BpBinder(mHandle=0)对象转换为IServiceManager接口(BpServiceManager)
  gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
分析:
ProcessState::self()->getContextObject(NULL)
  getStrongProxyForHandle(0);
    b = new BpBinder(handle); // mHandle=handle=0

interface_cast<IServiceManager>(new BpBinder(0)) // IInterface.h
  IServiceManager::asInterface(obj);
    return new BpServiceManager(obj); // mRemote=obj=new BpBinder(0);

4.2 获得BpHelloService对象的过程:
调用BpServiceManager的getService函数获得一个flat_binder_object,
从中取出handle, 创建一个BpBinder(handle),
然后使用interface_cast使用这个BpBinder创建一个BpHelloService对象

// binder是BpBinder对象, 里面含有HelloService的handle
sp<IBinder> binder = sm->getService(String16("hello")); // IServiceManager.cpp
            // 构造数据: 数据中肯定含有"hello"
            // 发送数据: 给handle 0, 即 service_manager进程
            // 从收到的回复中取出HelloService的handle
             return reply.readStrongBinder();
               unflatten_binder(ProcessState::self(), *this, &val);
                *out = proc->getStrongProxyForHandle(flat->handle);
                  new BpBinder(handle);

            // 把binder转换为IHelloService接口(BpHelloService对象)
            // binder是BpBinder对象, 里面含有HelloService的handle
sp<IHelloService> service = interface_cast<IHelloService>(binder);

4.3 代理类如何发送数据: ioctl, 数据里含有handle, 含有其他构造的参数
构造好数据之后,调用:
remote()->transact(...)
  IPCThreadState::self()->transact(mHandle, code, data, reply, flags);

5. 内部机制_数据传输: ProcessState和IPCThreadState

test_server主进程open、mmap的操作通过sp<ProcessState> proc(ProcessState::self())来实现

类对象是ProcessState,其是单例模式,每个进程只有一个ProcessState,通过ProcessState::self来得到对象gProcess

test_server会根据情况创建多个线程,每个线程有一个IPCThreadState,其也是单例模式,通过IPCThreadState::self来得到对象

ProcessState:

  gProcess = new ProcessState时open和mmap,fd存在mDriverFD里

每个线程都有自己的IPCThreadState对象,该对象是线程特有的,各自不同,它应该存在线程的局部空间里,在进程中通过pthread_key_create()创建一个key,有key就有value,键值对。同一个key对于线程其可以设置不同的value

在线程1中通过pthread_setspecific(k,v1)设置,通过pthread_getspecific(k)获得进程v1

IPCThreadState

  ProcessState::self()->startThreadPool();//创建子线程

  IPCThreadState::self()->joinThreadPool();//主线程

5.1 addService
对于不同服务,构造flat_binder_object结构体,里面的.binder/.cookie对于不同的服务它的值不一样

sm->addService(String16("hello"), new BnHelloService());
data.writeStrongBinder(service); // service = new BnHelloService();
flatten_binder(ProcessState::self(), val, this); // val = service = new BnHelloService();
flat_binder_object obj; // 参数 binder = val = service = new BnHelloService();
IBinder *local = binder->localBinder(); // =this = new BnHelloService();
obj.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local); // new BnHelloService();

5.2 server如何分辨client想使用哪一个服务
server收到数据里含有flat_binder_object结构体,
它可以根据.binder/.cookie分析client想使用哪一个服务

把.cookie转换为BnXXXX对象,然后调用它的函数:

// 根据cookie构造了一个BBinder指针, 实际上是指向某个BnXXX对象
sp<BBinder> b((BBinder*)tr.cookie);

// 然后调用它的transact函数
error = b->transact(tr.code, buffer, &reply, tr.flags);
err = onTransact(code, data, reply, flags); // 就会调用到BnXXX里实现的onTransact
// 它就会根据code值来调用不同的函数

5.3 怎么调用到HelloService所提供的函数

原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/9154836.html

时间: 2024-11-06 18:27:56

9.7 Binder系统_c++实现_内部机制1的相关文章

9.12 Binder系统_Java实现_内部机制_Client端

Java实现中client端的RPC层(java实现)如何通过JNI来调用IPC层(C++实现)发送数据 TestServer通过addService向Service_manager注册的时候TestServer是Client端,Service_manager是Server端: TestClient通过getService向Service_manager请求服务的时候TestClient是Client端,Service_manager是Server端: TestClient调用RPC层的sayh

9.13 Binder系统_Java实现_内部机制_Server端

logcat TestServer:* TestClient:* HelloService:* *:S &CLASSPATH=/mnt/android_fs/TestServer.jar app_process / TestServer &CLASSPATH=/mnt/android_fs/TestClient.jar app_process / TestClient helloCLASSPATH=/mnt/android_fs/TestClient.jar app_process / T

第7课第2节_Binder系统_c++实现_编译测试

七. Binder系统之服务的c++实现1. 编写代码参考文件:frameworks\av\include\media\IMediaPlayerService.h (IMediaPlayerService,BnMediaPlayerService)frameworks\av\media\libmedia\IMediaPlayerService.cpp (BpMediaPlayerService)frameworks\av\media\libmediaplayerservice\MediaPlay

Android驱动学习-内部机制_回顾binder框架关键点

内部机制_回顾binder框架关键点server注册服务时, 对每个服务都提供不同的ptr/cookie,在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie client使用服务前要先getService:会在驱动程序里对该服务构造一个binder_ref, binder_ref含有desc, node成员, desc是整数, node指向对应服务的binder_node 使用服务时, client构造数据,调用ioctl:数据里含有handle 驱动程序根据

Linux嵌入式学习-远程过程调用-Binder系统

Binder系统的C程序使用示例IPC : Inter-Process Communication, 进程间通信RPC : Remote Procedure Call, 远程过程调用 这里我们直接只用android系统中已经实现好的Bindrt系统. 具体源代码在 frameworks\native\cmds\servicemanager\目录下. service_manager.c :a. binder_openb. binder_become_context_managerc. binder

Android Binder 系统学习笔记(一)Binder系统的基本使用方法

1.什么是RPC(远程过程调用) Binder系统的目的是实现远程过程调用(RPC),即进程A去调用进程B的某个函数,它是在进程间通信(IPC)的基础上实现的.RPC的一个应用场景如下: A进程想去打开LED,它会去调用led_open,然后调用led_ctl,但是如果A进程并没有权限去打开驱动程序呢? 假设此时有一个进程B由权限去操作LED驱动程序,那么进程A可以通过如下方式来操作LED驱动: ①封装数据,即A进程首先把想要调用的B进程的某个函数的(事先约定好的)代号等信息封装成数据包 ②A进

android数据存储_内部存储

源码下载(免下载积分):下载 你可以直接存储数据到内部存储中,默认情况下,文件存储到内部存储中是私有的,不能被 其他程序访问,当卸载应用程序,这些文件会被移除. 创建并写入数据可以有两种方法: 使用java中的相关的方法, 使用android.content中的相关方法,  调用 openFileOutput(),并返回FileOutputStream对象 调用FileOutputStream对象的write()方法 关闭流 读文件也是基本相同的方式. 在读文件有一点小技巧:如果想在编译时保存一

Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6629298 在前面一篇文章浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路中, 介绍了在Android系统中Binder进程间通信机制中的Server角色是如何获得Service Manager远程接口的,即defaultServiceManager函数的实现.S

Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6633311 在上一篇文章中,我 们分析了Android系统进程间通信机制Binder中的Server在启动过程使用Service Manager的addService接口把自己添加到Service Manager守护过程中接受管理.在这一篇文章中,我们将深入到Binder驱动程序源代码去分析Client是如何通过Service Manager的