当前位置:网站首页>Binder ServiceManager解析
Binder ServiceManager解析
2022-08-02 14:08:00 【nginux】
1 Binder库介绍
在Binder库中,Service组件和Client组件分别使用模板BnInterface和BpInterface描述,其中前者成为Binder本地对象,后者成为Binder代理对象。Binder库中的Binder本地对象和Binder代理对象分别对应于Binder驱动程序中的Binder实体对象、Binder引用对象。
BpBinder类中有一个成员变量mHandle,代表一个Client组件的句柄值,每个Client组件在Binder驱动程序中都对应一个Binder引用对象,而每个引用对象都有个句柄值,其中Client组件就是通过这个句柄值来和Binder驱动程序中的Binder引用对象建立对应关系的。
BpBinder类的成员函数transact用来向运行在Server进程中的Service组件发送进程间通信的请求,这是通过Binder驱动程序间接实现的。BpBinder的成员函数transact会把BpBinder类的成员变量mHandle,以及进程间通信数据发送给Binder驱动程序,这样Binder驱动程序就能够根据这个句柄值来找到对应的Binder引用对象,继而找到对应的Binder实体对象,最后可以将进程间通信数据发送给对应的Service组件了。
无论是BBinder还是BpBinder都是通过IPCThreadState和Binder驱动程序交互的,每个使用Binder进程间通信机制的进程都一个Binder线程池,用来处理进程间通信请求。对于每一个Binder线程来说,它的内部都有一个IPCThreadState对象,我们可以通过IPCThreadState的静态成员函数self()获取,并且调用它的成员函数transact来和Binder驱动程序交互。在transact内部,与Binder驱动程序交互操作又是通过talkWithDriver来实现的,它一方面负责向Binder程序发送进程间的通信请求,另一方面又负责接收来自Binder驱动程序的进程间通信请求。
2 Binder机制运作的必要组成
- client组件:通信请求的发起端。
- service组件:通信请求的目标端。
- Service Manager:服务的管理者。
- binder驱动:进程间通信的执行者。
只有驱动运行在内核空间,其余的运行在用户空间
3 驱动中的两个重要数据结构
struct binder_node{
....
void __user *cookie;
...
};
struct binder_ref{
...
struct binder_node *node;
uint32_t desc;
...
};
这里只是介绍和service manager工作原理相关的几个成员变量。binder_node代表binder实体对象,binder_ref代表binder引用对象,他们都是binder驱动里面的结构体。
cookie:指向service组件的用户地址空间
node:指向对应的binder实体对象
desc:binder引用对象的句柄值
那么这两个结构体是什么时候创建呢,在Binder机制的中篇中,我们已经介绍过,当binder驱动检测到传输的数据是binder实体对象的时候就会创建binder_node、binder_ref,并且这个binder_ref通过成员变量node指向binder_node
另外一个问题就是什么时候binder驱动中传输的数据是binder对象呢?答案就是注册service组件的时候,注册service组件的过程下文会介绍。
4 Service Manager工作机制
Service Manager根据核心的任务其实就是提供addService、getService函数,分别实现注册service组件和获取service组件。addService到底对Service Mangager这个大管家做了什么手脚?下面我们就解开其神秘面纱。
addService的调用者严格意义上来说是ServiceManager的代理,这个代理充当了client端,真正的Service Manager服务是server端。Service Manager服务启动的时候会将自己注册为服务的管理者,并且它对应的代理对象句柄规定就是0(这个不再展开介绍)。
addService传入的参数是service组件的名称和service组件对象,当进入到binder驱动层的时候,驱动就检测到传输的数据是binder对象,然后在内核中创建binder_node、binder_ref,需要注意的是,binder_ref中函数service组件的句柄值,然后驱动将这个service组件的名字和分配的句柄值传给server端,即Service Manager对象,Service Manager对象中有个链表svlist,类型如下:
struct svcinfo{
struct svcinfo *next;
void *ptr;
struct binder_death death;
unsigned len;
uint16_t name[0];
};
name字段记录service组件的名称,ptr是service组件的句柄。Service Manager一旦接收到binder驱动传输过来的service组件名称和句柄值就创建一个svcinfo节点,并放入svlist当中,这样一来当client端通过getService()查找组件的时候就可以返回binder本地对象。
对于复杂的文字描述可能看到早就不耐烦了,下面通过一个图描述addService所做的工作(电脑没装viso挺恶心,先手绘吧^_^):
了解了addService原理,再理解getService就水道渠成啦,client端拿着serice组件的名称和Service Manager通信,Service Manager在svclist中对比组件名称,找到其对应的句柄,最后将返回一个binder代理对象
5 总结
本文介绍了Serverice Manager在Binder机制中的作用,并不涉及binder驱动层面,比如binder通信比较重要的通信协议等,以后有时间再补充。
边栏推荐
猜你喜欢
随机推荐
profiler network乱码
Ffmpeg交叉编译
2. Basic use RecyclerView
流,向量场,和微分方程
In the Visual studio code solutions have red wavy lines
【使用Pytorch实现ResNet网络模型:ResNet50、ResNet101和ResNet152】
PyTorch⑦---卷积神经网络_非线性激活
The overlapping effect of the two surfaceviews is similar to the video and handout practice in the live effect
PostgreSQL 性能谜题
针对多轮推理分类问题的软标签构造方法
It is not allowed to subscribe with a(n) xxx multiple times.Please create a fresh instance of xxx
MySQL知识总结 (二) 存储引擎
什么?都0202年了,你还不会屏幕适配?
自定义圆形seekBar,超简单
Flink时间和窗口
PyTorch②---transforms结构及用法
Detailed explanation of RecyclerView series article directory
Manifest merger failed with multiple errors, see logs
1. What is RecyclerView
再见篇:App专项技术优化