In the previous section The Android 10 system process Zygote starts The Zygote process is started. It is said that the Zygote process will create the SystemServer process and execute the main () function. The SystemServer process hosts the core services of the entire Android framework layer. Let's take a look at the main() function of / frameworks/base/services/java/com/android/server/SystemServer.java:
public static void main(String[] args) { new SystemServer().run(); }
Create a SystemServer object and execute its run () method:
private void run() { try { traceBeginAndSlog("InitBeforeStartServices"); // Record the process start information in sys props. //When creating this object, the following properties will be initialized, and these properties will be set to the system here SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));//Set the number of boot times 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 the clock of a device is before 1970 (before 0 years), //Then many APIs will crash because they handle negative numbers, especially java.io.File#setLastModified //I set the time to 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 time zone does not exist, set the time zone to 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"); } //Change the library file of the virtual machine. For Android 10.0, libart.so is used by default SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); // Mmmmmm... more memory! //Clear the upper limit of vm memory growth, because the startup process requires more virtual machine memory space VMRuntime.getRuntime().clearGrowthLimit(); ... //The system server must be running all the time, so it needs to use memory as efficiently as possible //Set the possible effective memory usage to 0.8 VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); //Some devices rely on runtime fingerprint generation, so please make sure we have defined it before starting further. Build.ensureFingerprintProperty(); //Before accessing environment variables, you need to specify users explicitly //In system_ In the server, any incoming package should be released to avoid throwing BadParcelableException. BaseBundle.setShouldDefuse(true); //In system_ In server, when packaging exceptions, the information needs to include stack traces Parcel.setStackTraceParceling(true); //Ensure that the binder call of the current system process always runs in the foreground priority BinderInternal.disableBackgroundScheduling(true); //Set system_ The maximum number of binder threads in the server. The maximum value is 31 BinderInternal.setMaxThreads(sMaxBinderThreads); //Prepare the main thread looper, that is, run on the current 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); //Load Android_ The servers.so library initializes the native service System.loadLibrary("android_servers"); // Debug builds - allow heap profiling. //In case of Debug version, heap memory analysis is allowed if (Build.IS_DEBUGGABLE) { initZygoteChildHeapProfiling(); } //Check whether the last shutdown process failed. This call may not return performPendingShutdown(); //Initialize system context createSystemContext(); //Create system service management -- System Service Manager mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); //Add mSystemServiceManager to the local service's member sLocalServiceObjects LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Prepare the thread pool for init tasks that can be parallelized //Prepare a thread pool for init tasks that can be parallelized SystemServerInitThreadPool.get(); } finally { traceEnd(); // InitBeforeStartServices } // Start services. //Start service try { traceBeginAndSlog("StartServices"); startBootstrapServices(); // Start boot service startCoreServices(); // Start core services startOtherServices(); // Start other services SystemServerInitThreadPool.shutdown(); //Stop thread pool } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { traceEnd(); } //Initialize VmPolicy for the current virtual machine StrictMode.initVmDefaults(null); ... // Loop forever. //Dead loop execution Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
Here, we mainly initialize some system variables, create the system context, create the system service management object SystemServiceManager, and finally start the system service. Here, the system service can be divided into three types: boot service, core service and other services. Let's go inside and have a look:
Create system context:
private void createSystemContext() { //Create context information for the systemserver process ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); //set up themes mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); //Get the systemui context information and set the theme final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); }
This process will create objects such as ActivityThread, Instrumentation, ContextImpl, LoadedApk and Application. One thing to note is that ActivityThread is created through its systemMain () method, while the normal Application process is created through ActivityThread through its main () method.
To create a system service management object SystemServiceManager:
The SystemServiceManager object is mainly used to create managed system services. This class is simplified as follows:
public class SystemServiceManager { private static final String TAG = "SystemServiceManager"; private final Context mContext; // Services that should receive lifecycle events. private final ArrayList<SystemService> mServices = new ArrayList<SystemService>(); SystemServiceManager(Context context) { mContext = context; } /* * Loads and initializes a class from the given classLoader. Returns the class. */ @SuppressWarnings("unchecked") private static Class<SystemService> loadClassFromLoader(String className, ClassLoader classLoader) { try { return (Class<SystemService>) Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException("Failed to create service " + className + " from class loader " + classLoader.toString() + ": service class not " + "found, usually indicates that the caller should " + "have called PackageManager.hasSystemFeature() to check whether the " + "feature is available on this device before trying to start the " + "services that implement it. Also ensure that the correct path for the " + "classloader is supplied, if applicable.", ex); } } /** * Creates and starts a system service. The class must be a subclass of * {@link com.android.server.SystemService}. * * @param serviceClass A Java class that implements the SystemService interface. * @return The service instance, never null. * @throws RuntimeException if the service fails to start. */ public <T extends SystemService> T startService(Class<T> serviceClass) { try { final String name = serviceClass.getName(); Slog.i(TAG, "Starting " + name); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name); // Create the service. if (!SystemService.class.isAssignableFrom(serviceClass)) { throw new RuntimeException("Failed to create " + name + ": service must extend " + SystemService.class.getName()); } final T service; try { Constructor<T> constructor = serviceClass.getConstructor(Context.class); service = constructor.newInstance(mContext); } catch (InstantiationException ex) { throw new RuntimeException("Failed to create service " + name + ": service could not be instantiated", ex); } catch (IllegalAccessException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (NoSuchMethodException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (InvocationTargetException ex) { throw new RuntimeException("Failed to create service " + name + ": service constructor threw an exception", ex); } startService(service); return service; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } public void startService(@NonNull final SystemService service) { // Register it. mServices.add(service); // Start it. long time = SystemClock.elapsedRealtime(); try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + service.getClass().getName() + ": onStart threw an exception", ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart"); } }
There is an mServices collection in this object. This collection mainly stores system services. You can see that all system services need to inherit com.android.server.SystemService, instantiate the system service object through reflection, and finally call the onStart() method of the system service. About the instantiated system service object, You can view the printed system service log by filtering the system service manager.
Start system service:
Starting system services can be divided into three categories, mainly through three methods:
startBootstrapServices(); // Start boot service startCoreServices(); // Start core services startOtherServices(); // Start other services
Here we mainly look at the other two implementation methods of startBootStrapServices():
private void startBootstrapServices() { traceBeginAndSlog("StartWatchdog"); //Start watchdog //Start watchdog as early as possible. If a deadlock occurs when starting up early, we can let the system_server crashes for detailed analysis final Watchdog watchdog = Watchdog.getInstance(); watchdog.start(); traceEnd(); ... //Block and wait for installd to complete startup, so as to have the opportunity to create a key directory with appropriate permissions, such as / data/user. //We need to complete this task before initializing other services. traceBeginAndSlog("StartInstaller"); Installer installer = mSystemServiceManager.startService(Installer.class); traceEnd(); ... //Start the service ActivityManagerService and set mSystemServiceManager and installer for it traceBeginAndSlog("StartActivityManager"); ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock = atm.getGlobalLock(); traceEnd(); //Start service PowerManagerService //Power manager needs to be started early because other services need it. //The native daemon may be monitoring its registration, //Therefore, it must be ready to process incoming binder calls immediately (including permissions that can verify these calls). traceBeginAndSlog("StartPowerManager"); mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); traceEnd(); ... //Initialize power management traceBeginAndSlog("InitPowerManagement"); mActivityManagerService.initPowerManagement(); traceEnd(); //Start the recovery system in case a reboot is required traceBeginAndSlog("StartRecoverySystemService"); mSystemServiceManager.startService(RecoverySystemService.class); traceEnd(); ... //Start LightsService //Manage the led and display backlight, so we need it to turn on the display traceBeginAndSlog("StartLightsService"); mSystemServiceManager.startService(LightsService.class); traceEnd(); ... //Start service DisplayManagerService //The display manager needs to provide display indicators before the package manager traceBeginAndSlog("StartDisplayManager"); mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); traceEnd(); //The default display is required before initializing package manager traceBeginAndSlog("WaitForDisplay"); mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); traceEnd(); //When the device is being encrypted, only the core is running 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 service PackageManagerService traceBeginAndSlog("StartPackageManagerService"); try { Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); } finally { Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain"); } ... //Start the service UserManagerService and create a new directory / data/user/ traceBeginAndSlog("StartUserManagerService"); mSystemServiceManager.startService(UserManagerService.LifeCycle.class); traceEnd(); // Set up the Application instance for the system process and get started. //Set up an application instance for the system process and start. //Set AMS traceBeginAndSlog("SetSystemProcess"); mActivityManagerService.setSystemProcess(); traceEnd(); //Use an ActivityManager instance to set watchdog and listen for restart, //This can only be done if the ActivityManagerService is started correctly as a system process traceBeginAndSlog("InitWatchdog"); watchdog.init(mSystemContext, mActivityManagerService); traceEnd(); //The sensor service needs to access package manager service, app ops service and permission service, //So we start it after them. //Start the sensor service in a separate thread. You should check the completion 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(); //Start sensor service traceLog.traceEnd(); }, START_SENSOR_SERVICE); }
It can be seen from here that services are basically created through startService () of SystemServiceManager, with the exception of PackageManagerService, which directly calls its main () method. About the creation of specific services, I will talk about specific services later.