SystemServer 是系统的核心之一,大部分android提供的服务都运行在这个进程中,SystemServer 中运行的服务大概有八十多种。为了防止应用进程对系统造成破坏,Android应用进程没有权限直接访问设备的底层资源,只能通过 SystemServer 中的服务代理访问。通过 Binder 用户进程使用 SystemServer 中的服务并没有太多不便之处。
创建 SystemServer 进程
- 之前讲过,Init.rc 中引用了 import /init.${ro.zygote}.rc ,实际上对应zygote 服务启动参数里面包含如下内容:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
因此,在 ZygoteInit 的 main 方法中调用了如下代码创建 SystemServer
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
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;
}
forkSystemServer 主要做了以下几件事
- 第一件事 准备启动参数,可以看到 uid 和 gid 都为 1000;它的可执行文件为 package com.android.server.SystemServer
- 第二件事 调用 Zygote.forkSystemServer fork 出 SystemServer 进程。下面贴出了 Zygote.java 中 forkSystemServer 方法,其中也是调用了 nativeForkSystemServer() 方法。其对应的 native 函数在 com_android_internal_os_Zygote.cpp 文件中。
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;
}
- nativeForkSystemServer
Zygote 会检查 SystemServer 是否启动成功,如果启动失败则会重启Zygote进程
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) {
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!");
}
bool low_ram_device = GetBoolProperty("ro.config.low_ram", false);
bool per_app_memcg = GetBoolProperty("ro.config.per_app_memcg", low_ram_device);
if (per_app_memcg) {
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;
}
上面代码调用了 ForkAndSpecializeCommon() 函数来fork 进程,在这个方法中调用了 SetSignalHandlers(); 函数。 还调用了 SigChldHandler 函数处理 SIGCHLD 信号,代码如下
static void SigChldHandler(int ) {
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
if (pid == gSystemServerPid) {
ALOGE("Exit zygote because system server (%d) has terminated", pid);
kill(getpid(), SIGKILL);
}
}
}
继续回到 Zygote.Init 的 forkSystemServer函数
第三件事:fork() 出子进程后,调用了 handleSystemServerProcess() 来初始化 SystemServer
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
- handleSystemServerProcess() 如下注释操作;最后会执行到 SystemServer 的 main() 方法
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);
}
}
SystemServer 初始化
- SystemServer 的入口如下:new 了一个 SystemServer 并执行 run 方法
public static void main(String[] args) {
new SystemServer().run();
}
- run
主要任务: 设置 JVM 运行库路径 调整系统时间 设置虚拟机堆利用率 装载 libandroid_services.so 库 获取 system context.设置 Context 创建并运行所有 Java 服务 Looper.loop() 开始消息循环
private void run() {
try {
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", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
Binder.setWarnOnBlocking(true);
PackageItemInfo.setForceSafeLabels(true);
SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;
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.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);
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);
}
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
- createSystemContext() ; 调用了 ActivityThread的静态方法 systemMain();得到了 ActivityThread对象,然后通过activityThread.getSystemContext 获取 Context 对象。并设置主题
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);
}
- ActivityThread.systemMain();
从下面代码中可以看出,在 systemMain中创建了 ActivityThread 对象。然后使用 true 调用了 thread.attach(true, 0);
public static ActivityThread systemMain() {
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
- 为什么 SystemServer 需要创建 ActivityThread 呢?
Zygote启动应用后将执行 main 方法,这里实际上 SystemServer 不仅是一个后台进程,它也是运行着组件 Service 的进程。很多系统对话框都是从 SystemServer 弹出的。因此 SystemServer 也需要上下文环境,attach方法传入 true 代表 SystemServer 中调用的。主要代码代码如下:
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);
}
那么 SystemServer 对应 的 apk 是哪个呢?
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
上面这行代码 getSystemContext() 在 mContetxt为null的情况 调用了 ContextImpl.createSystemContext
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
- ContextImpl.createSystemContext
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;
}
LoadedApk 用来保存一个 apk 信息,这个构造方法传入为使用 “android” 为包名而 framework_res.apk 的包名为 android 。所以启动的为 framework_res.apk。再回述前面 attach 创建的 ContextImpl 实际上是复制 mSystemContext 对象,创建的 application 为 framework_res.apk。所以 systemMain 创建了 framework_res.apk 的上下文环境。
|