從源碼角度看Android系統SystemServer進程啓動過程

SystemServer進程是由Zygote進程fork生成,進程名爲system_server,主要用於創建系統服務。

備註:本文將結合Android8.0的源碼看SystemServer進程的啓動過程以及SystemServer進程做了哪些重要工作。

1. SystemServer進程啓動的起點

《從源碼角度看Android系統Zygote進程啓動過程》一文中可知:Zygote進程啓動過程中會調用startSystemServer方法,而startSystemServer函數是system_server進程啓動流程的起點。

代碼路徑:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

深入到startSystemServer函數中:

private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
        throws Zygote.MethodAndArgsCaller, RuntimeException {

    ...省略...

	//參數準備,args數組中保存啓動SystemServer的啓動參數
    String args[] = { //註釋1
        "--setuid=1000",
        "--setgid=1000",
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
        "--capabilities=" + capabilities + "," + capabilities,
        "--nice-name=system_server",
        "--runtime-args",
        "com.android.server.SystemServer",
    };
    ZygoteConnection.Arguments parsedArgs = null;
    int pid;
    try {
		//用於解析參數,生成目標格式
        parsedArgs = new ZygoteConnection.Arguments(args); //註釋2
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

        //fork子進程,也是創建SystemServer進程
        pid = Zygote.forkSystemServer( //註釋3
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.debugFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    //運行在子進程中
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
		//關閉zygote原有的socket
        zygoteServer.closeServerSocket();
		//處理SystemServer進程
        handleSystemServerProcess(parsedArgs); //註釋4
    }
    return true;
}

註釋解析:

  • 註釋1創建args數組,主要用來保存啓動SystemServer的啓動參數。

其中:

可以看出SystemServer進程的的用戶id和用戶組id都被設置爲了1000,並且擁有用戶組1001-1010、1018、1021、1032、3001-3010的權限。

進程名爲:system_server

啓動的類名爲:com.android.server.SystemServer

  • 註釋2處將args數組封裝成Arguments對象,並給註釋3處的forkSystemServer函數調用

  • 註釋3處調用Zygote的forkSystemServer方法,其內部會調用nativeForkSystemServer這個Native方法,nativeForkSystemServer會通過fork函數在當前進程創建一個子進程,即SystemServer進程。

  • 註釋4處理SystemServer進程

2. 創建SystemServer進程

2.1 forkSystemServer

通過上面的註釋3可知:是調用Zygote的forkSystemServer方法去創建SystemServer進程。

代碼路徑:frameworks/base/core/java/com/android/internal/os/Zygote.java

深入到函數forkSystemServer中:

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();
	//調用natvie方法fork system_server進程
    int pid = nativeForkSystemServer(
            uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
    if (pid == 0) {
        Trace.setTracingEnabled(true);
    }
    VM_HOOKS.postForkCommon();
    return pid;
}

備註:這裏繼續往下看,需要懂一點JNI原理,這裏不做介紹,後續會單獨寫一篇《JNI學習總結》。

nativeForkSystemServer()方法是在AndroidRuntime.cpp中註冊的,通過com_android_internal_os_Zygote.cpp中的register_com_android_internal_os_Zygote()方法建立native方法的映射關係的。

2.2 nativeForkSystemServer

進入到com_android_internal_os_Zygote.cpp中:

代碼路徑:frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

nativeForkSystemServer方法在JNI層對應的方法是:com_android_internal_os_Zygote_nativeForkSystemServer

深入到函數com_android_internal_os_Zygote_nativeForkSystemServer中:

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) {
  //fork 子進程
  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) {
      // zygote進程檢測system_server進程是否創建
      gSystemServerPid = pid;
      int status;
      if (waitpid(pid, &status, WNOHANG) == pid) {
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
		  // 當system_server進程死亡後,重啓zygote進程
          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
      }
  }
  return pid;
}

從上面可知:

1: 調用ForkAndSpecializeCommon()方法fork子進程

