Android SystemServer
一、SystemServer启动做了哪些事?
启动各种服务,是将系统服务注册到ServiceManager中,/framewoks/base/core/java/android/app/SystemServiceRegister.java:
/** * Manages all of the system services that can be returned by {@link Context#getSystemService}. * Used by {@link ContextImpl}. * * @hide */ @SystemApi public final class SystemServiceRegistry { ……// Not instantiable. private SystemServiceRegistry() { } static { //CHECKSTYLE:OFF IndentationCheck …… registerService(Context.ACTIVITY_SERVICE, ActivityManager.class, new CachedServiceFetcher<ActivityManager>() { @Override public ActivityManager createService(ContextImpl ctx) { return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler()); }}); …… registerService(Context.WINDOW_SERVICE, WindowManager.class, new CachedServiceFetcher<WindowManager>() { @Override public WindowManager createService(ContextImpl ctx) { return new WindowManagerImpl(ctx); }}); …… } …… }
二、SystemServer实现:
SystemServer源码(frameworks/base/services/java/com/android/server/SystemServier.java)中,run函数:
private void run() { TimingsTraceAndSlog t = new TimingsTraceAndSlog(); try { t.traceBegin("InitBeforeStartServices"); // Record the process start information in 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); // // Default the timezone property to GMT if not set. // 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 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. 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!"); final long uptimeMillis = SystemClock.elapsedRealtime(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis); if (!mRuntimeRestart) { FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED, FrameworkStatsLog .BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SYSTEM_SERVER_INIT_START, 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'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(); // 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); SystemServiceRegistry.sEnableServiceNotFoundWtf = true; // Initialize native services. System.loadLibrary("android_servers"); // Allow heap / perf profiling. initZygoteChildHeapProfiling(); // Debug builds - spawn a thread to monitor for fd leaks. if (Build.IS_DEBUGGABLE) { spawnFdLeakCheckThread(); } // Check whether we failed to shut down last time we tried. // This call may not return. performPendingShutdown(); // Initialize the system context. createSystemContext(); // Call per-process mainline module initialization. ActivityThread.initializeMainlineModules(); // 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 SystemServerInitThreadPool.start(); // Attach JVMTI agent if this is a debuggable build and the system property is set. if (Build.IS_DEBUGGABLE) { // Property is of the form "library_path=parameters". String jvmtiAgent = SystemProperties.get("persist.sys.dalvik.jvmtiagent"); if (!jvmtiAgent.isEmpty()) { int equalIndex = jvmtiAgent.indexOf('='); String libraryPath = jvmtiAgent.substring(0, equalIndex); String parameterList = jvmtiAgent.substring(equalIndex + 1, jvmtiAgent.length()); // Attach the agent. try { Debug.attachJvmtiAgent(libraryPath, parameterList, null); } catch (Exception e) { Slog.e("System", "*************************************************"); Slog.e("System", "********** Failed to load jvmti plugin: " + jvmtiAgent); } } } } finally { t.traceEnd(); // InitBeforeStartServices } // Setup the default WTF handler RuntimeInit.setDefaultApplicationWtfHandler(SystemServer::handleEarlySystemWtf); // Start services. try { t.traceBegin("StartServices"); startBootstrapServices(t); startCoreServices(t); startOtherServices(t); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { t.traceEnd(); // StartServices } StrictMode.initVmDefaults(null); if (!mRuntimeRestart && !isFirstBootOrUpgrade()) { final long uptimeMillis = SystemClock.elapsedRealtime(); FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED, FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SYSTEM_SERVER_READY, uptimeMillis); final long maxUptimeMillis = 60 * 1000; if (uptimeMillis > maxUptimeMillis) { 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"); }
启动Binder机制:
// The system server should never make non-oneway calls Binder.setWarnOnBlocking(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);
启动系统服务:
// Initialize native services. System.loadLibrary("android_servers"); // Allow heap / perf profiling. initZygoteChildHeapProfiling(); // Debug builds - spawn a thread to monitor for fd leaks. if (Build.IS_DEBUGGABLE) { spawnFdLeakCheckThread(); } // Check whether we failed to shut down last time we tried. // This call may not return. performPendingShutdown(); // Initialize the system context. createSystemContext(); // Call per-process mainline module initialization. ActivityThread.initializeMainlineModules(); // 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 SystemServerInitThreadPool.start(); // Attach JVMTI agent if this is a debuggable build and the system property is set. if (Build.IS_DEBUGGABLE) { // Property is of the form "library_path=parameters". String jvmtiAgent = SystemProperties.get("persist.sys.dalvik.jvmtiagent"); if (!jvmtiAgent.isEmpty()) { int equalIndex = jvmtiAgent.indexOf('='); String libraryPath = jvmtiAgent.substring(0, equalIndex); String parameterList = jvmtiAgent.substring(equalIndex + 1, jvmtiAgent.length()); // Attach the agent. try { Debug.attachJvmtiAgent(libraryPath, parameterList, null); } catch (Exception e) { Slog.e("System", "*************************************************"); Slog.e("System", "********** Failed to load jvmti plugin: " + jvmtiAgent); } } } } finally { t.traceEnd(); // InitBeforeStartServices } // Setup the default WTF handler RuntimeInit.setDefaultApplicationWtfHandler(SystemServer::handleEarlySystemWtf); // Start services. try { t.traceBegin("StartServices"); startBootstrapServices(t); startCoreServices(t); startOtherServices(t); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { t.traceEnd(); // StartServices }
启动Socket Loop,不过在启动系统服务前先初始化Loop:
Looper.prepareMainLooper(); Looper.getMainLooper().setSlowLogThresholdMs(SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS); // Initialize native services. System.loadLibrary("android_servers"); …… // Loop forever. Looper.loop();