<Android开发> Android内核系统开发-启动过程详解(第3部分 系统关键服务的启动简析-续)
继上一篇讲解到handleChildProc这个函数会调用运行应用程序,应用程序经过一系列运行会执行到ActivityManagerService,这之间的详细过程,可查看相关应用程序的完整启动流程做详细的了解,后续作者有时间也会出相关文章。
下面开始继续分析。
当运行到ActivityManagerService中,ActivityManagerService会向Zygoye发起一个创建进程的请求。内容如下:
/* frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java */
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
mProcessList.startProcessLocked的内容如下:
/* frameworks/base/services/core/java/com/android/server/am/ProcessList.java */
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkSlow(startTime, "startProcess: after getProcessRecord");
if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
// If we are in the background, then check to see if this process
// is bad. If so, we will just silently fail.
if (mService.mAppErrors.isBadProcessLocked(info)) {
if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
+ "/" + info.processName);
return null;
}
} else {
// When the user is explicitly starting a process, then clear its
// crash count so that we won't make it bad until they see at
// least one crash dialog again, and make the process good again
// if it had been bad.
if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
+ "/" + info.processName);
mService.mAppErrors.resetProcessCrashTimeLocked(info);
if (mService.mAppErrors.isBadProcessLocked(info)) {
EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
UserHandle.getUserId(info.uid), info.uid,
info.processName);
mService.mAppErrors.clearBadProcessLocked(info);
if (app != null) {
app.bad = false;
}
}
}
} else {
// If this is an isolated process, it can't re-use an existing process.
// 如果这是一个孤立的进程,它不能重用现有的进程。
app = null;
}
// We don't have to do anything more if:
// (1) There is an existing application record; and
// (2) The caller doesn't think it is dead, OR there is no thread
// object attached to it so we know it couldn't have crashed; and
// (3) There is a pid assigned to it, so it is either starting or
// already running.
// 如果我们不需要再做任何事情
// (1) 已有申请记录; 和
// (2) 调用者不认为自己死了,或者没有线程 附加到它的对象,所以我们知道它不可能崩溃; 和
// (3) 有一个 pid 分配给它,所以它要么正在启动,要么已经在运行。
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
+ " app=" + app + " knownToBeDead=" + knownToBeDead
+ " thread=" + (app != null ? app.thread : null)
+ " pid=" + (app != null ? app.pid : -1));
if (app != null && app.pid > 0) {
if ((!knownToBeDead && !app.killed) || app.thread == null) {
// We already have the app running, or are waiting for it to
// come up (we have a pid but not yet its thread), so keep it.
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
checkSlow(startTime, "startProcess: done, added package to proc");
return app;
}
// An application record is attached to a previous process,
// clean it up now.
// 应用程序记录附加到前一个进程,现在清理它。
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
checkSlow(startTime, "startProcess: bad proc running, killing");
ProcessList.killProcessGroup(app.uid, app.pid);
mService.handleAppDiedLocked(app, true, true);
checkSlow(startTime, "startProcess: done killing old proc");
}
if (app == null) {
checkSlow(startTime, "startProcess: creating new process record");
app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
if (app == null) {
Slog.w(TAG, "Failed making new process record for "
+ processName + "/" + info.uid + " isolated=" + isolated);
return null;
}
app.crashHandler = crashHandler;
app.isolatedEntryPoint = entryPoint;
app.isolatedEntryPointArgs = entryPointArgs;
checkSlow(startTime, "startProcess: done creating new process record");
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
checkSlow(startTime, "startProcess: added package to existing proc");
}
// If the system is not ready yet, then hold off on starting this
// process until it is.
// 如果系统还没有准备好,则推迟启动这个过程,直到它准备好。
if (!mService.mProcessesReady
&& !mService.isAllowedWhileBooting(info)
&& !allowWhileBooting) {
if (!mService.mProcessesOnHold.contains(app)) {
mService.mProcessesOnHold.add(app);
}
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
"System not ready, putting on hold: " + app);
checkSlow(startTime, "startProcess: returning with proc on hold");
return app;
}
checkSlow(startTime, "startProcess: stepping in to startProcess");
final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
checkSlow(startTime, "startProcess: done starting proc!");
return success ? app : null;
}
向zygote发起请求的流程是:
(1)final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge)
(路径:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)
(2)mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid /, keepIfLarge,
null / ABI override /, null / entryPoint /, null / entryPointArgs /,
null / crashHandler */)
(路径:frameworks/base/services/core/java/com/android/server/am/ProcessList.java)
(3)startProcessLocked(app, hostingRecord, abiOverride)
(路径: frameworks/base/services/core/java/com/android/server/am/ProcessList.java)
(4)startProcessLocked(app, hostingRecord,
false /* disableHiddenApiChecks /, false / mountExtStorageFull */, abiOverride)
(路径: frameworks/base/services/core/java/com/android/server/am/ProcessList.java)
(5)startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
startTime)
(路径: frameworks/base/services/core/java/com/android/server/am/ProcessList.java)
最后一层函数的内容如下:
/* frameworks/base/services/core/java/com/android/server/am/ProcessList.java */
@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord,
String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
app.pendingStart = true;
app.killedByAm = false;
app.removed = false;
app.killed = false;
if (app.startSeq != 0) {
Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
+ " with non-zero startSeq:" + app.startSeq);
}
if (app.pid != 0) {
Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
+ " with non-zero pid:" + app.pid);
}
final long startSeq = app.startSeq = ++mProcStartSeqCounter;
app.setStartParams(uid, hostingRecord, seInfo, startTime);
app.setUsingWrapper(invokeWith != null
|| SystemProperties.get("wrap." + app.processName) != null);
mPendingStarts.put(startSeq, app);
if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
"Posting procStart msg for " + app.toShortString());
mService.mProcStartHandler.post(() -> {
try {
final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
synchronized (mService) {
handleProcessStartedLocked(app, startResult, startSeq);
}
} catch (RuntimeException e) {
synchronized (mService) {
Slog.e(ActivityManagerService.TAG, "Failure starting process "
+ app.processName, e);
mPendingStarts.remove(startSeq);
app.pendingStart = false;
mService.forceStopPackageLocked(app.info.packageName,
UserHandle.getAppId(app.uid),
false, false, true, false, false, app.userId, "start failure");
}
}
});
return true;
} else {
try {
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
invokeWith, startTime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
} catch (RuntimeException e) {
Slog.e(ActivityManagerService.TAG, "Failure starting process "
+ app.processName, e);
app.pendingStart = false;
mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
false, false, true, false, false, app.userId, "start failure");
}
return app.pid > 0;
}
}
其中最重要的之一是运行到
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
invokeWith, startTime);
Process的字面意思虽然是进程,但其实它只属于“进程类”,或者称为“进程管家”会贴切些。startProcess虽然是去启动一个新的进程以承载业务,而函数的第二个参数entryPoint,由各函数的传参可知默认固定为“android.app.ActivityThread”。ActivityManagerService传递过来的字符串形式的参数列表会被Arguments,parseArgs解析成Arguments中的各成员变量,如下表所示:
参数格式 | 对应的成员变量 |
---|---|
“–setuid–” | uid |
“–setgid–” | gid |
“–target-sdk-version=” | targetSdkVersion |
“–runtime-init” | runtiomeInit |
“-classpath” | classpath |
“–nice-name=” | nicename |
剩余参数 | remianingArgs |
由前面的函数跳转流程知entryPoint的值默认固定为“android.app.ActivityThread”。换句话说,Zygote中主动执行的类是ActivityThread,这同时也是我们熟知的Android应用程序的“主线程”。函数内容如下:
/* frameworks/base/core/java/android/app/ActivityThread.java */
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// Install selective syscall interception
// 安装选择性系统调用拦截
AndroidOs.install();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
// CloseGuard 默认为 true 并且可能非常垃圾。 我们在这里禁用它,
// 但稍后在调试版本中选择性地启用它(通过 StrictMode),但使用 DropBox,而不是日志。
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
// 确保受信任的证书存储在正确的位置查找 CA 证书
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
// 如果在命令行中提供,则查找 {@link #PROC_START_SEQ_IDENT} 的值。
// 格式为“seq=114”
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
// 事件结束 ActivityThreadMain
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
到目前为止,已经分析了Zygote作为守护进程时,如何为android应用程序的启动而服务的。接下来的内容中,将分析它的另一方面的工作,即引导系统各重要服务的启动过程。
从前面的分析可知,System Server的启动是在forkSystemServer中完成的。Zygote首先会利用Zygote.forkSystemServer来孵化出一个子进程,然后pid=0的分支中调用handleSystemServerProcess,后者在函数的末尾又会进一步调用ZygoteInit.zygoteInit。ZygoteInit.zygoteInit函数的内容如下:
/* frameworks/base/core/java/com/android/internal/os/ZygoteInit.java */
/**
* 通过zygote进程启动时调用的main函数。 如果 nativeFinishInit() 中的本机代码通过 Zygote 启动进行合理化,这可以与 main() 统一。<p>
*
* 当前公认的参数:
* <ul>
* <li> <code> [--] <开始类名> <参数>
* </ul>
*
* @param targetSdkVersion 目标 SDK 版本
* @param argv 参数字符串
*/
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);
}
函数zygoteInit通过3个方面来完成初始化,分别是:
-
commonInit
通用部分的初始化,包括设置默认的uncaught、exception、handler(具体对应的是RuntimeInit中的UncaughtHandler类);为HttpURLConnection准备好默认的HTTP User-Agent( User Agent包含了与系统浏览器相关的一系列信息,如“Dalvik/1.1.0(Linux;U;Android Eclair Build/MASTER)”.);开启trace模式(只在emulator下才有必要)等。 -
nativityZygoteInit
这是一个本地初始化函数,也是zygoteInit中的重点,后面会重点分析。 -
applicationInit
这个函数的声明为 protected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader);从中可看出它是程序运行的“起点”。在这里 程序指的是“System Service”,而“入口”是什么呢?这就和第二个参数argv有关系。这个String[]实际上包含了两个重要的成员变量,即startClass和startArgs。而这两个变量的赋值可以追溯到forkSystemServer中,具体代码如下:
/* frameworks/base/core/java/com/android/internal/os/ZygoteInit.java ---》forkSystemServer() */
/* Hardcoded command line to start the system server */
/* 硬编码命令行启动系统服务器 */
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",
};
根据实际的参数列表,startClass对应的就是"com.android.server.SystemServer"。因而applicationInit最终将调用main@SystemServer,内容如下:
/* frameworks/base/services/java/com/android/server/SystemServer.java */
/**
* The main entry point from zygote.
* zygote 的主要入口点。
*/
public static void main(String[] args) {
new SystemServer().run();
}
经过上面的初始化后,程序现在会有两个分支,其一是nativeZygoteInit主导的本地系统服务的启动;另一个则是applicationInit负责的Java层系统服务的启动。
(1)本地系统服务的启动
在JNI机制中,Native函数在Java层会有一个声明,然后在本地层得到真正的实现。那么当我们调用了Java层的函数后,系统是如何找到Native中与之对应的函数的呢?通常情况下,Native中的c++文件命名是以Java层的package为基础的,如Java层的包名为com.android.internal.xxx,那么其对应的JNI层文件则是com_android_internal_xxx。不过这种对应关系并不是绝对不变的,可以根据开发人员的需求进行调整。比如前面讲解的ZygoteInit所在的Java包是com.android.internal.os,而实际上JNI的实现则为AndroidRuntime.cpp。开发人员一定要学会这其中的规则,才能快速找到自身所需的资源。AndroidRuntime表面这个class的任务是“负责Android的运行时环境”。当我们调用了nativeZygoteInit后,实际上是执行了com_android_os_RuntimeInit_nativeZygoteInit@AndroidRntime.cpp,如下所示:
/* frameworks/base/core/jni/AndroidRuntime.cpp */
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
全局变量gCurRuntime是一个AndroidRuntime的对象,结合前面学习的内容,大家应该能够想到实际上AndroidRuntime是一个父类,真正的实现则在App_main.cpp中的AppRuntime。当我们新建AppRuntime对象时,它的父类的构造函数就会被调用,并为gCurRuntime赋值。上述的onZygoteInit也在这个App_main.cpp文件中,内容如下:
/* frameworks/base/cmds/app_process/app_main.cpp */
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
上面这段代码时Binder机制中的重要组成部分,其中startThreadPool将开启Binder线程池以保证其它进程可以正确访问到Zygote所提供的服务。Zygote通过JNI和回调的方式非常巧妙地把本地层和Java层、SystemServer和app process关联起来了。
关于Binder的更多信息,后续作者将出更多文章讲解分析。
(2)Java层系统服务的启动
Java层的系统服务比较多,它们各司其职,缺一不可。我们知道,zygote会为System Server的运行启动和初始化虚拟机,并通过入口main@SystemServer.java开启“系统服务之旅”。不过main函数只是起到“门”的作用,它又直接调用SystemServer().run(),而后者才是真正是实现服务的地方,函数内容如下:
/* frameworks/base/services/java/com/android/server/SystemServer.java */
private void run() {
try {
traceBeginAndSlog("InitBeforeStartServices");
// Record the process start information in sys props.
// 在 sys props 中记录进程启动信息。
SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));
SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));
EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
// java.io.File#setLastModified, so instead we fake it and
// hope that time from cell towers or NTP fixes it shortly.
// 如果设备的时钟在 1970 年之前(0 之前),很多 API 在处理负数时会崩溃,
// 尤其是 java.io.File#setLastModified,
// 所以我们伪造它并希望来自手机信号塔或 NTP 的时间能很快修复它 .
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//
// Default the timezone property to GMT if not set.
// 如果未设置,则默认时区属性为 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");
}
// If the system has "persist.sys.language" and friends set, replace them with
// "persist.sys.locale". Note that the default locale at this point is calculated
// using the "-Duser.locale" command line flag. That flag is usually populated by
// AndroidRuntime using the same set of system properties, but only the system_server
// and system apps are allowed to set them.
//
// NOTE: Most changes made here will need an equivalent change to
// core/jni/AndroidRuntime.cpp
// 如果系统设置了“persist.sys.language”和friends,则替换为“persist.sys.locale”。
// 请注意,此时的默认语言环境是使用“-Duser.locale”命令行标志计算的。
// 该标志通常由 AndroidRuntime 使用相同的系统属性集填充,但仅允许 system_server 和系统应用程序设置它们。
// 注意:此处所做的大多数更改都需要对 core/jni/AndroidRuntime.cpp 进行等效更改
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
// The system server should never make non-oneway calls
// 系统服务器不应该进行非单向调用
Binder.setWarnOnBlocking(true);
// The system server should always load safe labels
// 系统服务器应该总是加载安全标签
PackageItemInfo.forceSafeLabels();
// Default to FULL within the system server.
// 在系统服务器中默认为 FULL。
SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;
// Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
// 停用 SQLiteCompatibilityWalFlags,直到设置提供程序被初始化
SQLiteCompatibilityWalFlags.init(null);
// Here we go!
// 开始了!
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);
}
// In case the runtime switched since last boot (such as when
// the old runtime was removed in an OTA), set the system
// property so that it is in sync. We can | xq oqi't do this in
// libnativehelper's JniInvocation::Init code where we already
// had to fallback to a different runtime because it is
// running as root and we need to be the system user to set
// the property. http://b/11463182
// 如果运行时自上次启动后切换(例如在 OTA 中删除旧运行时),请设置系统属性以使其同步。
// 我们可以 | xq oqi 不会在 libnativehelper 的 JniInvocation::Init 代码中执行此操作,
// 我们已经不得不退回到不同的运行时,因为它以 root 身份运行并且我们需要成为系统用户来设置属性。
// http://b/11463182
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Mmmmmm... more memory!
// 嗯嗯……更多内存!
VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
// 系统服务器必须一直运行,因此它需要尽可能高效地使用内存。
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
// Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
// 某些设备依赖于运行时指纹生成,因此请确保我们在进一步启动之前已对其进行了定义。
Build.ensureFingerprintProperty();
// Within the system server, it is an error to access Environment paths without
// explicitly specifying a user.
// 在系统服务器中,在没有明确指定用户的情况下访问环境路径是错误的。
Environment.setUserRequired(true);
// Within the system server, any incoming Bundles should be defused
// to avoid throwing BadParcelableException.
// 在系统服务器中,任何传入的 Bundles 都应该被解散以避免抛出 BadParcelableException。
BaseBundle.setShouldDefuse(true);
// Within the system server, when parceling exceptions, include the stack trace
// 在系统服务器内,打包异常时,包括堆栈跟踪
Parcel.setStackTraceParceling(true);
// Ensure binder calls into the system always run at foreground priority.
// 确保对系统的绑定调用始终以前台优先级运行。
BinderInternal.disableBackgroundScheduling(true);
// Increase the number of binder threads in system_server
// 增加system_server中的binder线程数
BinderInternal.setMaxThreads(sMaxBinderThreads);
// Prepare the main looper thread (this thread).
// 准备主looper线程(这个线程)。
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper(); //准备循环主体
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
// Initialize native services.
// 初始化原生服务。
System.loadLibrary("android_servers"); //加载本地服务库
// Debug builds - allow heap profiling.
// 调试构建 - 允许堆分析。
if (Build.IS_DEBUGGABLE) {
initZygoteChildHeapProfiling();
}
// Check whether we failed to shut down last time we tried.
// This call may not return.
// 检查我们上次尝试是否关闭失败。 此调用可能不会返回。
performPendingShutdown();
// Initialize the system context.
// 初始化系统上下文。
createSystemContext();
// Create the system service manager.
// 创建系统服务管理器。
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
// 为可并行化的 init 任务准备线程池
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices // 启动服务前初始化
}
// Start services.
// 启动服务。
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices(); //分别启动各种类型的 System Server
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);
}
}
// Diagnostic to ensure that the system is in a base healthy state. Done here as a common
// non-zygote process.
// 诊断以确保系统处于基本健康状态。 在这里作为一个常见的非合子过程完成。
if (!VMRuntime.hasBootImageSpaces()) {
Slog.wtf(TAG, "Runtime is not running with a boot image!");
}
// Loop forever.
// 永远循环。
Looper.loop(); //进入死循环,直到关机
throw new RuntimeException("Main thread loop unexpectedly exited");
}
SystemServer在启动前首先要做很多初始化设置,包括VM的版本记录到系统变量中,设置线程优先级,设置堆的使用率等。我们知道Android系统服务会被分为两类,其一是Java层的,其二是本地层的。后者具体是由System.loadLibrary(“android_servers”)实现的,而Java层的服务将在接下来分析。
通过以上分析,可知app_process就是系统服务的“根据地”/它在init进程的帮助下,通过Zygote逐步建立起各SystemServer的运行环境,继而为上层的“繁殖壮大”提供“土壤环境”。
#1
#2
#3
#4
#5
#6
Android的“系统服务”------SystemServer
SystemServer是Android进入Launcher前的最后准备。由其名称就可看出,它提供了众多由Java语言编写的“系统服务”。
由前面的分析可知,一旦我们在init.rc中为Zygote指定了启动参数–start-system-server,那么ZygoteInit就会调用startSystemServer来进入SystemServer。而且系统服务有分别分为Java层和本地层两类。其中native层的服务的实现体现在android_servers中,需要在run@SystemServer中首先通过System.loadLibrary(“android_servers”)加载到内存中才能使用。这部分实现在各个android版本都有所不同,在其它版本中System.loadLibrary(“android_servers”)后面会紧接着有"nativeInit();//本地服务初始化",而nativeInit的实际内容是包含Sensor服务的, 但是高通的8155板子用的LA1.1基线代码在System.loadLibrary(“android_servers”)后面是没有nativeInit()的,高通将Sensor服务的相关服务初始化放到了startBootstrapServices()函数中。run@SystemServer中启动的服务包含三个方面,分别如下:
(1)startBootstrapServices(); //最先启动的服务
(2)startCoreServices(); //核心服务
(3)startOtherServices(); //分别启动各种类型的 System Server
接下来先讲解startBootstrapServices()函数,并分析Sensor有关服务。
Bootstrap Services
Bootstrap的原意是“引导程序”,用在这里则代表系统服务中最核心的那一部分。另外,这些Services间相互的依赖关系比较强,因而需要在一起统一管理启动,具体对应的是startBootstrapServices()这个函数。按照Android的建议,如果自己添加的系统服务和它们也有比较强的依赖,那么可以与这个系统服务统一放置,否则应该考虑下面所述的另外两类服务,startBootstrapServices由run@SystemServer调用; 下面的是startBootstrapServices()函数的内容:
/* frameworks/base/services/java/com/android/server/SystemServer.java */
/**
* Starts the small tangle of critical services that are needed to get the system off the
* ground. These services have complex mutual dependencies which is why we initialize them all
* in one place here. Unless your service is also entwined in these dependencies, it should be
* initialized in one of the other functions.
*/
/* 启动系统启动所需的关键服务的小纠结。 这些服务具有复杂的相互依赖关系,
* 这就是我们在这里将它们全部初始化的原因。 除非您的服务也与这些依赖关系交织在一起,
* 否则它应该在其他函数之一中初始化。
*/
private void startBootstrapServices() {
// Start the watchdog as early as possible so we can crash the system server
// if we deadlock during early boot
// 尽早启动看门狗,这样如果我们在早期启动过程中死锁,我们可以使系统服务器崩溃
traceBeginAndSlog("StartWatchdog"); //跟踪开始和 Slog
final Watchdog watchdog = Watchdog.getInstance();
watchdog.start();
traceEnd(); //跟踪结束
Slog.i(TAG, "Reading configuration...");
final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
traceBeginAndSlog(TAG_SYSTEM_CONFIG); //跟踪开始和 Slog
SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
traceEnd(); //跟踪结束
// Wait for installd to finish starting up so that it has a chance to
// create critical directories such as /data/user with the appropriate
// permissions. We need this to complete before we initialize other services.
// 等待 installd 完成启动,以便它有机会创建具有适当权限的关键目录,
// 例如 /data/user。 我们需要在初始化其他服务之前完成此操作。
traceBeginAndSlog("StartInstaller"); //跟踪开始和 Slog
Installer installer = mSystemServiceManager.startService(Installer.class);
traceEnd();//跟踪结束
// In some cases after launching an app we need to access device identifiers,
// therefore register the device identifier policy before the activity manager.
// 在某些情况下启动应用后我们需要访问设备标识符,因此在活动管理器之前注册设备标识符策略。
traceBeginAndSlog("DeviceIdentifiersPolicyService"); //跟踪开始和 Slog
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
traceEnd(); //跟踪结束
// Uri Grants Manager.
// Uri 授权管理器。
traceBeginAndSlog("UriGrantsManagerService");
mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
traceEnd(); //跟踪结束
// Activity manager runs the show.
// 活动管理器运行节目。
traceBeginAndSlog("StartActivityManager");//跟踪开始和 Slog
// TODO: Might need to move after migration to WM.
// TODO: 迁移到 WM 后可能需要移动。
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
traceEnd();//跟踪结束
// Power manager needs to be started early because other services need it.
// Native daemons may be watching for it to be registered so it must be ready
// to handle incoming binder calls immediately (including being able to verify
// the permissions for those calls).
// 电源管理器需要尽早启动,因为其他服务需要它。
// 本机守护进程可能正在监视它以进行注册,
// 因此它必须准备好立即处理传入的绑定器调用(包括能够验证这些调用的权限)。
traceBeginAndSlog("StartPowerManager"); //跟踪开始和 Slog
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
traceEnd(); //跟踪结束
traceBeginAndSlog("StartThermalManager");
mSystemServiceManager.startService(ThermalManagerService.class);
traceEnd();
// Now that the power manager has been started, let the activity manager
// initialize power management features.
// 现在电源管理器已经启动,让活动管理器初始化电源管理功能。
traceBeginAndSlog("InitPowerManagement"); //跟踪开始和 Slog
mActivityManagerService.initPowerManagement();
traceEnd(); //跟踪结束
// Bring up recovery system in case a rescue party needs a reboot
// 启动恢复系统以防救援方需要重启
traceBeginAndSlog("StartRecoverySystemService"); //跟踪开始和 Slog
mSystemServiceManager.startService(RecoverySystemService.class);
traceEnd();//跟踪结束
// Now that we have the bare essentials of the OS up and running, take
// note that we just booted, which might send out a rescue party if
// we're stuck in a runtime restart loop.
// 现在我们已经启动并运行了操作系统的基本要素,请注意我们刚刚启动,
// 如果我们陷入运行时重启循环,它可能会派出救援队。
RescueParty.noteBoot(mSystemContext);
// Manages LEDs and display backlight so we need it to bring up the display.
// 管理 LED 和显示屏背光,因此我们需要它来调出显示屏。
traceBeginAndSlog("StartLightsService"); //跟踪开始和 Slog
mSystemServiceManager.startService(LightsService.class);
traceEnd();//跟踪结束
traceBeginAndSlog("StartSidekickService");
// Package manager isn't started yet; need to use SysProp not hardware feature
// 包管理器尚未启动; 需要使用 SysProp 而不是硬件功能
if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {
mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
}
traceEnd();//跟踪结束
// Display manager is needed to provide display metrics before package manager
// starts up.
// 显示管理器需要在包管理器启动之前提供显示指标。
traceBeginAndSlog("StartDisplayManager"); //跟踪开始和 Slog
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
traceEnd();//跟踪结束
// We need the default display before we can initialize the package manager.
// 在初始化包管理器之前,我们需要默认显示。
traceBeginAndSlog("WaitForDisplay"); //跟踪开始和 Slog
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
traceEnd(); //跟踪结束
// Only run "core" apps if we're encrypting the device.
// 如果我们正在加密设备,则只运行“核心”应用程序。
String cryptState = VoldProperties.decrypt().orElse("");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
// Start the package manager.
// 启动包管理器。
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_package_manager_init_start",
(int) SystemClock.elapsedRealtime());
}
traceBeginAndSlog("StartPackageManagerService"); //跟踪开始和 Slog
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
traceEnd(); //跟踪结束
if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
MetricsLogger.histogram(null, "boot_package_manager_init_ready",
(int) SystemClock.elapsedRealtime());
}
// Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
// A/B artifacts after boot, before anything else might touch/need them.
// Note: this isn't needed during decryption (we don't have /data anyways).
// 管理 A/B OTA dexopting。 这是一个引导服务,因为我们需要它在引导后重命名 A/B 工件,
// 在其他任何东西可能触及/需要它们之前。 注意:解密期间不需要这(我们没有 /data 反正)。
if (!mOnlyCore) {
boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
false);
if (!disableOtaDexopt) {
traceBeginAndSlog("StartOtaDexOptService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("moveab");
OtaDexoptService.main(mSystemContext, mPackageManagerService);
} catch (Throwable e) {
reportWtf("starting OtaDexOptService", e);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("moveab");
traceEnd();
}
}
}
traceBeginAndSlog("StartUserManagerService"); //跟踪开始和 Slog
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
traceEnd(); //跟踪结束
// Initialize attribute cache used to cache resources from packages.
// 初始化用于缓存包资源的属性缓存。
traceBeginAndSlog("InitAttributerCache"); //跟踪开始和 Slog
AttributeCache.init(mSystemContext);
traceEnd(); //跟踪结束
// Set up the Application instance for the system process and get started.
// 为系统进程设置应用程序实例并开始。
traceBeginAndSlog("SetSystemProcess"); //跟踪开始和 Slog
mActivityManagerService.setSystemProcess();
traceEnd(); //跟踪结束
// Complete the watchdog setup with an ActivityManager instance and listen for reboots
// Do this only after the ActivityManagerService is properly started as a system process
// 使用 ActivityManager 实例完成看门狗设置并监听重启 仅在 ActivityManagerService 作为系统进程正确启动后执行此操作
traceBeginAndSlog("InitWatchdog"); //跟踪开始和 Slog
watchdog.init(mSystemContext, mActivityManagerService);
traceEnd(); //跟踪结束
// DisplayManagerService needs to setup android.display scheduling related policies
// since setSystemProcess() would have overridden policies due to setProcessGroup
// DisplayManagerService 需要设置 android.display 调度相关的策略,
// 因为 setSystemProcess() 会因为 setProcessGroup 而被覆盖策略
mDisplayManagerService.setupSchedulerPolicies();
// Manages Overlay packages
// 管理覆盖包
traceBeginAndSlog("StartOverlayManagerService"); //跟踪开始和 Slog
mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
traceEnd(); //跟踪结束
traceBeginAndSlog("StartSensorPrivacyService"); //跟踪开始和 Slog
mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext));
traceEnd(); //跟踪结束
if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {
// DisplayManager needs the overlay immediately.
mActivityManagerService.updateSystemUiContext();
LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();
}
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
// Start sensor service in a separate thread. Completion should be checked
// before using it.
// 传感器服务需要访问包管理服务、应用操作服务和权限服务,因此我们在它们之后启动它。
// 在单独的线程中启动传感器服务。 使用前应检查是否完成。
mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(START_SENSOR_SERVICE);
startSensorService();
traceLog.traceEnd();
}, START_SENSOR_SERVICE);
}
从startBootstrapServices的内容中可看到,函数内调用最多的语句是mSystemServiceManager.startService。这和旧版本的Android系统中服务“各自为政”的做法有不小差异,换句话说,目前所有SystemService都统一由SystemServiceManager来管理。
在函数startBootstrapServices中可看到,是先通过SystemServiceManager启动Installer,这是为了Installer可以优先完成初始化,并完成关键目录(如/data/user)的创建。这些都是其它服务可以顺利启动的先决条件。接下来启动的系统服务是ActivityManagerService,作者将在后续出相关文章分析,这里就不赘述。
在AMS(ActivityManagerService)之后相继启动的服务包括电源管理PowerManager、终端管理ThermalManager、恢复系统服务RecoverySystemService、LED和显示屏背光服务LightsService、显示管理DisplayManager、包管理服务PackageManagerService等等。最后调用“mActivityManagerService.setSystemProcess();”来添加进程相关的服务,如meminfo、gfxinfo、dbinfo、cpuinfo等。从而完成最核心部分系统服务的启动。
在startBootstrapServices函数最后调用了startSensorService(),这是用来启动和初始化Sensor的,Android系统中的Sensor可以理解为比较小的硬件器件,如光线传感器、陀螺仪、重力感应等。它们在属性特征上相对一致,而在数据量上则普遍不大。传统的Android模拟器对其中一些Sensor实现了简单的模拟,功能有限。市面上也有一些厂商为了便于开发者调试应用程序,推出了专门的器件模拟功能,而且与IDE进行了“无缝集成”。有兴趣的读者可自行查阅相关资料。startSensorService函数内容如下:
/* frameworks/base/services/core/jni/com_android_server_SystemServer.cpp */
static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
SensorService::publish(false /* allowIsolated */,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
}
}
接下来是Core Services。
Core Services
Core Services相对BootStrap的优先级略底,主要包括电池电量管理、应用程序使用情况管理、binder 调用中花费的 cpu 时间、处理程序中处理消息所花费的时间、管理 apk 回滚、捕获错误报告的服务、GPU 和 GPU 驱动程序的服务等。startCoreServices()函数内容如下:
/* frameworks/base/services/java/com/android/server/SystemServer.java */
/**
* Starts some essential services that are not tangled up in the bootstrap process.
* 启动一些在引导过程中没有纠结的基本服务。
*/
private void startCoreServices() {
traceBeginAndSlog("StartBatteryService");
// Tracks the battery level. Requires LightService.
// 跟踪电池电量。 需要 LightService。
mSystemServiceManager.startService(BatteryService.class);
traceEnd();
// Tracks application usage stats.
// 跟踪应用程序使用情况统计。
traceBeginAndSlog("StartUsageService");
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
traceEnd();
// Tracks whether the updatable WebView is in a ready state and watches for update installs.
// 跟踪可更新的 WebView 是否处于就绪状态并监视更新安装。
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
traceBeginAndSlog("StartWebViewUpdateService");
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
traceEnd();
}
// Tracks and caches the device state.
// 跟踪和缓存设备状态。
traceBeginAndSlog("StartCachedDeviceStateService");
mSystemServiceManager.startService(CachedDeviceStateService.class);
traceEnd();
// Tracks cpu time spent in binder calls
// 跟踪在 binder 调用中花费的 cpu 时间
traceBeginAndSlog("StartBinderCallsStatsService");
mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);
traceEnd();
// Tracks time spent in handling messages in handlers.
// 跟踪处理程序中处理消息所花费的时间。
traceBeginAndSlog("StartLooperStatsService");
mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);
traceEnd();
// Manages apk rollbacks.
// 管理 apk 回滚。
traceBeginAndSlog("StartRollbackManagerService");
mSystemServiceManager.startService(RollbackManagerService.class);
traceEnd();
// Service to capture bugreports.
// 捕获错误报告的服务。
traceBeginAndSlog("StartBugreportManagerService");
mSystemServiceManager.startService(BugreportManagerService.class);
traceEnd();
// Serivce for GPU and GPU driver.
// GPU 和 GPU 驱动程序的服务。
traceBeginAndSlog("GpuService");
mSystemServiceManager.startService(GpuService.class);
traceEnd();
}
Other Services
OtherServices这部分服务在3类服务中优先级最低,但数量却是最多。比如AccountManagerService、VibratorService、StatsCompanionService、IncidentCompanionService、MmsService、ClipboardService、AppServiceManager、LauncherAppsService、MediaProjectionManager、BiometricService、MediaRouterService、StartMidiManager、WiredAccessoryManager、WifiScanningService等。这些服务全面构筑起Android系统这座“参天大厦”,为其他进程、应用程序的正常运行奠定了基础。由于startOtherServices()函数内容多长,这里就不贴出源码了。
至此,SystemServer通过Looper.loop()进入长循环中,并依托onZygoteInit中启动的Binder系统服务接受和处理外界的请求,android系统自此开始。