2: 當system_server進程死亡後,會重啓zygote進程

擴展知識:

在Android5.0以上時,會有兩個zygote進程,分別是zygote和zygote64。一般在64位系統中system_server的父進程是zygote64。

在64位系統中,kill system_server、zygote、zygote64三個進程是否重啓的關係圖如下:

繼續深入到ForkAndSpecializeCommon()方法中。

2.3 ForkAndSpecializeCommon

代碼路徑:frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

深入到ForkAndSpecializeCommon方法中:

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) {

  //設置子進程的signal信號處理
  SetSigChldHandler();

  ...省略...
  //fork 子進程
  pid_t pid = fork();
  // 進入子進程
  if (pid == 0) {
    
	...省略...

    //關閉並清除文件描述符
    DetachDescriptors(env, fdsToClose);

    ...省略...

    if (!is_system_server) {//如果是非system_server子進程,則創建進程組
        int rc = createProcessGroup(uid, getpid());
        if (rc != 0) {
            if (rc == -EROFS) {
                ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
            } else {
                ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));
            }
        }
    }
	//設置group
    SetGids(env, javaGids);
	//設置資源limit
    SetRLimits(env, javaRlimits);

    ...省略...
    //selinux上下文
    rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);
    if (rc == -1) {
      ALOGE("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,
            is_system_server, se_info_c_str, se_name_c_str);
      RuntimeAbort(env, __LINE__, "selinux_android_setcontext failed");
    }
    if (se_info_c_str == NULL && is_system_server) {
      se_name_c_str = "system_server";
    }
    if (se_info_c_str != NULL) {
	  //設置線程名爲system_server
      SetThreadName(se_name_c_str);
    }

    delete se_info;
    delete se_name;
	//設置子進程的signal信號處理函數爲默認函數
    UnsetSigChldHandler();
	//等價於調用zygote.callPostForkChildHooks()
    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
                              is_system_server, instructionSet);
    if (env->ExceptionCheck()) {
      RuntimeAbort(env, __LINE__, "Error calling post fork hooks.");
    }
  } else if (pid > 0) {
    //進入父進程(zygote進程)
    if (sigprocmask(SIG_UNBLOCK, &sigchld, nullptr) == -1) {
      ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno));
      RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_UNBLOCK, { SIGCHLD }) failed.");
    }
  }
  return pid;
}
}

到這裏system_server進程就已經創建成功了。接下來就是system_server進程開始真正工作了。

從前面的startSystemServer()方法中可知:zygote進程在執行forkSystemServer()方法後,即system_server進程創建後,就調用handleSystemServerProcess()方法處理system_server進程真正的工作。

3. SystemServer進程啓動後的準備工作

3.1 handleSystemServerProcess

代碼路徑:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

深入到handleSystemServerProcess函數中:

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

    //設置當前進程名爲"system_server"
    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
		//執行dex優化操作
        performSystemServerDexOpt(systemServerClasspath); //註釋1
        
		...省略...
    }

    if (parsedArgs.invokeWith != null) {
        String[] args = parsedArgs.remainingArgs;
        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.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                VMRuntime.getCurrentInstructionSet(), null, args);
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion); //註釋2
            Thread.currentThread().setContextClassLoader(cl);
        }
        ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); //註釋3
    }

    /* should never reach here */
}

註釋解析:

  • 註釋1處執行dex優化操作

  • 註釋2處創建類加載器,並賦予給當前線程

  • 註釋3處調用 ZygoteInit的zygoteInit的方法

3.2 performSystemServerDexOpt

深入跟蹤執行dex優化操作的邏輯。

代碼路徑:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

深入到performSystemServerDexOpt函數中:

