binder域
为了明确划分框架(独立于设备)和供应商(特定于设备)代码之间的 Binder 流量,Android O 介绍了一个 Binder 上下文的概念。每个 Binder 上下文都拥有自己的设备节点以及上下文(服务)管理者。当您通过某个上下文传递 Binder 节点时,您只能通过它所属的设备节点来访问对应的上下文管理器,它只能通过另一个进程来访问,从而使得各个域完全隔离。
散集列表
在以往的 Android 版本中,Binder 调用的每一个数据都会被复制三次:
一次是在调用的进程中将数据序列化为一个 Parcel。
一次是在内核驱动中将 Parcel 拷贝给目标进程。
一次是在目标进程中将 Parcel 反序列化。
Binder IPC
在 Android O 中,/dev/binder 设备节点成为了独立于框架进程的存在,这就意味着供应商进程不能再访问它。供应商进程可以访问 /dev/hwbinder,但必须将它们的 AIDL 接口转换为 HIDL 接口。对于需要继续在供应商进程间使用 AILD 接口的供应商,Android 支持如下所述的 Binder IPC。
vndbinder
Android O 支持由供应商服务所使用的一个新的域,使用 /dev/vndbinder 代替对 /dev/binder 的访问。在添加 /dev/vndbinder 之后,目前 Binder IPC 共有以下三个域:
通常供应商进程不会直接打开 Binder 驱动,而是连接到 libbinder 用户空间库去,这个库打开了 Binder 驱动。加入一个方法为 ::android::ProcessState() 选择用于 libbinder 的 Binder 驱动程序。在供应商进程调用 ProcessState, IPCThreadState 或对任何 Binder 的一般性调用之前,这一方法就应该被调用了。要使用它,则请在供应商进程(客户端和服务端)的主函数之后进行如下调用:
ProcessState::initWithDriver("/dev/vndbinder");
vndservicemanager
在以前,Binder 驱动会注册到 servicemanager 中,这样它可以被其它进程获取。而在 Android O 中,servicemanager 目前已经完全只由框架与应用程序来使用,而供应商进程已经无法访问它。
供应商服务现在可以使用 vndservicemanager,这是用 /dev/vndbinder 代替了 /dev/binder 而构成的新的 servicemanager 实例,它与框架层的 servicemanager 是用同一源码所构建的。供应商进程不需要为了与 vndservicemanager 进行通讯而做出更改,当供应商进程打开 /dev/vndbinder 后,服务就会自动查找到 vndservicemanager。
vndservicemanager 的二进制文件已经包含在 Android 默认的设备 makefile 中。
SELinux 策略
需要使用 Binder 的功能以同其它进程通讯的供应商进程需要以下几个条件:
访问 /dev/vndbinder。
Binder 的钩子函数 {transfer, call} 设置到 vndservicemanager 中。
binder_call(A, B) 用于想要通过供应商 Binder 接口来调用到供应商域 B 的供应商域 A。
在 vndservicemanager 中获得 {add, find} 的服务权限。