引言

前面系列文章介绍了Android系统的第一个用户进程——init进程由解析init.rc脚本启动,完成属性系统的初始化等工作后紧接着启动Android系统上的造物者——Zygote进程在Zygote 进程启动过程中会把Android 最核心进程SystemServer进程创建并启动。

基于Android 26,方法在本系列文章代表Java层,函数指Native层的,仅供参考。

一、SystemServer 进程概述

SystemServer进程(System进程,名为system_server)在Android 系统中运行着各种系统核心服务ActivityManagerService、PackageManagerService、ContentService、WindowManagerService等六十多种服务,为了保护Android系统,Android 应用没有权限直接访问设备的底层资源,都是通过Binder去调用SystemService中的服务代理对象。在Zygote 进程启动后,由Zygote fork自身创建SystemServer进程并马上启动执行SystemServer类的main方法。

由于System进程是由Zygote fork自身而得到的,就是说System进程复制了Zygote进程的地址空间,也同样在启动时创建了一个socket。

安卓 dialog 层级 SYSTEM_ALERT_WINDOW 设置不生效 安卓 system_server_Android

二、SystemServer进程的创建

整体上可以把SystemServer进程创建分为两个阶段:首先是Zygote 进程fork 创建初始化SystemServer进程,然后是返回到SystemServer进程中执行SystemServer#main方法初始化和启动各种系统服务

/frameworks/base/cmds/app_process/app_main.cpp # main 解析init.rc 脚本传入的参数,触发AppRuntime #start函数进而执行ZygoteInit#main 方法。

1、ZygoteInit.main方法里调用startSystemServer方法触发SystemServer 进程的创建

前面分析得知在init.rc脚本中定义的Zygote进程的启动参数中包括了--start-system-server等,因此Zygote 进程会在ZygoteInit.main方法里调用startSystemServer方法来 fork 出SystemServer进程,startSystemServer 方法主要是做了三件事:

  1. 为SystemServer 准备启动参数(包括制定uid和gid为1000,执行Java类为com.android.SystemServer等)
  2. 通过调用Zygote.forkSystemServer方法真正fork 出SystemServer进程(JNI调用nativeForkSystemServer函数)
  3. fork 创建SystemServer进程后,返回到SystemServer进程中,真正开始初始化SystemServer(执行ZygoteInit.java #handleSystemServerProcess(parsedArgs)方法)。
private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {

        /* Hardcoded command line to start the system server */
        //System进程启动的参数,可以看到System进程的用户ID和用户组ID都是1000,同时还有其他用户组的权限
        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 */
            //fork 创建System进程
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        }
        /* For child process  fork 后返回到SystemServer进程*/
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                if(isBox){
                    waitForSecondaryZygote(socketName);
                }
                Log.d(TAG,"--------call waitForSecondaryZygote,skip this---,abiList= "+abiList);
            }
            // 处理System进程启动事宜
            handleSystemServerProcess(parsedArgs);
        }
        return true;
    }

2、Zygote.forkSystemServer 方法触发fork 创建SystemServer进程

应用启动时会调用Zygote 类的forkAndSpecialize 方法来fork出子进程,而SystemServer进程是由forkSystemServer方法 fork出来的,虽然本质都是通过JNI 调用\frameworks\base\core\jni\com_android_internal_os_Zygote.cpp中native函数完成

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) {
    //真正去调用系统调用fork 创建
  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) {
      ALOGI("System server process %d has been created", pid);
      gSystemServerPid = pid;
      int status;
      //Zygote进程中检查SystemServer 是否启动成功
      if (waitpid(pid, &status, WNOHANG) == pid) {
          ALOGE("System server process %d has died. Restarting Zygote!", pid);
          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
      }
  }
  return pid;
}