private static void performSystemServerDexOpt(String classPath) {
    final String[] classPathElements = classPath.split(":");
	//通過AIDL與installd建立連接
    final IInstalld installd = IInstalld.Stub
            .asInterface(ServiceManager.getService("installd"));
    final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();

    String sharedLibraries = "";
    for (String classPathElement : classPathElements) {
        
		...省略...

        if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {

            ...省略...

            try {
				//執行dex文件
                installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
                        instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
                        uuid, sharedLibraries, seInfo);
            } catch (RemoteException | ServiceSpecificException e) {
                Log.w(TAG, "Failed compiling classpath element for system server: "
                        + classPathElement, e);
            }
        }

        if (!sharedLibraries.isEmpty()) {
            sharedLibraries += ":";
        }
        sharedLibraries += classPathElement;
    }
}

上面主要的操作就是將classPath字符串中的apk分別進行dex優化。而真正執行優化的工作是通過AIDL通信將命令參數傳給installd來完成。

3.3 zygoteInit

深入跟蹤上面3.1中註釋3處的zygoteInit方法

代碼路徑:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

深入到zygoteInit函數中:

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

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
	//重定向log輸出
    RuntimeInit.redirectLogStreams();
	//初始化通用信息
    RuntimeInit.commonInit();
	//zygote初始化
    ZygoteInit.nativeZygoteInit(); //註釋1
	//進入SystemServer的main方法
    RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); //註釋2
}

註釋解析:

  • 註釋1處調用Native層的代碼,主要用來啓動Binder線程池,從而SystemServer進程就可以使用Binder與其它進程進行通信。

  • 註釋2處是用於進入SystemServer的main方法

下面繼續跟蹤註釋1和註釋2的源碼。

3.4 nativeZygoteInit

nativeZygoteInit是一個Native方法,在AndroidRuntime.cpp中,進行了jni映射。

代碼路徑:frameworks/base/core/jni/AndroidRuntime.cpp

int register_com_android_internal_os_ZygoteInit(JNIEnv* env)
{
    const JNINativeMethod methods[] = {
        { "nativeZygoteInit", "()V",
            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
        methods, NELEM(methods));
}

從上面可知:nativeZygoteInit()方法對應的是JNI文件AndroidRuntime.cpp中的com_android_internal_os_ZygoteInit_nativeZygoteInit函數:

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

其中:gCurRuntime是AndroidRuntime類型的指針,具體指向的是AndroidRuntime的子類AppRuntime,而AppRuntime又是定義在app_main.cpp中的內部類。

故深入到app_main.cpp的內部類AppRuntime的onZygoteInit方法:

virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool(); //註釋1
}

註釋解析:

  • 註釋1處啓動了一個Binder線程池,這樣SystemServer進程就可以使用Binder與其它進程進行通信了。
3.5 applicationInit

代碼路徑:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

深入到applicationInit函數中:

protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws Zygote.MethodAndArgsCaller {

    //true代表應用程序退出時不調用AppRuntime.onExit(),否則會在退出前調用
    nativeSetExitWithoutCleanup(true);

    //設置虛擬機的內存利用率參數值爲0.75
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

    final Arguments args;
    try {
		//解析參數
        args = new Arguments(argv);
    } catch (IllegalArgumentException ex) {
        Slog.e(TAG, ex.getMessage());
        return;
    }

    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    //繼續調用invokeStaticMain方法
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

繼續深入到invokeStaticMain方法中。

3.6 invokeStaticMain

代碼路徑:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

深入到invokeStaticMain函數中:

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

    try {
		//通過反射得到SystemServer類
        cl = Class.forName(className, true, classLoader); //註釋1
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }

    Method m;
    try {
		//找到SystemServer的main方法
        m = cl.getMethod("main", new Class[] { String[].class }); //註釋2
    } 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();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }
	//通過拋出異常,回到ZygoteInit.main()。這樣做好處是能清空棧幀,提高棧幀利用率
    throw new Zygote.MethodAndArgsCaller(m, argv); //註釋3
}

註釋解析:

  • 註釋1處的className爲com.android.server.SystemServer,通過反射機制可以得到SystemServer類

  • 註釋2處找到SystemServer中的main方法

  • 註釋3處將找到的main方法傳入到MethodAndArgsCaller異常中並拋出該異常,而捕獲MethodAndArgsCaller異常的代碼在ZygoteInit.java的main方法中,而這個方法又會調用SystemServer的main方法。

