The SystemServer process is a process that comes out of Zygote fork. Here's how the zygote process executes
frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
// The zygote process is from the init process through fork
AppRuntime runtime;
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer ? "start-system-server" : "");
}
}
/frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const char* options)
{
/*
* We want to call main() with a String array with arguments in it.
* At present we have two arguments, the class name and an option string.
* Create an array to hold them.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
jstring optionsStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(2, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
optionsStr = env->NewStringUTF(options);
env->SetObjectArrayElement(strArray, 1, optionsStr);
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className);
// Get "com.android.internal.os.ZygoteInit"Class"
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {
// main method to get ZygoteInit class
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {
// Call main method of ZygoteInit class
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
}
Here we goCom.android.internal.Os.ZygoteInitIn the main method of.
public static void main(String argv[]) {
try {
......
// Start SystemServer
if (argv[1].equals("start-system-server")) {
startSystemServer();
}
......
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
......
}
}
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
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
);
/* 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,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--runtime-init",
"--nice-name=system_server",
"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 */
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) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
The parameter to set the process is system_server, the corresponding class isCom.android.server.SystemServer.
Zygote.forkSystemServer A real fork is a process whose parameters have been set before, so the process that this fork comes out of is system_server, which is a child of zygote
Once the SystemServer process has been created, the handleSystemServerProcess method is executed below.
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
// Modify the process name to system_server
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
null, parsedArgs.remainingArgs);
} else {
//The method will eventually be called
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
}
}
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
redirectLogStreams();
// Do some general initialization
commonInit();
// Initialization of the native layer
nativeZygoteInit();
// Call main method of application java layer
applicationInit(targetSdkVersion, argv);
}
private static void applicationInit(int targetSdkVersion, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
return;
}
// Call the static main method of the class passed in
invokeStaticMain(args.startClass, args.startArgs);
}
private static void invokeStaticMain(String className, String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;
try {
// LoadCom.android.serverSystemServer class
cl = Class.forName(className);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
// Get 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);
}
int modifiers = m.getModifiers();
// Judging the type of main function
if (! (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.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
ZygoteInit.MethodAndArgsCaller Is a class inherited from Exception, invokeStaticMain was not called directlyCom.android.serverThe main method of.SystemServer, instead, throws aZygoteInit.MethodAndArgsCalleException of type.
public static void main(String argv[]) {
try {
......
if (argv[1].equals("start-system-server")) {
startSystemServer();
}
......
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
......
}
}
The MethodAndArgsCaller exception is finally caught in the main function by try-catch and handled by the run function of the exception class.
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
// Constructor saves parameters
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
// The run function calls the main function
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
......
}
}
}
}
Reference article:
http://blog.csdn.net/hu3167343/article/details/38375167