Android 系统启动 - SystemServer 进程

前言

SystemServer 是 Android 系统非常重要和核心的服务,其进程名为 system_server,它会在创建后启动系统中的其他服务,然后成为所有服务的管理者,向应用程序和其他服务提供服务。

SystemServer 启动过程

在 Android 系统启动 - Zygote 进程 中,我们提到,Zygote 进程在创建虚拟机,注册 JNI 本地方法,预加载类和资源等操作后,会启动 SystemServer 进程:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
    try {
        ···
        if (startSystemServer) {
            // 启动 SystemServer 进程
            startSystemServer(abiList, socketName);
        }
    } catch (MethodAndArgsCaller caller) {
        caller.run(); // 真正启动 SystemServer
    } 
    ···
}

SystemServer 进程的启动是由 startSystemServer 负责:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        ···
        /* Hardcoded command line to start the system server */
        // 启动SystemServer进程的参数
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
            // 请求创建SystemServer进程
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        // 进入SystemServer进程
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            // 处理SystemServer进程剩余工作
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

从该函数中可以看到,startSystemServer 最终通过 Zygote.forkSystemServer 方法创建了 SystemServer 进程,并且从传递启动 SystemServer 进程的参数可以得知:SystemServer 进程的 uid=pid=1000;进程名为 system_server;启动的类名为com.android.server.SystemServer。

对于 Zygote.forkSystemServer 方法,其内部其实是通过 JNI 方法调用 C++ 层代码,最终通过调用 fork 函数创建子进程,也即:SystemServer 进程。由于我们这边侧重于对流程的解析,所以我们就不深入分析 Zygote.forkSystemServer 的具体过程。感兴趣者可以查看:Android系统启动-SystemServer上篇

startSystemServer 通过 Zygote.forkSystemServer 成功创建完 SystemServer 进程后,就会进入 handleSystemServerProcess 函数,对 SystemServer 进程做进一步操作:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static void handleSystemServerProcess(
        ZygoteConnection.Arguments parsedArgs)
        throws ZygoteInit.MethodAndArgsCaller {

    //关闭复制父进程zygote的Socket
    closeServerSocket();

    // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO);

    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName); //设置当前进程名为"system_server"
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        // 进行dex优化
        performSystemServerDexOpt(systemServerClasspath);
    }

    if (parsedArgs.invokeWith != null) {
        String[] args = parsedArgs.remainingArgs;
        // If we have a non-null system server class path, we'll have to duplicate the
        // existing arguments and append the classpath to it. ART will handle the classpath
        // correctly when we exec a new process.
        if (systemServerClasspath != null) {
            String[] amendedArgs = new String[args.length + 2];
            amendedArgs[0] = "-cp";
            amendedArgs[1] = systemServerClasspath;
            System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
        }
        // 启动应用进程
        WrapperInit.execApplication(parsedArgs.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                VMRuntime.getCurrentInstructionSet(), null, args);
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            // 创建类加载器,并赋予当前线程
            cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
         * Pass the remaining arguments to SystemServer.
         */
        // 传递剩余参数给到SystemServer进程,做进一步处理
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }

    /* should never reach here */
}

该函数其实主要做了三件事:

  • 关闭从父进程 Zygote 复制而来的 Socket:closeServerSocket
  • 设置当前进程名为 system_serverProcess.setArgV0
  • 进行 dex 优化:performSystemServerDexOpt
  • 对 SystemServer 进程做进一步处理:RuntimeInit.zygoteInit

我们主要来看下 RuntimeInit.zygoteInit
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
    // 将 System.out,System.err 重定向到 Android Log
    redirectLogStreams();
    // 进行一些通用操作的初始化
    commonInit();
    // JNI 调用本地方法启动Binder线程池
    nativeZygoteInit();
    // 应用初始化
    applicationInit(targetSdkVersion, argv, classLoader);
}

zygoteInit 函数主要做了四件事:

  • 重定向系统输出流/错误流 到 Android Log 输出:redirectLogStreams
  • 进行一些通用操作的初始化:设置默认的未捕获异常处理,时区设置,设置默认 HTTP User-Agent 头部等等:commonInit
  • 使用 JNI 调用本地方法启动 Binder 线程池:nativeZygoteInit
  • 对 SystemServer 的进一步初始化:applicationInit

我们主要来看下:nativeZygoteInitapplicationInit

先查看下 nativeZygoteInit 源码实现:见名知意,该方法调用的是一个本地方法,其对应的 JNI 文件为:frameworks/base/core/jni/AndroidRuntime.cpp