当native层执行完毕ForkAndSpecializeCommon函数后,还会返回Zygote进程中检查SystemServer 是否启动成功,如果SystemServer 启动不成功,系统会从Zygote开始再启动一遍。

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();
	...
  pid_t pid = fork();
	...
  if (pid == 0) {
    rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);
	...
    if (se_info_c_str == NULL && is_system_server) {
      se_name_c_str = "system_server";
    }
    if (se_info_c_str != NULL) {
      SetThreadName(se_name_c_str);
    }
    UnsetSigChldHandler();
    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
                              is_system_server, instructionSet);
							  ...
  }
  return pid;
}

从代码中可以看到在fork之前,首先注册了SIGCHILD信号的处理函数SIGChildHandler 函数,当捕捉到这个SIGCHILD信号(通常是子进程死亡时)后,除了调用waitpid来防止子进程变“僵尸”外,还会再判断是否是SystemServer进程,如果是,Zygote进程会自杀,进而导致Init进程杀死所有用户进程并重启Zygote。

三、SystemServer 进程的初始化

1、返回ZygoteInit#handleSystemServerProcess方法SystemServer开始初始化工作

\frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

当Zygote进程在main方法里fork出SystemServer进程后,回到ZygoteInit.main方法中继续往下执行ZygoteInit#handleSystemServerProcess方法开始初始化SystemServer进程,首先将SystemServer进程的umask设为0077,这样当SystemServer 创建的文件的属性就是0077,即只有SystemServer 进程才可以访问,然后把SystemServer进程的名称修改为system_server

/**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
		    // 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");
        if (systemServerClasspath != null) {
            performSystemServerDexOpt(systemServerClasspath);
        }

        if (parsedArgs.invokeWith != null) {
            ...
        } else {
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

                Thread.currentThread().setContextClassLoader(cl);
            }
            /*
             * Pass the remaining arguments to SystemServer.
             */
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    }

首次执行时parsedArgs.invokeWith 为null,所以首先是执行 ZygoteInit.zygoteInit方法来反射调用SystemServer类的main方法。

2、执行/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java # zygoteInit 方法继续初始化System进程

在返回到System进程后最终执行 RuntimeInit.java # zygoteInit 方法继续启动System进程:

  • commonInit 方法配置System进程的时区、键盘布局等通用信息
  • nativeZygoteInit 方法在System进程中开启一个Binder线程池
  • 执行invokeStaticMain方法,表示要触发类名为“"com.android.server.SystemServer”静态成员main方法,即作为System进程的”入口“

在ZygoteInit.java # startSystemServer 中fork System 进程时传递的类名为"com.android.server.SystemServer“

/**
     * The main function called when started through the zygote process. This
     * could be unified with main(), if the native code in nativeFinishInit()
     * were rationalized with Zygote startup.<p>
     * @param targetSdkVersion target SDK version
     * @param argv arg strings argv 最后一个参数的值为"com.android.server.SystemServer"
     */
    public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
        redirectLogStreams();

        commonInit();
        nativeZygoteInit();
        //invokeStaticMain 在这里被执行
        applicationInit(targetSdkVersion, argv, classLoader);
    }

实际上System进程进入到com.android.server.SystemServer # main方法时,已经执行了很多代码量,从严格意义上讲main方法并不是System进程的入口方法,只不过Runtime#invokeStaticMain 使用了巧妙地方法来调用它使之变成是System进程的入口。

3、执行 /frameworks/base/services/java/com/android/server/SystemServer.java # main方法完成SystemServer的初始化

在SystemServer.java # main方法里完成系统属性的初始化、核心系统服务的启动、Handler 消息机制的初始化以及其他重要系统服务的启动。

