一:概要
对android的binder通信机制,服务进程通过向 ServiceManager 添加对应的服务aidl实现binder对象,向其他应用提供服务能力。客户进程则是通过对应服务名从 ServiceManager 中获取对应的服务binder对象。
android在最新版本中有三个不同的 ServiceManager ,分别为 ServiceManager,vndServiceManager,hwServiceManager。本文能过分析最近几个版本中的ServiceManager和不同版本中的核心差异来学习 ServiceManager 。
二:binder驱动
通过查看设备节点,我们发现最新的版本中是有三个binder的驱动节点的,分别为 /dev/binder,/dev/vndbinder,/dev/hwbinder。查看内核驱动代码/drivers/android/,通过Kconfig和binder的init函数,可以得知,在binder驱动初始化的时候,通过Kconfig的配置,默认生成了三个设备节点。(????)
三:ServiceManager 和 vndServiceManager
ServiceManager 的源码在 /frameworks/native/cmds/servicemanager/
ServiceManager 和 vndServiceManager 是使用同一套代码编译出不同的bin文件,并通过不同的启动配置运行。两者的差异主要在运行时的权限管理上,后续提到 ServiceManager 时,默认指 ServiceManager和vndServiceManager。
ServiceManager 在 android11时被重构了一次,所以分析时,android11以前和android11之后的需分开说明。
一:旧版 ServiceManager
在旧版中,ServiceManager直接打开驱动节点,解析binder数据。对应的binder服务名和binder对象 通过一个list存起来。
在这个版本的 ServiceManager 中,其他进程只能通过addService把服务添加到sm中,通过getService 获取到对应的服务。服务add后无法主动移出,也无法在add新服务后通知关注对应服务的进程来获取。功能相对单一。
二:新版 ServiceManager
新版的 ServiceManager 参考了 hwServiceManager 的实现,通过新增一个 IServiceManager.aidl 接口,在ServiceManager中实现了这一接口,同时,具体的binder调用就直接使用libbinder库。做到了更高的模块化。
在服务管理上,新版 ServiceManager 通过一个map来管理服务,服务的binder信息存放在一个service的结构体中。新增了两个回调接口,可以把服务的状态变更实时通知道到客户端进程中。
classDiagram
class ServiceManager{
+ServiceMap mNameToService
+ServiceCallbackMap mNameToRegistrationCallback
+ClientCallbackMap mNameToClientCallback
+addService()
+getService()
}
class Service {
+sp<IBinder> binder
}
class IServiceCallback{
<<interface>>
+onRegistration()
}
class IClientCallback{
<<interface>>
+onClients()
}
ServiceManager "1" *-- "1" Service
ServiceManager "1" *-- "n" IServiceCallback
ServiceManager "1" *-- "n" IClientCallback
四:hwServiceManager
hwServiceManager 的源码在 /system/hwservicemanager/