/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
    { "nativeFinishInit", "()V",
        (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
    { "nativeZygoteInit", "()V",
        (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
    { "nativeSetExitWithoutCleanup", "(Z)V",
        (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
};

因此,nativeZygoteInit 对应的本地方法(C++)为:com_android_internal_os_RuntimeInit_nativeZygoteInit

···
static AndroidRuntime* gCurRuntime = NULL;
···
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
  //gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的
    gCurRuntime->onZygoteInit();
}

此处的 gCurRuntimeAndroidRuntime 类型,但其真实类型为 AndroidRuntime 的子类型:AppRuntime。所以 nativeZygoteInit 最终调用的是 AppRuntime.onZygoteInit
frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
{
    sp proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool(); // 启动 Binder 线程池
}

可以看到,nativeZygoteInit 最终通过 ProcessState.startThreadPool 启动了一个 Binder 线程池。到此,SystemServer 进程就具备了与其他进程通过 Binder 进程通信的功能了。

所以,nativeZygoteInit 的作用就是启动 Binder 线程池。

接下来我们来看下:applicationInit
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用
    nativeSetExitWithoutCleanup(true);

    // 设置虚拟机的内存利用率参数值为0.75
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

    final Arguments args;
    try {
        // 解析参数
        args = new Arguments(argv);
    } catch (IllegalArgumentException ex) {
        Slog.e(TAG, ex.getMessage());
        // let the process exit
        return;
    }

    // The end of of the RuntimeInit event (see #zygoteInit).
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    // Remaining arguments are passed to the start class's static main
    // 调用类"com.android.server.SystemServer" 的 main 方法
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

applicationInit 最终调用了 invokeStaticMain 方法,此处:args.startClass 为 "com.android.server.SystemServer",我们进入 invokeStaticMain 方法查看下:
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    Class cl;

    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        ···
    }

    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        ···
    }
    ···
    /*
     * This throw gets caught in ZygoteInit.main(), which responds
     * by invoking the exception's run() method. This arrangement
     * clears up all the stack frames that were required in setting
     * up the process.
     */
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

这里其实就是通过反射找到类 com.android.server.SystemServermain 方法,然后通过主动抛出一个 ZygoteInit.MethodAndArgsCaller 异常,该异常会被 ZygoteInit.main() 函数捕获,然后再捕获该异常处会通过 MethodAndArgsCaller.run 最终反射调用 SystemServer.main 函数,具体源码如下:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
    try {
        ···
    } catch (MethodAndArgsCaller caller) {
        caller.run();
    } catch (RuntimeException ex) {
        ···
    }
}

public static class MethodAndArgsCaller extends Exception
        implements Runnable {
    ···
    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            ···
        }
    }
}

到这里,SystemServer.main 函数就启动了,接下来的操作才是 SystemServer 真正发挥 Android 核心服务的体现。

那接下来我们就来分析下 SystemServer.main 函数,看下其做了哪些事情。

SystemServer 核心操作 过程

先来看下 SystemServer.main 函数:
frameworks/base/services/java/com/android/server/SystemServer.java

public static void main(String[] args) {
        new SystemServer().run();
    }

直接创建一个 SystemServer 实例,并调用其 run 方法:

private void run() {
    ···
    // Ensure binder calls into the system always run at foreground priority.
    // 确保当前进程的 binder 调用总是运行在前台优先级
    BinderInternal.disableBackgroundScheduling(true);
    ···
    // 创建主线程 Looper
    Looper.prepareMainLooper();

    // Initialize native services.
    // 加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下
    System.loadLibrary("android_servers");
    ···
    // Initialize the system context.
    // 初始化系统上下文
    createSystemContext();

    // Create the system service manager.
    //创建系统服务管理
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    // 将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

    // Start services.
    //  启动各种系统服务
    try {
        startBootstrapServices(); // 启动引导服务
        startCoreServices();      // 启动核心服务
        startOtherServices();     // 启动其他服务
    } catch (Throwable ex) {
        ···
    }
    ···
    // Loop forever.
    // 启动 Looper 循环
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

SystemServer.run 方法做了很多事情,其中最主要的就是:

  • 创建并启动主线程 Looper,使能线程间通讯:Looper.prepareMainLooperLooper.loop
  • 加载 android_servers.so 库:System.loadLibrary("android_servers")
  • 初始化系统上下文:createSystemContext
  • 创建系统服务管理 ServiceManagernew SystemServiceManager
  • 启动各种服务startBootstrapServicesstartCoreServicesstartOtherServices

我们主要来看下启动各种服务的大概过程:

首先看下 引导服务 启动过程:startBootstrapServices
frameworks/base/services/java/com/android/server/SystemServer.java

private void startBootstrapServices() {
    // Wait for installd to finish starting up so that it has a chance to
    // create critical directories such as /data/user with the appropriate
    // permissions.  We need this to complete before we initialize other services.
    // 阻塞等待与installd建立socket通道
    Installer installer = mSystemServiceManager.startService(Installer.class);

    // Activity manager runs the show.
    // 启动服务ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

    // Power manager needs to be started early because other services need it.
    // Native daemons may be watching for it to be registered so it must be ready
    // to handle incoming binder calls immediately (including being able to verify
    // the permissions for those calls).
    // 启动服务PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
    ···
    // Manages LEDs and display backlight so we need it to bring up the display.
    // 启动服务LightsService
    mSystemServiceManager.startService(LightsService.class);

    // Display manager is needed to provide display metrics before package manager
    // starts up.
    // 启动服务DisplayManagerService
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    // We need the default display before we can initialize the package manager.
    // Phase100:在初始化package manager之前,需要默认的显示
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    ···
    // Start the package manager.
    // 启动服务PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();

    // 启动服务UserManagerService,新建目录/data/user/
    ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
    ···
    // Set up the Application instance for the system process and get started.
    // 设置 AMS
    mActivityManagerService.setSystemProcess();

    // The sensor service needs access to package manager service, app ops
    // service, and permissions service, therefore we start it after them.
    // 启动传感器服务
    startSensorService();
}

startBootstrapServices 主要做的就是启动各种引导服务(共 7 个):
ActivityManagerService,PowerManagerService,LightsService,DisplayManagerService,PackageManagerService,UserManagerService,SensorService。

接下来看下 核心服务 启动过程:startCoreServices
frameworks/base/services/java/com/android/server/SystemServer.java

private void startCoreServices() {
    // Tracks the battery level.  Requires LightService.
    // 启动服务BatteryService,用于统计电量
    mSystemServiceManager.startService(BatteryService.class);

    // Tracks application usage stats.
    // 启动服务UsageStatsService,用于统计应用使用情况
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));
    // Update after UsageStatsService is available, needed before performBootDexOpt.
    mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();

    // Tracks whether the updatable WebView is in a ready state and watches for update installs.
    // 启动服务WebViewUpdateService
    mSystemServiceManager.startService(WebViewUpdateService.class);
}

