SystemServer startup is started in the Zygote startSystemServer method. Zygote service is configured to pass “– start-system-server” in init.zygote32.rc. After the main method in app_main. CPP does a middle conversion to “start-system-server”, the startSystemServer flag is set to true, StartSystemServer is finally called to startSystemServer.

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public class ZygoteInit {...public static void main(String argv[]) {
        try{...boolean startSystemServer = false; .for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    ......
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    ......
                } else {
                    throw new RuntimeException("Unknown command line argument: "+ argv[i]); }}...if (startSystemServer) {
                / / start SystemServerstartSystemServer(abiList, socketName); }... }catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throwex; }}... }Copy the code

Next, go to the startSystemServer function. It is used to prepare parameters and derive them for the SystemServer process.

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public class ZygoteInit {...private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_BLOCK_SUSPEND,
            OsConstants.CAP_KILL,
            OsConstants.CAP_NET_ADMIN,
            OsConstants.CAP_NET_BIND_SERVICE,
            OsConstants.CAP_NET_BROADCAST,
            OsConstants.CAP_NET_RAW,
            OsConstants.CAP_SYS_MODULE,
            OsConstants.CAP_SYS_NICE,
            OsConstants.CAP_SYS_RESOURCE,
            OsConstants.CAP_SYS_TIME,
            OsConstants.CAP_SYS_TTY_CONFIG
        );
        /* Hardcode the command line to start the system server */
        String args[] = {
            "--setuid=1000"."--setgid=1000"."-- setgroups = 1001100 2100 3100 4100 5100 6100 7100 8100 9101 0101 8102 1103 2300 1300 2300 3300 6300 7"."--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server"."--runtime-args"."com.android.server.SystemServer"}; ZygoteConnection.Arguments parsedArgs =null;

        int pid;

        try {
            // Parse the parameters
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request a derived system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* Child processing */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            handleSystemServerProcess(parsedArgs);
        }

        return true; }... }Copy the code

ForkSystemServer is a special method to start a system server process by calling the nativeForkSystemServer JNI method.

frameworks/base/core/java/com/android/internal/os/Zygote.java

public final class Zygote {...public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        VM_HOOKS.preFork();
        int pid = nativeForkSystemServer(
                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
        // Enable tracing as soon as we enter the system_server.
        if (pid == 0) {
            Trace.setTracingEnabled(true);
        }
        VM_HOOKS.postForkCommon();
        returnpid; }... }Copy the code

ForkAndSpecializeCommon is called in the nativeForkSystemServer method to complete the fork action.

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
        jlong effectiveCapabilities) {
  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
                                      debug_flags, rlimits,
                                      permittedCapabilities, effectiveCapabilities,
                                      MOUNT_EXTERNAL_DEFAULT, NULL.NULL.true.NULL.NULL.NULL);
  if (pid > 0) {
      The zygote process checks whether the child process (SystemServer) is dead
      ALOGI("System server process %d has been created", pid);
      gSystemServerPid = pid;
      // There is a small window indicating that the system server process has crashed, but since we have not released its PID yet, it is not noticed.
      // Therefore, we are rechecking here just to make sure everything is ok.
      int status;
      if (waitpid(pid, &status, WNOHANG) == pid) {
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
          RuntimeAbort(env); }}return pid;
}
Copy the code

ForkAndSpecializeCommon invokes the fork system call to create a child process (SystemServer).

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
                                     jint debug_flags, jobjectArray javaRlimits,
                                     jlong permittedCapabilities, jlong effectiveCapabilities,
                                     jint mount_external,
                                     jstring java_se_info, jstring java_se_name,
                                     bool is_system_server, jintArray fdsToClose,
                                     jstring instructionSet, jstring dataDir) {...pid_tpid = fork(); . }Copy the code

Return to ZygoteInit startSystemServer method, and then will call handleSystemServerProcess method starts processing SystemServer process.

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

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

        closeServerSocket();

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

        if(parsedArgs.niceName ! =null) {
            Process.setArgV0(parsedArgs.niceName);
        }

        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if(systemServerClasspath ! =null) {
            performSystemServerDexOpt(systemServerClasspath);
        }

        if(parsedArgs.invokeWith ! =null) {... }else {
            ClassLoader cl = null;
            if(systemServerClasspath ! =null) {
                cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
                Thread.currentThread().setContextClassLoader(cl);
            }

            /* * Pass the remaining parameters to SystemServer. * /
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }

        /* should never reach here */}... }Copy the code

