源码详解Android 9.0(P) 系统启动流程目录:
源码详解Android 9.0(P)系统启动流程之init进程(第一阶段) 源码详解Android 9.0(P)系统启动流程之init进程(第二阶段) 源码详解Android 9.0(P)系统启动流程之init.rc语法规则 源码详解Android 9.0(P)系统启动流程之init进程(第三阶段) 源码详解Android 9.0(P)系统启动流程之核心服务和关键进程启动 源码详解Android 9.0(P)系统启动流程之Zygote进程 源码详解Android 9.0(P)系统启动流程之SystemServer
Android系统启动流程 SystemServer
0. 前言
??在前面的篇章源码详解Android 9.0§ 系统启动流程之Zygote进程中我们重点分析了zygote启动的流程,但是剩余了两个重点的知识点没有讲解,其中之一就是Android system_server进程启动的完整流程,在本篇中我们将要揭开system_server的神秘面纱分析分析它究竟是怎么启动的。
??SystemServer进程是zygote进程启动后,主动“分裂”的第一个进程。如果说zygote孵化了整个Android的Java世界,那么system_server进程就是它的左膀右臂一起掌管Android的Java世界。它负责启动大量的Android系统核心服务,其重要性不言而喻。一旦该进程崩溃,整个Android系统将重新启动。?? ??SystemServer对Android意味着什么?这个答案是不言而喻的,它是Android Java世界的精神支柱,虽然Android的Java世界可以说由zygote孵化而来的,但是在我看来zygote也是一个甩手掌柜。而system_server进程则是Android Java世界的核心管理者,为了Java世界的繁华提供着各种服务,事必亲力亲为。 ??正是由于zygote和system_server的关系如此密切,所以这两者之间任何一个发生异常,都会导致Android Java的崩溃(所有由Zygote孵化的Java进程都会被销毁,而SystemServer就是由Zygote孵化而来)。若Android Java真的崩溃了,那么Linux系统中的进程init会重新启动“两大支柱”以重建Android Java,也有可能陷入无限死循环启动不了这个就要根据实际情况来看了。
??由此我们也能看出SystemServer地位之高,因此对它的来源、作用和流程我们都需要有一定的了解,废话不多说,代码见~ 其中涉及的源码路径如下:
frameworks//base/core/java/com/android/internal/os/ZygoteInit.java
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
frameworks/base/core/java/com/android/internal/os/Zygote.java
frameworks/base/core/jni/AndroidRuntime.cpp
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/LoadedApk.java
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
1. system_server启动的整体概述
??老规矩,在正式开始源码前,先奉上system_server进程启动的整体流程图,这样有助于童靴们心里构建一个整体的流程图谱,这样就可以根据图谱再结合源码达到一一击破,逐个分析的功效。
2. system_server进程启动
??在前面的篇章源码详解Android 9.0§ 系统启动流程之Zygote进程中我们知道当zygote进程进入到java世界后,在ZygoteInit.java中,将调用startSystemServer函数启动SystemServer进程,其关键代码是:
public static void main(String argv[]) {
......
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
......
}
这段代码中我们重点关注forkSystemServer,从它开始下手。
2.1 forkSystemServer
该代码定义于frameworks//base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
......
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
??从上述源码我们可以看出,该代码的逻辑划分如下:
- 准备要启动system_server相关的参数并fork新的进程,从上面可以看出system server进程参数信息为uid=1000,gid=1000,进程名为sytem_server
- 如果对于有两个zygote进程情况,需等待第2个zygote创建完成,这种情况通常发生在加载zygote启动的rc文件为init.zygote32_64.rc或者init.zygote64_32.rc这两种情况下
- 从zygote进程fork新进程后,关闭zygote原有的socket
- 调用handleSystemServerProcess,返回一个Runable对象
2.2 Zygote.forkSystemServer
??该代码定义于frameworks/base/core/java/com/android/internal/os/Zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
resetNicePriority();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
}
VM_HOOKS.postForkCommon();
return pid;
}
??通过前面我们对zygote启动的流程分析我们可知Android系统的JNI函数绝大分布都是在androidRuntime.cpp中进行注册的,nativeForkSystemServer()本地方法也不例外。这里nativeForkSystemServer会调用com_android_internal_os_Zygote.cpp中的register_com_android_internal_os_Zygote()方法建立native方法的映射关系,所以接下来进入如下方法。
这里有一个小窍门,怎么找到Android系统中Java的本地方法对应的Jni所在文件呢,一般的规则如下:
- 将Java类所在的包名中的.转换成_,譬如我们这里的Zygote所在包名为com.android.internal.os,转换后即为com_android_internal_os
- 将上述转换后的字符串+"_"+Java类名.cpp,就是我们要找的Jni文件了,譬如我们这里的com_android_internal_os_Zygote.cpp
2.3 nativeForkSystemServer
??通过前面章节我们知道nativeForkSystemServer是一个本地方法,最终通过Jni调用到了com_android_internal_os_Zygote.cpp中的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 runtime_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, getpid(), 1 | (0 << IOPRIO_CLASS_SHIFT));
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, false, NULL, NULL);
if (pid > 0) {
ALOGI("System server process %d has been created", pid);
gSystemServerPid = pid;
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
if (!access("/dev/memcg/system/tasks", F_OK) &&
!WriteStringToFile(StringPrintf("%d", pid), "/dev/memcg/system/tasks")) {
ALOGE("couldn't write %d to /dev/memcg/system/tasks", pid);
}
}
return pid;
}
??通过上面的代码可以看到,当system_server创建如果夭折了的话,那么Android将不得不重启zygote进程了。但是需要注意的是,对于Android 5.0以上系统,有两个zygote进程,分别是zygote、zygote64两个进程,system_server的父进程,一般来说64位系统其父进程是zygote64进程(这个是参考gityuan的,不保证正确)。
- 当kill system_server进程后,只重启zygote64和system_server,不重启zygote;
- 当kill zygote64进程后,只重启zygote64和system_server,也不重启zygote;
- 当kill zygote进程,则重启zygote、zygote64以及system_server。
这里提供一个小方法教大伙看系统中那些进程是由zygote64启动的那些是由zygote启动的,具体的步骤如下:
-
通过ps | grep zygote 命令查看当前Android终端运行了几个zygote进程 -
根据进程号PID看看上面zygote进程的执行文件 cd /proc/PID(这里的PID为上面进程获取的)
ls -ali | grep exe
-
我们只要看那些进程的PPID为上述的PID值就可以看出进程分别是由谁孵化的了 ps | grep PID(这里的PID为上面进程获取的)
2.4 ForkAndSpecializeCommon
??该代码依然还是定义在com_android_internal_os_Zygote.cpp中,冗余细节有点多,我们这里只抓主要的,细节的先行放过。
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
jint runtime_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, bool is_child_zygote,
jstring instructionSet, jstring dataDir) {
SetSignalHandlers();
......
pid_t pid = fork();
if (pid == 0) {
PreApplicationInit();
if (!DetachDescriptors(env, fdsToClose, &error_msg)) {
fail_fn(error_msg);
}
......
if (!is_system_server && getuid() == 0) {
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));
}
}
}
std::string error_msg;
if (!SetGids(env, javaGids, &error_msg)) {
fail_fn(error_msg);
}
if (!SetRLimits(env, javaRlimits, &error_msg)) {
fail_fn(error_msg);
}
......
if (!SetCapabilities(permittedCapabilities, effectiveCapabilities, permittedCapabilities,
&error_msg)) {
fail_fn(error_msg);
}
if (!SetSchedulerPolicy(&error_msg)) {
fail_fn(error_msg);
}
.....
rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);
if (rc == -1) {
fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,
is_system_server, se_info_c_str, se_name_c_str));
}
if (se_name_c_str == NULL && is_system_server) {
se_name_c_str = "system_server";
}
if (se_name_c_str != NULL) {
SetThreadName(se_name_c_str);
}
delete se_info;
delete se_name;
UnsetChldSignalHandler();
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
is_system_server, is_child_zygote, instructionSet);
if (env->ExceptionCheck()) {
fail_fn("Error calling post fork hooks.");
}
} else if (pid > 0) {
if (sigprocmask(SIG_UNBLOCK, &sigchld, nullptr) == -1) {
fail_fn(CREATE_ERROR("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)));
}
}
return pid;
}
??这里可以看到ForkAndSpecializeCommon函数最终调用的是fork()函数创建新的进程,而fork创建进程采用的是COW(写时拷贝技术)这是linux创建进程的标准方法,会有两次return,对于pid==0为子进程的返回,对于pid>0为父进程的返回。
??在文章的开篇我们说到,zygote进程和system_server几乎是同生共死,休戚相关的,那是怎么做到的呢?这里我们看到在zygote进程fork之前,调用SetSigChldHandler函数注册了一个子进程信号监听器。由于子进程共享父进程中的堆及栈信息,因此在子进程中也会有相应的信号处理器。为了避免该信号监听器对子进程的影响,可以看到在子进程中进行了UnsetSigChldHandler的操作。zygote进程和system_server同生共死的密码就在SetSigChldHandler中了。
2.4.1 SetSignalHandlers
??该代码依然还是定义在com_android_internal_os_Zygote.cpp中,我们看看它究竟做了些什么什么操作!
static void SetSignalHandlers() {
struct sigaction sig_chld = {};
sig_chld.sa_handler = SigChldHandler;
if (sigaction(SIGCHLD, &sig_chld, NULL) < 0) {
ALOGW("Error setting SIGCHLD handler: %s", strerror(errno));
}
struct sigaction sig_hup = {};
sig_hup.sa_handler = SIG_IGN;
if (sigaction(SIGHUP, &sig_hup, NULL) < 0) {
ALOGW("Error setting SIGHUP handler: %s", strerror(errno));
}
}
这个代码并不神秘,在前面讲解init进程源码分析中也分析过类似的。在这里注册一个信号处理器,来监听子进程的死亡。当子进程死亡后,利用SigChldHandler进行操作。需要注意的是,zygote的信号监听器,关注的是zygote所有的子进程,而不只是SystemServer进程(每次创建一个新的进程时,zygote都会注册对应的监听器)。
2.4.2 SigChldHandler
让我们继续分析SigChldHandler看看它做了些什么工作
static void SigChldHandler(int ) {
pid_t pid;
int status;
int saved_errno = errno;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
if (WIFEXITED(status)) {
ALOGI("Process %d exited cleanly (%d)", pid, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
ALOGI("Process %d exited due to signal (%d)", pid, WTERMSIG(status));
if (WCOREDUMP(status)) {
ALOGI("Process %d dumped core.", pid);
}
}
if (pid == gSystemServerPid) {
ALOGE("Exit zygote because system server (%d) has terminated", pid);
kill(getpid(), SIGKILL);
}
}
if (pid < 0 && errno != ECHILD) {
ALOGW("Zygote SIGCHLD error in waitpid: %s", strerror(errno));
}
errno = saved_errno;
}
看到这里大伙应该明白了,所有zygote的子进程中,zygote只关心了SystemServer的死活。当其它子进程crash时,zygote只打印了log信息(有点天要下雨娘要嫁人随他去的感觉)。看来我们的zygote是有点偏心长子啊。
2.4.3 UnsetChldSignalHandler
??对于system_server进程恢复默认信号处理,代码位于frameworks\base\core\jni\com_android_internal_os_Zygote.cpp
static void UnsetChldSignalHandler() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
if (sigaction(SIGCHLD, &sa, NULL) < 0) {
ALOGW("Error unsetting SIGCHLD handler: %s", strerror(errno));
}
}
??到此system_server进程已完成了创建的所有工作,接下来开始了system_server进程的真正工作。在前面startSystemServer()方法中,zygote进程执行完forkSystemServer()后,新创建出来的system_server进程便进入handleSystemServerProcess()方法。
2.5 handleSystemServerProcess
??兜兜转转又回到了ZygoteInit.java中的handleSystemServerProcess方法中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
Os.umask(S_IRWXG | S_IRWXO);
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
try {
prepareSystemServerProfile(systemServerClasspath);
} catch (Exception e) {
Log.wtf(TAG, "Failed to set up system server profile", e);
}
}
}
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);
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
??从上面的代码可以看出,接下来的流程进入到ZygoteInit的zygoteInit函数。zygoteInit函数将根据classLoader和参数,完成不同进程所需要的初始化工作(SystemServer进程与zygote的其它子进程均将使用zygoteInit函数)。
2.6 performSystemServerDexOpt
??在分析performSystemServerDexOpt我们先来看看Os.getenv(“SYSTEMSERVERCLASSPATH”)获取的环境变量是什么,我们可以通过echo $SYSTEMSERVERCLASSPATH 命令获取SYSTEMSERVERCLASSPATH 环境变量值,如下:
/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar
??了解了performSystemServerDexOpt的传入参数,我们接着继续分析下面的代码,该代码的逻辑如下:
- 建立和installd的socket通信通道
- 以":"分割传递过来的字符串
- 判断是否需要dex优化services.jar和ethernet-service.jar
- 如果需要优化,则调用dexopt优化上面的三个jar包中的需要优化的
private static void performSystemServerDexOpt(String classPath) {
final String[] classPathElements = classPath.split(":");
final IInstalld installd = IInstalld.Stub
.asInterface(ServiceManager.getService("installd"));
final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
String classPathForElement = "";
for (String classPathElement : classPathElements) {
String systemServerFilter = SystemProperties.get(
"dalvik.vm.systemservercompilerfilter", "speed");
int dexoptNeeded;
try {
dexoptNeeded = DexFile.getDexOptNeeded(
classPathElement, instructionSet, systemServerFilter,
null , false , false );
} catch (FileNotFoundException ignored) {
Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
continue;
} catch (IOException e) {
Log.w(TAG, "Error checking classpath element for system server: "
+ classPathElement, e);
dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
}
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {**加粗样式**
final String packageName = "*";
final String outputPath = null;
final int dexFlags = 0;
final String compilerFilter = systemServerFilter;
final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
final String seInfo = null;
final String classLoaderContext =
getSystemServerClassLoaderContext(classPathForElement);
final int targetSdkVersion = 0;
try {
installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
uuid, classLoaderContext, seInfo, false ,
targetSdkVersion, null, null,
"server-dexopt");
} catch (RemoteException | ServiceSpecificException e) {
Log.w(TAG, "Failed compiling classpath element for system server: "
+ classPathElement, e);
}
}
classPathForElement = encodeSystemServerClassPath(
classPathForElement, classPathElement);
}
}
2.7 zygoteInit
??在前面的2.5章节我们知道parsedArgs.invokeWith属性默认为null,最后调用RuntimeInit.zygoteInit来进一步启动system_server进程。 代码定义于frameworks\base\core\java\com\android\internal\os\ZygoteInit.java,在zygoteInit中执行的主要代码逻辑如下:
- 重定义Log输出
- 通用的初始化
- 启动Binder线程池
- 应用初始化
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);
}
2.8 commonInit
??该代码定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java中,主要是做了一些常规的初始化,从逻辑上分析主要分为如下几个方面:
- 设置未捕获异常的处理方法
- 设置时区
- 重置log配置
- 设置默认的HTTP User-agent格式,用于 HttpURLConnection
- 设置流量统计Socket tag
protected static final void commonInit() {
if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
LoggingHandler loggingHandler = new LoggingHandler();
Thread.setUncaughtExceptionPreHandler(loggingHandler);
Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
TimezoneGetter.setInstance(new TimezoneGetter() {
@Override
public String getId() {
return SystemProperties.get("persist.sys.timezone");
}
});
TimeZone.setDefault(null);
LogManager.getLogManager().reset();
new AndroidConfig();
String userAgent = getDefaultUserAgent();
System.setProperty("http.agent", userAgent);
NetworkManagementSocketTagger.install();
String trace = SystemProperties.get("ro.kernel.android.tracing");
if (trace.equals("1")) {
Slog.i(TAG, "NOTE: emulator trace profiling enabled");
Debug.enableEmulatorTraceOutput();
}
initialized = true;
}
??这其中User-Agent是Http协议中的一部分,属于头域的组成部分,是一种向访问网站者提供你所使用的浏览器类型,操作系统,浏览器内核等信息的标识。通过这个标识,用户所访问的网站可以显示不同的排版,从而为用户提供更好的体验或者进行信息统计。
2.9 nativeZygoteInit
??一看方法名称就知道是要调用native方法进行初始化,通过调用nativeZygoteInit主要是用来启动Binder线程池的。该方法nativeZyoteInit实现在frameworks/base/core/jni/AndroidRuntime.cpp中,对应的JNI映射如下所示:
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(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));
}
??通过JNI的gMethods数组,可以看出nativeZygoteInit函数对应的是JNI文件AndroidRuntime.cpp的com_android_internal_os_RuntimeInit_nativeZygoteInit函数:
JavaVM* AndroidRuntime::mJavaVM = NULL;
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
mExitWithoutCleanup(false),
mArgBlockStart(argBlockStart),
mArgBlockLength(argBlockLength)
{
SkGraphics::Init();
mOptions.setCapacity(20);
assert(gCurRuntime == NULL);
gCurRuntime = this;
}
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
??这里可以看到gCurRuntime是AndroidRuntime类型的指针,可是AndroidRuntime的onZygoteInit却是一个虚函数,那么就应该在其子类中实现了。那么gCurRuntime究竟指的是什么呢?
??在我们前面的篇章中介绍zygote启动过程中,在app_main.cpp的main函数中,创建出了AppRuntime对象,其逻辑如下:
int main(int argc, char* const argv[])
{
......
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
......
}
而AppRuntime 的定义也在app_main.c中其如下:
class AppRuntime : public AndroidRuntime
{
public:
AppRuntime(char* argBlockStart, const size_t argBlockLength)
: AndroidRuntime(argBlockStart, argBlockLength)
, mClass(NULL)
{
}
......
}
接着继续来看看AppRuntime的父类AndroidRuntime的代码:
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
mExitWithoutCleanup(false),
mArgBlockStart(argBlockStart),
mArgBlockLength(argBlockLength)
{
SkGraphics::Init();
mOptions.setCapacity(20);
assert(gCurRuntime == NULL);
gCurRuntime = this;
}
??从代码可以看出,AndroidRuntime初始化时定义了gCurRuntime。gCurRuntime指向对象自身,也就是说gCurRuntime指向的是AppRuntime对象(有时候感觉继承搞起来是比较麻烦,我们驱动的同事就说看着面向对象里面那一堆堆的继承,就头疼)。
??由于SystemServer进程由zygote进程fork出来,于是system server进程中也存在gCurRuntime对象,类型为AppRuntime。至此我们知道,Native函数中gCurRuntime->onZygoteInit将调用AppRuntime中的onZygoteInit。
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
??ProcessState::self()是单例模式,主要工作是调用open()打开/dev/binder驱动设备,再利用mmap()映射内核的地址空间,将Binder驱动的fd赋值ProcessState对象中的变量mDriverFD,用于交互操作。startThreadPool()是创建一个新的binder线程,不断进行talkWithDriver(),这里就不过多阐述了。这样将当前线程注册到Binder驱动程序中,这样我们创建的线程就加入了Binder线程池中,这样新创建的SyetemServer进程就支持Binder进程间通信了。
2.10 applicationInit
??继续回到ZygoteInit.java类中的applicationInit看看它做了些什么,applicationInit定义在frameworks\base\core\java\com\android\internal\os\RuntimeInit.java中,其主要逻辑如下:
- 调用nativeSetExitWithoutCleanup(true),从而使应用退出时不调用System.exit()
- 设置虚拟机的内存利用率参数值
- 接着调用findStaticMain继续下一步操作
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args = new Arguments(argv);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
2.11 findStaticMain
??接着分析findStaticMain方法,其中传递进来的参数className是om.android.server.SystemServer ,所以其主要逻辑如下:
- 因此通过Class.forName反射返回的cl为SystemServer类
- 获取SystemServer类的main方法
- 判断SystemServer类的main方法修饰符是不是public和static
- 接着返回MethodAndArgsCaller
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
return new MethodAndArgsCaller(m, argv);
}
这里有一点需要重点注意的,在Android 8之前的版本都是通过直接在MethodAndArgsCaller抛出该异常,然后在ZygoteInit.java中的main方法中捕获,但是Android 8及以后都改变了这种策略是通过返回MethodAndArgsCaller,然后在main中直接调用,其逻辑如下所示,接着判断Runnable 是否为空,如果不为空则调用run方法
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
2.12 MethodAndArgsCaller
??在ZygoteInit.java中的main方法中运行r.run直捣黄龙,启动SystemServer的main方法。
static class MethodAndArgsCaller implements Runnable {
private final Method mMethod;
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
经过层层的拨山涉水,我们终于总算是进入到了SystemServer类的main()方法,但是这还只是分析system_server进程的开端,后面我们将要看看system_server进程作为Android世界的肱骨大臣究竟有何功劳,能在Android世界享有如此美誉能和zygote同生共死。下面就让我们来看看system_serveer究竟有何丰功伟绩,让我们细品!
3. SystemServer启动
??通过前面章节我们知道最后通过反射调用mMethod.invoke开启了SystemServer的彪悍人生,最终会调用到SystemServer.main()方法,还等什么让我们一探究竟。整个system_server进程启动流程图如下: SystemServer.main()启动流程图示意如下,这章主要详细分析如下几个流程:
3.1 SystemServer.main
??无过多修饰,直接创建new一个SystemServer对象并调用其run方法。
public static void main(String[] args) {
new SystemServer().run();
}
3.2 SystemServer.run
??前面main函数很简单,现在run函数就要老实干活了,其主要逻辑总结如下:
- 初始化一些零碎事务
- createSystemContext初始化system_server进程的context,这个是重点需要分析的
- startBootstrapServices启动第一阶段服务
- startCoreServices启动核心服务
- startOtherServices启动其它服务
private void run() {
try {
android.os.Process.setThreadPriority(-19);
traceBeginAndSlog("InitBeforeStartServices");
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
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");
}
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", "zh-CN");
SystemProperties.set("persist.sys.localevar", "");
}
Binder.setWarnOnBlocking(true);
PackageItemInfo.setForceSafeLabels(true);
SQLiteCompatibilityWalFlags.init(null);
Slog.i(TAG, "Entered the Android system server!");
int uptimeMillis = (int) SystemClock.elapsedRealtime();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
}
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
VMRuntime.getRuntime().clearGrowthLimit();
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
Build.ensureFingerprintProperty();
Environment.setUserRequired(true);
BaseBundle.setShouldDefuse(true);
Parcel.setStackTraceParceling(true);
BinderInternal.disableBackgroundScheduling(true);
BinderInternal.setMaxThreads(sMaxBinderThreads);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
System.loadLibrary("android_servers");
performPendingShutdown();
createSystemContext();
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
SystemServerInitThreadPool.get();
} finally {
traceEnd();
}
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
StrictMode.initVmDefaults(null);
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);
}
}
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
可以看到run方法的工作主要有以下几点:
- 对Binder进行了一些设置,这个等到之后分析Binder的时候再看;
- performPendingShutdown:判断是否要关机或者重启;
- createSystemContext:创建系统上下文,这个留到分析Context的时候再看;
- 创建ServiceManager
- 开启各种服务,然后进入Looper消息循环
3.2.1 performPendingShutdown
??这个地方不是很明白为啥要检测sys.shutdown.requested值是否为空,然后为空后需要重启终端。这个各位如果了解,也可以沟通沟通!
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;
}
}
}
}
Runnable runnable = new Runnable() {
@Override
public void run() {
synchronized (this) {
ShutdownThread.rebootOrShutdown(null, reboot, reason);
}
}
};
Message msg = Message.obtain(UiThread.getHandler(), runnable);
msg.setAsynchronous(true);
UiThread.getHandler().sendMessage(msg);
}
}
3.3 createSystemContext初始化系统上下文
??这个知识点比较重要,我们分析分析该方法,其代码逻辑如下:
- 创建system_server进程的上下文环境
- 设置主题样式
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);
}
3.3.1 ActivityThread.systemMain
??该类定义在frameworks/base/core/java/android/app/ActivityThread.java中,这个类大伙因该比较熟悉或者耳闻过其大名。
ActivityThread() {
mResourcesManager = ResourcesManager.getInstance();
}
public static ActivityThread systemMain() {
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
3.3.2 ActivityThread.attach
让我们接着继续分析attach函数,揭开其面纱看看其到底干了些啥!
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
......
} else {
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
DropBox.setReporter(new DropBoxReporter());
ViewRootImpl.ConfigChangedCallback configChangedCallback
= (Configuration globalConfig) -> {
synchronized (mResourcesManager) {
if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
null )) {
updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
mResourcesManager.getConfiguration().getLocales());
if (mPendingConfiguration == null
|| mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
mPendingConfiguration = globalConfig;
sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
}
}
}
};
ViewRootImpl.addConfigCallback(configChangedCallback);
}
??通过上述的代码分析,我们可以归纳此时的attach主要干了如下几个事情:
- 创建系统上下文:getSystemContext() → createSystemContext() → new ContextImpl()
- 创建应用上下文:ContextImpl.createAppContext() → new ContextImpl()
- 添加回调configChangedCallback到ViewRootImpl
3.3.3 ActivityThread.getSystemContext
??让我们继续跟进getSystemContext,该函数比较简单直接调用ContextImpl.createSystemContext创建系统上下文。
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
3.3.4 ContextImpl.createSystemContext
??该方法定义在frameworks/base/core/java/android/app/ContextImpl.java中,代码如下:
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
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;
}
3.3.5 ContextImpl.createAppContext()创建应用上下文
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
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,而应用上下文只是作为函数中的局部变量临时使用。这是我的理解,不知道谷歌的工程师是不是这么认为的,或者童靴们你们有另外的理解!
3.3.6 LoadedApk.makeApplication
??让我们回头看下ActivityThread.attach中创建上下文的内容:
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
??接下来让我们继续分析makeApplication,该方法定义在frameworks/base/core/java/android/app/LoadedApk.java中,源码如下:
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
......
return app;
}
3.3.7 createSystemContext总结
??createSystemContext这一章节涉及的知识面比较多,且比较重要,我们分析总结一番。在这一章节里面我们主要是创建了一个ActivityThread对象,这个对象大伙应该都不会感到陌生,然后然后执行了该对象的attach()方法,attach()方法中创建了系统上下文mSystemContext(类型为ContextImpl),并创建Application对象。系统上下文中,new了一个LoadedApk的成员变量,并将ActivityThread对象传给LoadedApk成员,后面的Application对象就是LoadedApk使用ActivityThread创建的,LoadedApk创建了Application对象后,将Application添加到ActivityThread的应用列表中。关于这个章节内容还有很多可以扩展的地方,未来会单独写一章节进行学习。
3.4 初始化SystemServiceManager系统服务管理类
??让我们收回思路,回到SystemServer中的run方法中看看创建系统服务管理类的代码。
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
这一流程比较简单,主要逻辑有如下几点:
- 以前面章节创建的系统上下文mSystemContext初始化SystemServiceManager对象
- 设置mSystemServiceManager 对象启动信息,主要是时间和是否是重启等
- 将构建的mSystemServiceManager 其添加到本地服务列表中,本地服务列表是以类为key保存的一个列表,即列表中某种类型的对象最多只能有一个
3.4.1 SystemServiceManager简单分析
??该类定义在frameworks/base/services/core/java/com/android/server/SystemServiceManager.java中,主要代码逻辑如下:
public class SystemServiceManager {
......
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
private int mCurrentPhase = -1;
......
@SuppressWarnings("unchecked")
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
try {
serviceClass = (Class<SystemService>)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);
}
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
public void startService(@NonNull final SystemService service) {
mServices.add(service);
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");
}
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);
}
}
......
}
??我们这里说mCurrentPhase表示当前处于开机过程的那个阶段,有如下几个阶段,定义在frameworks/base/services/core/java/com/android/server/SystemService.java中,如下所示:
public abstract class SystemService {
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;
public static final int PHASE_LOCK_SETTINGS_READY = 480;
public static final int PHASE_SYSTEM_SERVICES_READY = 500;
public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
public static final int PHASE_BOOT_COMPLETED = 1000;
......
}
3.4.2 LocalServices
??该类定义在frameworks/base/core/java/com/android/server/LocalServices.java中,逻辑so easy就是将SystemService 存放在hash表中,供后续使用。
public final class LocalServices {
private LocalServices() {}
private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
new ArrayMap<Class<?>, Object>();
@SuppressWarnings("unchecked")
public static <T> T getService(Class<T> type) {
synchronized (sLocalServiceObjects) {
return (T) sLocalServiceObjects.get(type);
}
}
public static <T> void addService(Class<T> type, T service) {
synchronized (sLocalServiceObjects) {
if (sLocalServiceObjects.containsKey(type)) {
throw new IllegalStateException("Overriding service registration");
}
sLocalServiceObjects.put(type, service);
}
}
@VisibleForTesting
public static <T> void removeServiceForTest(Class<T> type) {
synchronized (sLocalServiceObjects) {
sLocalServiceObjects.remove(type);
}
}
}
3.5 startBootstrapServices启动引导服务
??个人感觉,能被称为引导的东西都是牛逼的东西,例如windows下的BIOS引导程序,当然这里的引导服务也不例外,基本都是Android界的实干家,牛逼的很。
private void startBootstrapServices() {
......
Installer installer = mSystemServiceManager.startService(Installer.class);
......
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
mActivityManagerService.initPowerManagement();
mSystemServiceManager.startService(RecoverySystemService.class);
RescueParty.noteBoot(mSystemContext);
mSystemServiceManager.startService(LightsService.class);
if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {
mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
}
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
traceEnd();
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;
}
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_package_manager_init_start",
(int) SystemClock.elapsedRealtime());
}
traceBeginAndSlog("StartPackageManagerService");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
traceEnd();
if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
MetricsLogger.histogram(null, "boot_package_manager_init_ready",
(int) SystemClock.elapsedRealtime());
}
if (!mOnlyCore) {
boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
false);
if (!disableOtaDexopt) {
traceBeginAndSlog("StartOtaDexOptService");
try {
OtaDexoptService.main(mSystemContext, mPackageManagerService);
} catch (Throwable e) {
reportWtf("starting OtaDexOptService", e);
} finally {
traceEnd();
}
}
}
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
AttributeCache.init(mSystemContext);
mActivityManagerService.setSystemProcess();
mDisplayManagerService.setupSchedulerPolicies();
mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(START_SENSOR_SERVICE);
startSensorService();
traceLog.traceEnd();
}, START_SENSOR_SERVICE);
}
??这里可以看到startBootstrapServices会首先等待installd启动完成,然后阻塞等待和建立连接。接着会启动一系列相关联的重要服务,其中比较常见的和经常会用到的如下表格所示:
引导服务 | 功能 |
---|
Installer | 注意和installd的关联,这个是在系统安装apk时的一个服务类, 启动完成installer服务之后才能启动其它的系统服务,是installd的客户端和installd是C-S端架构 | ActivityManagerService | 牛逼的AMS服务,负责四大组件的启动,切换,调度等相关工作 | PowerManagerService | 负责Android系统中和Power相关的计算,决策系统的电源策略 | LightsService | 管理和显示Android相关指示灯服务 | DisplayManagerService | 用来管理Android所有显示设备服务 | PackageManagerService | 牛逼的PKMS服务,主要用来管理apk的安装,解析,验签,删除,升级等功能 | UserManagerService | 多用户模式管理服务 | SensorService | Android各种感应器管理服务! |
3.6 startCoreServices启动核心服务
??无需多言,主要是启动Android系统各种核心服务,核心是啥各位应该都懂!
private void startCoreServices() {
traceBeginAndSlog("StartBatteryService");
mSystemServiceManager.startService(BatteryService.class);
traceEnd();
traceBeginAndSlog("StartUsageService");
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
traceEnd();
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
traceBeginAndSlog("StartWebViewUpdateService");
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
traceEnd();
}
traceBeginAndSlog("StartBinderCallsStatsService");
BinderCallsStatsService.start();
traceEnd();
}
??其中核心服务中常见的和其作用如下表格所示:
核心服务 | 功能 |
---|
BatteryService | 电源管理服务,管理电池的各种状态 | UsageStatsService | 主要用于统计应用的使用情况,如时长,使用频率等 | WebViewUpdateService | 用于管理webview的更新 |
3.7 startOtherServices启动其它服务
??该方法比较长,有近千行代码,逻辑很简单,主要是启动一系列的服务,这里就不具体列举源码了,在第四节直接对其中的服务进行一个简单分类。
private void startOtherServices() {
......
mSystemServiceManager.startService(KeyChainSystemService.class);
ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
mSystemServiceManager.startService(TelecomLoaderService.class);
telephonyRegistry = new TelephonyRegistry(context);
ServiceManager.addService("telephony.registry", telephonyRegistry);
mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
mSystemServiceManager.startService(CONTENT_SERVICE_CLASS);
mActivityManagerService.installSystemProviders();
mSystemServiceManager.startService(DropBoxManagerService.class);
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
mSystemServiceManager.startService(AlarmManagerService.class);
watchdog.init(context, mActivityManagerService);
inputManager = new InputManagerService(context);
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm, false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
false, DUMP_FLAG_PRIORITY_CRITICAL);
mActivityManagerService.setWindowManager(wm);
startHidlServices();
mSystemServiceManager.startService(VrManagerService.class);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
mDisplayManagerService.windowManagerAndInputReady();
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
mActivityManagerService.systemReady(() -> {
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
}
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
}
??在这一阶段启动的服务太多了,就不一一列举出来,在该阶段的最后调用AMS.systemReady()启动默认Lancher进而完成了整个的开机流程。到此, System_server主线程的启动工作总算完成, 进入Looper.loop()状态,等待其他线程通过handler发送消息到主线再处理。最后附上该阶段启动的相关服务常见列表!
其他服务 | 功能 |
---|
CameraServiceProxy | 顾名思义摄像相关服务 | AlarmManagerService | 定时器管理服务 | InputManagerservice | 输入事件管理服务 | WindowManagerService | WMS窗口管理服务 | VrManagerService | VR管理服务 | BluetoothService | 蓝牙管理服务 | NotificationManagerService | 通知栏管理服务 | DeviceStorageMonitorService | 存储管理相关服务 | LocationManagerService | 定位管理服务 | AudioService | 音频相关管理服务 | LockSettingsService | 屏幕锁定服务,管理每个用户的相关锁屏信息 | DeviceIdleController | 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 | 指纹服务 |
4. SystemServer服务启动阶段
??通过前面的章节我们发现在SystemServer启动服务的三个阶段过程中,SystemServiceManager的startBootPhase()贯穿system_server进程以及服务的整个启动过程,基本示意图如下所示: ??其中最后的PHASE_BOOT_COMPLETED=1000 ,该阶段是发生在Boot完成和home应用启动完毕,从而完成了真正意义上的Android终端开机启动流程。系统服务更倾向于监听该阶段,而不是注册广播ACTION_BOOT_COMPLETED,从而降低系统延迟。
各个启动阶段所在源码的大致位置:
public final class SystemServer {
private void startBootstrapServices() {
...
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
...
}
private void startCoreServices() {
...
}
private void startOtherServices() {
...
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
...
mActivityManagerService.systemReady(() -> {
......
mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
......
}, BOOT_TIMINGS_TRACE_LOG);
}
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
final void finishBooting() {
......
mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
......
}
......
}
??如上就是Systemserver启动服务的各个阶段相关标志的设置,那么下面我们简单分析分析各个阶段主要完成的相关工作。
4.1 PHASE_START(0)
??在源码中是没有这个阶阶段的,这个是我们让更好的理解,本人强行加上去的,可以理解为system_server进程启动之后并启动SystemSever的开始阶段,在这一阶段主要创建了如下几个引导服务:
- installer服务,主要是提供给其它服务使用
- ActivityManagerService
- PowerManagerService
- RecoverySystemService
- DisplayManagerService
4.2 PHASE_WAIT_FOR_DEFAULT_DISPLAY(100)
??进入该阶段后,将会回调4阶段创建的相关服务的onBootPhase(100)方法,然后继续创建下列相关的服务:
- PackageManagerService
- UserManagerService
- OverlayManagerService
- BatteryService
- UsageStatsService
- InputManagerService
- WindowManagerService
- NetworkWatchlistService
4.3 PHASE_LOCK_SETTINGS_READY(480)
??进入该阶段后会回调前面阶段创建服务的onBootPhase(480)方法,该阶段非常短调用完上述方法后会直接进入PHASE_SYSTEM_SERVICES_READY(500)阶段。
4.4 PHASE_SYSTEM_SERVICES_READY(500)
??进入该阶段后会回调前面阶段创建服务的onBootPhase(500)方法,并依次执行如下服务的systemReady方法:
- WindowManagerService.systemReady():
- PowerManagerService.systemReady():
- PackageManagerService.systemReady():
- DisplayManagerService.systemReady():
接下来就绪AMS.systemReady方法,这个方法非常重要!
4.5 PHASE_ACTIVITY_MANAGER_READY(550)
??该阶段中将设置AMS的mSystemReady为true表明AMS已准备就绪,进入该阶段服务能广播Intent;但是system_server主线程并没有就绪,然后继续会调用前面创建服务的onBootPhase(550)方法!接下来执行: (AMS启动native crash监控, 加载WebView,启动SystemUi等),如下:
- mActivityManagerService.startObservingNativeCrashes()
- mWebViewUpdateService.prepareWebViewInSystemServer
- startSystemUi(context)
- networkManagementF.systemReady
- pSecServiceF.systemReady
- networkStatsF.systemRead
- connectivityF.systemReady
- networkPolicyF.systemReady
- Watchdog.getInstance().start()
4.6 PHASE_THIRD_PARTY_APPS_CAN_START(600)
??该阶段依次会调用前面阶段创建服务的onBootPhase(600),接着调用如下服务的systemRunning方法:
- locationF.systemRunning
- countryDetectorF.systemRunning
- networkTimeUpdaterF.systemRunning
- commonTimeMgmtServiceF.systemRunning
- inputManagerF.systemRunning
- telephonyRegistryF.systemRunning
- mediaRouterF.systemRunning
- mmsServiceF.systemRunning
- incident.systemRunning
4.7 PHASE_BOOT_COMPLETED(1000)
??在经过如上一系列流程,最终调用AMS.finishBooting()时,则进入阶段PHASE_BOOT_COMPLETED(1000)。 到此,系统服务启动阶段完成就绪,system_server进程启动完成则进入Looper.loop()状态,随时待命,等待消息队列MessageQueue中的消息到来,则马上进入执行状态。
5. 总结
??system_server进程启动篇章终于告一段落了,在后续篇章中我们将要讲述zygote进程怎么否孵化普通App进程的,这个也是后续篇章的重点,也是Android启动流程系列的最后一篇。
|