疑問:爲什麼不在invokeStaticMain中直接調用SystemServer的main方法呢?

因爲:

  1. 這種拋出異常的處理會清除所有的設置過程需要的堆棧幀,提高了棧幀利用率。

  2. 讓SystemServer的main方法看起來像是SystemServer進程的入口方法。

備註:其實在Zygote啓動了SystemServer進程後,在調用SystemServer的main方法之前,已經做了很多準備工作,從而使得SystemServer的main方法不像是SystemServer進程的入口方法,而通過拋出異常交由ZygoteInit.java的main方法來處理,會讓SystemServer的main方法看起來像是SystemServer進程的入口方法。

下面繼續看ZygoteInit.java的main方法是如何捕獲MethodAndArgsCaller異常:

3.7 ZygoteInit.java中捕獲MethodAndArgsCaller異常

代碼路徑:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

深入到捕獲MethodAndArgsCaller異常的地方:

public static void main(String argv[]) {
    
	...省略...

        zygoteServer.closeServerSocket();
    } catch (Zygote.MethodAndArgsCaller caller) { // 捕獲MethodAndArgsCaller異常
        caller.run();
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        zygoteServer.closeServerSocket();
        throw ex;
    }
}

從捕獲MethodAndArgsCaller異常的地方可知,當捕獲到MethodAndArgsCaller異常時,會調用Zygote.java中的靜態內部類MethodAndArgsCaller

3.8 Zygote.java中的靜態內部類MethodAndArgsCaller

代碼路徑:frameworks/base/core/java/com/android/internal/os/Zygote.java

深入到靜態內部類MethodAndArgsCaller中:

public static class MethodAndArgsCaller extends Exception
        implements Runnable {
    private final Method mMethod;

    private final String[] mArgs;

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

    public void run() {
        try {
			//根據傳遞過來的參數,可知此處通過反射機制調用的是SystemServer.main()方法
            mMethod.invoke(null, new Object[] { mArgs }); //註釋1
        } 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);
        }
    }
}

註釋解析:

  • 註釋1處的mMethod指的就是SystemServer的main方法。

到此爲止SystemServer的main方法就調用了,下面正式進入到SystemServer的main方法中。

3.9 SystemServer進程時序圖和函數調用流程圖

結合上面的源碼跟蹤分析,下面給出Zygote進程處理SystemServer進程時序圖和啓動流程圖。

時序圖:

啓動流程圖:

4. SystemServer進程啓動後的核心工作

下面進入到SystemServer的main方法。

代碼路徑:frameworks/base/services/java/com/android/server/SystemServer.java

深入到main方法中:

public static void main(String[] args) {
	//初始SystemServer對象,再調用run方法
    new SystemServer().run();
}

可以看到main方法中只調用了SystemServer的run方法。

run方法如下:

