美文网首页
Android 系统启动 - SystemServer 进程

Android 系统启动 - SystemServer 进程

作者: Whyn | 来源:发表于2019-03-15 00:48 被阅读0次

    前言

    SystemServer 是 Android 系统非常重要和核心的服务,其进程名为 system_server,它会在创建后启动系统中的其他服务,然后成为所有服务的管理者,向应用程序和其他服务提供服务。

    SystemServer 启动过程

    Android 系统启动 - Zygote 进程 中,我们提到,Zygote 进程在创建虚拟机,注册 JNI 本地方法,预加载类和资源等操作后,会启动 SystemServer 进程:
    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    public static void main(String argv[]) {
        try {
            ···
            if (startSystemServer) {
                // 启动 SystemServer 进程
                startSystemServer(abiList, socketName);
            }
        } catch (MethodAndArgsCaller caller) {
            caller.run(); // 真正启动 SystemServer
        } 
        ···
    }
    

    SystemServer 进程的启动是由 startSystemServer 负责:
    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    private static boolean startSystemServer(String abiList, String socketName)
                throws MethodAndArgsCaller, RuntimeException {
            ···
            /* Hardcoded command line to start the system server */
            // 启动SystemServer进程的参数
            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",
                "--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 */
                // 请求创建SystemServer进程
                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 */
            // 进入SystemServer进程
            if (pid == 0) {
                if (hasSecondZygote(abiList)) {
                    waitForSecondaryZygote(socketName);
                }
                // 处理SystemServer进程剩余工作
                handleSystemServerProcess(parsedArgs);
            }
    
            return true;
        }
    

    从该函数中可以看到,startSystemServer 最终通过 Zygote.forkSystemServer 方法创建了 SystemServer 进程,并且从传递启动 SystemServer 进程的参数可以得知:SystemServer 进程的 uid=pid=1000;进程名为 system_server;启动的类名为com.android.server.SystemServer。

    对于 Zygote.forkSystemServer 方法,其内部其实是通过 JNI 方法调用 C++ 层代码,最终通过调用 fork 函数创建子进程,也即:SystemServer 进程。由于我们这边侧重于对流程的解析,所以我们就不深入分析 Zygote.forkSystemServer 的具体过程。感兴趣者可以查看:Android系统启动-SystemServer上篇

    startSystemServer 通过 Zygote.forkSystemServer 成功创建完 SystemServer 进程后,就会进入 handleSystemServerProcess 函数,对 SystemServer 进程做进一步操作:
    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
    
        //关闭复制父进程zygote的Socket
        closeServerSocket();
    
        // 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); //设置当前进程名为"system_server"
        }
    
        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            // 进行dex优化
            performSystemServerDexOpt(systemServerClasspath);
        }
    
        if (parsedArgs.invokeWith != null) {
            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 = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
                Thread.currentThread().setContextClassLoader(cl);
            }
    
            /*
             * Pass the remaining arguments to SystemServer.
             */
            // 传递剩余参数给到SystemServer进程,做进一步处理
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    
        /* should never reach here */
    }
    

    该函数其实主要做了三件事:

    • 关闭从父进程 Zygote 复制而来的 Socket:closeServerSocket
    • 设置当前进程名为 system_serverProcess.setArgV0
    • 进行 dex 优化:performSystemServerDexOpt
    • 对 SystemServer 进程做进一步处理:RuntimeInit.zygoteInit

    我们主要来看下 RuntimeInit.zygoteInit
    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");
        // 将 System.out,System.err 重定向到 Android Log
        redirectLogStreams();
        // 进行一些通用操作的初始化
        commonInit();
        // JNI 调用本地方法启动Binder线程池
        nativeZygoteInit();
        // 应用初始化
        applicationInit(targetSdkVersion, argv, classLoader);
    }
    

    zygoteInit 函数主要做了四件事:

    • 重定向系统输出流/错误流 到 Android Log 输出:redirectLogStreams
    • 进行一些通用操作的初始化:设置默认的未捕获异常处理,时区设置,设置默认 HTTP User-Agent 头部等等:commonInit
    • 使用 JNI 调用本地方法启动 Binder 线程池:nativeZygoteInit
    • 对 SystemServer 的进一步初始化:applicationInit

    我们主要来看下:nativeZygoteInitapplicationInit

    先查看下 nativeZygoteInit 源码实现:见名知意,该方法调用的是一个本地方法,其对应的 JNI 文件为:frameworks/base/core/jni/AndroidRuntime.cpp

    /*
     * JNI registration.
     */
    static JNINativeMethod gMethods[] = {
        { "nativeFinishInit", "()V",
            (void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
        { "nativeZygoteInit", "()V",
            (void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
        { "nativeSetExitWithoutCleanup", "(Z)V",
            (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
    };
    

    因此,nativeZygoteInit 对应的本地方法(C++)为:com_android_internal_os_RuntimeInit_nativeZygoteInit

    ···
    static AndroidRuntime* gCurRuntime = NULL;
    ···
    static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
      //gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的
        gCurRuntime->onZygoteInit();
    }
    

    此处的 gCurRuntimeAndroidRuntime 类型,但其真实类型为 AndroidRuntime 的子类型:AppRuntime。所以 nativeZygoteInit 最终调用的是 AppRuntime.onZygoteInit
    frameworks/base/cmds/app_process/app_main.cpp

    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool(); // 启动 Binder 线程池
    }
    

    可以看到,nativeZygoteInit 最终通过 ProcessState.startThreadPool 启动了一个 Binder 线程池。到此,SystemServer 进程就具备了与其他进程通过 Binder 进程通信的功能了。

    所以,nativeZygoteInit 的作用就是启动 Binder 线程池。

    接下来我们来看下:applicationInit
    frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

    private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用
        nativeSetExitWithoutCleanup(true);
    
        // 设置虚拟机的内存利用率参数值为0.75
        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());
            // 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
        // 调用类"com.android.server.SystemServer" 的 main 方法
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }
    

    applicationInit 最终调用了 invokeStaticMain 方法,此处:args.startClass 为 "com.android.server.SystemServer",我们进入 invokeStaticMain 方法查看下:
    frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

    private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;
    
        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            ···
        }
    
        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            ···
        }
        ···
        /*
         * 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);
    }
    

    这里其实就是通过反射找到类 com.android.server.SystemServermain 方法,然后通过主动抛出一个 ZygoteInit.MethodAndArgsCaller 异常,该异常会被 ZygoteInit.main() 函数捕获,然后再捕获该异常处会通过 MethodAndArgsCaller.run 最终反射调用 SystemServer.main 函数,具体源码如下:
    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    public static void main(String argv[]) {
        try {
            ···
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            ···
        }
    }
    
    public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        ···
        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                ···
            }
        }
    }
    

    到这里,SystemServer.main 函数就启动了,接下来的操作才是 SystemServer 真正发挥 Android 核心服务的体现。

    那接下来我们就来分析下 SystemServer.main 函数,看下其做了哪些事情。

    SystemServer 核心操作 过程

    先来看下 SystemServer.main 函数:
    frameworks/base/services/java/com/android/server/SystemServer.java

    public static void main(String[] args) {
            new SystemServer().run();
        }
    

    直接创建一个 SystemServer 实例,并调用其 run 方法:

    private void run() {
        ···
        // Ensure binder calls into the system always run at foreground priority.
        // 确保当前进程的 binder 调用总是运行在前台优先级
        BinderInternal.disableBackgroundScheduling(true);
        ···
        // 创建主线程 Looper
        Looper.prepareMainLooper();
    
        // Initialize native services.
        // 加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下
        System.loadLibrary("android_servers");
        ···
        // Initialize the system context.
        // 初始化系统上下文
        createSystemContext();
    
        // Create the system service manager.
        //创建系统服务管理
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        // 将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    
        // Start services.
        //  启动各种系统服务
        try {
            startBootstrapServices(); // 启动引导服务
            startCoreServices();      // 启动核心服务
            startOtherServices();     // 启动其他服务
        } catch (Throwable ex) {
            ···
        }
        ···
        // Loop forever.
        // 启动 Looper 循环
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    

    SystemServer.run 方法做了很多事情,其中最主要的就是:

    • 创建并启动主线程 Looper,使能线程间通讯:Looper.prepareMainLooperLooper.loop
    • 加载 android_servers.so 库:System.loadLibrary("android_servers")
    • 初始化系统上下文:createSystemContext
    • 创建系统服务管理 ServiceManagernew SystemServiceManager
    • 启动各种服务startBootstrapServicesstartCoreServicesstartOtherServices

    我们主要来看下启动各种服务的大概过程:

    首先看下 引导服务 启动过程:startBootstrapServices
    frameworks/base/services/java/com/android/server/SystemServer.java

    private void startBootstrapServices() {
        // Wait for installd to finish starting up so that it has a chance to
        // create critical directories such as /data/user with the appropriate
        // permissions.  We need this to complete before we initialize other services.
        // 阻塞等待与installd建立socket通道
        Installer installer = mSystemServiceManager.startService(Installer.class);
    
        // Activity manager runs the show.
        // 启动服务ActivityManagerService
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
    
        // Power manager needs to be started early because other services need it.
        // Native daemons may be watching for it to be registered so it must be ready
        // to handle incoming binder calls immediately (including being able to verify
        // the permissions for those calls).
        // 启动服务PowerManagerService
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
        ···
        // Manages LEDs and display backlight so we need it to bring up the display.
        // 启动服务LightsService
        mSystemServiceManager.startService(LightsService.class);
    
        // Display manager is needed to provide display metrics before package manager
        // starts up.
        // 启动服务DisplayManagerService
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
    
        // We need the default display before we can initialize the package manager.
        // Phase100:在初始化package manager之前,需要默认的显示
        mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
        ···
        // Start the package manager.
        // 启动服务PackageManagerService
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
    
        // 启动服务UserManagerService,新建目录/data/user/
        ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
        ···
        // Set up the Application instance for the system process and get started.
        // 设置 AMS
        mActivityManagerService.setSystemProcess();
    
        // The sensor service needs access to package manager service, app ops
        // service, and permissions service, therefore we start it after them.
        // 启动传感器服务
        startSensorService();
    }
    

    startBootstrapServices 主要做的就是启动各种引导服务(共 7 个):
    ActivityManagerService,PowerManagerService,LightsService,DisplayManagerService,PackageManagerService,UserManagerService,SensorService。

    接下来看下 核心服务 启动过程:startCoreServices
    frameworks/base/services/java/com/android/server/SystemServer.java

    private void startCoreServices() {
        // Tracks the battery level.  Requires LightService.
        // 启动服务BatteryService,用于统计电量
        mSystemServiceManager.startService(BatteryService.class);
    
        // Tracks application usage stats.
        // 启动服务UsageStatsService,用于统计应用使用情况
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));
        // Update after UsageStatsService is available, needed before performBootDexOpt.
        mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
    
        // Tracks whether the updatable WebView is in a ready state and watches for update installs.
        // 启动服务WebViewUpdateService
        mSystemServiceManager.startService(WebViewUpdateService.class);
    }
    

    startCoreServices 就是用来启动 BatteryService,UsageStatsService,WebViewUpdateService 这些核心服务。

    最后来看下 其他服务 启动情况:startOtherServices
    frameworks/base/services/java/com/android/server/SystemServer.java

     private void startOtherServices() {
            ...
            SystemConfig.getInstance();
            mContentResolver = context.getContentResolver(); // resolver
            ...
            mActivityManagerService.installSystemProviders(); //provider
            mSystemServiceManager.startService(AlarmManagerService.class); // alarm
            // watchdog
            watchdog.init(context, mActivityManagerService); 
            inputManager = new InputManagerService(context); // input
            wm = WindowManagerService.main(...); // window
            inputManager.start();  //启动input
            mDisplayManagerService.windowManagerAndInputReady();
            ...
            mSystemServiceManager.startService(MOUNT_SERVICE_CLASS); // mount
            mPackageManagerService.performBootDexOpt();  // dexopt操作
            ActivityManagerNative.getDefault().showBootMessage(...); //显示启动界面
            ...
            statusBar = new StatusBarManagerService(context, wm); //statusBar
            //dropbox
            ServiceManager.addService(Context.DROPBOX_SERVICE,
                        new DropBoxManagerService(context, new File("/data/system/dropbox")));
             mSystemServiceManager.startService(JobSchedulerService.class); //JobScheduler
             lockSettings.systemReady(); //lockSettings
    
            //phase480 和phase500
            mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
            mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
            ...
            // 准备好window, power, package, display服务
            wm.systemReady();
            mPowerManagerService.systemReady(...);
            mPackageManagerService.systemReady();
            mDisplayManagerService.systemReady(...);
            
            //重头戏[见小节2.1]
            mActivityManagerService.systemReady(new Runnable() {
                public void run() {
                  ...
                }
            });
        }
    

    startOtherServices 的源码很长,但其主要做的就是启动一系列的服务(共 70 余个),如:AlarmManagerService,VibratorService 等。

    SystemServer 启动完成各种服务后,最后就会开启 SystemServer 进程主线程消息循环 Looper.loop,使能 SystemServer 进程线程间通讯。

    到此,SystemServer 进程已分析完毕。

    总结

    SystemServer 进程是由 Zygote 进程孵化(fork)出来的,具体为:Zygote 进程会通过 JNI 调用本地方法,fork 出一个子进程,也即 SystemServer 进程,然后 SystemServer 进程会通过一些列的操作,最终调用到 SystemServer.main函数,在此完成了 SystemServer 最主要的一些操作,让其成为 Android 承载核心业务的服务。

    简单来讲,SystemServer 进程其主要做了以下几件事:

    • 创建自身的 Binder 线程池,使能进程间通讯
    • 创建系统服务管理:SystemServiceManager,用于管理系统中的所有服务
    • 启动各种服务
    • 启动线程间通讯

    参考

    相关文章

      网友评论

          本文标题:Android 系统启动 - SystemServer 进程

          本文链接:https://www.haomeiwen.com/subject/jzkhmqtx.html