/**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }
    private void run() {
        try {
            if (!SystemProperties.get("persist.sys.language").isEmpty()) {
                final String languageTag = Locale.getDefault().toLanguageTag();
                SystemProperties.set("persist.sys.locale", languageTag);
                SystemProperties.set("persist.sys.language", "");
                SystemProperties.set("persist.sys.country", "");
                SystemProperties.set("persist.sys.localevar", "");
            }
    			...
            // Here we go!
            Slog.i(TAG, "Entered the Android system server!");
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
            //设置当前的虚拟机的运行库路径
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
            // Mmmmmm... more memory!
            VMRuntime.getRuntime().clearGrowthLimit();

            // The system server has to run all of the time, so it needs to be
            // as efficient as possible with its memory usage.
            VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);    
            // Increase the number of binder threads in system_server
            BinderInternal.setMaxThreads(sMaxBinderThreads);

            // Prepare the main looper thread (this thread).
            android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            Looper.prepareMainLooper();

            // Initialize native services.
            System.loadLibrary("android_servers");

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // Initialize the system context.
            createSystemContext();
                      
            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }

        // Start services.
        try {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
        } catch (Throwable ex) {
            throw ex;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }

3.1、 System.loadLibrary(“android_servers”) 加载framework/base/services/jni下的libandroid_servers.so库并初始化相关native服务

3.2、 createSystemContext() 获取系统的Context并设置主题

通过ActivityThread的systemMain方法来获取ActivityThread对象进而获取系统的Context,最终设置系统主题

private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }
3.2.1、在ActivityThread.systemMain方法中创建ActivityThread对象并调用ActivityThread#attach方法
public static ActivityThread systemMain() {
        ...
        ActivityThread thread = new ActivityThread();
        thread.attach(true);
        return thread;
    }
3.2.2、在ActivityThread.attach方法中创建Instrumentation对象和Context(ContextImpl)对象
private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
        	...
        } else {
            try {
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }
        ...
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

attach时传入的system参数值为true时,会创建一个类似应用的环境,创建了ContextImpl、Application对象并调用Application#onCreate方法,完全是在创建一个应用。每一个上下文对象都需要对应一个APK文件,注意查看ContextImpl里的PackgeInfo对象(来源于ActivityThread#getSystemContext方法)

每一个上下文对象都需要对应一个APK文件,换言之每一个Context对象对应着一个APP的环境,同时每个App 也对应着一个Application对象

public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                mSystemContext = ContextImpl.createSystemContext(this);
            }
            return mSystemContext;
        }
    }

当mSystemContext为null时,会调用ContextImpl.createSystemContext方法中创建。

3.2.3、在ContextImpl.createSystemContext方法中创建LoadedApk对象
static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                null);
        context.setResources(packageInfo.getResources());
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        return context;
    }

而LoadedApk 构造方法

/**
     * Create information about the system package.
     * Must call {@link #installSystemApplicationInfo} later.
     */    
LoadedApk(ActivityThread activityThread) {
        mActivityThread = activityThread;
        mApplicationInfo = new ApplicationInfo();
        mApplicationInfo.packageName = "android";
        mPackageName = "android";
        ...
        mClassLoader = ClassLoader.getSystemClassLoader();
        mResources = Resources.getSystem();
    }

可以看到包名为android(framework-res.apk的包名也是android),自然getSystemContext方法放回的mSystemContext 所对应的apk文件其实是framework-res.apk,当attach方法被执行时,新建的ContextImpl对象本质上是在复制mSystemContext,最终创建的Application对象相当于是framework-res.apk。总而言之,Activity#systemMain方法相当于创建了一个framework-res.apk 的上下文环境。

3.3、创建SystemServiceManager对象(管理系统服务)

3.4、startBootstrapServices、startCoreServices、startOtherServices启动所有系统服务

至于具体系统服务的启动系列留到后续文章一一详细分析,需要注意的是除了初始化系统服务之外,SystemServer还需要监控各种系统服务是否正常工作,因此设计了一套软件“看门狗方案”并在startOtherServices方法里创建并启动,至此SystemServer进程启动完毕,SystemServer进程在初始化的时候也需要和普通应用进程一样,创建一个类似应用的环境。