private void run() {
    try {
        traceBeginAndSlog("InitBeforeStartServices");
        //當系統時間比1970年更早,就設置當前系統時間爲1970年
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }


        //如果沒有設置時區屬性,則默認爲GMT
        String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
        if (timezoneProperty == null || timezoneProperty.isEmpty()) {
            Slog.w(TAG, "Timezone not set; setting to GMT.");
            SystemProperties.set("persist.sys.timezone", "GMT");
        }

		...省略...

		//設置虛擬機的庫文件,在Android6.0上用的是libart.so
        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        ...省略...

        //清除vm內存增長上限,由於啓動過程需要較多的虛擬機內存空間
        VMRuntime.getRuntime().clearGrowthLimit();

        //設置內存的可能有效使用率爲0.8
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        //針對部分設備依賴於運行時就產生指紋信息,因此需要在開機完成前已經定義
        Build.ensureFingerprintProperty();

        //訪問環境變量前,需要明確地指定用戶
        Environment.setUserRequired(true);

        //在系統服務器中,應該對任何傳入的bundle進行解壓縮,以避免拋出BadParcelableException
        BaseBundle.setShouldDefuse(true);

        //確保當前系統進程的binder調用,總是運行在前臺優先級
        BinderInternal.disableBackgroundScheduling(true);

        //增加system_server中binder線程的數量
        BinderInternal.setMaxThreads(sMaxBinderThreads);

        //爲主looper thread做準備
        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
		//創建消息Looper
        Looper.prepareMainLooper();

        //加載android_servers.so庫,該庫包含的源碼在frameworks/base/services/目錄下
        System.loadLibrary("android_servers");

        //檢測上次關機過程是否失敗,該方法可能不會返回
        performPendingShutdown(); //註釋1

        //初始化系統上下文
        createSystemContext(); //註釋2

        //創建系統服務管理
        mSystemServiceManager = new SystemServiceManager(mSystemContext); //註釋3
        mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
		//將mSystemServiceManager添加到本地服務的成員sLocalServiceObjects
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
		//爲可以並行化的init任務準備線程池
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }

    // Start services.
    try {
        traceBeginAndSlog("StartServices");
		//啓動引導服務
        startBootstrapServices(); //註釋4
		//啓動核心服務
        startCoreServices(); //註釋5
		//啓動其他服務
        startOtherServices(); //註釋6
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }

    //用於debug版本,將log事件不斷循環地輸出到dropbox(用於分析)
    if (StrictMode.conditionallyEnableDebugLogging()) {
        Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    }
    if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
        int uptimeMillis = (int) SystemClock.elapsedRealtime();
        MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
        final int MAX_UPTIME_MILLIS = 60 * 1000;
        if (uptimeMillis > MAX_UPTIME_MILLIS) {
            Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                    "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
        }
    }

    //一直循環執行
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

註釋解析:

  • 註釋1處檢查上次關機是否失敗

  • 註釋2處創建系統上下文

  • 註釋3處創建SystemServiceManager,它會對系統服務進行創建、啓動和生命週期管理

  • 註釋4處啓動系統中的引導服務

  • 註釋5處啓動系統中的核心服務

  • 註釋6處啓動系統中的其它服務

下面分別對註釋1-6對應的源碼進行跟蹤查閱。

4.1 performPendingShutdown

代碼路徑:frameworks/base/services/java/com/android/server/SystemServer.java

深入到performPendingShutdown函數中:

