在分析Android系统进入zygote进程一文中知道SystemServer是系统中非常核心的进程
SystemServer在ZygoteInit中进行创建,并且启动起来的.代码位置frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
if (startSystemServer) { //根据init中传来的参数可知startSystemServer为true
startSystemServer(abiList, socketName); //启动SystemServer
}
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
//.......
/* Hardcoded command line to start the system server */
String args[] = { //准备启动System Server所需要的参数
"--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", //进程的名字为system_server
"--runtime-args",
"com.android.server.SystemServer", //包名
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args); //通过ZygoteConnection对参数进行封装
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer( //请求孵化SystemServer进程, 将创建的进程号赋值给pid
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) { //pid=0为zygote的子进程
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName); //等待zygote第二阶段
}
handleSystemServerProcess(parsedArgs); //运行SystemServer,之后SystemServer就与Zygote分道扬镳,在自己的进程中运行
}
return true;
}
下面将分两部分讲解进入SystemServer流程:
1.创建SystemServer进程
2.运行SystemServer进程
创建SystemServer进程
Zygote调用forkSystenServer函数来进行创建SystemServer进程,具体代码位置frameworks/base/core/java/com/android/internal/os/Zygote.java
/* @return 0 if this is the child, pid of the child
* if this is the parent, or -1 on error.
*/
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork(); //将所有守护进程停止运行
int pid = nativeForkSystemServer( //调用native函数孵化进程
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true); //进入SystemServer进程,可以输出trace
}
VM_HOOKS.postForkCommon(); //重新运行各个守护进程
return pid;
}
native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
通过JNI调用到native函数中,代码位置frameworks/base/core/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) { //pid大于0为父进程, 检查子进程是否已经死掉
// The zygote process checks whether the child process has died or not.
ALOGI("System server process %d has been created", pid); //输出SystemServer进程信息
gSystemServerPid = pid;
// There is a slight window that the system server process has crashed
// but it went unnoticed because we haven't published its pid yet. So
// we recheck here just to make sure that all is well.
int status;
if (waitpid(pid, &status, WNOHANG) == pid) { //判断子进程是否死掉, 如果死掉重启zygote
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
}
return pid;
}
调用底层进行fork system server,在JNI中主要通过函数ForkAndSpecializeCommon中调用fork()函数孵化SystemServer进程。
Fork函数其实就是使用Linux调用fork创建进程。如果创建出的进程pid为0,说明新进程为Zygote的子进程,系统会为他设置uid,gid等参数。新创建进程的pid大于0的话,说明该进程为进程SystemServer的进程号,Zygote进程会检查一下该进程有没有died,如果进程died了就会重新启动Zygote进程。SystemServer进程创建完成后,就会重新启动垃圾回收后台进程。之后回到ZygoteInit中,SystemServer进程就与Zygote进程正式分道扬镳,pid=0为子进程,以后的代码都运行在了SystemServer进程中了
// Utility routine to fork zygote and specialize the child process.
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) {
SetSigChldHandler();
#ifdef ENABLE_SCHED_BOOST
SetForkLoad(true);
#endif
pid_t pid = fork(); //孵化进程
if (pid == 0) {
// The child process.
gMallocLeakZygoteChild = 1;
// Clean up any descriptors which must be closed immediately
DetachDescriptors(env, fdsToClose);
// Keep capabilities across UID change, unless we're staying root.
if (uid != 0) {
EnableKeepCapabilities(env);
}
//........
if (!is_system_server) {
int rc = createProcessGroup(uid, getpid());
if (rc != 0) {
if (rc == -EROFS) {
ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
} else {
ALOGE("createProcessGroup(%d, %d) failed: %s", uid, pid, strerror(-rc));
}
}
}
SetGids(env, javaGids);
SetRLimits(env, javaRlimits);
//...
rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str); //设置selinux安全上下文
//....
} else if (pid > 0) {
// the parent process
#ifdef ENABLE_SCHED_BOOST
// unset scheduler knob
SetForkLoad(false);
#endif
}
return pid;
}
} // anonymous namespace
根据上文分析创建完成SystemServer后会调用函数handleSystemServerProcess处理,继续其未完成的使命。
当Zygote复制出新的进程时,由于复制出的新进程与Zygote进程共享内存空间,而在Zygote进程中创建的服务端Socket是新进程不需要的,所以新创建的进程需要关闭该Socket服务端。系统会将该进程的名字赋值为system_server,我们可以通过ps命令查看。
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket(); //关闭zygote中的socket
// set umask to 0077 so 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"); //获取systemServerClasspath
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath); //对该路径中的文件做dexopt优化
}
if (parsedArgs.invokeWith != null) { //invokeWith为空故走else
String[] args = parsedArgs.remainingArgs;
// If we have a non-null system server class path, we'll have to duplicate the
// existing arguments and append the classpath to it. ART will handle the classpath
// correctly when we exec a new process.
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
}
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createSystemServerClassLoader(systemServerClasspath,
parsedArgs.targetSdkVersion); //为systemServer创建ClassLoader, 让他可以进入平台的私有本地类库
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); //调用到RuntimeInit中
}
/* should never reach here */
}
classPath中的内容为systemServerClasspath = /system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar三个jar包, 之后会将这三个jar从路径中获取出来,判断是否要进行dexopt优化. 如果需要就调用installer进行优化. apk/jar做dexopt会在后文详细讲解 TODO.
/**
* Performs dex-opt on the elements of {@code classPath}, if needed. We
* choose the instruction set of the current runtime.
*/
private static void performSystemServerDexOpt(String classPath) {
final String[] classPathElements = classPath.split(":"); //将所需要优化的元素保存在string数组中
final InstallerConnection installer = new InstallerConnection();
installer.waitForConnection();
final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
try {
String sharedLibraries = "";
for (String classPathElement : classPathElements) {
// System server is fully AOTed and never profiled
// for profile guided compilation.
// TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?
final int dexoptNeeded = DexFile.getDexOptNeeded( //调用DexFile判断该元素是否要进行dexopt优化
classPathElement, instructionSet, "speed",
false /* newProfile */);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { //如果返回值不为NO_DEXOPT_NEEDED就进行优化
installer.dexopt(classPathElement, Process.SYSTEM_UID, instructionSet,
dexoptNeeded, 0 /*dexFlags*/, "speed", null /*volumeUuid*/,
sharedLibraries);
}
if (!sharedLibraries.isEmpty()) {
sharedLibraries += ":";
}
sharedLibraries += classPathElement;
}
} catch (IOException | InstallerException e) {
throw new RuntimeException("Error starting system_server", e);
} finally {
installer.disconnect();
}
}
上面工作完成之后, 根据systemServerClasspath创建classLoader, 最后,将启动SystemServer的参数解析完剩余的参数“com.android.server.SystemServer”保存在remainingArgs中,并将参数传入RuntimeInit中。代码位置frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
redirectLogStreams(); //初始化Android LOG输出流, 并且将system.out, system.err关闭, 将两者重新定向到Android log中
commonInit(); //初始化运行环境
nativeZygoteInit(); //创建BInder线程池
applicationInit(targetSdkVersion, argv, classLoader);
}
private static final native void nativeZygoteInit(); //jni调用
通过JNI调用到AndroidRuntime.cpp中,代码位置framework/base/core/jni/AndroidRuntime.cpp
static AndroidRuntime* gCurRuntime = NULL;
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit(); //调用onZygoteInit函数
}
/*
* JNI registration.
*/
static const JNINativeMethod gMethods[] = {
{ "nativeFinishInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeZygoteInit }, //JNI注册函数, nativeZygoteInit对应的jni函数
{ "nativeSetExitWithoutCleanup", "(Z)V",
(void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
};
由于app_main.cpp为AndroidRuntime的子类, 所以就调用到app_main中的onZygoteInit函数,具体代码位置frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
sp proc = ProcessState::self(); //创建ProcessState
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool(); //启动线程池
}
代码位置frameworks/native/libs/binder/ProcessState.cpp
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true); //开始孵化线程池
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) { //变量为true
String8 name = makeBinderThreadName(); //获取binder的name
ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp t = new PoolThread(isMain);
t->run(name.string()); //将binder放入线程池, 运行线程
}
}
String8 ProcessState::makeBinderThreadName() {
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
pid_t pid = getpid(); //获取进程pid
String8 name;
name.appendFormat("Binder:%d_%X", pid, s); //为binder命名
return name;
}
之后调用applicationInit函数,继续向SystemServer中挺进.
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
//...........
final Arguments args;
try {
args = new Arguments(argv); //将argv参数封装到Argument中
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader); //args.startClass为com.android.Server.SystemServer
}
在调用入口函数invokeStaticMain之前会将从ZygoteInit中传过来的参数进行处理,将com.android.server.SystemServer赋值给startClass,之后进入进程入口函数:
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class> cl;
try {
cl = Class.forName(className, true, classLoader); //通过反射获得SystemServer的class
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class }); //通过反射获取SystemServer的main函数
} 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(); //获取main函数的修饰符
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { //如果main函数不是静态公共的将会抛出异常
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异常,并在ZygoteInit.main中捕获该异常。这样就可以清除应用程序进程在创建过程中的调用栈。将应用程序入口设置为SystemServer的main函数。
public static void main(String argv[]) {
//.....
try {
//.....
} catch (MethodAndArgsCaller caller) {
caller.run(); //在函数中捕获异常, 并调用MethodAndArgsCaller的run函数
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
其实MethodAndArgsCaller继承于Exception,并且实现于Runnable.
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; //构造函数, 将SystemServer的main函数赋值给mMethod
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs }); //执行SystemServer的main函数, 从而进入到SystemServer中
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (IllegalArgumentException 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);
}
}
}
后文将继续讲解进入SystemServer后系统做了那些事情.