I. overview
When Android starts, it will involve many system level services, such as activity manager service (AMS), package manager service (PMS), etc. when are they started?
Concepts to know:
Start process of SystemServer: zygoteinit - > SystemServer
2, System server startup sequence diagram
To be supplemented
3, Source code analysis of system server startup
Class ZygoteInit
public static void main(String argv[]) {
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
try {
// ... omit large code
// Zygote process unmounts root storage spaces.
Zygote.nativeUnmountStorageOnInit();
// Open SystemServer here
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
// ... omit large code
} catch (MethodAndArgsCaller caller) {
caller.run();// Let's pay attention here
} catch (Throwable ex) {
throw ex;
}
}
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
// ... omit code
/* Hardcoded command line to start the system server */
// Parameters required to start SystemService
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,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
// Zygote starts system server through 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 */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
// Method of executing system server process
handleSystemServerProcess(parsedArgs);
}
return true;
}
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
// ... omit code
if (parsedArgs.niceName != null) {
// niceName = system_server
Process.setArgV0(parsedArgs.niceName);
}
// Get the path to the SystemServer class
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
}
if (parsedArgs.invokeWith != null) {
// ... omit code
} else {
// ... omit code
/*
* Pass the remaining arguments to SystemServer.
*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
Class RuntimeInit
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
// Transfer the output of Java System.out and System.err to Android log system
redirectLogStreams();
commonInit(); //General initialization
nativeZygoteInit(); //Initialization of native layer
//
applicationInit(targetSdkVersion, argv, classLoader);
}
/**
* Redirect System.out and System.err to the Android log.
*/
public static void redirectLogStreams() {
System.out.close();
System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
System.err.close();
System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
}
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
// ... omit large code
// Start the main method of the specified class (startClass is the class name of the class to start)
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;
try {
// 1. Get the class object according to the class name
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
// 2. Declare the main method
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);
}
// 3. Verify whether the modifier of main method is public static;
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/*
* After all the above are satisfied, an exception is thrown, which is caught in ZygoteInit.main(),
* This is what we need to pay attention to. Execute the caller.run() method where the exception is caught;
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
Class methodandargscaler
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
// mMethod is the SystemServer.main() method;
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);
}
}
}
4, System server source code analysis
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
//Set the runtime path of the current virtual machine
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Create a Looper object for the main thread here;
Looper.prepareMainLooper();
/*
* Initialize native services.
* This is often used in adding. so libraries;
*/
System.loadLibrary("android_servers");
/*
* Initialize the system context.
* 1.The Context(ContextImpl instance) of the system will be created here
* 2.Call ActivityThread.systemMain() to generate an activitythread instance in the system process, and associate activitythread with Context;
*/
createSystemContext();
/*
* Create the system service manager.
* Create a Manager of system services, which contains list < SystemService > mservices for storing open systemservices;
*/
mSystemServiceManager = new SystemServiceManager(mSystemContext);
/*
* Add the system service manager created above to the local services,
* LocalServices An arraymap < class <? > and Object > slocalserviceobjects are held in;
*
* That is, a local service can correspond to a system service manager,
* A system service manager stores multiple system services;
*/
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Services required to start the system
try {
// Analyze this method, similar below;
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
throw ex;
}
//Open the Looper loop to get the messages in the message queue;
Looper.loop();
}
private void startBootstrapServices() {
Installer installer = mSystemServiceManager.startService(Installer.class);
// Create an ActivityManagerService(AMS) instance
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// Display manager is needed to provide display metrics before package manager starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
// Create PackageManagerService instance
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
// Set instance for application process and start
mActivityManagerService.setSystemProcess();
// To create a sensor service, it depends on PMS, ops service and permissions service, so it can only be created after they are initialized;
startSensorService();
}