private void performPendingShutdown() {
    final String shutdownAction = SystemProperties.get(
            ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
    if (shutdownAction != null && shutdownAction.length() > 0) {
        boolean reboot = (shutdownAction.charAt(0) == '1');

        final String reason;
        if (shutdownAction.length() > 1) {
            reason = shutdownAction.substring(1, shutdownAction.length());
        } else {
            reason = null;
        }
        if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {
            File packageFile = new File(UNCRYPT_PACKAGE_FILE);
            if (packageFile.exists()) {
                String filename = null;
                try {
                    filename = FileUtils.readTextFile(packageFile, 0, null);
                } catch (IOException e) {
                    Slog.e(TAG, "Error reading uncrypt package file", e);
                }

                if (filename != null && filename.startsWith("/data")) {
                    if (!new File(BLOCK_MAP_FILE).exists()) {
                        Slog.e(TAG, "Can't find block map file, uncrypt failed or " +
                                   "unexpected runtime restart?");
                        return;
                    }
                }
            }
        }
		//當"sys.shutdown.requested"值不爲空,則會重啓或者關機
        ShutdownThread.rebootOrShutdown(null, reboot, reason);
    }
}
4.2 createSystemContext

代碼路徑:frameworks/base/services/java/com/android/server/SystemServer.java

深入到createSystemContext函數中:

private void createSystemContext() {
	//創建system_server進程的上下文信息
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
	//設置主題
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

	//創建SystemUi的上下文信息並設置主題
    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
4.3 SystemServiceManager啓動Service

代碼路徑:frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

系統服務啓動的邏輯都是相似的,這裏以PowerManagerService來舉例,啓動代碼如下:

mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

深入到SystemServiceManager的startService函數中:

public void startService(@NonNull final SystemService service) {
    //註冊Service
    mServices.add(service); //註釋1
    long time = System.currentTimeMillis();
    try {
		//啓動Service
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + service.getClass().getName()
                + ": onStart threw an exception", ex);
    }
    warnIfTooLong(System.currentTimeMillis() - time, service, "onStart");
}

除了調用SystemServiceManager的startService函數來啓動系統服務外,也可以通過如下形式來啓動系統服務,以PackageManagerServcie爲例:

mPackageManagerService = PackageManagerServcie.main(mSystemContext,intaller,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF,mOnlyCore);

直接調用了PackageManagerServcie的main方法。

代碼路徑:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

深入到PackageManagerServcie的main方法中:

public static PackageManagerService main(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
    //自檢初始的設置
    PackageManagerServiceCompilerMapping.checkProperties();
    PackageManagerService m = new PackageManagerService(context, installer,
            factoryTest, onlyCore); //註釋1
    m.enableSystemUserPackages();
    ServiceManager.addService("package", m); //註釋2
    return m;
}

註釋解析:

  • 註釋1處創建一個PackageManagerService對象

  • 註釋2處將創建的PackageManagerService對象註冊到ServiceManager中

ServiceManager是用來管理系統中的各種Service,用於系統C/S架構中的Binder通信機制:Client端要使用某個Service,需要先到ServiceManager中查下Service的相關信息,然後根據Service的相關信息與Service所在的Server進程建立通信,這樣Client就可以使用Service了。

4.4 startBootstrapServices

代碼路徑:frameworks/base/services/java/com/android/server/SystemServer.java

深入到startBootstrapServices函數中:

private void startBootstrapServices() {
    
	...省略...
	//阻塞等待與installd建立socket通道
    Installer installer = mSystemServiceManager.startService(Installer.class);
	
	...省略...
    //在activity manager之前註冊DeviceIdentifiersPolicyService
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
  
	...省略...
	//啓動服務ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

	...省略...
    //啓動服務PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
    
	...省略...
	//初始化PowerManagement
    mActivityManagerService.initPowerManagement();

    ...省略...
	//啓動服務LightsService
    mSystemServiceManager.startService(LightsService.class);
    
	...省略...
	//啓動服務DisplayManagerService
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
   	
	...省略...
	//Phase100: 在初始化package manager之前,需要默認的顯示
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    
	//當設備正在加密時,僅運行核心
    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;
    }

    ...省略...
	//啓動服務PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();
   
	...省略...
    //啓動服務UserManagerService
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
    
	//設置AMS
    mActivityManagerService.setSystemProcess();
    
	...省略...
	//啓動服務OverlayManagerService
    mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
    
    mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
        BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
                SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
        traceLog.traceBegin(START_SENSOR_SERVICE);
		//啓動傳感器服務
        startSensorService();
        traceLog.traceEnd();
    }, START_SENSOR_SERVICE);
}

綜上所述:該方法啓動的引導服務有:ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService、PackageManagerService、UserManagerService、OverlayManagerService和SensorService。

4.5 startCoreServices

代碼路徑:frameworks/base/services/java/com/android/server/SystemServer.java

深入到startCoreServices函數中:

private void startCoreServices() {
    //啓動服務DropBoxManagerService,用於生成和管理系統運行時的一些日誌文件
    mSystemServiceManager.startService(DropBoxManagerService.class);

	//啓動服務BatteryService,用於統計電池電量,需要LightService
    mSystemServiceManager.startService(BatteryService.class);

    //啓動服務UsageStatsService,用於統計應用使用情況
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));
    
	//啓動服務WebViewUpdateService,用於WebView更新服務
    mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}

