ServiceManager是什么?
ServiceManager是binder服务的大管家,由Init进程解析init.rc文件创建,其本身也是一个Binder服务,但并没有采用libbinder中的多线程模型来与Binder驱动通信,而是自行编写了binder.c直接和Binder驱动来通信,并且只有一个循环binder_loop来进行读取和处理事务,这样的好处是简单而高效。
ServiceManager的作用?
ServiceManager的作用相对简单,主要是“注册和查询”服务。
ServiceManager的工作流程?
启动流程
Init进程解析配置文件,其所对应的可执行程序/system/bin/servicemanager,所对应的源文件是service_manager.c
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
启动Service Manager的入口函数是service_manager.c中的main()方法,代码如下:
int main(int argc, char **argv) {
struct binder_state *bs;
//打开binder驱动,申请128k字节大小的内存空间 【见小节2.2】
bs = binder_open(128*1024);
...
//成为上下文管理者 【见小节2.3】
if (binder_become_context_manager(bs)) {
return -1;
}
selinux_enabled = is_selinux_enabled(); //selinux权限是否使能
sehandle = selinux_android_service_context_handle();
selinux_status_open(true);
if (selinux_enabled > 0) {
if (sehandle == NULL) {
abort(); //无法获取sehandle
}
if (getcon(&service_manager_context) != 0) {
abort(); //无法获取service_manager上下文
}
}
...
//进入无限循环,处理client端发来的请求 【见小节2.4】
binder_loop(bs, svcmgr_handler);
return 0;
}
主要有下面三个流程:
- 打开binder驱动:binder_open;
- 注册成为binder服务的大管家:binder_become_context_manager;
- 进入无限循环,处理client端发来的请求:binder_loop;
添加服务
ServiceManager对应的Java类是ServiceManager.java,Android中的系统服务注册正式通过这个类完成的。我们看看它的addService方法:
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
再看看getIServiceManager()方法:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
可以看到是通过BinderInternal.getContextObject()转换成IServiceManager这个binder代理类的,我们看看它的方法介绍:
/**
* Return the global "context object" of the system. This is usually
* an implementation of IServiceManager, which you can use to find
* other services.
*/
public static final native IBinder getContextObject();
看注释可以知道这个返回的IBinder就是IServiceManager的binder代理类,为什么要这么做呢?因为其他进程和ServiceManager通讯的目的是为了注册或者查询服务,但是这些进程和ServiceManager又是属于不同但进程,这里又需要跨进程通讯,所以Native层就干脆把IServiceManager的binder放在固定的一个位置,其他进程可以直接拿到这个IBinder对象。