Android SystemServer分析
一.Zygote到SystemServer
??SystemServer是由Zygote fork生成的,進程名為system_server,這個進程包含里framework中的核心服務,在Zygote的分析中有提到,SystemServer是在zygote中通過startSystemServer來調用起來
1.1 ZygoteInit.java中的startSystemServer函數
private static boolean startSystemServer(String abiList, String socketName)throws MethodAndArgsCaller, RuntimeException {…………../* 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,1032,3001,3002,3003,3006,3007","--capabilities=" + capabilities + "," + capabilities,"--nice-name=system_server","--runtime-args","com.android.server.SystemServer",};ZygoteConnection.Arguments parsedArgs = null;int pid;try {// 解析參數,將上面的字符串數據轉換成Arguments對象parsedArgs = new ZygoteConnection.Arguments(args);ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);/* Request to fork the system server process */// fork一個子進程,子進程就是system_server進程pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,parsedArgs.debugFlags,null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);} catch (IllegalArgumentException ex) {throw new RuntimeException(ex);}/* For child process */// ford返回值等于0,表明是子進程即system_server所在分支代碼if (pid == 0) {if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}// system_server進程所做的工作,在這里會啟動各種支撐系統運行的System serverhandleSystemServerProcess(parsedArgs);}return true; }1.2 Zygote.java中的forSystemServer函數
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {VM_HOOKS.preFork();int pid = nativeForkSystemServer(uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);// Enable tracing as soon as we enter the system_server.if (pid == 0) {Trace.setTracingEnabled(true);}VM_HOOKS.postForkCommon();return pid; }??nativeForkSystemServer會通過JNI調用com_android_internal_os_Zygote.cpp中的com_
android_internal_os_Zygote_nativeForkSystemServer方法。
1.3 Com_android_internal_os_Zygote.cpp中com_internal_os_Zygote_nativeForkSystemServer方法
static jint com_android_internal_os_Zygote_nativeForkSystemServer(JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,jlong effectiveCapabilities) {// 下面的調用會fork一個子進程pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,debug_flags, rlimits,permittedCapabilities, effectiveCapabilities,MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,NULL, NULL);if (pid > 0) {// pid>0 代表在Zygote進程內,下面檢測system_server進程是否已經創建// 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;// 等待子進程退出,WNOHANG表示非阻塞if (waitpid(pid, &status, WNOHANG) == pid) {// 如果system_server剛剛創建就crash,重啟zygoteALOGE("System server process %d has died. Restarting Zygote!", pid);RuntimeAbort(env);}}return pid; }??當system_server進程創建失敗時,將會重啟zygote進程。這里需要注意,對于Android 5.0以上系統,有兩個zygote進程,分別是zygote、zygote64兩個進程,system_server的父進程,一般來說64位系統其父進程是zygote64進程。
1.4 com_android_internal_os_Zygote.cpp中ForkAndSpecializeCommon函數
??這個函數有點復雜,設置處理信號這邊大家還是看原生注釋吧,有些地方我這邊也不是看得特別明白。
// Utility routine to fork zygote and specialize the child process. static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,jint debug_flags, jobjectArray javaRlimits,jlong permittedCapabilities, jlong effectiveCapabilities,jint mount_external,jstring java_se_info, jstring java_se_name,bool is_system_server, jintArray fdsToClose,jstring instructionSet, jstring dataDir) {// 設置子進程的signal信號處理函數SetSigChldHandler();sigset_t sigchld;sigemptyset(&sigchld);sigaddset(&sigchld, SIGCHLD);// Temporarily block SIGCHLD during forks. The SIGCHLD handler might// log, which would result in the logging FDs we close being reopened.// This would cause failures because the FDs are not whitelisted.//// Note that the zygote process is single threaded at this point.// 大概意思是暫時屏蔽SIGCHLD信號,不然SIGCHLD會產生log,而被我們關閉掉的// logging文件描述符會對這個信號進行相應,所以會報錯if (sigprocmask(SIG_BLOCK, &sigchld, NULL) == -1) {ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno));RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_BLOCK, { SIGCHLD }) failed.");}// Close any logging related FDs before we start evaluating the list of// file descriptors.__android_log_close();// If this is the first fork for this zygote, create the open FD table.// If it isn't, we just need to check whether the list of open files has// changed (and it shouldn't in the normal case).if (gOpenFdTable == NULL) {gOpenFdTable = FileDescriptorTable::Create();if (gOpenFdTable == NULL) {RuntimeAbort(env, __LINE__, "Unable to construct file descriptor table.");}} else if (!gOpenFdTable->Restat()) {RuntimeAbort(env, __LINE__, "Unable to restat file descriptor table.");}// Linux fork調用,創建子進程pid_t pid = fork();if (pid == 0) {// The child process.gMallocLeakZygoteChild = 1;// Clean up any descriptors which must be closed immediately// 清除一部分文件描述符DetachDescriptors(env, fdsToClose);// Re-open all remaining open file descriptors so that they aren't shared// with the zygote across a fork.if (!gOpenFdTable->ReopenOrDetach()) {RuntimeAbort(env, __LINE__, "Unable to reopen whitelisted descriptors.");}if (sigprocmask(SIG_UNBLOCK, &sigchld, NULL) == -1) {ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno));RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_UNBLOCK, { SIGCHLD }) failed.");}// Keep capabilities across UID change, unless we're staying root.// 非root,禁止動態改變進程權限if (uid != 0) {EnableKeepCapabilities(env);}// 取消進程已有的Capabilities權限DropCapabilitiesBoundingSet(env);bool use_native_bridge = !is_system_server && (instructionSet != NULL)&& android::NativeBridgeAvailable();if (use_native_bridge) {ScopedUtfChars isa_string(env, instructionSet);use_native_bridge = android::NeedsNativeBridge(isa_string.c_str());}if (use_native_bridge && dataDir == NULL) {// dataDir should never be null if we need to use a native bridge.// In general, dataDir will never be null for normal applications. It can only happen in// special cases (for isolated processes which are not associated with any app). These are// launched by the framework and should not be emulated anyway.use_native_bridge = false;ALOGW("Native bridge will not be used because dataDir == NULL.");}if (!MountEmulatedStorage(uid, mount_external, use_native_bridge)) {ALOGW("Failed to mount emulated storage: %s", strerror(errno));if (errno == ENOTCONN || errno == EROFS) {// When device is actively encrypting, we get ENOTCONN here// since FUSE was mounted before the framework restarted.// When encrypted device is booting, we get EROFS since// FUSE hasn't been created yet by init.// In either case, continue without external storage.} else {ALOGE("Cannot continue without emulated storage");RuntimeAbort(env);}}if (!is_system_server) {// 對于非system_server,創建進程組int rc = createProcessGroup(uid, getpid());if (rc != 0) {if (rc == -EROFS) {ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");} else {ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));}}}// 設置組代碼SetGids(env, javaGids);// 設置資源限制SetRLimits(env, javaRlimits);if (use_native_bridge) {ScopedUtfChars isa_string(env, instructionSet);ScopedUtfChars data_dir(env, dataDir);android::PreInitializeNativeBridge(data_dir.c_str(), isa_string.c_str());}// 設置真實的、有效的和保存過的組IDint rc = setresgid(gid, gid, gid);if (rc == -1) {ALOGE("setresgid(%d) failed: %s", gid, strerror(errno));RuntimeAbort(env);}// 設置真實的、有效的和保存過的用戶IDrc = setresuid(uid, uid, uid);if (rc == -1) {ALOGE("setresuid(%d) failed: %s", uid, strerror(errno));RuntimeAbort(env);}if (NeedsNoRandomizeWorkaround()) {// Work around ARM kernel ASLR lossage (http://b/5817320).int old_personality = personality(0xffffffff);int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);if (new_personality == -1) {ALOGW("personality(%d) failed: %s", new_personality, strerror(errno));}}// 設置新的capabilities權限SetCapabilities(env, permittedCapabilities, effectiveCapabilities);// 設置調度策略SetSchedulerPolicy(env);const char* se_info_c_str = NULL;ScopedUtfChars* se_info = NULL;if (java_se_info != NULL) {se_info = new ScopedUtfChars(env, java_se_info);se_info_c_str = se_info->c_str();if (se_info_c_str == NULL) {ALOGE("se_info_c_str == NULL");RuntimeAbort(env);}}const char* se_name_c_str = NULL;ScopedUtfChars* se_name = NULL;if (java_se_name != NULL) {se_name = new ScopedUtfChars(env, java_se_name);se_name_c_str = se_name->c_str();if (se_name_c_str == NULL) {ALOGE("se_name_c_str == NULL");RuntimeAbort(env);}}// 設置selinux domain上下文rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);if (rc == -1) {ALOGE("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid,is_system_server, se_info_c_str, se_name_c_str);RuntimeAbort(env);}// Make it easier to debug audit logs by setting the main thread's name to the// nice name rather than "app_process".if (se_info_c_str == NULL && is_system_server) {se_name_c_str = "system_server";}if (se_info_c_str != NULL) {SetThreadName(se_name_c_str);}delete se_info;delete se_name;// 將子進程system_server的SIGCHLD信號的處理函數修改回系統默認函數UnsetSigChldHandler();// JNI調,相當于zygote.callPostForkChildHooks()env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,is_system_server ? NULL : instructionSet);if (env->ExceptionCheck()) {ALOGE("Error calling post fork hooks.");RuntimeAbort(env);}} else if (pid > 0) {// 父進程中取消上面被屏蔽的SIGCHLD信號處理// the parent process// We blocked SIGCHLD prior to a fork, we unblock it here.if (sigprocmask(SIG_UNBLOCK, &sigchld, NULL) == -1) {ALOGE("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno));RuntimeAbort(env, __LINE__, "Call to sigprocmask(SIG_UNBLOCK, { SIGCHLD }) failed.");}}return pid; }??至此,fork的工作就基本做完了,剩下的就是在handleSystemServerProcess中對SystemServer的剩余工作進行處理了。
1.5 ZygoteInit.java中的handleSystemServerProcess函數
/*** Finish remaining work for the newly forked system server process.*/ private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)throws ZygoteInit.MethodAndArgsCaller {// 關閉從父進程Zygote中繼承得來的sServersocketcloseServerSocket();// set umask to 0077 so new files and directories will default to owner-only permissions.Os.umask(S_IRWXG | S_IRWXO);// 設置進程名為system_serverif (parsedArgs.niceName != null) {Process.setArgV0(parsedArgs.niceName);}//?SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jarfinal String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");if (systemServerClasspath != null) {// 進行dexopt優化performSystemServerDexOpt(systemServerClasspath);}// system_server的invokeWith為nullif (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(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);}// 啟動應用程序WrapperInit.execApplication(parsedArgs.invokeWith,parsedArgs.niceName, parsedArgs.targetSdkVersion,VMRuntime.getCurrentInstructionSet(), null, args);} else {// system_server走該分支ClassLoader cl = null;if (systemServerClasspath != null) {// 創建類加載器cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());// 設置當前進程即system_server的類加載器Thread.currentThread().setContextClassLoader(cl);}/** Pass the remaining arguments to SystemServer.*/// 最后調用zygoteinitRuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);}/* should never reach here */ }1.6 ZygoteInit.java中的performSystemServerDexOpt函數
/*** Performs dex-opt on the elements of {@code classPath}, if needed. We* choose the instruction set of the current runtime.*/ private static void performSystemServerDexOpt(String classPath) {final String[] classPathElements = classPath.split(":");// 創建一個InstallerConnection對象final InstallerConnection installer = new InstallerConnection();// 等待,直到與installed服務端連通為止installer.waitForConnection();final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();try {for (String classPathElement : classPathElements) {final int dexoptNeeded = DexFile.getDexOptNeeded(classPathElement, "*", instructionSet, false /* defer */);if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {// 以system身份,執行dex優化installer.dexopt(classPathElement, Process.SYSTEM_UID, false,instructionSet, dexoptNeeded);}}} catch (IOException ioe) {throw new RuntimeException("Error starting system_server", ioe);} finally {// 斷開與installed的socket連接installer.disconnect();} }1.7 RuntimeInit.java中的ZygoteInit函數
public static final void zygoteInit(int targetSdkVersion, String[] argv) throws MethodAndArgsCaller {redirectLogStreams(); // 重定向Log輸出commonInit(); // 通用初始化nativeZygoteInit(); // Zygote初始化applicationInit(targetSdkVersion, argv); // 應用初始化 }1.8 RuntimeInit.java中的commonInit函數
private static final void commonInit() {// 設置當前線程的未捕獲異常處設置為默認處理方法Thread.setDefaultUncaughtExceptionHandler(new RuntimeInit.UncaughtHandler(null));// 設置時區TimezoneGetter.setInstance(new TimezoneGetter() {public String getId() {return SystemProperties.get("persist.sys.timezone");}});TimeZone.setDefault((TimeZone)null);// 重置Log設置LogManager.getLogManager().reset();// 設置Android Lognew AndroidConfig();// 獲取默認的userAgentString userAgent = getDefaultUserAgent();// 獲取默認的HTTP user-agent,用于HttpURLConnection連接System.setProperty("http.agent", userAgent);// 設置網絡流量統計NetworkManagementSocketTagger.install();// 如果是通過模擬器啟動Android,可以通過F9/F10隨時追蹤kernel運行情況String trace = SystemProperties.get("ro.kernel.android.tracing");if(trace.equals("1")) {Slog.i("AndroidRuntime", "NOTE: emulator trace profiling enabled");Debug.enableEmulatorTraceOutput();}initialized = true; }1.9 AndroidRuntime.cpp中的com_android_internal_os_RuntimeInit_nativeZygoteInit方法
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz) {gCurRuntime->onZygoteInit(); }??onZygote的代碼在app_main.cpp中,代碼如下:
virtual void onZygoteInit() {// 獲取ProcessState對象sp proc = ProcessState::self();ALOGV("App process: starting thread pool.\n");// 啟動線程池proc->startThreadPool(); }1.10 RuntimeInit.java中的applicationInit方法
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {// If the application calls System.exit(), terminate the process// immediately without running any shutdown hooks. It is not possible to// shutdown an Android application gracefully. Among other things, the// Android runtime shutdown hooks close the Binder driver, which can cause// leftover running threads to crash before the process actually exits.// true代表在退出的時候不調用AppRuntime.onExit()nativeSetExitWithoutCleanup(true);// We want to be fairly aggressive about heap utilization, to avoid// holding on to a lot of memory that isn't needed.// 設置虛擬機內存堆利用率為%75VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);final Arguments args;try {// 解析傳入的參數args = new Arguments(argv);} catch (IllegalArgumentException ex) {Slog.e(TAG, ex.getMessage());// let the process exitreturn;}// The end of of the RuntimeInit event (see #zygoteInit).Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);// Remaining arguments are passed to the start class's static main// 調用startClass=“com.android.server.Systemserver”的static main方法invokeStaticMain(args.startClass, args.startArgs, classLoader); }1.11 RuntimeInit.java中的invokeStaticMain方法
/*** Invokes a static "main(argv[]) method on class "className".* Converts various failing exceptions into RuntimeExceptions, with* the assumption that they will then cause the VM instance to exit.** @param className Fully-qualified class name* @param argv Argument vector for main()* @param classLoader the classLoader to load {@className} with*/ // 用于啟動className指向的類的static main(argv[])方法 private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {Class<?> cl;try {// 裝載className=”com.android.server.Systemserver”類,并初始化cl = Class.forName(className, true, classLoader);} catch (ClassNotFoundException ex) {throw new RuntimeException("Missing class when invoking static main " + className,ex);}Method m;try {// 獲取className=”com.android.server.Systemserver”中的main方法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);}// 獲取main方法的修飾符int modifiers = m.getModifiers();// main方法的修飾符需要是public staticif (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {throw new RuntimeException("Main method is not public and static on " + className);}/** This throw gets caught in ZygoteInit.main(), which responds* by invoking the exception's run() method. This arrangement* clears up all the stack frames that were required in setting* up the process.*/// 通過拋出異常的方式,將調用返回到ZygoteInit.main函數中throw new ZygoteInit.MethodAndArgsCaller(m, argv); }??上面的函數調用最后是通過拋出ZygoteInit.MethodAndArgsCaller異常的方法,將方法的調用棧返回到ZygoteInit.main()函數中,下面我們在重新看看ZygoteInit的main函數是怎么處理這個異常的。
1.12 ZygoteInit.java中的main函數
public static void main(String argv[]) {// 前面的代碼在前面分析了,這里就省略不貼出來………………/// M: Added for BOOTPROFaddBootEvent(new String("Zygote:Preload End"));if (startSystemServer) {startSystemServer(abiList, socketName);}Log.i(TAG, "Accepting command socket connections");runSelectLoop(abiList);closeServerSocket();} catch (MethodAndArgsCaller caller) {// 在RuntimeInit.java的invokeStaticMain方法中拋出的異常在這里捕獲// 然后調用MethodAndArgsCaller的run方法caller.run();} catch (RuntimeException ex) {Log.e(TAG, "Zygote died with exception", ex);closeServerSocket();throw ex;} }1.13 ZygoteInit.java中的MethodAndArgsCaller類
/*** Helper exception class which holds a method and arguments and* can call them. This is used as part of a trampoline to get rid of* the initial process setup stack frames.*/ public static class MethodAndArgsCaller extends Exceptionimplements Runnable {/** method to call */private final Method mMethod;/** argument array */private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {// com.android.server.SystemServer類的main方法mMethod = method;// 傳給main方法的參數mArgs = args;}public void run() {try {// 調用com.android.server.SystemServer類的main方法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);}} }2. SystemServer的實際內容
??第一部分介紹到Zygote最后會執行com.android.server.Systemserver的main函數,那程序就會直接跳轉到main函數。
2.1 SystemServer.java中的main函數
/*** The main entry point from zygote.*/ public static void main(String[] args) {new SystemServer().run(); }2.2 SystemServer.java中的run函數
private void run() {// 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年,這里就將時間強制設置為1970年if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {Slog.w(TAG, "System clock is before 1970; setting to 1970.");SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);}// 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.cppif (!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", "");}// Here we go!Slog.i(TAG, "Entered the Android system server!");EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());/// M: BOOTPROF @{mMTPROF_disable = "1".equals(SystemProperties.get("ro.mtprof.disable"));addBootEvent(new String("Android:SysServerInit_START"));/// @}// 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'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/11463182SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());// Enable the sampling profiler.// 啟動SampleingProfilerIntegration進行性能統計if (SamplingProfilerIntegration.isEnabled()) {SamplingProfilerIntegration.start();mProfilerSnapshotTimer = new Timer();mProfilerSnapshotTimer.schedule(new TimerTask() {@Overridepublic void run() {SamplingProfilerIntegration.writeSnapshot("system_server", null);}// SNAPSHOT_INTERVAL=60*60*1000,所以是一個小時進行一次性能統計// 保存的snapshot保存到/data/snapshots/system_server中}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);}// 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.// 設置虛擬機運行時內存堆利用率為80%VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);// Some devices rely on runtime fingerprint generation, so make sure// we've defined it before booting further.// 確認ro.build.fingerprint屬性值是否存在,如果不存在則設置該屬性值Build.ensureFingerprintProperty();// Within the system server, it is an error to access Environment paths without// explicitly specifying a user.// 需要設置指定用戶后才能夠訪問環境變量Environment.setUserRequired(true);// Ensure binder calls into the system always run at foreground priority. // 確保binder系統調用運行在前臺優先級BinderInternal.disableBackgroundScheduling(true);// Prepare the main looper thread (this thread).// 設置system_server的優先級為前臺優先級android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);// 禁止system_server將自身設置為后臺優先級android.os.Process.setCanSelfBackground(false);// 創建主線程looperLooper.prepareMainLooper();// Initialize native services.// 加載android_servers.so庫System.loadLibrary("android_servers");///M:Add for low storage feature,to delete the reserver file.@{try {Runtime.getRuntime().exec("rm -r /data/piggybank");} catch (IOException e) {Slog.e(TAG, "system server init delete piggybank fail" + e);}///@}// 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.// 創建SystemServiceManagermSystemServiceManager = new SystemServiceManager(mSystemContext);// 將SystemServiceManager成員添加到本地service對象中LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);// Start services.try {// 啟動引導服務startBootstrapServices();// 啟動核心服務startCoreServices();// 啟動剩余的其他服務startOtherServices();} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);/// M: RecoveryManagerService @{if (mRecoveryManagerService != null && ex instanceof RuntimeException) {mRecoveryManagerService.handleException((RuntimeException) ex, true);} else {throw ex;}/// @}}// For debug builds, log event loop stalls to dropbox for analysis.if (StrictMode.conditionallyEnableDebugLogging()) {Slog.i(TAG, "Enabled StrictMode for system server main thread.");}/// M: BOOTPROFaddBootEvent(new String("Android:SysServerInit_END"));// Loop forever.// 進入消息處理循環Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited"); }2.3 SystemServer.java中的performPendingShutdown函數
private void performPendingShutdown() {// SHUTDOWN_ACTION_PROPERTY=”sys.shutdown.requested”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;}// 如果sys.shutdown.requested的值不為空,就會重啟或者關機ShutdownThread.rebootOrShutdown(null, reboot, reason);} }2.4 SystemServer.java中的createSystemcontext函數
private void createSystemContext() {// 獲取ActivityThread對象ActivityThread activityThread = ActivityThread.systemMain();// 創建并獲取ContextImpl對象mSystemContext = activityThread.getSystemContext();// 設置系統主題 mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar); }2.5 SystemServer.java中的startBootstrapServices函數
/*** 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() {// 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.// 啟動Installer系統服務Installer installer = mSystemServiceManager.startService(Installer.class);/// M: MSG Logger Manager @{if (!IS_USER_BUILD) {try {MessageMonitorService msgMonitorService = null;msgMonitorService = new MessageMonitorService();Slog.e(TAG, "Create message monitor service successfully .");// Add this service to service managerServiceManager.addService(Context.MESSAGE_MONITOR_SERVICE,msgMonitorService.asBinder());} catch (Throwable e) {Slog.e(TAG, "Starting message monitor service exception ", e);}}/// MSG Logger Manager @}// Activity manager runs the show.// 啟動AMS,同時設置AMS的SystemServiceManager和InstallermActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();mActivityManagerService.setSystemServiceManager(mSystemServiceManager);mActivityManagerService.setInstaller(installer);// 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).// 啟動PowerManagerServicemPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);// Now that the power manager has been started, let the activity manager// initialize power management features.// 初始化PowerManagerServicemActivityManagerService.initPowerManagement();// Manages LEDs and display backlight so we need it to bring up the display.// 啟動LightServicemSystemServiceManager.startService(LightsService.class);// Display manager is needed to provide display metrics before package manager// starts up.// 啟動DisplayManagerServicemDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);// We need the default display before we can initialize the package manager.// 等待Display默認顯示mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);// Only run "core" apps if we're encrypting the device.// 當設備處于加密過程中,則只運行核心應用程序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;}// Start the package manager.Slog.i(TAG, "Package Manager");// 啟動PackageManagerServicemPackageManagerService = PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);// 判斷手機是否是第一次啟動mFirstBoot = mPackageManagerService.isFirstBoot();// 獲取PakcageManager對象mPackageManager = mSystemContext.getPackageManager();Slog.i(TAG, "User Service");// 啟動UserManagerService,并添加到ServiceManager中ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());// Initialize attribute cache used to cache resources from packages.// 初始化屬性緩存AttributeCache.init(mSystemContext);// Set up the Application instance for the system process and get started.// 設置AMSmActivityManagerService.setSystemProcess();// The sensor service needs access to package manager service, app ops// service, and permissions service, therefore we start it after them.// 啟動SensorServicestartSensorService(); }2.6 SystemServer.java中的startCoreServices函數
/*** Starts some essential services that are not tangled up in the bootstrap process.*/ private void startCoreServices() {// Tracks the battery level. Requires LightService.// 啟動BatteryService,用于統計電池電量信息mSystemServiceManager.startService(BatteryService.class);// Tracks application usage stats.// 啟動UsageStatsService,用于統計應用使用情況mSystemServiceManager.startService(UsageStatsService.class);mActivityManagerService.setUsageStatsManager(LocalServices.getService(UsageStatsManagerInternal.class));// Update after UsageStatsService is available, needed before performBootDexOpt.mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();// Tracks whether the updatable WebView is in a ready state and watches for update installs.// 啟動WebViewUpdateServicemSystemServiceManager.startService(WebViewUpdateService.class); }2.7 其余Service
??最后就是通過SystemServer.java中的startOtherService方法啟動的service了,因為start OtherService這個方法里面啟動的service比較多,例如:AudioService、CameraService、AccountService等,而且方法內容長,所以就不貼出來了,各位有興趣可以自己去看,后續如果有分析到具體的某一個service,到時候再拿出來看就好了。
2.8 小總結
??從代碼中可以看到,System_server啟動service的方法主要是通過兩種方式:一種是通過SystemServiceManager的startService(),這個方法主要是用來啟動繼承于SystemService的服務。主要過程為,首先創建serviceClass類的對象,然后將剛剛創建的serviceClass類對象添加到SystemServiceManager的成員對象mServices(是一個Arraylist),然后再調用剛創建對象的onStart方法。對于那些啟動到一定階段的服務,進入到相應階段的Phase后,還會調用到SystemServiceManager的startBootPhase()回掉方法,這個方法會循環遍歷所有向SystemServiceManager注冊過的service的onBootPhase()方法;另外一種就是通過ServiceManager的addService(String name, IBinder service),該方法用于初始化繼承于IBinder的服務。
??啟動過程中各個Phase所代表的階段如下:
/** Boot Phases*/ // 該階段需要等待Display有默認顯示 public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?/*** After receiving this boot phase, services can obtain lock settings data.*/ // 該階段后服務可以獲取到鎖屏設置的數據了 public static final int PHASE_LOCK_SETTINGS_READY = 480;/*** After receiving this boot phase, services can safely call into core system services* such as the PowerManager or PackageManager.*/ // 該階段后,服務可以安全的調用核心系統服務了,例如Power Manager和PackageManager public static final int PHASE_SYSTEM_SERVICES_READY = 500;/*** After receiving this boot phase, services can broadcast Intents.*/ // 該階段后,服務可以接收到廣播Intents public static final int PHASE_ACTIVITY_MANAGER_READY = 550;/*** After receiving this boot phase, services can start/bind to third party apps.* Apps will be able to make Binder calls into services at this point.*/ // 該階段后,服務可以啟動/綁定到第三方的app了 public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;/*** After receiving this boot phase, services can allow user interaction with the device.* This phase occurs when boot has completed and the home application has started.* System services may prefer to listen to this phase rather than registering a* broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.*/ // 該階段后,允許用戶和設備進行交互了,該階段發生再啟動完成以及home ap已經啟動了,系統的服務更傾向于注冊監聽該廣播而非ACTION_BOOT_COMPLETED public static final int PHASE_BOOT_COMPLETED = 1000;贊過:
http://blog4jimmy.com/2018/01/328.html
總結
以上是生活随笔為你收集整理的Android SystemServer分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Zygote分析
- 下一篇: Android SystemServic