赞
踩
SystemServer 是系统的核心之一,大部分android提供的服务都运行在这个进程中,SystemServer 中运行的服务大概有八十多种。为了防止应用进程对系统造成破坏,Android应用进程没有权限直接访问设备的底层资源,只能通过 SystemServer 中的服务代理访问。通过 Binder 用户进程使用 SystemServer 中的服务并没有太多不便之处。
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
因此,在 ZygoteInit 的 main 方法中调用了如下代码创建 SystemServer
if (startSystemServer) {
// 准备 SystemServer 参数并且 fork 出 SystemServer 进程
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) { // 代码略..... /* Hardcoded command line to start the system server */ // 准备参数 ,可以看到 进程 ID 和 组ID 都为 1000 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; } /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.runtimeFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } /* For child process */ 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();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
}
VM_HOOKS.postForkCommon();
return pid;
}
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) { // fork 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) { // The zygote process checks whether the child process has died or not. ALOGI("System server process %d has been created", pid); gSystemServerPid = pid; // There is a slight window that the system server process has crashed // but it went unnoticed because we haven't published its pid yet. So // we recheck here just to make sure that all is well. 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) { // Assign system_server to the correct memory cgroup. // Not all devices mount /dev/memcg so check for the file first // to avoid unnecessarily printing errors and denials in the logs. 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 /*signal_number*/) {
//...
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
// ...
if (pid == gSystemServerPid) {
// 如果 SystemServer 死亡则退出 zygote
ALOGE("Exit zygote because system server (%d) has terminated", pid);
kill(getpid(), SIGKILL);
}
}
// ...
}
继续回到 Zygote.Init 的 forkSystemServer函数
第三件事:fork() 出子进程后,调用了 handleSystemServerProcess() 来初始化 SystemServer
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
/** * Finish remaining work for the newly forked system server process. */ private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) { // set umask to 0077 so new files and directories will default to owner-only permissions. // 将 SystemServer 进程umask设置成 0077 这样只有SystemServer可以访问 Os.umask(S_IRWXG | S_IRWXO); if (parsedArgs.niceName != null) { // 修改进程名为参数传入的 niceName (system_server) Process.setArgV0(parsedArgs.niceName); } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { performSystemServerDexOpt(systemServerClasspath); // Capturing profiles is only supported for debug or eng builds since selinux normally // prevents it. 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); } } } // invokeWith 通常为 null if (parsedArgs.invokeWith != null) { String[] args = parsedArgs.remainingArgs; // If we have a non-null system server class path, we'll have to duplicate the // existing arguments and append the classpath to it. ART will handle the classpath // correctly when we exec a new process. 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); } /* * Pass the remaining arguments to SystemServer. 在这里面会执行 SystemServer 的 main 方法。 */ return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } /* should never reach here */ }
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
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); } // // 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 (!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.setForceSafeLabels(true); // Default to FULL within the system server. SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL; // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized 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 // 下面设置一些虚拟机参数 运行路径 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. 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 BinderInternal.setMaxThreads(sMaxBinderThreads); // Prepare the main looper thread (this thread). 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. 装载 libandroid_servers.so 库 System.loadLibrary("android_servers"); // 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. 创建 SystemServiceManager 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 SystemServerInitThreadPool.get(); } finally { traceEnd(); // InitBeforeStartServices } // Start services. 启动所有的 Java service 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); } } // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
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);
}
public static ActivityThread systemMain() {
// The system process on low-memory devices do not get to use hardware
// accelerated drawing, since this can add too much overhead to the
// process.
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
Zygote启动应用后将执行 main 方法,这里实际上 SystemServer 不仅是一个后台进程,它也是运行着组件 Service 的进程。很多系统对话框都是从 SystemServer 弹出的。因此 SystemServer 也需要上下文环境,attach方法传入 true 代表 SystemServer 中调用的。主要代码代码如下:
// 如果传入 true 走下面代码 这里就像创建普通应用一样 创建了ContextImpl 还执行了 application 的 onCreate 方法
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;
}
}
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 的上下文环境。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。