The zygoteInit method in the RuntimeInit class ends up calling applicationInit to run the SystemServer static main method. For details about the Process of calling the zygoteInit method in RuntimeInit, see Android AOSP 6.0.1 Process Start Process analysis (2).

The SystemServer main method code is very simple, it creates a new SystemServer object inside, and calls the run method.

frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {...public static void main(String[] args) {
        newSystemServer().run(); }... }Copy the code

The SystemServer run method starts a series of familiar system-level services, such as ActivityManagerService, PowerManagerService, and so on.

frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {...private void run(a) {
        // The system clock is set before 1970; Set it to 1970.
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); }...// Clear the memory growth limit
        VMRuntime.getRuntime().clearGrowthLimit();

        // The system server must be running all the time, so you need to be as efficient as possible in terms of memory usage.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8 f);

        // Some devices rely on run-time fingerprint generation, so make sure it is defined before further booting.
        Build.ensureFingerprintProperty();

        Inside the system server, it is an error to access the environment path without explicitly specifying the user.
        Environment.setUserRequired(true);

        // Ensure that binder calls to the system always run at previous station priority.
        BinderInternal.disableBackgroundScheduling(true);

        // Prepare the master looper
        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        Looper.prepareMainLooper();

        // Initialize the native service
        System.loadLibrary("android_servers");

        // Check if the last attempt to shut down failed. This call may not return
        performPendingShutdown();

        // Initialize the system context
        createSystemContext();

        // Create system Service Manager
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

        // Start the service
        try {
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        } catch (Throwable ex) {
            Slog.e("System"."* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
            Slog.e("System"."************ Failure starting system services", ex);
            throw ex;
        }

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }

        // Loop forever
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited"); }... }Copy the code

Next let’s look at startBootstrapServices which services are started?

frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {...private void startBootstrapServices(a) {
        // Wait for the installation to complete and start so that it has a chance to create critical directories with appropriate permissions,
        // Such as /data/user. This operation needs to be completed before any other services can be initialized.
        Installer installer = mSystemServiceManager.startService(Installer.class);

        / / start ActivityManagerService
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);

        / / PowerManagerService startup
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

        // ActivityManagerService is now started to initialize the power management function.
        mActivityManagerService.initPowerManagement();

        // Manage the LED and display backlight, so we need it to start the display.
        mSystemServiceManager.startService(LightsService.class);

        // Before PackageManagerService starts, DisplayManagerService needs to provide display metrics.
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

        // Use the default display before initializing the PackageManagerService.
        mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

        // If we are encrypting the device, only the "core" application will be run.
        String cryptState = SystemProperties.get("vold.decrypt");
        if (ENCRYPTING_STATE.equals(cryptState)) {
            Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
            mOnlyCore = true;
        } else if (ENCRYPTED_STATE.equals(cryptState)) {
            Slog.w(TAG, "Device encrypted - only parsing core apps");
            mOnlyCore = true;
        }

        / / start PackageManagerService
        Slog.i(TAG, "Package Manager"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode ! = FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); Slog.i(TAG,"User Service");
        / / add UserManagerService
        ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());

        // Initializes the property cache used to cache resources in the package.
        AttributeCache.init(mSystemContext);

        // Set up the Application instance for the system process and start using it.
        mActivityManagerService.setSystemProcess();

        // The sensor service needs to access the package manager service, the application action service, and the permission service, so we start it after them.startSensorService(); }... }Copy the code

Now what services does startCoreServices start?

frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {...private void startCoreServices(a) {
        // Track the battery level. Need LightService. Start the BatteryService
        mSystemServiceManager.startService(BatteryService.class);

        // Start UsageStatsService to track application usage statistics
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));
        // Update UsageStatsService after it becomes available, which is required before PerformBootDexOpt.
        mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();

        // Track whether updatable WebViews are ready and monitor the update installation. Start the WebViewUpdateServicemSystemServiceManager.startService(WebViewUpdateService.class); }... }Copy the code

StartOtherServices starts the remaining required services. All system services have been started!

Below is a sequence diagram.