Android15 Framework(3):系统服务进程 SystemServer 解析

前言

在前面2篇文章

我们看了Init、Zygote进程,本文是Android 15 Framework解析系列的第三篇,一起来看看 SystemServer 进程的启动与核心服务的初始化全流程吧。

注意:本文出现的源码基于Android - 15.0.0_r1。另外本文关注主要逻辑,省略部分代码。

一、 Android系统启动流程

本文是介绍SystemServer,照例先看下Android系统启动流程:

启动电源及系统启动 -> Bootloader -> Linux内核启动 -> Init -> Zygote -> SystemServer -> Launcher

二、 SystemServer

SystemServer 是 Android 系统的核心进程,它会启动并管理几乎所有关键的系统服务,如 AMS、WMS等。

我们就从SystemServer的启动开始看吧。

2.1 SystemServer的启动

SystemServer的启动是在ZygoteInit::main方法中,调用了forkSystemServer方法 /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

Java 复制代码
    @UnsupportedAppUsage
    public static void main(String[] argv) {
        ...
        if (startSystemServer) {
           // 此处调用了forkSystemServer
           Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
           ...
        }
        ...
    }

    private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        // 特权能力
        long capabilities = posixCapabilitiesAsBits(
                OsConstants.CAP_IPC_LOCK,
                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_PTRACE,
                OsConstants.CAP_SYS_TIME,
                OsConstants.CAP_SYS_TTY_CONFIG,
                OsConstants.CAP_WAKE_ALARM,
                OsConstants.CAP_BLOCK_SUSPEND
        );
        /* Containers run without some capabilities, so drop any caps that are not available. */
        StructCapUserHeader header = new StructCapUserHeader(
                OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
        StructCapUserData[] data;
        try {
            data = Os.capget(header);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to capget()", ex);
        }
        capabilities &= Integer.toUnsignedLong(data[0].effective) |
                (Integer.toUnsignedLong(data[1].effective) << 32);

        /* Hardcoded command line to start the system server */
        String[] args = {
                "--setuid=1000",
                "--setgid=1000",
                "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                        + "1024,1032,1065,3001,3002,3003,3005,3006,3007,3009,3010,3011,3012",
                "--capabilities=" + capabilities + "," + capabilities,
                "--nice-name=system_server",
                "--runtime-args",
                "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
                "com.android.server.SystemServer",
        };
        ZygoteArguments parsedArgs;

        int pid;

        try {
            ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
            try {
                parsedArgs = ZygoteArguments.getInstance(commandBuffer);
            } catch (EOFException e) {
                throw new AssertionError("Unexpected argument error for forking system server", e);
            }
            commandBuffer.close();
            Zygote.applyDebuggerSystemProperty(parsedArgs);
            Zygote.applyInvokeWithSystemProperty(parsedArgs);

            if (Zygote.nativeSupportsMemoryTagging()) {
                String mode = SystemProperties.get("persist.arm64.memtag.system_server", "");
                if (mode.isEmpty()) {
                  /* The system server has ASYNC MTE by default, in order to allow
                   * system services to specify their own MTE level later, as you
                   * can't re-enable MTE once it's disabled. */
                  mode = SystemProperties.get("persist.arm64.memtag.default", "async");
                }
                if (mode.equals("async")) {
                    parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_ASYNC;
                } else if (mode.equals("sync")) {
                    parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_SYNC;
                } else if (!mode.equals("off")) {
                    /* When we have an invalid memory tag level, keep the current level. */
                    parsedArgs.mRuntimeFlags |= Zygote.nativeCurrentTaggingLevel();
                    Slog.e(TAG, "Unknown memory tag level for the system server: \"" + mode + "\"");
                }
            } else if (Zygote.nativeSupportsTaggedPointers()) {
                /* Enable pointer tagging in the system server. Hardware support for this is present
                 * in all ARMv8 CPUs. */
                parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI;
            }

            /* Enable gwp-asan on the system server with a small probability. This is the same
             * policy as applied to native processes and system apps. */
            parsedArgs.mRuntimeFlags |= Zygote.GWP_ASAN_LEVEL_LOTTERY;

            if (shouldProfileSystemServer()) {
                parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
            }

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }
    
    static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        ZygoteHooks.preFork();

        int pid = nativeForkSystemServer(
                uid, gid, gids, runtimeFlags, rlimits,
                permittedCapabilities, effectiveCapabilities);

        // Set the Java Language thread priority to the default value for new apps.
        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);

        ZygoteHooks.postForkCommon();
        return pid;
    }

// 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 runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
        jlong effective_capabilities) {
  ...

  // ForkCommon会调用fork函数
  pid_t pid = zygote::ForkCommon(env, true,
                                 fds_to_close,
                                 fds_to_ignore,
                                 true);
  ...
  return pid;
}
    
pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
                         const std::vector<int>& fds_to_close,
                         const std::vector<int>& fds_to_ignore,
                         bool is_priority_fork,
                         bool purge) {
  ...

  pid_t pid = fork();
  ...

  return pid;
}

在forkSystemServer中,调用了nativeForkSystemServer方法,最后会调用fork,并将返回pid。执行完forkSystemServer之后,会继续看后面的代码,会执行handleSystemServerProcess

Java 复制代码
    private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
        // set umask to 0077 so new files and directories will default to owner-only permissions.
        Os.umask(S_IRWXG | S_IRWXO);

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

        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            // Capturing profiles is only supported for debug or eng builds since selinux normally
            // prevents it.
            if (shouldProfileSystemServer() && (Build.IS_USERDEBUG || Build.IS_ENG)) {
                try {
                    Log.d(TAG, "Preparing system server profile");
                    final String standaloneSystemServerJars =
                            Os.getenv("STANDALONE_SYSTEMSERVER_JARS");
                    final String systemServerPaths = standaloneSystemServerJars != null
                            ? String.join(":", systemServerClasspath, standaloneSystemServerJars)
                            : systemServerClasspath;
                    prepareSystemServerProfile(systemServerPaths);
                } catch (Exception e) {
                    Log.wtf(TAG, "Failed to set up system server profile", e);
                }
            }
        }

        // parsedArgs.mInvokeWith 为null,走else分支
        if (parsedArgs.mInvokeWith != null) {
            String[] args = parsedArgs.mRemainingArgs;
            // 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(args, 0, amendedArgs, 2, args.length);
                args = amendedArgs;
            }

            WrapperInit.execApplication(parsedArgs.mInvokeWith,
                    parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(), null, args);

            throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
        } else {
            // 创建SystemServerClassLoader, 实现是构建的PathClassLoader对象
            ClassLoader cl = getOrCreateSystemServerClassLoader();
            if (cl != null) {
                Thread.currentThread().setContextClassLoader(cl);
            }

            // 调用ZygoteInit.zygoteInit
            return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                    parsedArgs.mDisabledCompatChanges,
                    parsedArgs.mRemainingArgs, cl);
        }

        /* should never reach here */
    }
    
    public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
                classLoader);
    }
    
    protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
            String[] argv, ClassLoader classLoader) {
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);

        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
        VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);

        final Arguments args = new Arguments(argv);

        // 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
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }
    
    protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;

        try {
            // 根据类名动态加载目标类
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
            // 获取目标类的 main 方法
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        // 验证方法修饰符:必须是 public static
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }
        
        // MethodAndArgsCaller实现了Runnable接口,后续ZygoteInit会调用run() 方法 
        // 最终结果:子进程直接从目标类的 main 方法开始执行, 这里就是SystemServer::main方法
        return new MethodAndArgsCaller(m, argv);
    }
    
    // RuntimeInit.java
    static class MethodAndArgsCaller implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }

从上面代码可以看到,先通过fork创建子进程,再通过反射找到SystemServer::main方法,后续在ZygoteInit.main()中,调用run方法,会执行mMethod.invoke,从而也就到了SystemServer::main,即启动了SystemServer

还记得在handleSystemServerProcess方法中,调用了getOrCreateSystemServerClassLoader,去创建SystemServerClassLoader,这个方法调用链,我贴下面吧,感兴趣可以自己看看,也可以越过这部分,直接看2.2小节,不影响Android启动流程

Java 复制代码
    private static ClassLoader getOrCreateSystemServerClassLoader() {
        if (sCachedSystemServerClassLoader == null) {
            final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
            if (systemServerClasspath != null) {
                sCachedSystemServerClassLoader = createPathClassLoader(systemServerClasspath,
                        VMRuntime.SDK_VERSION_CUR_DEVELOPMENT);
            }
        }
        return sCachedSystemServerClassLoader;
    }
    
    static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
        String libraryPath = System.getProperty("java.library.path");

        // We use the boot class loader, that's what the runtime expects at AOT.
        ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();

        // 注意这里的classLoaderName传的是null,后面会根据这个参数来判断使用哪种ClassLoader
        return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
                parent, targetSdkVersion, true /* isNamespaceShared */, null /* classLoaderName */);
    }
    
    // classLoaderName为null
    public static ClassLoader createClassLoader(String dexPath,
            String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
            int targetSdkVersion, boolean isNamespaceShared, String classLoaderName) {
        List<String> nativeSharedLibraries = new ArrayList<>();
        nativeSharedLibraries.add("ALL");

        return createClassLoader(dexPath, librarySearchPath, libraryPermittedPath,
            parent, targetSdkVersion, isNamespaceShared, classLoaderName, null,
            nativeSharedLibraries, null);
    }
    
     // classLoaderName为null
    public static ClassLoader createClassLoader(String dexPath,
            String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
            int targetSdkVersion, boolean isNamespaceShared, String classLoaderName,
            List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries,
            List<ClassLoader> sharedLibrariesAfter) {

        final ClassLoader classLoader = createClassLoader(dexPath, librarySearchPath, parent,
                classLoaderName, sharedLibraries, sharedLibrariesAfter);
        ...

        return classLoader;
    }
    
     // classLoaderName为null
    public static ClassLoader createClassLoader(String dexPath,
            String librarySearchPath, ClassLoader parent, String classloaderName,
            List<ClassLoader> sharedLibraries, List<ClassLoader> sharedLibrariesLoadedAfter) {
        ClassLoader[] arrayOfSharedLibraries = (sharedLibraries == null)
                ? null
                : sharedLibraries.toArray(new ClassLoader[sharedLibraries.size()]);
        ClassLoader[] arrayOfSharedLibrariesLoadedAfterApp = (sharedLibrariesLoadedAfter == null)
                ? null
                : sharedLibrariesLoadedAfter.toArray(
                        new ClassLoader[sharedLibrariesLoadedAfter.size()]);
        // 在createPathClassLoader方法调用ClassLoaderFactory.createClassLoader时,传递的classloaderName为null
        // isPathClassLoaderName判断这个参数为null,会返回true
        if (isPathClassLoaderName(classloaderName)) {
            // 因此SystemServerClassLoader是用的PathClassLoader
            return new PathClassLoader(dexPath, librarySearchPath, parent, arrayOfSharedLibraries,
                    arrayOfSharedLibrariesLoadedAfterApp);
        } else if (isDelegateLastClassLoaderName(classloaderName)) {
            return new DelegateLastClassLoader(dexPath, librarySearchPath, parent,
                    arrayOfSharedLibraries, arrayOfSharedLibrariesLoadedAfterApp);
        }

        throw new AssertionError("Invalid classLoaderName: " + classloaderName);
    }
    
    // 这里的参数name,也就是从传下来classloaderName,为null,此方法返回true
    public static boolean isPathClassLoaderName(String name) {
        return name == null || PATH_CLASS_LOADER_NAME.equals(name) ||
                DEX_CLASS_LOADER_NAME.equals(name);
    }

2.2 SystemServer

通过上一小节的调用,就跑到了SystemServer::main方法中

Java 复制代码
    public static void main(String[] args) {
        new SystemServer().run();
    }

    public SystemServer() {
        ...

        mStartCount = SystemProperties.getInt(SYSPROP_START_COUNT, 0) + 1;
        // 设备启动(开机)以来经过的真实时间
        mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
        // 设备启动以来经过的有效运行时间
        mRuntimeStartUptime = SystemClock.uptimeMillis();
        Process.setStartTimes(mRuntimeStartElapsedTime, mRuntimeStartUptime,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);

        // Remember if it's runtime restart or reboot.
        mRuntimeRestart = mStartCount > 1;
    }

    private void run() {
        TimingsTraceAndSlog t = new TimingsTraceAndSlog();
        try {
            t.traceBegin("InitBeforeStartServices");

            // 设置一些属性值
            SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
            SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));
            SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));

            EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
                    mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);

            // Set the device's time zone (a system property) if it is not set or is invalid.
            SystemTimeZone.initializeTimeZoneSettingsIfRequired();

            // If the system has "persist.sys.language" and friends set, replace them with
            // "persist.sys.locale". Note that the default locale at this point is calculated
            // using the "-Duser.locale" command line flag. That flag is usually populated by
            // AndroidRuntime using the same set of system properties, but only the system_server
            // and system apps are allowed to set them.
            //
            // NOTE: Most changes made here will need an equivalent change to
            // core/jni/AndroidRuntime.cpp
            if (!SystemProperties.get("persist.sys.language").isEmpty()) {
                final String languageTag = Locale.getDefault().toLanguageTag();

                SystemProperties.set("persist.sys.locale", languageTag);
                SystemProperties.set("persist.sys.language", "");
                SystemProperties.set("persist.sys.country", "");
                SystemProperties.set("persist.sys.localevar", "");
            }

            // The system server should never make non-oneway calls
            Binder.setWarnOnBlocking(true);
            // The system server should always load safe labels
            PackageItemInfo.forceSafeLabels();

            // Default to FULL within the system server.
            SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;

            // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
            SQLiteCompatibilityWalFlags.init(null);

            // Here we go!
            Slog.i(TAG, "Entered the Android system server!");
            final long uptimeMillis = SystemClock.elapsedRealtime();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
            if (!mRuntimeRestart) {
                FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                        FrameworkStatsLog
                                .BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SYSTEM_SERVER_INIT_START,
                        uptimeMillis);
            }

            // In case the runtime switched since last boot (such as when
            // the old runtime was removed in an OTA), set the system
            // property so that it is in sync. We can't do this in
            // libnativehelper's JniInvocation::Init code where we already
            // had to fallback to a different runtime because it is
            // running as root and we need to be the system user to set
            // the property. http://b/11463182
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

            // Mmmmmm... more memory!
            VMRuntime.getRuntime().clearGrowthLimit();

            // Some devices rely on runtime fingerprint generation, so make sure
            // we've defined it before booting further.
            Build.ensureFingerprintProperty();

            // Within the system server, it is an error to access Environment paths without
            // explicitly specifying a user.
            Environment.setUserRequired(true);

            // Within the system server, any incoming Bundles should be defused
            // to avoid throwing BadParcelableException.
            BaseBundle.setShouldDefuse(true);

            // Within the system server, when parceling exceptions, include the stack trace
            Parcel.setStackTraceParceling(true);

            // Ensure binder calls into the system always run at foreground priority.
            BinderInternal.disableBackgroundScheduling(true);

            // Increase the number of binder threads in system_server
            BinderInternal.setMaxThreads(sMaxBinderThreads);

            // Prepare the main looper thread (this thread).
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            Looper.prepareMainLooper();
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

            SystemServiceRegistry.sEnableServiceNotFoundWtf = true;

            // 加载libandroid_servers.so
            System.loadLibrary("android_servers");

            // Allow heap / perf profiling.
            initZygoteChildHeapProfiling();

            // Debug builds - spawn a thread to monitor for fd leaks.
            if (Build.IS_DEBUGGABLE) {
                spawnFdLeakCheckThread();
            }

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // 创建 system context.
            createSystemContext();

            // Call per-process mainline module initialization.
            ActivityThread.initializeMainlineModules();

            // Sets the dumper service
            ServiceManager.addService("system_server_dumper", mDumper);
            mDumper.addDumpable(this);

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
            mDumper.addDumpable(mSystemServiceManager);

            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
            mDumper.addDumpable(tp);

            // Lazily load the pre-installed system font map in SystemServer only if we're not doing
            // the optimized font loading in the FontManagerService.
            if (!com.android.text.flags.Flags.useOptimizedBoottimeFontLoading()
                    && Typeface.ENABLE_LAZY_TYPEFACE_INITIALIZATION) {
                Slog.i(TAG, "Loading pre-installed system font map.");
                Typeface.loadPreinstalledSystemFontMap();
            }

            // Attach JVMTI agent if this is a debuggable build and the system property is set.
            if (Build.IS_DEBUGGABLE) {
                // Property is of the form "library_path=parameters".
                String jvmtiAgent = SystemProperties.get("persist.sys.dalvik.jvmtiagent");
                if (!jvmtiAgent.isEmpty()) {
                    int equalIndex = jvmtiAgent.indexOf('=');
                    String libraryPath = jvmtiAgent.substring(0, equalIndex);
                    String parameterList =
                            jvmtiAgent.substring(equalIndex + 1, jvmtiAgent.length());
                    // Attach the agent.
                    try {
                        Debug.attachJvmtiAgent(libraryPath, parameterList, null);
                    } catch (Exception e) {
                        Slog.e("System", "*************************************************");
                        Slog.e("System", "********** Failed to load jvmti plugin: " + jvmtiAgent);
                    }
                }
            }
        } finally {
            t.traceEnd();  // InitBeforeStartServices
        }

        // Setup the default WTF handler
        RuntimeInit.setDefaultApplicationWtfHandler(SystemServer::handleEarlySystemWtf);

        // 启动服务
        try {
            t.traceBegin("StartServices");
            // 引导服务,如ATMS, AMS,DMS
            startBootstrapServices(t);
            // 核心服务,如BatteryService
            startCoreServices(t);
            // 其他服务,如WMS, IMS
            startOtherServices(t);
            startApexServices(t);
            // Only update the timeout after starting all the services so that we use
            // the default timeout to start system server.
            updateWatchdogTimeout(t);
            CriticalEventLog.getInstance().logSystemServerStarted();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            t.traceEnd(); // StartServices
        }

        StrictMode.initVmDefaults(null);

        if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
            final long uptimeMillis = SystemClock.elapsedRealtime();
            FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
                    FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SYSTEM_SERVER_READY,
                    uptimeMillis);
            final long maxUptimeMillis = 60 * 1000;
            if (uptimeMillis > maxUptimeMillis) {
                Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                        "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
            }
        }

        // Set binder transaction callback after starting system services
        Binder.setTransactionCallback(new IBinderCallback() {
            @Override
            public void onTransactionError(int pid, int code, int flags, int err) {
                mActivityManagerService.frozenBinderTransactionDetected(pid, code, flags, err);
            }
        });

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

在SystemServer::main中,先调用SystemServer的构造方法,然后再调用了SystemServer::run。run方法中,做了很多事,我们还是只看比较重要的。

  • createSystemContext
  • startBootstrapServices
  • startCoreServices
  • startOtherServices
  • startApexServices

那么就依次看看具体代码吧

2.2.1 createSystemContext

Java 复制代码
    private void createSystemContext() {
        // 获取ActivityThread
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
        Trace.registerWithPerfetto();
    }

    // ActivityThread.java
    public static ActivityThread systemMain() {
        ThreadedRenderer.initForSystemProcess();
        ActivityThread thread = new ActivityThread();
        thread.attach(true, 0);
        return thread;
    }
    
    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mConfigurationController = new ConfigurationController(this);
        mSystemThread = system;
        mStartSeq = startSeq;
        mDdmSyncStageUpdater.next(Stage.Attach);

        // system为true,执行eles分支
        if (!system) {
            ...
        } else {
            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
                // 创建ContextImpl
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                // 通过反射创建mInitialApplication,调用onCreate()
                mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }

        ...
    }

    public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                mSystemContext = ContextImpl.createSystemContext(this);
            }
            return mSystemContext;
        }
    }
    
   // ContextImpl.java
   static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
                ContextParams.EMPTY, null, null, null, null, null, 0, null, null,
                DEVICE_ID_DEFAULT, false);
        context.setResources(packageInfo.getResources());
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
        return context;
    }

在createSystemContext方法中,会创建System Context, 并且还通过反射创建mInitialApplication,调用它的onCreate()。

2.2.2 startBootstrapServices

Java 复制代码
    private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
        ...
        
        // 启动看门狗
        final Watchdog watchdog = Watchdog.getInstance();
        watchdog.start();
        ...
        
        // 开启Installer
        Installer installer = mSystemServiceManager.startService(Installer.class);
        ...
        
        // 开启PowerStatsService
        mSystemServiceManager.startService(PowerStatsService.class);
        ...
        
        // 开启ATMS, AMS
        ActivityTaskManagerService atm = mSystemServiceManager.startService(
                ActivityTaskManagerService.Lifecycle.class).getService();
        mActivityManagerService = ActivityManagerService.Lifecycle.startService(
                mSystemServiceManager, atm);
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);

        ...
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
        ...

        // 添加一个设备重启监听
        watchdog.init(mSystemContext, mActivityManagerService);
        ...
    }
    
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
                // 获取构造方法
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                // 构造实例
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (InvocationTargetException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service constructor threw an exception", ex);
            }
            
            // 启动服务
            startService(service);
            // 返回服务实例
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
    
    public void startService(@NonNull final SystemService service) {
        // Check if already started
        String className = service.getClass().getName();
        // mServiceClassnames是一个Set, 防止反复启动同一服务
        if (mServiceClassnames.contains(className)) {
            Slog.i(TAG, "Not starting an already started service " + className);
            return;
        }
        mServiceClassnames.add(className);

        // Register it.
        mServices.add(service);

        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            // 调用启动服务的onStart方法,实际就是往ServiceManager中注册当前启动的服务
            service.onStart方法();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }

在startBootstrapServices中, 会启动看门狗以及启动一些服务,比如ATMS, AMS,DMS等。看门狗的作用是进程监听并管理, 如果监听的进程出现了问题,会把SystemServer杀死,而Zygote收到SystemServer被杀死之后,会把自己也杀死,然后Init会重新启动Zygote,Zygote再重新启动SystemServer。

而在startBootstrapServices中启动服务是通过mSystemServiceManager.startService(xxx.class)的方式,会通过反射获取服务实例,后续还会调用service.onStart方法(),向ServiceManager中注册当前启动的服务。这样client端才能通过Binder和Server端通信。

后续还会写Binder的文章,到时再一起讲ServiceManage

2.2.3 startCoreServices

Java 复制代码
    private void startCoreServices(@NonNull TimingsTraceAndSlog t) {
        t.traceBegin("startCoreServices");

        // Service for system config
        t.traceBegin("StartSystemConfigService");
        mSystemServiceManager.startService(SystemConfigService.class);
        t.traceEnd();

        t.traceBegin("StartBatteryService");
        // Tracks the battery level.  Requires LightService.
        mSystemServiceManager.startService(BatteryService.class);
        t.traceEnd();

        // Tracks application usage stats.
        t.traceBegin("StartUsageService");
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));
        t.traceEnd();

        // Tracks whether the updatable WebView is in a ready state and watches for update installs.
        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
            t.traceBegin("StartWebViewUpdateService");
            mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
            t.traceEnd();
        }

        // Tracks and caches the device state.
        t.traceBegin("StartCachedDeviceStateService");
        mSystemServiceManager.startService(CachedDeviceStateService.class);
        t.traceEnd();

        // Tracks cpu time spent in binder calls
        t.traceBegin("StartBinderCallsStatsService");
        mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);
        t.traceEnd();

        // Tracks time spent in handling messages in handlers.
        t.traceBegin("StartLooperStatsService");
        mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);
        t.traceEnd();

        // Manages apk rollbacks.
        t.traceBegin("StartRollbackManagerService");
        mSystemServiceManager.startService(RollbackManagerService.class);
        t.traceEnd();

        // Tracks native tombstones.
        t.traceBegin("StartNativeTombstoneManagerService");
        mSystemServiceManager.startService(NativeTombstoneManagerService.class);
        t.traceEnd();

        // Service to capture bugreports.
        t.traceBegin("StartBugreportManagerService");
        mSystemServiceManager.startService(BugreportManagerService.class);
        t.traceEnd();

        // Service for GPU and GPU driver.
        t.traceBegin("GpuService");
        mSystemServiceManager.startService(GpuService.class);
        t.traceEnd();

        // Handles system process requests for remotely provisioned keys & data.
        t.traceBegin("StartRemoteProvisioningService");
        mSystemServiceManager.startService(RemoteProvisioningService.class);
        t.traceEnd();

        // TODO(b/277600174): Start CpuMonitorService on all builds and not just on debuggable
        // builds once the Android JobScheduler starts using this service.
        if (Build.IS_DEBUGGABLE || Build.IS_ENG) {
          // Service for CPU monitor.
          t.traceBegin("CpuMonitorService");
          mSystemServiceManager.startService(CpuMonitorService.class);
          t.traceEnd();
        }

        t.traceEnd(); // startCoreServices
    }

在startCoreServices中,同样是通过SystemServiceManager::startService启动了很多服务,如SystemConfigService,BatteryService...

2.2.4 startOtherServices

Java 复制代码
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
        t.traceBegin("startOtherServices");
        mSystemServiceManager.updateOtherServicesStartIndex();

        final Context context = mSystemContext;
        DynamicSystemService dynamicSystem = null;
        IStorageManager storageManager = null;
        NetworkManagementService networkManagement = null;
        VpnManagerService vpnManager = null;
        VcnManagementService vcnManagement = null;
        NetworkPolicyManagerService networkPolicy = null;
        WindowManagerService wm = null;
        NetworkTimeUpdateService networkTimeUpdater = null;
        InputManagerService inputManager = null;
        ...

        try {
            ...

            t.traceBegin("StartInputManagerService");
            inputManager = new InputManagerService(context);
            t.traceEnd();

            t.traceBegin("DeviceStateManagerService");
            mSystemServiceManager.startService(DeviceStateManagerService.class);
            t.traceEnd();

            if (!disableCameraService) {
                t.traceBegin("StartCameraServiceProxy");
                mSystemServiceManager.startService(CameraServiceProxy.class);
                t.traceEnd();
            }

            t.traceBegin("StartWindowManagerService");
            // WMS needs sensor service ready
            mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
            // 启动WMS,WMS需要IMS的协助处理,因此会将IMS对象传入WMS中
            wm = WindowManagerService.main(context, inputManager, !mFirstBoot,
                    new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
                            | DUMP_FLAG_PROTO);
            ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
            t.traceEnd();

            t.traceBegin("SetWindowManagerService");
            mActivityManagerService.setWindowManager(wm);
            t.traceEnd();

            t.traceBegin("WindowManagerServiceOnInitReady");
            wm.onInitReady();
            t.traceEnd();

            ...

            t.traceBegin("StartInputManager");
            inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
            // 启动InputManagerService
            inputManager.start();
        }
        ...
            

        t.traceBegin("StartSystemUI");
        try {
            // 启动SystemUi
            startSystemUi(context, windowManagerF);
        } catch (Throwable e) {
            reportWtf("starting System UI", e);
        }
        t.traceEnd();

        t.traceEnd(); // startOtherServices
    }
    
    private static void startSystemUi(Context context, WindowManagerService windowManager) {
        PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
        Intent intent = new Intent();
        intent.setComponent(pm.getSystemUiServiceComponent());
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.SYSTEM);
        windowManager.onSystemUiStarted();
    }
    
    // InputManagerService.java
    public void start() {
        Slog.i(TAG, "Starting input manager");
        mNative.start();

        // Add ourselves to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this);
    }

// com_android_server_input_InputManagerService.cpp
static void nativeStart(JNIEnv* env, jobject nativeImplObj) {
    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);

    status_t result = im->getInputManager()->start();
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}

在startOtherServices中,同样也是启动了很多服务,比较重要的有WMS, IMS等,最后还会启动SystemUI

2.2.5 startApexServices

Java 复制代码
    private void startApexServices(@NonNull TimingsTraceAndSlog t) {
        if (Flags.recoverabilityDetection()) {
            // For debugging RescueParty
            if (Build.IS_DEBUGGABLE
                    && SystemProperties.getBoolean("debug.crash_system", false)) {
                throw new RuntimeException();
            }
        }

        t.traceBegin("startApexServices");
        // TODO(b/192880996): get the list from "android" package, once the manifest entries
        // are migrated to system manifest.
        List<ApexSystemServiceInfo> services = ApexManager.getInstance().getApexSystemServices();
        for (ApexSystemServiceInfo info : services) {
            String name = info.getName();
            String jarPath = info.getJarPath();
            t.traceBegin("starting " + name);
            if (TextUtils.isEmpty(jarPath)) {
                mSystemServiceManager.startService(name);
            } else {
                mSystemServiceManager.startServiceFromJar(name, jarPath);
            }
            t.traceEnd();
        }

        // make sure no other services are started after this point
        mSystemServiceManager.sealStartedServices();

        t.traceEnd(); // startApexServices
    }

startApexServices其实就是去遍历List<ApexSystemServiceInfo>,启动此list中的services。

贴下官网APEX的图:

具体APEX的说明,请去官网了解: APEX 文件格式 | Android Open Source Project

这里就简单介绍下APEX

定义 :APEX(Android Pony EXpress)是从 Android 10 (Q) 开始引入的系统模块更新容器格式 。它与APK类似,但专为更新底层系统模块(如运行时库、硬件抽象层HAL)而设计。

目的 :用于支持无需完整OTA的系统模块动态更新。这解决了传统APK模型无法在系统启动早期加载、以及对底层模块更新不灵活的问题。

启动时机:在 startOtherServices 之后, 所有常规服务启动完成之后,会调用 startApexServices, 这避免 APEX 被正在初始化的核心服务所依赖,从而保证系统启动流程稳定。

三、小结

本文介绍了Andorid系统启动流程中的SystemServer,它创建System Context了,并启动各种服务,比如AMS, WMS,IMS等等,最后还启动SystemUi。

用一个时序图总结下SystemServer吧

感谢阅读,希望本文对你有所帮助,如有任何不对的地方,欢迎大家指出

四、参考资料

  1. 《Android进阶解密》
  2. APEX 文件格式 | Android Open Source Project
相关推荐
没有了遇见1 小时前
Android 之Google Play bundletool 校验 AAB包
android·google
yuanhello2 小时前
【Android】Android的键值对存储方案对比
android·java·android studio
Ditglu.2 小时前
CentOS7 MySQL5.7 主从复制最终版搭建流程(避坑完整版)
android·adb
恋猫de小郭2 小时前
Android Studio Otter 2 Feature 发布,最值得更新的 Android Studio
android·前端·flutter
走在路上的菜鸟2 小时前
Android学Dart学习笔记第十二节 函数
android·笔记·学习·flutter
没有了遇见2 小时前
Android + Google Play:老项目适配实战指南
android·google
怀君2 小时前
Uniapp——开发Android插件教程
android·uni-app
Lei活在当下3 小时前
【Perfetto从入门到精通】1. 初识 Perfetto
android·性能优化·架构
用户41659673693553 小时前
深度解析 Android 权限机制:从清单注册到 Android 14 适配实战
android