startCoreServices 就是用来启动 BatteryService,UsageStatsService,WebViewUpdateService 这些核心服务。

最后来看下 其他服务 启动情况:startOtherServices
frameworks/base/services/java/com/android/server/SystemServer.java

 private void startOtherServices() {
        ...
        SystemConfig.getInstance();
        mContentResolver = context.getContentResolver(); // resolver
        ...
        mActivityManagerService.installSystemProviders(); //provider
        mSystemServiceManager.startService(AlarmManagerService.class); // alarm
        // watchdog
        watchdog.init(context, mActivityManagerService); 
        inputManager = new InputManagerService(context); // input
        wm = WindowManagerService.main(...); // window
        inputManager.start();  //启动input
        mDisplayManagerService.windowManagerAndInputReady();
        ...
        mSystemServiceManager.startService(MOUNT_SERVICE_CLASS); // mount
        mPackageManagerService.performBootDexOpt();  // dexopt操作
        ActivityManagerNative.getDefault().showBootMessage(...); //显示启动界面
        ...
        statusBar = new StatusBarManagerService(context, wm); //statusBar
        //dropbox
        ServiceManager.addService(Context.DROPBOX_SERVICE,
                    new DropBoxManagerService(context, new File("/data/system/dropbox")));
         mSystemServiceManager.startService(JobSchedulerService.class); //JobScheduler
         lockSettings.systemReady(); //lockSettings

        //phase480 和phase500
        mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
        mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
        ...
        // 准备好window, power, package, display服务
        wm.systemReady();
        mPowerManagerService.systemReady(...);
        mPackageManagerService.systemReady();
        mDisplayManagerService.systemReady(...);
        
        //重头戏[见小节2.1]
        mActivityManagerService.systemReady(new Runnable() {
            public void run() {
              ...
            }
        });
    }

startOtherServices 的源码很长,但其主要做的就是启动一系列的服务(共 70 余个),如:AlarmManagerService,VibratorService 等。

SystemServer 启动完成各种服务后,最后就会开启 SystemServer 进程主线程消息循环 Looper.loop,使能 SystemServer 进程线程间通讯。

到此,SystemServer 进程已分析完毕。

总结

SystemServer 进程是由 Zygote 进程孵化(fork)出来的,具体为:Zygote 进程会通过 JNI 调用本地方法,fork 出一个子进程,也即 SystemServer 进程,然后 SystemServer 进程会通过一些列的操作,最终调用到 SystemServer.main函数,在此完成了 SystemServer 最主要的一些操作,让其成为 Android 承载核心业务的服务。

简单来讲,SystemServer 进程其主要做了以下几件事:

  • 创建自身的 Binder 线程池,使能进程间通讯
  • 创建系统服务管理:SystemServiceManager,用于管理系统中的所有服务
  • 启动各种服务
  • 启动线程间通讯

参考

  • Android系统启动-SystemServer上篇

  • Android系统启动-SystemServer下篇

  • Android系统启动流程(三)解析SyetemServer进程启动过程

  • Android6.0系统启动流程分析三:SystemServer进程

你可能感兴趣的:(Android 系统启动 - SystemServer 进程)