綜上所述:該方法啓動的核心服務有:DropBoxManagerService、BatteryService、UsageStatsService和WebViewUpdateService。

4.6 startOtherServices

代碼路徑:frameworks/base/services/java/com/android/server/SystemServer.java

深入到startOtherServices函數中:

private void startOtherServices() {
    
		...省略...

        mContentResolver = context.getContentResolver(); //resolver

        ...省略...
        mActivityManagerService.installSystemProviders(); //provider
        
		...省略...
		//啓動服務AlarmManagerService
        mSystemServiceManager.startService(AlarmManagerService.class);
        
		//初始化watchdog
        watchdog.init(context, mActivityManagerService);
        
		...省略...
        inputManager = new InputManagerService(context); //input
        
		//啓動WindowManagerService
        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);
        
        SystemServerInitThreadPool.get().submit(() -> {
            traceBeginAndSlog(START_HIDL_SERVICES);
			//啓動服務startHidlServices
            startHidlServices();
            traceEnd();
        }, START_HIDL_SERVICES);

        if (!disableVrManager) {
            traceBeginAndSlog("StartVrManagerService");
			//啓動服務VrManagerService
            mSystemServiceManager.startService(VrManagerService.class);
            traceEnd();
        }

        ...省略...
		//啓動服務IpConnectivityMetrics
        mSystemServiceManager.startService(IpConnectivityMetrics.class);

        //啓動服務PinnerService
        mSystemServiceManager.startService(PinnerService.class);
        traceEnd();
    } catch (RuntimeException e) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting core service", e);
    }

  	...省略...

    //準備好vibrator、lockSettings、window、power、package、display等服務
        vibrator.systemReady();
        lockSettings.systemReady();
        wm.systemReady();
        mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
        mPackageManagerService.systemReady();
        mDisplayManagerService.systemReady(safeMode, mOnlyCore);

	...省略...
}

該方法啓動了一些非緊要和不需要立即啓動的服務。

5. Android系統部分服務及其作用

在system_server進程啓動中,將系統服務分爲三大類:引導服務、核心服務和其他服務。下面簡單的羅列下Android系統中常見的服務及其作用。

引導服務

  • Installer :系統安裝APK時的一個服務類,啓動完成Installer服務之後才能啓動其他的系統服務

  • ActivityManagerService :負責四大組件的啓動、切換、調度

  • PowerManagerService :計算系統中與Power相關的計算,然後決策系統應該如何反應

  • LightsService :管理和顯示背光LED

  • DisplayManagerService :用來管理所有顯示設備

  • UserManagerService :多用戶模式管理

  • SensorService :爲系統提供各種感應器服務

  • PackageManagerService :對apk進行安裝、解析、刪除、卸載等操作

…and so on …

核心服務

  • DropBoxManagerService :用於生成和管理系統運行時的一些日誌文件

  • BatteryService : 管理電池相關的服務

  • UsageStatsService : 收集用戶使用每一個App的頻率、使用時長

  • WebViewUpdateService :WebView更新服務

其他服務

  • CameraService :攝像頭相關服務

  • AlarmManagerService : 全局定時器管理服務

  • InputManagerService : 管理輸入事件

  • WindowManagerService :窗口管理服務

  • VrManagerService : VR模式管理服務

  • BluetoothService : 藍牙管理服務

  • NotificationManagerService : 通知管理服務

  • DeviceStorageMonitorService : 存儲相關管理服務

  • LocationManagerService : 定位管理服務

  • AndioServcie : 音頻相關管理服務

…and so on …

6. SystemServer進程啓動總結

SystemServer進程被創建後,主要做了如下工作:

  1. 啓動Binder線程池,使得system_server進程能與其它進程通信

  2. 創建SystemServiceManager,用於對系統的服務進程創建、啓動和生命週期管理

  3. 啓動系統中的引導服務、核心服務和其它服務

非常感謝您的耐心閱讀,希望我的文章對您有幫助。歡迎點評、轉發或分享給您的朋友或技術羣。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章