小秦哥 发表于 2024-6-15 02:33:41

【Android】一文总结Android系统服务大管家-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中,存在如下文件结构:
https://img-blog.csdnimg.cn/img_convert/abc2a94b0dcade8feb1b767aee5262fa.png
从Android.bp可知,ServiceManager本质上会以程序的方式构建,源码入口位于main.cpp文件中:
https://img-blog.csdnimg.cn/img_convert/1ff2f807a5d264998193ef0029dc0591.png
main()函数内容如下:
//framework/native/cmds/servicemanager/main.cpp

int main(int argc, char** argv) {
    if (argc > 2) {
      LOG(FATAL) << "usage: " << argv << " ";
    }

    const char* driver = argc == 2 ? argv : "/dev/binder";

    sp<ProcessState> ps = ProcessState::initWithDriver(driver);
    ps->setThreadPoolMaxThreadCount(0);
    ps->setCallRestriction(ProcessState::CallRestriction::FATAL_IF_NOT_ONEWAY);

    sp<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
    if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
      LOG(ERROR) << "Could not self register servicemanager";
    }

    IPCThreadState::self()->setTheContextObject(manager);
    ps->becomeContextManager(nullptr, nullptr);

    sp<Looper> 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<ProcessState> ps = ProcessState::initWithDriver(driver);
在Android系统中,关于binder机制,ProcessState是一个重要的类,位于/frameworks/native/libs/binder/ProcessState.cpp中,用于管理每个应用历程中的binder操作。以是在servicemanager启动过程中,调用了initWithDriver()初始化ProcessState,该函数可以用来配置libbinder支持差别的binder节点。initWithDriver()实现代码如下:
sp<ProcessState> 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<ServiceManager> manager = new ServiceManager(std::make_unique<Access>());
if (!manager->addService("manager", manager, false /*allowIsolated*/, IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()) {
    LOG(ERROR) << "Could not self register servicemanager";
}
(3-4)设置上下文对象

将创建好的ServiceManager实例manger设置为上下文对象,代码如下:
IPCThreadState::self()->setTheContextObject(manager);
ps->becomeContextManager(nullptr, nullptr);
(3-5)创建looper,并实验pollAll

经过上文四个步调的预备后,则进入servicemanager的焦点操作:
sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);

//将BinderCallback设置到looper
BinderCallback::setupTo(looper);

//将ClientCallbackCallback设置到looper和manager
ClientCallbackCallback::setupTo(looper, manager);

while(true) {
    looper->pollAll(-1);
}
起首调用Looper::prepare()静态成员函数,预备Looper,该函数实现如下:
sp<Looper> Looper::prepare(int opts) {
    bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS;
    sp<Looper> 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 <= 0) {
      int result;
      do {
            result = pollOnce(timeoutMillis, outFd, outEvents, outData);
      } while (result == POLL_CALLBACK);
      return result;
    } else {
      nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)
                + milliseconds_to_nanoseconds(timeoutMillis);

      for (;;) {
            int result = pollOnce(timeoutMillis, outFd, outEvents, outData);
            if (result != POLL_CALLBACK) {
                return result;
            }

            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
            timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
            if (timeoutMillis == 0) {
                return POLL_TIMEOUT;
            }
      }
    }
}
上述代码中,焦点操作由pollOnce()完成,在该函数中继承调用pollInner()实现焦点操作(函数内容较长),该函数中将实现以下操作:


[*] (1)调用epoll_wait()等候由mEpollFd.get()获取到的文件描述符fd的相关事件是否发生。由于timeout为-1,以是将一直壅闭,直到对应I/O事件的发生。
[*] (2)假如mEpollFd文件描述符fd的相关事件发生,则将被唤醒继承实验后续的代码,具体操作是:检测poll错误,检查pool是否有事件需要处理。
[*] (3)处理所有事件。
[*] (4)调用挂起的MessageEnvelopes回调:
在该步调中,将从MessageEnvelopes表中逐一取出MessageEnvelope,获取对应的MessageHandler,接着调用handleMessage()对应的回调函数处理消息,如下代码:
https://img-blog.csdnimg.cn/img_convert/5b04d1ccb4ed7c592e28458f514aac48.png
[*] (5)调用所有Response的回调:
https://img-blog.csdnimg.cn/img_convert/ab9f8ec1fc5db86a88f57f1603047667.png
上述则是pollAll()的具体实验流程,也是servicemanager服务的具体功能实现。
四、ServiceManager的唤醒

ServiceManager 被唤醒的时机主要包罗以下几种情况:

[*] 系统启动时: 在 Android 系统启动时,ServiceManager 会被初始化,并开始运行。它会加载系统中预定义的服务,并在 Binder 机制的支持下,为其他系统组件和应用程序提供服务的注册和查询。
[*] 服务注册和查询: 当有服务需要注册到 ServiceManager 大概其他组件需要查询某个服务时,ServiceManager 会被唤醒。注册服务时,ServiceManager 会将服务的信息保存起来,以供其他组件查询。查询服务时,其他组件会向 ServiceManager 发送请求,并等候其响应。
[*] 动态加载服务: 在运行时,某些服务可能会被动态加载或卸载,这时候 ServiceManager 也会被唤醒。动态加载服务时,ServiceManager 会更新其内部的服务列表;卸载服务时,ServiceManager 会将相应的服务从其列表中移除。
五、总结

在Android系统中,ServiceManager是一个重要的系统服务,它允许应用程序和系统组件通过Binder机制举行跨历程通信,从而访问和管理系统级的服务。ServiceManager的主要作用如下:

[*] 服务注册与查找: ServiceManager 允许系统中的服务在启动时向其注册,这些服务可以是系统级的服务,如电源管理、网络管理、传感器服务等,也可以是由应用程序提供的服务。注册后,其他应用程序或系统组件可以通过 ServiceManager 查询已注册的服务,并获取其引用,从而实现跨历程通信。
[*] 历程间通信(IPC): ServiceManager 提供了一种方便的机制,使得应用程序和系统组件可以通过 Binder 机制举行跨历程通信。通过 ServiceManager,客户端可以获取到服务的 Binder 对象,然后使用 Binder 机制与服务举行通信,包罗调用服务提供的方法、传递数据等。
[*] 系统服务的启动和管理: ServiceManager 管理着 Android 系统中的许多焦点服务,如 ActivityManager、PackageManager、WindowManager 等。这些服务通常是由系统启动时注册到 ServiceManager 中的,其他系统组件或应用程序可以通过 ServiceManager 获取这些系统服务的引用,并与之交互,从而实现系统功能的实现和控制。
[*] 提供系统服务的单例实例: ServiceManager 确保系统中的每个服务都是单例的,即同一个服务只有一个实例存在。当客户端通过 ServiceManager 获取服务的引用时,ServiceManager 会确保返回的是同一个实例对象,如许可以确保系统中的服务状态和数据的划一性。
总的来说,ServiceManager 在 Android 系统中起着非常重要的作用,它是实现系统服务和应用程序之间通信的关键组件之一,为 Android 系统的功能提供了丰富的扩展性和机动性。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【Android】一文总结Android系统服务大管家-ServiceManager