这一期我们来学习一下Android ServiceManager是如何来管理我们系统服务的。
ServiceManager服务是我们Android系统中的服务的一个程序,是Android系统中的核心服务之一。它主要有两个作用,第一是系统服务的管理,它用来管理系统和医用向系统添加的服务;第二个是处理查询获取服务的一个过程,比如我们的一个服务,要请求其他服务的话,那么这个ServiceManager就要响应我们一个client的请求,并且返回到client端所请求的相应服务。
下面我们再来看一下ServiceManager:
1.我们的ServiceManager是在init脚本中定义的启动的比较早的程序,如果我们这个程序连续几次异常退出的话,那么我们的系统就会重启,可见他也是一个很重要的服务
2.如果该服务重启,那么当重新启动ServiceManager的时候,我们需要重启我们的media服务、zygote服务、surfaceflinger服务。
3.如果系统中的某一个服务或者我们的应用需要调用其他的服务,那么我们必须使用ServiceManager它所提供的一种机制,才能真正的获取我们的服务。
下面我们来看一下我们init脚本中是如何来定义这个服务的,我们打开system/core/rootdir/init.rc,然后找到我们的ServiceManager服务
在这里定义了一个servicemanager的服务,他调用的其实是我们/system/bin/servicemanager这个程序,然后我们可以看到我们的class、user、group分别是core、system、system,还定义了一个关键字critical,这个的意思就是,如果说我们的服务连续挂掉几次,我们整个系统就会重启,如果我们的servicemanager出错了,需要重启的话,那么我们可以看到他会重新启动healthd、zygote、media等都要做一个重启,因为这些都是一个服务,他们都需要加载到servicemanager中,所以当servicemanager重启的时候,他们也会跟着重新启动。
下面我们来看一下servicemanager的启动过程,以及一个简单地实现原理
在这里会涉及到一个知识点,也就是我们的binder机制,binder机制是Android系统特有的一种进程间特有的通讯方式,我们在这里只需要知道这个servicemanager是基于binder机制的,当我们servicemanager启动的时候,首先他要去打开binder,然后映射了一段内存,这个内存是128*1024字节大小,然后通过一些设置,把他设置成context_manager,然后会进入到一个循环机制,去接收其他进程通过binder机制发送过来的消息,然后调用我们servicemanager的一个处理方式,也就是我们的svcmgr_handler,通过这个函数来处理其他进程发过来的binder消息,这些消息一般都是添加、查询、获取服务,在做这些的时候对我们的应用程序的一个权限做一个设置。
下面我们在代码中看一下,servicemanager是如何实现的,首先打开servicemanager的源代码,路径为:frameworks/native/cmds/servicemanager/servicemanager.c,找到他的main入口函数,进来之后首先打开binder机制,我们来看一下binder的实现。
他在这里直接打开dev/binder这个设备,然后做了一个映射,这个映射的内存就是我们刚才的128*1024,也就是128K,拿到句柄之后返回,然后做了一个binder_become_context_manager(bs)操作,这个操作就是将我们的binder设置为context_manager,这只碗之后就进入了一个binder_loop的函数,他就是不断接收其他binder机制发过来的消息,首先会读取消息,然后调用binder_parse来对我们的消息进行解析,我们来看一下这个函数
它所传进来的参数一个是我们的bs,一个是我们所读到的内容。进入这个函数之后他会根据我们的命令去做不同的操作,我们的命令是BR打头的一系列操作,最主要的是我们的BR_TRANSACTION,这个是我们主要处理的,处理之后他会调用一个回调函数,也就是我们刚才进binder_loop的时候传进来的那个函数,然后调用我们的回调函数做一些处理,处理完之后会调用binder_send_reply,也就是一个应用的请求一直到我们的servicemanager,servicemanager处理完之后再给他一个应答,这样就完成了一次进程间的交互。我们来看一下这个回调函数,看他是如何实现的
他首先会做一个处理,这个处理就是来看一下我们所传进来的svcmgr_id和我们传进来的s是否一致,如果不一致就直接返回了,svcmgr_id是一个字符串,内容是android.os.IServiceManager,如果和s一致的话,说明请求的是我们的servicemanager服务,在这里会处理下面几条主要的消息:第一个是get_service,第二个是check_service,第三个是add_service,第四个是list_service。在这里我们想要get或者check的话,首先会做一个do_find_service,我们先来看一下ADD_SERVICE
如果我们调用了这个函数,首先我们会发一个SVC_MGR_ADD_SERVICE我们进入do_add_service
在进入的时候首先会做一下判断,svc_can_register()就是看一下当前进程的uid是否有权限在这里做一些服务的注册,如果没有权限就直接返回了,如果有权限的话,那么就看一下当前的服务列表中有没有和我们名字一样的服务,如果有了就直接返回一个si,如果有这个si,那么就会把他重新置一下;如果没有的话他就会在我们的服务列表中重新添加一个服务。这就是servicemanager管理服务的一个过程。
接下来我们来看一下servicemanager处理消息的一个整个架构图
在这里主要涉及到三个部分,第一个是我们的应用程序包括其他的服务,这个主要是做getservice和addservice的一个操作。第二个就是我们的binder机制,我们中间的交互机制是通过我们的binder服务来实现的。第三个就是我们的service_manager,他用来管理和处理我们的请求。
如果我们要添加一个service,我们首先会向binder机制发送一个消息,在我们add过程中会添加一个相应的字段,这样我们binder就会找到我们相应的服务的进程,然后向我们相应的进程发送请求,这样我们的一个add消息就发送给我们的service_manager。,而service_manager拿到一个消息之后,首先会检查一下当前的请求的进程,他有没有我们添加服务的一个权限,如果有权限,他会继续检查列表中有没有这个服务,如果已经注册过了,就会把它重新添加过来,如果没有的话那么我们就会创建一个新的对象,新的结构,把这个对象添加进来,添加到我们服务列表中,这样我们服务列表中就会有一系列的服务,当我们添加完之后,如果说我们的一个应用程序,他需要请求这个服务,那么我们就发送一个getservice,这个消息之后还是找到我们的service_manager,然后调用我们getservice的处理方法,去我们服务列表中查询他所需要的服务,查找到这个服务之后,就会把相应的结构返回给我们的应用程序,这样我们的应用程序就会获取我们服务的一个操作权限,然后去调用这些服务的内容。我们这些服务的一些状态和信息也是实时更新的,这就是我们servicemanager管理服务的一个大概流程和大概的框架,以及他的一个实现原理。