从源码角度看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); //注釋2ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);//fork子進程,也是創建SystemServer進程pid = Zygote.forkSystemServer( //注釋3parsedArgs.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原有的socketzygoteServer.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));}}}//設置groupSetGids(env, javaGids);//設置資源limitSetRLimits(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_serverSetThreadName(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); //注釋2Thread.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.75VMRuntime.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方法呢?
因為:
這種拋出異常的處理會清除所有的設置過程需要的堆棧幀,提高了棧幀利用率。
讓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 Exceptionimplements 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);}//如果沒有設置時區屬性,則默認為GMTString 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.soSystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());...省略...//清除vm內存增長上限,由于啟動過程需要較多的虛擬機內存空間VMRuntime.getRuntime().clearGrowthLimit();//設置內存的可能有效使用率為0.8VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);//針對部分設備依賴于運行時就產生指紋信息,因此需要在開機完成前已經定義Build.ensureFingerprintProperty();//訪問環境變量前,需要明確地指定用戶Environment.setUserRequired(true);//在系統服務器中,應該對任何傳入的bundle進行解壓縮,以避免拋出BadParcelableExceptionBaseBundle.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);//創建消息LooperLooper.prepareMainLooper();//加載android_servers.so庫,該庫包含的源碼在frameworks/base/services/目錄下System.loadLibrary("android_servers");//檢測上次關機過程是否失敗,該方法可能不會返回performPendingShutdown(); //注釋1//初始化系統上下文createSystemContext(); //注釋2//創建系統服務管理mSystemServiceManager = new SystemServiceManager(mSystemContext); //注釋3mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);//將mSystemServiceManager添加到本地服務的成員sLocalServiceObjectsLocalServices.addService(SystemServiceManager.class, mSystemServiceManager);//為可以并行化的init任務準備線程池SystemServerInitThreadPool.get();} finally {traceEnd(); // InitBeforeStartServices}// Start services.try {traceBeginAndSlog("StartServices");//啟動引導服務startBootstrapServices(); //注釋4//啟動核心服務startCoreServices(); //注釋5//啟動其他服務startOtherServices(); //注釋6SystemServerInitThreadPool.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) {//注冊ServicemServices.add(service); //注釋1long time = System.currentTimeMillis();try {//啟動Serviceservice.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); //注釋1m.enableSystemUserPackages();ServiceManager.addService("package", m); //注釋2return 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之前注冊DeviceIdentifiersPolicyServicemSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);...省略...//啟動服務ActivityManagerServicemActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);...省略...//啟動服務PowerManagerServicemPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);...省略...//初始化PowerManagementmActivityManagerService.initPowerManagement();...省略...//啟動服務LightsServicemSystemServiceManager.startService(LightsService.class);...省略...//啟動服務DisplayManagerServicemDisplayManagerService = 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;}...省略...//啟動服務PackageManagerServicemPackageManagerService = PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);mFirstBoot = mPackageManagerService.isFirstBoot();mPackageManager = mSystemContext.getPackageManager();...省略...//啟動服務UserManagerServicemSystemServiceManager.startService(UserManagerService.LifeCycle.class);//設置AMSmActivityManagerService.setSystemProcess();...省略...//啟動服務OverlayManagerServicemSystemServiceManager.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,用于統計電池電量,需要LightServicemSystemServiceManager.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...省略...//啟動服務AlarmManagerServicemSystemServiceManager.startService(AlarmManagerService.class);//初始化watchdogwatchdog.init(context, mActivityManagerService);...省略...inputManager = new InputManagerService(context); //input//啟動WindowManagerServicewm = 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);//啟動服務startHidlServicesstartHidlServices();traceEnd();}, START_HIDL_SERVICES);if (!disableVrManager) {traceBeginAndSlog("StartVrManagerService");//啟動服務VrManagerServicemSystemServiceManager.startService(VrManagerService.class);traceEnd();}...省略...//啟動服務IpConnectivityMetricsmSystemServiceManager.startService(IpConnectivityMetrics.class);//啟動服務PinnerServicemSystemServiceManager.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進程被創建后,主要做了如下工作:
啟動Binder線程池,使得system_server進程能與其它進程通信
創建SystemServiceManager,用于對系統的服務進程創建、啟動和生命周期管理
啟動系統中的引導服務、核心服務和其它服務
非常感謝您的耐心閱讀,希望我的文章對您有幫助。歡迎點評、轉發或分享給您的朋友或技術群。
總結
以上是生活随笔為你收集整理的从源码角度看Android系统SystemServer进程启动过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从源码角度看Android系统Zygot
- 下一篇: 从源码角度看Android系统Launc