• 作者:老汪软件技巧
  • 发表时间:2024-12-27 21:05
  • 浏览量:

SystemServer进程主要用于创建系统服务,我们比较熟知的AMS、PMS和WMS都是由它创建的。

环境参数:

在线源码网址:xrefandroid

Zygote处理SystemServer进程

Zygote进程的主要任务之一就是启动SystemServer进程,那SystemServer是如何被启动的呢?先看Zygote进程的main函数:

@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#main
public static void main(String[] argv) {
    ZygoteServer zygoteServer = null;
    ...
    Runnable caller;
    try {
        ...
        zygoteServer = new ZygoteServer(isPrimaryZygote);
        //默认为ture,用于启动SystemServer
        if (startSystemServer) {
            //fork出SystemServer进程并启动
            //在子进程中返回Runnable对象用于在SystemServer进程中去启动执行
            //在父进程中返回null
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
            if (r != null) {
                //表示当前代码逻辑在子进程SystemServer中
                r.run();
                return;
            }
        }
        ...
    } 
    ...
}

在Zygote进程的main()函数中,通过forkSystemServer()方法去创建SystemServer进程,并在子进程中返回了一个Runnable对象。直接走进forkSystemServer()方法:

@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#forkSystemServer
private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
    ....    
    /* 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,1021,1023,"
                    + "1024,1032,1065,3001,3002,3003,3005,3006,3007,3009,3010,3011,3012",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            //注意此字符串,后面会用到
            "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs;
    int pid;
    try {
        ...
        /* Request to fork the system server process */
        //fork出SystemServer进程
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }
    /* For child process */
    //1
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
        //关闭zygote进程创建的Socket
        zygoteServer.closeServerSocket();
        return handleSystemServerProcess(parsedArgs);
    }
    return null;
}

在forkSystemServer()方法中,定义了参数数组args,其中com.android.server.SystemServer非常重要;后面通过Zygote.forkSystemServer()方法fork出SystemServer进程,根据fork机制,返回来的pid为0则表示当前逻辑位于fork出来的进程。

注释1处的代码只会在SystemServer进程中运行,首先会根据判断,去启动32位的Secondary Zygote。其次因为SystemServer进程复制了Zygote进程的地址空间,所以会得到Zygote进程创建的Socket,但是这个Socket对于SystemServer进程没有用处,因此在System进程中调用closeServerSocket()方法去关闭该Socket。随后通过handleSystemServerProcess()方法去处理SystemServer进程后续的事务。

如何fork出SystemServer进程

根据前文,Zygote进程通过Zygote.forkSystemServer()方法fork出SystemServer进程,具体如下:

@frameworks/base/core/java/com/android/internal/os/Zygote.java#forkSystemServer
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    ZygoteHooks.preFork();
    int pid = nativeForkSystemServer(
            uid, gid, gids, runtimeFlags, rlimits,
            permittedCapabilities, effectiveCapabilities);
    // Set the Java Language thread priority to the default value for new apps.
    Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
    ZygoteHooks.postForkCommon();
    return pid;
}
private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
        int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

核心点在于方法nativeForkSystemServer(),找到其对应的Native方法,位于frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

@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 runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
        jlong effective_capabilities) {
  ...
  //1
  pid_t pid = zygote::ForkCommon(env, true,
                                 fds_to_close,
                                 fds_to_ignore,
                                 true);
  if (pid == 0) {
      // System server prcoess does not need data isolation so no need to
      // know pkg_data_info_list.
      SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,
                       effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
                       false, nullptr, nullptr, /* is_top_app= */ false,
                       /* pkg_data_info_list */ nullptr,
                       /* allowlisted_data_info_list */ nullptr, false, false);
  } 
  ...
  return pid;
}

进入ForkCommon()函数

@frameworks/base/core/jni/com_android_internal_os_Zygote.cpp#ForkCommon
pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
                         const std::vector<int>& fds_to_close,
                         const std::vector<int>& fds_to_ignore,
                         bool is_priority_fork,
                         bool purge) {
  ...
  //fork
  pid_t pid = fork();
  ...
  return pid;
}

最终看到是通过fork()函数创建子进程,自此SystemServer进程就创建成功了。

总结:Zygote进程在Java层通过JNI定义接口调用到Native层fork()方法,创建了SystemServer进程。

上文提到通过Zygote.forkSystemServer()方法fork出SystemServer进程后,会通过handleSystemServerProcess()方法去处理SystemServer进程的后续事务:

@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#handleSystemServerProcess
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    ...
    if (parsedArgs.mInvokeWith != null) {
        ...
        throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
    } else {
        ...
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                parsedArgs.mDisabledCompatChanges,
                parsedArgs.mRemainingArgs, cl);
    }
}

