diff --git a/Software/OperatingSystem/Android/SystemServer/Android_8.1_源码_启动篇_深入研究_SystemServer.md b/Software/OperatingSystem/Android/SystemServer/Android_8.1_源码_启动篇_深入研究_SystemServer.md new file mode 100644 index 0000000..ebac2e1 --- /dev/null +++ b/Software/OperatingSystem/Android/SystemServer/Android_8.1_源码_启动篇_深入研究_SystemServer.md @@ -0,0 +1,1253 @@ +# [Android 8.1 源码_启动篇 -- 深入研究 SystemServer](https://segmentfault.com/a/1190000015945581) + +## 前言 + +SystemServer进程是zygote进程启动后,主动“分裂”的第一个进程。它负责启动大量的Android系统核心服务,其重要性不言而喻。一旦该进程崩溃,整个Android系统将重新启动。 + +## 开篇 + +### 核心源码 + +| 关键类 | 路径 | +| :-- | :-- | +| com_android_internal_os_Zygote.cpp | frameworks/base/core/jni/com_android_internal_os_Zygote.cpp | +| AndroidRuntime.cpp | frameworks/base/core/jni/AndroidRuntime.cpp | +| ZygoteInit.java | frameworks/base/core/java/com/android/internal/os/ZygoteInit.java | +| Zygote.java | frameworks/base/core/java/com/android/internal/os/Zygote.java | +| ActivityThread.java | frameworks/base/core/java/android/app/ActivityThread.java | +| ContextImpl.java.java | frameworks/base/core/java/android/app/ContextImpl.java | +| LoadedApk.java.java | frameworks/base/core/java/android/app/LoadedApk.java | +| SystemServer.java | frameworks/base/services/java/com/android/server/SystemServer.java | +| RuntimeInit.java | frameworks/base/core/java/com/android/internal/os/RuntimeInit.java | + +### 概述 + + SystemServer是什么?它是Android Java的两大支柱之一。另外一个支柱是专门负责孵化Java进程的Zygote(Zygote进程是整个android系统的根进程)。这两个支柱倒了任何一个,都会导致Android Java的崩溃(所有由Zygote孵化的Java进程都会被销毁,而SystemServer就是由Zygote孵化而来)。 + 若Android Java真的崩溃了,那么Linux系统中的进程init会重新启动“两大支柱”以重建Android Java。 + SystemServer和系统服务有着重要的关系,Android系统中几乎所有的核心服务都是在这个进程中,如:ActivityManagerService、PowerManagerService和WindowManagerService等。当我们的应用需要使用各种系统服务的时候,其实也是通过与SystemServer进程通讯获取各种服务对象的句柄,进而执行相应的操作。 + +## Read The Fucking Code + + SystemServer是由Zygote孵化而来的一个进程,通过ps命令,我们发现其进程名为:system_server。 + +### 启动SystemServer进程 + +在分析zygote进程时,我们知道当zygote进程进入到java世界后,在ZygoteInit.java中,将调用startSystemServer函数启动SystemServer进程,其关键代码是: + +```cpp + if (startSystemServer) { + Runnable r = forkSystemServer(abiList, socketName, zygoteServer); // fork出system server + + // {@code r == null} in the parent (zygote) process, and {@code r != null} in the + // child (system_server) process. + if (r != null) { + r.run(); + return; + } + } +``` + +我们看下forkSystemServer(): + +```cpp +// 我们这边挑出重要代码讲解,详细代码分析请参考Zygote篇 +/* Request to fork the system server process */ +pid = Zygote.forkSystemServer( + parsedArgs.uid, parsedArgs.gid, + parsedArgs.gids, + parsedArgs.debugFlags, + null, + parsedArgs.permittedCapabilities, + parsedArgs.effectiveCapabilities); +``` + +老样子,源码继续跟下去: + +```cpp + public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, + int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { + VM_HOOKS.preFork(); + // Resets nice priority for zygote process. + resetNicePriority(); + 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, debugFlags); + } + VM_HOOKS.postForkCommon(); + return pid; + } +``` + +容易看出,该函数通过调用native方法,完成实际的创建操作。该Native方法定义于frameworks/base/core/jni/com_android_internal_os_Zygote.cpp中。 我们来看看对应的native函数。 + +```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, NULL); + if (pid > 0) { + // The zygote process checks whether the child process has died or not. + ALOGI("System server process %d has been created", pid); + + // 这里SystemServer进程已经创建出来,pid > 0 说明在父进程中 + // 将子进程SystemServer的pid存在zygote进程的全局变量中 + gSystemServerPid = pid; + + // There is a slight window that the system server process has crashed + // but it went unnoticed because we haven't published its pid yet. So + // we recheck here just to make sure that all is well. + int status; + if (waitpid(pid, &status, WNOHANG) == pid) { + // 小概率,SystemServer进程刚创建,就crash;此时需要重启zygote + ALOGE("System server process %d has died. Restarting Zygote!", pid); + RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!"); + } + + // Assign system_server to the correct memory cgroup. + if (!WriteStringToFile(StringPrintf("%d", pid), "/dev/memcg/system/tasks")) { + ALOGE("couldn't write %d to /dev/memcg/system/tasks", pid); + } + } + return pid; +} +``` + +上述代码中,实际的“分裂”工作,由函数ForAndSpecializeCommon完成。 + +```cpp +// Utility routine to fork zygote and specialize the child process. +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, + jintArray fdsToIgnore, + jstring instructionSet, jstring dataDir) { + SetSigChldHandler(); // 注册信号监听器 + ... ... + + pid_t pid = fork(); + + if (pid == 0) { + ... ... // 根据传入参数进行对应的处理,例如设置进程名,设置各种id(用户id,组id)等 + + UnsetSigChldHandler(); // 反注册掉信号监听器 + ... ... + + } else if (pid > 0) { + ... ... + + } + return pid; +} +``` + +从上面的代码可以看出,ForkAndSpecializeCommon最终是通过fork的方式,分裂出子进程。 +这里需要关注一下的是,在zygote进程fork之前,调用SetSigChldHandler函数注册了一个子进程信号监听器。由于子进程共享父进程中的堆及栈信息,因此在子进程中也会有相应的信号处理器。 +为了避免该信号监听器对子进程的影响,可以看到在子进程中进行了UnsetSigChldHandler的操作。 + +分别看一下SetSigChldHandler和UnsetSigChldHandler所作工作! + +#### SetSigChldHandler + +我们看看SetSigChldHandler进行了哪些操作。 + +```cpp +// Configures the SIGCHLD handler for the zygote process. This is configured +// very late, because earlier in the runtime we may fork() and exec() +// other processes, and we want to waitpid() for those rather than +// have them be harvested immediately. +// +// This ends up being called repeatedly before each fork(), but there's +// no real harm in that. +static void SetSigChldHandler() { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SigChldHandler; + + // 该信号监听器关注子进程结束,对应的处理函数为SigChldHandler + int err = sigaction(SIGCHLD, &sa, NULL); + if (err < 0) { + ALOGW("Error setting SIGCHLD handler: %s", strerror(errno)); + } +} +``` + +从上面的代码可以看出,SetSigChldHandler函数将注册一个信号处理器,来监听子进程的死亡。当子进程死亡后,利用SigChldHandler进行操作。需要注意的是,zygote的信号监听器,关注的是zygote所有的子进程,而不只是SystemServer进程(每次创建一个新的进程时,zygote都会注册对应的监听器)。 + +那就继续分析一下SigChldHandler吧: + +```cpp +static void SigChldHandler(int /*signal_number*/) { + pid_t pid; + int status; + ... ... + + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { + // 通过status判断子进程结束的原因,并打印相应的log + ... ... + + // If the just-crashed process is the system_server, bring down zygote + // so that it is restarted by init and system server will be restarted + // from there. + if (pid == gSystemServerPid) { // 上文已经介绍过,gSystemServerPid中记录了SystemServer的pid + ... ... + + kill(getpid(), SIGKILL); // 如果结束的子进程为SystemServer,Zygote也将结束自己 + } + } + ... ... + +} +``` + +发现没?所有zygote的子进程中,zygote只关心了SystemServer的死活。当其它子进程crash时,zygote只打印了log信息。 + +#### UnsetSigChldHandler + +最后看看UnsetSigChldHandler函数: + +```cpp +// Sets the SIGCHLD handler back to default behavior in zygote children. +static void UnsetSigChldHandler() { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + + int err = sigaction(SIGCHLD, &sa, NULL); + if (err < 0) { + ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno)); + } +} + +``` + +### SystemServer工作流程 + +在分析zygote进程时,我们知道当ZygoteInit.java的startSystemServer函数,通过fork创建出SystemServer进程后,SystemServer进程调用handleSystemServerProcess函数,开始执行自己的工作。 + +#### handleSystemServerProcess + +```cpp + /* For child process */ + if (pid == 0) { + if (hasSecondZygote(abiList)) { + waitForSecondaryZygote(socketName); + } + + zygoteServer.closeServerSocket(); // 关闭从zygote进程那里继承下来server socket + return handleSystemServerProcess(parsedArgs); + } +``` + +接下来,我们来看看handleSystemServerProcess函数的主要内容。 + +```cpp + /** + * Finish remaining work for the newly forked system server process. + */ + private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) { + // 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); + } + + // 加载SystemServer对应的文件 + final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); + if (systemServerClasspath != null) { + performSystemServerDexOpt(systemServerClasspath); + ... ... + + if (parsedArgs.invokeWith != null) { + ... ... + } else { + // 利用systemServerClass对应的路径构建对应的ClassLoader + ClassLoader cl = null; + if (systemServerClasspath != null) { + cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); + + Thread.currentThread().setContextClassLoader(cl); + } + + /* + * Pass the remaining arguments to SystemServer. + */ + // 将剩余参数及classLoader递交给ZygoteInit的zygoteInit函数 + return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); + } + + /* should never reach here */ + } +``` + +从上面的代码可以看出,接下来的流程进入到ZygoteInit的zygoteInit函数。zygoteInit函数将根据classLoader和参数,完成不同进程所需要的初始化工作(SystemServer进程与zygote的其它子进程均将使用zygoteInit函数)。 + +#### zygoteInit + +```cpp + public static final Runnable zygoteInit(int targetSdkVersion, 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, argv, classLoader); + } +``` + +##### commonInit + +commonInit主要进行一些常规初始化。由于自己是做通信的,所以比较关注的是创建UA(user agent): frameworks/base/core/java/com/android/internal/os/RuntimeInit.java + +```cpp + protected static final void commonInit() { + + ... ... + + /* + * Sets the default HTTP User-Agent used by HttpURLConnection. + */ + String userAgent = getDefaultUserAgent(); + System.setProperty("http.agent", userAgent); + + ... ... + } +``` + +User-Agent是Http协议中的一部分,属于头域的组成部分,是一种向访问网站提供你所使用的浏览器类型、操作系统、浏览器内核等信息的标识。通过这个标识,用户所访问的网站可以显示不同的排版,从而为用户提供更好的体验或者进行信息统计。 + +##### nativeZygoteInit + +函数nativeZyoteInit实现在frameworks/base/core/jni/AndroidRuntime.cpp中,主要用于为Binder通信打下基础。 + +```cpp +static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz) +{ + gCurRuntime->onZygoteInit(); +} +``` + +这里需要关注的是,SystemServer进程中的gCurRuntime指的是什么呢? + +实际上在zygote进程启动时,在app_main.cpp的main函数中,创建出了AppRuntime: + +```cpp +int main(int argc, char* const argv[]) +{ + ........ + AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); + ........ +``` + +AppRuntime定义如下: + +```cpp +class AppRuntime : public AndroidRuntime +{ +public: + AppRuntime(char* argBlockStart, const size_t argBlockLength) + : AndroidRuntime(argBlockStart, argBlockLength) + , mClass(NULL) + { + } + ... ... +} +``` + +看看AppRuntime的父类AndroidRuntime: + +```cpp +AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) : + mExitWithoutCleanup(false), + mArgBlockStart(argBlockStart), + mArgBlockLength(argBlockLength) +{ + SkGraphics::Init(); + + // Pre-allocate enough space to hold a fair number of options. + mOptions.setCapacity(20); + + assert(gCurRuntime == NULL); // one per process + gCurRuntime = this; +} +``` + +从代码可以看出,AndroidRuntime初始化时定义了gCurRuntime。gCurRuntime指向对象自身,也就是说gCurRuntime指向的是AppRuntime对象。 + +由于SystemServer进程由zygote进程fork出来,于是system server进程中也存在gCurRuntime对象,类型为AppRuntime。至此我们知道,Native函数中gCurRuntime->onZygoteInit将调用AppRuntime中的onZygoteInit。 + +```cpp + virtual void onZygoteInit() + { + sp proc = ProcessState::self(); + ALOGV("App process: starting thread pool.\n"); + proc->startThreadPool(); + } +``` + +onZygoteInit的用途是启动一个线程,用于binder通信。 + +##### applicationInit + +```cpp + protected static Runnable applicationInit(int targetSdkVersion, String[] argv, + ClassLoader classLoader) { + // 设置一些进程退出的处理策略,可用堆栈上限等 + ... ... + + // Remaining arguments are passed to the start class's static main + return findStaticMain(args.startClass, args.startArgs, classLoader); + } +``` + +继续分析findStaticMain函数: + +```cpp + private static Runnable findStaticMain(String className, String[] argv, + ClassLoader classLoader) { + // className为进行初始化工作的进程类名 + // 在SystemServer初始化时,为com.android.server.SystemServer + Class cl; + + try { + // 下面就是通过反射得到对应类的main方法 + cl = Class.forName(className, true, classLoader); + } catch (ClassNotFoundException ex) { + throw new RuntimeException( + "Missing class when invoking static main " + className, + 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. + */ + return new MethodAndArgsCaller(m, argv); // 捕获MethodAndArgsCaller异常 + } +``` + +### main函数 + +接下来就进入了SystemServer.java的main函数,其代码如下: + +```cpp + /** + * The main entry point from zygote. + */ + public static void main(String[] args) { + new SystemServer().run(); // 创建并运行,简单粗暴! + } +``` + +这里比较简单,只是new出一个SystemServer对象并执行其run方法: + +```cpp + private void run() { + try { + traceBeginAndSlog("InitBeforeStartServices"); + // If a device's clock is before 1970 (before 0), a lot of + // APIs crash dealing with negative numbers, notably + // java.io.File#setLastModified, so instead we fake it and + // hope that time from cell towers or NTP fixes it shortly. + // 如何系统时钟早于1970年,则设置系统始终从1970年开始 + if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { + Slog.w(TAG, "System clock is before 1970; setting to 1970."); + // private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000; + SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); + } + + ... ... + + // 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", ""); + } + + // Mmmmmm... more memory! + // 清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间 + VMRuntime.getRuntime().clearGrowthLimit(); + + // The system server has to run all of the time, so it needs to be + // as efficient as possible with its memory usage. + // 设置堆栈利用率,GC后会重新计算堆栈空间大小 + VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); + + // 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); + + ... ... + + // Initialize native services. + // 加载动态库libandroid_services.so + System.loadLibrary("android_servers"); + + // Check whether we failed to shut down last time we tried. + // This call may not return. + // 检测上次关机过程是否失败,该方法可能不会返回 + performPendingShutdown(); + + // Initialize the system context. + // 在SystemServer进程中也需要创建Context对象,初始化系统上下文 + createSystemContext(); + + // Create the system service manager. + // 通过SystemServiceManager的构造方法创建了一个新的SystemServiceManager对象 + mSystemServiceManager = new SystemServiceManager(mSystemContext); + + // SystemServer进程主要是用来构建系统各种service服务,而SystemServiceManager就是这些服务的管理对象 + mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); + + // 将SystemServiceManager对象保存到SystemServer进程中的一个数据结构中 + LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); + + // Prepare the thread pool for init tasks that can be parallelized + SystemServerInitThreadPool.get(); + } finally { + traceEnd(); // InitBeforeStartServices + } + + // Start services. + try { // 分种类启动不同的system service + // 主要用于启动系统Boot级服务 + startBootstrapServices(); + + // 主要用于启动系统核心的服务 + startCoreServices(); + + // 主要用于启动一些非紧要或者非需要及时启动的服务 + startOtherServices(); + + SystemServerInitThreadPool.shutdown(); + } catch (Throwable ex) { + Slog.e("System", "******************************************"); + Slog.e("System", "************ Failure starting system services", ex); + throw ex; + } finally { + traceEnd(); + } + + ... ... + + // Loop forever. + // //启动looper,以处理到来的消息,一直循环执行 + Looper.loop(); + throw new RuntimeException("Main thread loop unexpectedly exited"); + } +``` + + 以上就是SystemServer的run函数整个流程,我们做个简化,如下: + +```cpp + private void run() { + try { + // Initialize the system context. + createSystemContext(); // 🍁🍁🍁 01.初始化系统上下文 🍁🍁🍁 + + // Create the system service manager. + mSystemServiceManager = new SystemServiceManager(mSystemContext); // 🍁🍁🍁 02.创建系统服务管理 🍁🍁🍁 + mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); + LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); + } finally { + traceEnd(); // InitBeforeStartServices + } + + // Start services. // 🍁🍁🍁 03.启动系统各种服务 🍁🍁🍁 + try { + startBootstrapServices(); // 启动引导服务 + startCoreServices(); // 启动核心服务 + startOtherServices(); // 启动其他服务 + SystemServerInitThreadPool.shutdown(); + } catch (Throwable ex) { + Slog.e("System", "******************************************"); + Slog.e("System", "************ Failure starting system services", ex); + throw ex; + } finally { + traceEnd(); + } + + ... ... + + // Loop forever. + Looper.loop(); // 一直循环执行 + throw new RuntimeException("Main thread loop unexpectedly exited"); + } +``` + + OK,接下来我们针对SystemServer所做的三部分工作,进行逐个分析! + +* * * + +### 初始化上下文 + +```cpp + private void run() { + try { + // Initialize the system context. + createSystemContext(); // 🍁🍁🍁 01.初始化系统上下文 🍁🍁🍁 +``` + + 跟踪createSystemContext函数: + +```cpp + private void createSystemContext() { + ActivityThread activityThread = ActivityThread.systemMain(); + mSystemContext = activityThread.getSystemContext(); + mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); + + final Context systemUiContext = activityThread.getSystemUiContext(); + systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); + } +``` + + 跟踪systemMain函数: + +```cpp + public static ActivityThread systemMain() { + // The system process on low-memory devices do not get to use hardware + // accelerated drawing, since this can add too much overhead to the + // process. + if (!ActivityManager.isHighEndGfx()) { + ThreadedRenderer.disable(true); // 对于低内存的设备,禁用硬件加速 + } else { + ThreadedRenderer.enableForegroundTrimming(); + } + ActivityThread thread = new ActivityThread(); + thread.attach(true); + return thread; + } + + ActivityThread() { + mResourcesManager = ResourcesManager.getInstance(); // 使用单例模式获得一个ResourcesManager实例 + } +``` + + 继续跟踪attach函数: + +```cpp + private void attach(boolean system) { + sCurrentActivityThread = this; + mSystemThread = system; + 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. + // 设置SystemServer进程在DDMS中显示的名字为"system_process" + android.ddm.DdmHandleAppName.setAppName("system_process", + UserHandle.myUserId()); // 如不设置,则显示"?",无法调试该进程 + try { + mInstrumentation = new Instrumentation(); + // 首先通过getSystemContext()创建系统上下文,然后创建应用上下文 + ContextImpl context = ContextImpl.createAppContext( + this, getSystemContext().mPackageInfo); + // 创建Application + mInitialApplication = context.mPackageInfo.makeApplication(true, null); + // 调用Application的onCreate() + mInitialApplication.onCreate(); + } catch (Exception e) { + throw new RuntimeException( + "Unable to instantiate Application():" + e.toString(), e); + } + } + + // add dropbox logging to libcore + DropBox.setReporter(new DropBoxReporter()); + + ViewRootImpl.ConfigChangedCallback configChangedCallback + = (Configuration globalConfig) -> { + synchronized (mResourcesManager) { + // We need to apply this change to the resources immediately, because upon returning + // the view hierarchy will be informed about it. + if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig, + null /* compat */)) { + updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), + mResourcesManager.getConfiguration().getLocales()); + + // This actually changed the resources! Tell everyone about it. + if (mPendingConfiguration == null + || mPendingConfiguration.isOtherSeqNewer(globalConfig)) { + mPendingConfiguration = globalConfig; + sendMessage(H.CONFIGURATION_CHANGED, globalConfig); + } + } + } + }; + // 添加回调 + ViewRootImpl.addConfigCallback(configChangedCallback); + } +``` + +可以看出,attach主要做了三件事: + (1)创建系统上下文:getSystemContext() --> createSystemContext() --> new ContextImpl() + (2)创建应用上下文 ContextImpl.createAppContext() --> new ContextImpl() + (3)添加回调configChangedCallback到ViewRootImpl + +* * * + +#### 创建系统上下文 + +getSystemContext(): + +```cpp + public ContextImpl getSystemContext() { + synchronized (this) { + if (mSystemContext == null) { + mSystemContext = ContextImpl.createSystemContext(this); + } + return mSystemContext; + } + } +``` + +跟踪createSystemContext函数: + +```cpp + static ContextImpl createSystemContext(ActivityThread mainThread) { + // 这边new出来的LoadedApk将作为创建应用上下文的参数packageInfo + LoadedApk packageInfo = new LoadedApk(mainThread); + // ContextImpl()创建系统上下文 + ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, + null); + context.setResources(packageInfo.getResources()); + context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), + context.mResourcesManager.getDisplayMetrics()); + return context; + } +``` + +#### 创建应用上下文 + +ContextImpl.createAppContext(): + +```cpp + static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { + if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); + // ContextImpl()创建应用上下文 + ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, + null); + context.setResources(packageInfo.getResources()); + return context; + } +``` + +我们可以看出:new ContextImpl时,系统上下文和应用上下文的参数是一样的,createAppContext()中的参数packageInfo,就是createSystemContext()中new的LoadedApk。 +创建完成之后,系统上下文赋值给了ActivityThread的成员变量mSystemContext,而应用上下文只是作为函数中的局部变量临时使用。 +我们回顾一下创建上下文的代码: + +```cpp + try { + mInstrumentation = new Instrumentation(); + // 首先通过getSystemContext()创建系统上下文,然后创建应用上下文 + ContextImpl context = ContextImpl.createAppContext( + this, getSystemContext().mPackageInfo); + // 创建Application + mInitialApplication = context.mPackageInfo.makeApplication(true, null); + // 调用Application的onCreate() + mInitialApplication.onCreate(); +``` + +接下来就继续看下创建Application的流程: + +#### 创建Application + +```cpp + public Application makeApplication(boolean forceDefaultAppClass, + Instrumentation instrumentation) { + if (mApplication != null) { + return mApplication; + } + + Application app = null; + + String appClass = mApplicationInfo.className; + // 参数forceDefaultAppClass为true + if (forceDefaultAppClass || (appClass == null)) { + appClass = "android.app.Application"; + } + + try { + java.lang.ClassLoader cl = getClassLoader(); + // 此LoadedApk对象是createSystemContext时new的,mPackageName="android" + if (!mPackageName.equals("android")) { + initializeJavaContextClassLoader(); + } + // 又创建了一个局部应用上下文 + ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); + // 创建Application + app = mActivityThread.mInstrumentation.newApplication( + cl, appClass, appContext); + appContext.setOuterContext(app); + } catch (Exception e) { + ... ... + } + + // 将前面创建的app添加到应用列表 + mActivityThread.mAllApplications.add(app); + mApplication = app; + + ... ... + + return app; + } +``` + +这一步主要创建了一个ActivityThread对象,然后执行了该对象的attach()方法,attach()方法中创建了系统上下文mSystemContext(类型为ContextImpl),并创建Application对象。 +系统上下文中,new了一个LoadedApk的成员变量,并将ActivityThread对象传给LoadedApk成员,后面的Application对象就是LoadedApk使用ActivityThread创建的,LoadedApk创建了Application对象后,将Application添加到ActivityThread的应用列表中。 + +### 创建系统服务管理 + +我们回顾下相关代码: + +```cpp + // Create the system service manager. + mSystemServiceManager = new SystemServiceManager(mSystemContext); + mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart); + LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); +``` + +这一步比较简单,只是new了一个SystemServiceManager,并将其添加到本地服务列表中。mSystemContext为第一步中创建的系统上下文。本地服务列表是以类为key保存的一个列表,即列表中某种类型的对象最多只能有一个。 + +```cpp +public class SystemServiceManager { + ... ... + + // Services that should receive lifecycle events. + // 系统服务列表,系统服务必须继承SystemService + private final ArrayList mServices = new ArrayList(); + + // 当前处于开机过程的哪个阶段,SystemService.PHASE_XXXXX + private int mCurrentPhase = -1; + + SystemServiceManager(Context context) { + mContext = context; + } + + /** + * Starts a service by class name. + * + * @return The service instance. + */ + @SuppressWarnings("unchecked") + // 通过类名启动系统服务,可能会找不到类而抛异常 + public SystemService startService(String className) { + final Class serviceClass; + try { + serviceClass = (Class)Class.forName(className); + } catch (ClassNotFoundException ex) { + Slog.i(TAG, "Starting " + className); + throw new RuntimeException("Failed to create service " + className + + ": service class not found, usually indicates that the caller should " + + "have called PackageManager.hasSystemFeature() to check whether the " + + "feature is available on this device before trying to start the " + + "services that implement it", ex); + } + return startService(serviceClass); + } + + /** + * Creates and starts a system service. The class must be a subclass of + * {@link com.android.server.SystemService}. + * + * @param serviceClass A Java class that implements the SystemService interface. + * @return The service instance, never null. + * @throws RuntimeException if the service fails to start. + */ + @SuppressWarnings("unchecked") + // 创建并启动系统服务,系统服务类必须继承SystemService + public T startService(Class 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 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) { + // Register it. + mServices.add(service); + // Start it. + long time = SystemClock.elapsedRealtime(); + try { + 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"); + } + + /** + * Starts the specified boot phase for all system services that have been started up to + * this point. + * + * @param phase The boot phase to start. + */ + // 通知系统服务到了开机的哪个阶段,会遍历调用所有系统服务的onBootPhase()函数 + public void startBootPhase(final int phase) { + if (phase <= mCurrentPhase) { + throw new IllegalArgumentException("Next phase must be larger than previous"); + } + mCurrentPhase = phase; + + Slog.i(TAG, "Starting phase " + mCurrentPhase); + try { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase); + final int serviceLen = mServices.size(); + for (int i = 0; i < serviceLen; i++) { + final SystemService service = mServices.get(i); + long time = SystemClock.elapsedRealtime(); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName()); + try { + service.onBootPhase(mCurrentPhase); + } catch (Exception ex) { + throw new RuntimeException("Failed to boot service " + + service.getClass().getName() + + ": onBootPhase threw an exception during phase " + + mCurrentPhase, ex); + } + warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase"); + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + } + } +``` + +### 启动系统各种服务 + +```cpp + try { + startBootstrapServices(); // 启动引导服务 + startCoreServices(); // 启动核心服务 + startOtherServices(); // 启动其他服务 +``` + +#### 启动引导服务 + +首先来看下startBootstrapServices(): + +```cpp + private void startBootstrapServices() { + ... ... + + // 启动Installer服务,阻塞等待与installd建立socket通道 + Installer installer = mSystemServiceManager.startService(Installer.class); + + mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class); + + // 启动ActivityManagerService(AMS),关于AMS我们后面会详细讲解 + mActivityManagerService = mSystemServiceManager.startService( + ActivityManagerService.Lifecycle.class).getService(); + mActivityManagerService.setSystemServiceManager(mSystemServiceManager); + mActivityManagerService.setInstaller(installer); + + // 启动PowerManagerService + mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); + + // PowerManagerService就绪,AMS初始化电源管理 + mActivityManagerService.initPowerManagement(); + + // Bring up recovery system in case a rescue party needs a reboot + if (!SystemProperties.getBoolean("config.disable_noncore", false)) { + traceBeginAndSlog("StartRecoverySystemService"); + mSystemServiceManager.startService(RecoverySystemService.class); + traceEnd(); + } + + RescueParty.noteBoot(mSystemContext); + + // 启动LightsService + mSystemServiceManager.startService(LightsService.class); + + // 启动DisplayManagerService(before package manager) + mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); + + // 初始化package manager之前,需要默认显示。阻塞,10s超时,see DisplayManagerService.onBootPhase() + mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); + + // Only run "core" apps if we're encrypting the device. + // 当设备正在加密时,仅运行核心应用 + 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 the package manager. + if (!mRuntimeRestart) { + MetricsLogger.histogram(null, "boot_package_manager_init_start", + (int) SystemClock.elapsedRealtime()); + } + + // 启动PackageManagerService + mPackageManagerService = PackageManagerService.main(mSystemContext, installer, + mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); + mFirstBoot = mPackageManagerService.isFirstBoot(); + mPackageManager = mSystemContext.getPackageManager(); + + ... ... + + // 将UserManagerService添加到服务列表,该服务是在PackageManagerService中初始化的 + mSystemServiceManager.startService(UserManagerService.LifeCycle.class); + + // Initialize attribute cache used to cache resources from packages. + // 初始化用来缓存包资源的属性缓存 + AttributeCache.init(mSystemContext); + + // 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. + // Start sensor service in a separate thread. Completion should be checked + // before using it. + mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> { + TimingsTraceLog traceLog = new TimingsTraceLog( + SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); + traceLog.traceBegin(START_SENSOR_SERVICE); + // 启动传感器服务(native 服务,依赖PackageManagerService、AppOpsService、permissions service) + startSensorService(); + traceLog.traceEnd(); + }, START_SENSOR_SERVICE); + } +``` + +这步首先等待installd启动完成,然后启动一些相互依赖的关键服务。所创建的服务:ActivityManagerService,PowerManagerService,LightsService,DisplayManagerService,PackageManagerService,UserManagerService,sensor服务。 + +#### 启动核心服务 + +接下来继续看下核心服务: + +```cpp + /** + * Starts some essential services that are not tangled up in the bootstrap process. + */ + private void startCoreServices() { + mSystemServiceManager.startService(DropBoxManagerService.class); + + // 启动BatteryService,用于统计电池电量,需要LightService + mSystemServiceManager.startService(BatteryService.class); + + // 启动UsageStatsService,用于统计应用使用情况 + mSystemServiceManager.startService(UsageStatsService.class); + mActivityManagerService.setUsageStatsManager( + LocalServices.getService(UsageStatsManagerInternal.class)); + + // 启动WebViewUpdateService + mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class); + } +``` + +启动服务DropBoxManagerService、BatteryService,UsageStatsService,WebViewUpdateService。 + +#### 启动其他服务 + +代码很长(1200多行...),但是逻辑简单,主要是启动各种服务。 + +```cpp + /** + * Starts a miscellaneous grab bag of stuff that has yet to be refactored + * and organized. + */ + private void startOtherServices() { + ... ... + + try { + + ... ... + traceBeginAndSlog("StartSchedulingPolicyService"); // 调度策略 + ServiceManager.addService("scheduling_policy", new SchedulingPolicyService()); + traceEnd(); + + traceBeginAndSlog("StartTelecomLoaderService"); + mSystemServiceManager.startService(TelecomLoaderService.class); + traceEnd(); + + traceBeginAndSlog("StartTelephonyRegistry"); // 提供电话注册、管理服务,可以获取电话的链接状态、信号强度等 + telephonyRegistry = new TelephonyRegistry(context); + ServiceManager.addService("telephony.registry", telephonyRegistry); + traceEnd(); + + traceBeginAndSlog("StartEntropyMixer"); // 随机数相关,原名EntropyService + mEntropyMixer = new EntropyMixer(context); + traceEnd(); + + mContentResolver = context.getContentResolver(); + + // The AccountManager must come before the ContentService + traceBeginAndSlog("StartAccountManagerService"); // 提供所有账号、密码、认证管理等等的服务 + mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS); + traceEnd(); + + traceBeginAndSlog("StartContentService"); // ContentProvider服务,提供跨进程数据交换 + mSystemServiceManager.startService(CONTENT_SERVICE_CLASS); + traceEnd(); + + traceBeginAndSlog("InstallSystemProviders"); + mActivityManagerService.installSystemProviders(); + traceEnd(); + + traceBeginAndSlog("StartVibratorService"); // 振动器服务 + vibrator = new VibratorService(context); + ServiceManager.addService("vibrator", vibrator); + traceEnd(); + + ... ... + + traceBeginAndSlog("InitWatchdog"); // 初始化 Watchdog + final Watchdog watchdog = Watchdog.getInstance(); + watchdog.init(context, mActivityManagerService); + traceEnd(); + + traceBeginAndSlog("StartInputManagerService"); // 事件传递分发服务 + inputManager = new InputManagerService(context); + traceEnd(); + + traceBeginAndSlog("StartWindowManagerService"); // 窗口管理服务 + // WMS needs sensor service ready + ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE); + mSensorServiceStart = null; + wm = WindowManagerService.main(context, inputManager, + mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, + !mFirstBoot, mOnlyCore, new PhoneWindowManager()); + ServiceManager.addService(Context.WINDOW_SERVICE, wm); + ServiceManager.addService(Context.INPUT_SERVICE, inputManager); + traceEnd(); + ... ... + } + + ... ... + + LockSettingsService // 屏幕锁定服务,管理每个用户的相关锁屏信息 + DeviceIdleController // Doze模式的主要驱动,参考“深入Android 'M' Doze” + DevicePolicyManagerService // 提供一些系统级别的设置及属性 + StatusBarManagerService // 状态栏管理服务 + ClipboardService // 系统剪切板服务 + NetworkManagementService // 网络管理服务 + TextServicesManagerService // 文本服务,例如文本检查等 + NetworkScoreService // 网络评分服务 + NetworkStatsService // 网络状态服务 + NetworkPolicyManagerService // 网络策略服务 + WifiP2pService // Wifi Direct服务 + WifiService // Wifi服务 + WifiScanningService // Wifi扫描服务 + RttService // Wifi相关 + EthernetService // 以太网服务 + ConnectivityService // 网络连接管理服务 + NsdService // 网络发现服务 + ... ... + + NotificationManagerService // 通知栏管理服务 + DeviceStorageMonitorService // 磁盘空间状态检测服务 + LocationManagerService // 位置服务,GPS、定位等 + CountryDetectorService // 检测用户国家 + SearchManagerService // 搜索管理服务 + DropBoxManagerService // 用于系统运行时日志的存储于管理 + WallpaperManagerService // 壁纸管理服务 + AudioService // AudioFlinger的上层管理封装,主要是音量、音效、声道及铃声等的管理 + DockObserver // 如果系统有个座子,当手机装上或拔出这个座子的话,就得靠他来管理了 + WiredAccessoryManager // 监视手机和底座上的耳机 + UsbService // USB服务 + SerialService // 串口服务 + TwilightService // 指出用户当前所在位置是否为晚上,被UiModeManager等用来调整夜间模式。 + BackupManagerService // 备份服务 + AppWidgetService // 提供Widget的管理和相关服务 + VoiceInteractionManagerService // 语音交互管理服务 + DiskStatsService // 磁盘统计服务,供dumpsys使用 + SamplingProfilerService // 用于耗时统计等 + NetworkTimeUpdateService // 监视网络时间,当网络时间变化时更新本地时间。 + CommonTimeManagementService // 管理本地常见的时间服务的配置,在网络配置变化时重新配置本地服务。 + CertBlacklister // 提供一种机制更新SSL certificate blacklist + DreamManagerService // 屏幕保护 + AssetAtlasService // 负责将预加载的bitmap组装成纹理贴图,生成的纹理贴图可以被用来跨进程使用,以减少内存。 + PrintManagerService // 打印服务 + HdmiControlService // HDMI控制服务 + FingerprintService // 指纹服务 + ... ... + } +``` + +以上代码仅按顺序列出启动的服务,有些服务根据条件,如是否是工厂模式,或系统属性配置,选择性启动,这里不考虑条件判断和异常处理。 + +自此,SystemServer相关源码分析完毕。 + +## 参考Blog + +1. [https://blog.csdn.net/kingodc...](https://blog.csdn.net/kingodcool/article/details/52171331) +2. [https://blog.csdn.net/qq_2354...](https://blog.csdn.net/qq_23547831/article/details/51105171) +3. [https://blog.csdn.net/gaugame...](https://blog.csdn.net/gaugamela/article/details/52261075)