SystemServer startup is started in the Zygote startSystemServer method. Zygote service is configured to pass “– start-system-server” in init.zygote32.rc. After the main method in app_main. CPP does a middle conversion to “start-system-server”, the startSystemServer flag is set to true, StartSystemServer is finally called to startSystemServer.
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {...public static void main(String argv[]) {
try{...boolean startSystemServer = false; .for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
......
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
......
} else {
throw new RuntimeException("Unknown command line argument: "+ argv[i]); }}...if (startSystemServer) {
/ / start SystemServerstartSystemServer(abiList, socketName); }... }catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throwex; }}... }Copy the code
Next, go to the startSystemServer function. It is used to prepare parameters and derive them for the SystemServer process.
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {...private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_BLOCK_SUSPEND,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_RESOURCE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG
);
/* Hardcode the command line to start the system server */
String args[] = {
"--setuid=1000"."--setgid=1000"."-- setgroups = 1001100 2100 3100 4100 5100 6100 7100 8100 9101 0101 8102 1103 2300 1300 2300 3300 6300 7"."--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server"."--runtime-args"."com.android.server.SystemServer"}; ZygoteConnection.Arguments parsedArgs =null;
int pid;
try {
// Parse the parameters
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request a derived system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* Child processing */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
handleSystemServerProcess(parsedArgs);
}
return true; }... }Copy the code
ForkSystemServer is a special method to start a system server process by calling the nativeForkSystemServer JNI method.
frameworks/base/core/java/com/android/internal/os/Zygote.java
public final class Zygote {...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();
returnpid; }... }Copy the code
ForkAndSpecializeCommon is called in the nativeForkSystemServer method to complete the fork action.
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
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) {
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) {
The zygote process checks whether the child process (SystemServer) is dead
ALOGI("System server process %d has been created", pid);
gSystemServerPid = pid;
// There is a small window indicating that the system server process has crashed, but since we have not released its PID yet, it is not noticed.
// Therefore, we are rechecking here just to make sure everything is ok.
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env); }}return pid;
}
Copy the code
ForkAndSpecializeCommon invokes the fork system call to create a child process (SystemServer).
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
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) {...pid_tpid = fork(); . }Copy the code
Return to ZygoteInit startSystemServer method, and then will call handleSystemServerProcess method starts processing SystemServer process.
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {...private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
// Set umask to 0077 so that new files and directories will default to owner-only permissions.
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);
}
if(parsedArgs.invokeWith ! =null) {... }else {
ClassLoader cl = null;
if(systemServerClasspath ! =null) {
cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(cl);
}
/* * Pass the remaining parameters to SystemServer. * /
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */}... }Copy the code
The zygoteInit method in the RuntimeInit class ends up calling applicationInit to run the SystemServer static main method. For details about the Process of calling the zygoteInit method in RuntimeInit, see Android AOSP 6.0.1 Process Start Process analysis (2).
The SystemServer main method code is very simple, it creates a new SystemServer object inside, and calls the run method.
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {...public static void main(String[] args) {
newSystemServer().run(); }... }Copy the code
The SystemServer run method starts a series of familiar system-level services, such as ActivityManagerService, PowerManagerService, and so on.
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {...private void run(a) {
// The system clock is set before 1970; Set it to 1970.
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); }...// Clear the memory growth limit
VMRuntime.getRuntime().clearGrowthLimit();
// The system server must be running all the time, so you need to be as efficient as possible in terms of memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8 f);
// Some devices rely on run-time fingerprint generation, so make sure it is defined before further booting.
Build.ensureFingerprintProperty();
Inside the system server, it is an error to access the environment path without explicitly specifying the user.
Environment.setUserRequired(true);
// Ensure that binder calls to the system always run at previous station priority.
BinderInternal.disableBackgroundScheduling(true);
// Prepare the master looper
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// Initialize the native service
System.loadLibrary("android_servers");
// Check if the last attempt to shut down failed. This call may not return
performPendingShutdown();
// Initialize the system context
createSystemContext();
// Create system Service Manager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Start the service
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System"."* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
Slog.e("System"."************ Failure starting system services", ex);
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.");
}
// Loop forever
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited"); }... }Copy the code
Next let’s look at startBootstrapServices which services are started?
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {...private void startBootstrapServices(a) {
// Wait for the installation to complete and start so that it has a chance to create critical directories with appropriate permissions,
// Such as /data/user. This operation needs to be completed before any other services can be initialized.
Installer installer = mSystemServiceManager.startService(Installer.class);
/ / start ActivityManagerService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
/ / PowerManagerService startup
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// ActivityManagerService is now started to initialize the power management function.
mActivityManagerService.initPowerManagement();
// Manage the LED and display backlight, so we need it to start the display.
mSystemServiceManager.startService(LightsService.class);
// Before PackageManagerService starts, DisplayManagerService needs to provide display metrics.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// Use the default display before initializing the PackageManagerService.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
// If we are encrypting the device, only the "core" application will be run.
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 PackageManagerService
Slog.i(TAG, "Package Manager"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode ! = FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); Slog.i(TAG,"User Service");
/ / add UserManagerService
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
// Initializes the property cache used to cache resources in the package.
AttributeCache.init(mSystemContext);
// Set up the Application instance for the system process and start using it.
mActivityManagerService.setSystemProcess();
// The sensor service needs to access the package manager service, the application action service, and the permission service, so we start it after them.startSensorService(); }... }Copy the code
Now what services does startCoreServices start?
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {...private void startCoreServices(a) {
// Track the battery level. Need LightService. Start the BatteryService
mSystemServiceManager.startService(BatteryService.class);
// Start UsageStatsService to track application usage statistics
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// Update UsageStatsService after it becomes available, which is required before PerformBootDexOpt.
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
// Track whether updatable WebViews are ready and monitor the update installation. Start the WebViewUpdateServicemSystemServiceManager.startService(WebViewUpdateService.class); }... }Copy the code
StartOtherServices starts the remaining required services. All system services have been started!
Below is a sequence diagram.