继续走到ZygoteInit的静态方法zygoteInit()中去:

@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#zygoteInit
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
    ...
    RuntimeInit.commonInit();
    //1.启动Binder线程池
    ZygoteInit.nativeZygoteInit();
    //返回Runnable,被调用run方法后进入SystemServer的main方法
    return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
            classLoader);
}
private static native void nativeZygoteInit();

注释1调用Native方法nativeZygoteInit(),用来启动Binder线程池。注释2用于进入SystemServer的main()方法。

启动Binder线程池

进程流程图__进程和流程

nativeZygoteInit()是一个Native方法,我们需要找到它对应的JNI文件,根据JNI的命名规则,其对应的C++方法为com_android_internal_os_ZygoteInit_nativeZygoteInit() :

@frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

gCurRuntime为AndroidRunTime类型的指针,指向其子类AppRunTime,它在app_main.cpp中定义:

@frameworks/base/cmds/app_process/app_main.cpp#onZygoteInit
virtual void onZygoteInit()
{
    sp proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    proc->startThreadPool();
}

startThreadPool()方法用于启动一个Binder线程池,SystemServer进程可以通过使用Binder与其他进程进行通信。

SystemServer进程首先会去启动一个Binder线程池的,主要是方便与其他进程进程通信。

进入SystemServer的main方法

回到ZygoteInit.java#zygoteInit()方法,启动Binder线程池后,会调用RuntimeInit的applicationInit()方法,向上返回一个Runnable对象:

@frameworks/base/core/java/com/android/internal/os/RuntimeInit.java#applicationInit
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
        String[] argv, ClassLoader classLoader) {
    ...
    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

继续进入到findStaticMain()方法

@frameworks/base/core/java/com/android/internal/os/RuntimeInit.java#findStaticMain
protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    Class> cl;
    try {
        //1.反射获取对象
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }
    Method m;
    try {
        //得到main方法
        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();
    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.
     */
    return new MethodAndArgsCaller(m, argv);
}

参数className为前面提到com.android.server.SystemServer,通过反射创建SystemServer对象,然后找到main函数,随后封装为一个Runnable类型的MethodAndArgsCaller对象返回,最终会返回到ZygoteInit.java的main函数中:

@frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#main
public static void main(String[] argv) {
    ...
    try {
        ...
        //默认为ture,用于启动SystemServer
        if (startSystemServer) {
            //fork出SystemServer进程并启动
            //在子进程中返回Runnable对象用于在SystemServer进程中去启动执行
            Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
            if (r != null) {
                //表示当前代码逻辑在子进程SystemServer中
                r.run();
                return;
            }
        }
        ...
    } 
    ...
}

调用MethodAndArgsCaller的run()方法

static class MethodAndArgsCaller 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 {
            //调用传进来的方法,也就是前面的main方法
            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);
        }
    }
}

当run()方法被调用,SystemServer进程就会走到SystemServer.java的main()方法中去。

systemserver.png

注意:最后将SystemServer.java的main()函数调用逻辑封装成Runnable类型的MethodAndArgsCaller对象,该对象作为ZygoteInit.java中forkSytemServer()函数的返回值,在ZygoteInit.java的main()函数中调用其run()函数去启动,主要是为了让SystemServer的main()方法看起来像是SystemServer进程的入口函数。

因此SystemServer进程由Zygote进程调用本地方法fork而出,随后SystemServer首先去开启了Binder线程池,便于与其他进程通信,然后再通过反射创建SystemSever对象,随后进入SystemServe的main()方法。

解析SystemServer进程

下面来看SystemSever的main()方法:

@frameworks/base/services/java/com/android/server/SystemServer.java#main
public static void main(String[] args) {
    new SystemServer().run();
}

直接new了一个对象后进入到run方法:

private void run() {
    try {
        ...
        //创建消息Looper
        Looper.prepareMainLooper();
        ...
        //加载动态库android_serves.so
        // Initialize native services.
        System.loadLibrary("android_servers");
        
        //初始化系统上下文
        // Initialize the system context.
        createSystemContext();
        ...
        //创建SystemServiceManager
        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
    }
    // Start services.
    try {
        t.traceBegin("StartServices");
        //启动引导服务
        startBootstrapServices(t);
        //启动核心服务
        startCoreServices(t);
        //启动其他服务
        startOtherServices(t);
        //启动Apex相关服务
        startApexServices(t);
    } 
    ...
    //进入loop()循环等待和处理请求
    // Loop forever.
    Looper.loop();
}

总结

systemserverall.png

SystemServer进程相关内容可以大致分为3步:

Zygote进程fork出SystemServer进程SystemServer进程做一些准备工作,比如启动Binder线程池,然后再去找到执行下一步的入口,SystemServer的main函数进入SystemServer的main函数: