1. 前言
本文主要是binder系列文章的总结笔记,主要是理清binder的总体流程和总体架构,期间会对照源码进行代码重读,也会按照自己的理解对内容进行调整,以加深对binder总体的理解。本文主要概述部分。
Android:R
Linux: kernel4.19
2. binder架构
以activity调用ActivityManagerService的startServcie为例:
- Java应用层: 对于上层应用通过调用AMP.startService, 完全可以不用关心底层,经过层层调用,最终必然会调用到AMS.startService.
- Java IPC层: Binder通信是采用C/S架构, Android系统的基础架构便已设计好Binder在Java framework层的Binder客户类BinderProxy和服务类Binder;
- Native IPC层: 对于Native层,如果需要直接使用Binder(比如media相关), 则可以直接使用BpBinder和BBinder(当然这里还有JavaBBinder)即可, 对于上一层Java IPC的通信也是基于这个层面.
- Kernel物理层: 这里是Binder Driver, 前面3层都跑在用户空间,对于用户空间的内存资源是不共享的,每个Android的进程只能运行在自己进程所拥有的虚拟地址空间, 而内核空间却是可共享的. 真正通信的核心环节还是在Binder Driver.
2. Binder原理
Binder通信采用C/S架构,从组件视角来说,包含Client、Server、ServiceManager以及binder驱动,其中ServiceManager用于管理系统中的各种服务。架构图如下所示:
可以看出无论是注册服务和获取服务的过程都需要ServiceManager,需要注意的是此处的Service Manager是指Native层的ServiceManager(C++),并非指framework层的ServiceManager(Java)。ServiceManager是整个Binder通信机制的大管家,是Android进程间通信机制Binder的守护进程,要掌握Binder机制,首先需要了解系统是如何首次启动Service Manager。当Service Manager启动之后,Client端和Server端通信时都需要先获取Service Manager接口,才能开始通信服务。
图中Client/Server/ServiceManage之间的相互通信都是基于Binder机制。既然基于Binder机制通信,那么同样也是C/S架构,则图中的3大步骤都有相应的Client端与Server端。
1.注册服务(addService):Server进程要先注册Service到ServiceManager。该过程:Server是客户端,ServiceManager是服务端。
2.获取服务(getService):Client进程使用某个Service前,须先向ServiceManager中获取相应的Service。该过程:Client是客户端,ServiceManager是服务端。
3.使用服务:Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互。该过程:client是客户端,server是服务端。
图中的Client,Server,Service Manager之间交互都是虚线表示,是由于它们彼此之间不是直接交互的,而是都通过与Binder驱动进行交互的,从而实现IPC通信方式。其中Binder驱动位于内核空间,Client,Server,Service Manager位于用户空间。Binder驱动和Service Manager可以看做是Android平台的基础架构,而Client和Server是Android的应用层,开发人员只需自定义实现client、Server端,借助Android的基本平台架构便可以直接进行IPC通信。
3. binder通信模型
以BC_TRANSACTION为例,图示如下:
Binder协议包含在IPC数据中,分为两类:
1.BINDER_COMMAND_PROTOCOL:binder请求码,以”BC_“开头,简称BC码,用于从IPC层传递到Binder Driver层;
2.BINDER_RETURN_PROTOCOL :binder响应码,以”BR_“开头,简称BR码,用于从Binder Driver层传递到IPC层;
Binder IPC通信至少是两个进程的交互:
1.client进程执行binder_thread_write,根据BC_XXX命令,生成相应的binder_work;
2.server进程执行binder_thread_read,根据binder_work.type类型,生成BR_XXX,发送到用户空间处理。
3.1 用户->driver
binder请求码,是用enum binder_driver_command_protocol来定义的,是用于应用程序向binder驱动设备发送请求消息,应用程序包含Client端和Server端,以BC_开头,总17条;(-代表目前不支持的请求码)
请求码 | 参数类型 | 作用 |
---|---|---|
BC_TRANSACTION | binder_transaction_data | Client向Binder驱动发送请求数据 |
BC_REPLY | binder_transaction_data | Server向Binder驱动发送请求数据 |
BC_FREE_BUFFER | binder_uintptr_t(指针) | 释放内存 |
BC_INCREFS | __u32(descriptor) | binder_ref弱引用加1操作 |
BC_DECREFS | __u32(descriptor) | binder_ref弱引用减1操作 |
BC_ACQUIRE | __u32(descriptor) | binder_ref强引用加1操作 |
BC_RELEASE | __u32(descriptor) | binder_ref强引用减1操作 |
BC_ACQUIRE_DONE | binder_ptr_cookie | binder_node强引用减1操作 |
BC_INCREFS_DONE | binder_ptr_cookie | binder_node弱引用减1操作 |
BC_REGISTER_LOOPER | 无参数 | 创建新的looper线程 |
BC_ENTER_LOOPER | 无参数 | 应用线程进入looper |
BC_EXIT_LOOPER | 无参数 | 应用线程退出looper |
BC_REQUEST_DEATH_NOTIFICATION | binder_handle_cookie | 注册死亡通知 |
BC_CLEAR_DEATH_NOTIFICATION | binder_handle_cookie | 取消注册的死亡通知 |
BC_DEAD_BINDER_DONE | binder_uintptr_t(指针) | 已完成binder的死亡通知 |
BC_ACQUIRE_RESULT | - | - |
BC_ATTEMPT_ACQUIRE | - | - |
3.2 driver->用户
binder响应码,是用enum binder_driver_return_protocol来定义的,是binder设备向应用程序回复的消息,应用程序包含Client端和Server端,以BR_开头
响应码 | 参数类型 | 作用 |
---|---|---|
BR_ERROR | __s32 | 操作发生错误 |
BR_OK | 无参数 | 操作完成 |
BR_NOOP | 无参数 | 不做任何事 |
BR_SPAWN_LOOPER | 无参数 | 创建新的Looper线程 |
BR_TRANSACTION | binder_transaction_data | Binder驱动向Server端发送请求数据 |
BR_REPLY | binder_transaction_data | Binder驱动向Client端发送回复数据 |
BR_TRANSACTION_COMPLETE | 无参数 | 对请求发送的成功反馈 |
BR_DEAD_REPLY | 无参数 | 回复失败,往往是线程或节点为空 |
BR_FAILED_REPLY | 无参数 | 回复失败,往往是transaction出错导致 |
BR_INCREFS | binder_ptr_cookie | binder_ref弱引用加1操作(Server端) |
BR_DECREFS | binder_ptr_cookie | binder_ref弱引用减1操作(Server端) |
BR_ACQUIRE | binder_ptr_cookie | binder_ref强引用加1操作(Server端) |
BR_RELEASE | binder_ptr_cookie | binder_ref强引用减1操作(Server端) |
BR_DEAD_BINDER | binder_uintptr_t(指针) | Binder驱动向client端发送死亡通知 |
BR_CLEAR_DEATH_NOTIFICATION_DONE | binder_uintptr_t(指针) | BC_CLEAR_DEATH_NOTIFICATION命令对应的响应码 |
BR_ACQUIRE_RESULT | - | - |
BR_ATTEMPT_ACQUIRE | - | - |
BR_FINISHED | - | - |
参考文档
Binder系列2—Binder Driver再探
彻底理解Android Binder通信架构