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方法呢?
因爲:
-
這種拋出異常的處理會清除所有的設置過程需要的堆棧幀,提高了棧幀利用率。
-
讓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進程被創建後,主要做了如下工作:
-
啓動Binder線程池,使得system_server進程能與其它進程通信
-
創建SystemServiceManager,用於對系統的服務進程創建、啓動和生命週期管理
-
啓動系統中的引導服務、核心服務和其它服務