行业知识
【Android】一文总结Android系统服务大管家-ServiceManager
文章目录
- 一、ServiceManager简介
- 二、ServiceManager的启动
- 三、ServiceManager详细剖析
- (3-1)获取驱动的名称
- (3-2)初始化进程状态ProcessState并设置重要参数
- (3-3)创建ServiceManager实例
- (3-4)设置上下文对象
- (3-5)创建looper,并执行pollAll
- 四、ServiceManager的唤醒
- 五、总结
本文涉及到的源码文件:
- /frameworks/native/cmds/servicemanager/main.cpp
- /frameworks/native/libs/binder/ProcessState.cpp
- /frameworks/native/cmds/servicemanager/ServiceManager.cpp
- /frameworks/native/libs/binder/IPCThreadState.cpp
- /system/core/libutils/Looper.cpp
一、ServiceManager简介
本文基于Android 11
ServiceManager是一个由C/C++编写的系统服务,源码位于/framework/native/cmds/servicemanager中,存在如下文件结构:
从Android.bp可知,ServiceManager本质上会以程序的方式构建,源码入口位于main.cpp文件中:
main()函数内容如下:
//framework/native/cmds/servicemanager/main.cppint main(int argc, char** argv) { if (argc > 2) { LOG(FATAL) addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) { LOG(ERROR) setTheContextObject(manager); ps->becomeContextManager(nullptr, nullptr); sp looper = Looper::prepare(false /*allowNonCallbacks*/); BinderCallback::setupTo(looper); ClientCallbackCallback::setupTo(looper, manager); while(true) { looper->pollAll(-1); } // should not be reached return EXIT_FAILURE;}从上述代码可以明确知道:ServiceManager程序一旦启动运行,则不会停止(系统不宕机的情况下),将会一直looper->pollAll(-1)。除此之外,还知道ServiceManager默认情况依托于/dev/binder这个设备节点,当然可以通过向ServiceManager传递参数指定设备节点。ServiceManager作为binder机制的核心组件之一,在实现进程间通信中占据着不可获取的地位。
从Android.bp可以知道,ServiceManager对应的程序名称是servicemanager。从Android.bp文件中,还存在一个名为vndservicemanager的程序,它们的源码都是一样的,只是rc文件存在出入,将传入/dev/vndbinder作为binder驱动。在Android启动启动过程中,vndservicemanager和vndservicemanager都会被init拉起,他俩的区别总结如下:
1、对于servicemanager:
- servicemanager是 Android 系统中的核心服务管理器,用于管理系统级的服务。
- servicemanager管理的服务包括系统级服务(如ActivityManager、PackageManager、WindowManager等)和由应用程序注册的系统服务。
- servicemanager的访问权限较高,一般只有系统级应用或者具有系统权限的应用程序才能够使用servicemanager进行服务的注册和查询。
2、对于vndservicemanager:
- vndservicemanager是 servicemanager的一个扩展,用于管理供应商特定的服务。
- vndservicemanager管理的服务通常是供应商(vendor)特定的、定制化的服务,例如硬件厂商提供的驱动程序或服务。
- vndservicemanager的访问权限一般较低,通常只有供应商特定的应用程序或系统组件才能够使用vndservicemanager进行服务的注册和查询。
二、ServiceManager的启动
第一小节简要介绍了ServiceManager,我们知道ServiceManager是一个具体程序,如果是个程序,那么该程序是如何启动的呢?又在什么时候触发运行的呢?
我们知道Android系统的第一个进程是init,这是由内核决定的。那么在init中将通过解析init.rc来启动系统的一些关键服务进程。其中ServiceManager就在这个时候启动运行。
在/framework/native/cmds/servicemanager/目录中存在一个servicemanager.rc,该文件是servicemanager的初始化配置文件,文件内容如下:
service servicemanager /system/bin/servicemanager class core animation user system group system readproc critical onrestart restart healthd onrestart restart zygote onrestart restart audioserver onrestart restart media onrestart restart surfaceflinger onrestart restart inputflinger onrestart restart drm onrestart restart cameraserver onrestart restart keystore onrestart restart gatekeeperd onrestart restart thermalservice writepid /dev/cpuset/system-background/tasks shutdown critical
三、ServiceManager详细剖析
本小节将从main函数分段展开描述。
(3-1)获取驱动的名称
如果在运行servicemanager时传入了驱动名称参数,则使用该参数作为驱动;否则使用/dev/binder作为驱动名称。vndservicemanager则以此方式运行!
(3-2)初始化进程状态ProcessState并设置重要参数
- 初始化ProcessState,代码如下:
sp ps = ProcessState::initWithDriver(driver);
在Android系统中,关于binder机制,ProcessState是一个重要的类,位于/frameworks/native/libs/binder/ProcessState.cpp中,用于管理每个应用进程中的binder操作。所以在servicemanager启动过程中,调用了initWithDriver()初始化ProcessState,该函数可以用来配置libbinder支持不同的binder节点。initWithDriver()实现代码如下:
sp ProcessState::initWithDriver(const char* driver){ Mutex::Autolock _l(gProcessMutex); if (gProcess != nullptr) { // Allow for initWithDriver to be called repeatedly with the same // driver. if (!strcmp(gProcess->getDriverName().c_str(), driver)) { return gProcess; } LOG_ALWAYS_FATAL("ProcessState was already initialized."); } if (access(driver, R_OK) == -1) { ALOGE("Binder driver %s is unavailable. Using /dev/binder instead.", driver); driver = "/dev/binder"; } gProcess = new ProcessState(driver); return gProcess;}在执行完initWithDriver()后,ProcessState实例对象就创建完成了,且调用open_driver()打开了对应的驱动程序。
随后设置线程池最大线程数为0。设置线程池调用限制为FATAL_IF_NOT_ONEWAY,表示中断阻塞调用的进程。(必须在线程池启动之前设置调用限制)。
(3-3)创建ServiceManager实例
接下来将创建ServiceManager实例manger,并将自己添加为Service。如下代码片段:
sp manager = new ServiceManager(std::make_unique());if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) { LOG(ERROR) setTheContextObject(manager);ps->becomeContextManager(nullptr, nullptr);(3-5)创建looper,并执行pollAll
经过上文四个步骤的准备后,则进入servicemanager的核心操作:
sp looper = Looper::prepare(false /*allowNonCallbacks*/);//将BinderCallback设置到looperBinderCallback::setupTo(looper);//将ClientCallbackCallback设置到looper和managerClientCallbackCallback::setupTo(looper, manager);while(true) { looper->pollAll(-1);}首先调用Looper::prepare()静态成员函数,准备Looper,该函数实现如下:
sp Looper::prepare(int opts) { bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS; sp looper = Looper::getForThread(); if (looper == nullptr) { looper = new Looper(allowNonCallbacks); Looper::setForThread(looper); } if (looper->getAllowNonCallbacks() != allowNonCallbacks) { ALOGW("Looper already prepared for this thread with a different value for the " "LOOPER_PREPARE_ALLOW_NON_CALLBACKS option."); } return looper;}上述代码首先调用Looper::getForThread()从Thread中获取对应的looper,如果looper不存在则使用new创建,并调用Looper::setForThread(loope)将其设置到Thread。这两个函数本质上都是调用到线程库API实现,相关API有:
void *pthread_getspecific(pthread_key_t key);int pthread_setspecific(pthread_key_t key, const void *value);int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));int pthread_once(pthread_once_t *once_control,void (*init_routine)(void));
总而言之,Looper::prepare()将准备一个与调用线程相关联的Looper,并返回该Looper。如果线程已经有Looper,则返回该Looper。否则将创建一个新的Looper,并与线程关联,然后返回。
回到servicemanager的核心操作过程中,接着会将BinderCallback设置到looper,将ClientCallbackCallback设置到looper和manager。BinderCallback和ClientCallbackCallback都是继承自LooperCallback。
最后在一个while(true){}中调用pollAll(-1),pollAll()用于执行所有挂起的回调,直到数据已被消耗或文件描述符可用且没有回调。该函数实现在/system/core/libutils/Looper.cpp中:
int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { if (timeoutMillis
- 初始化ProcessState,代码如下:
上一篇:dns服务器怎么增加网址?
下一篇:微信里怎么没有服务器连接?