美文网首页
SystemServer

SystemServer

作者: 开开向前冲 | 来源:发表于2017-08-25 18:49 被阅读0次

    版权说明:本文为 开开向前冲 原创文章,转载请注明出处;
    注:限于作者水平有限,文中有不对的地方还请指教

    如果你细心的话,前文Zygote-Java文章中有一个核心调用没讲——caller.run();
    本章将会描述该核心调用在什么时候被调用;

    SystemServer是从Zygote的嫡子,下面从Zygote开始看看SystemServer的诞生;

    startSystemServer
    /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java  
    
        /**
         * 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[] = {
                "--setuid=1000",//设置UID,GID
                "--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 */
                pid = Zygote.forkSystemServer( //Zygote fork出子进程,这里会调到JNI中
                //com_android_internal_os_Zygote.cpp中的ForkAndSpecializeCommon,最终调用fork()创建SystemServer进程
                        parsedArgs.gids,
                        parsedArgs.debugFlags,
                        null,
                        parsedArgs.permittedCapabilities,
                        parsedArgs.effectiveCapabilities);
            } catch (IllegalArgumentException ex) {
                throw new RuntimeException(ex);
            }
            /* For child process */
            if (pid == 0) {//pid==0 代表新的进程
                if (hasSecondZygote(abiList)) {
                    waitForSecondaryZygote(socketName);
                }
                handleSystemServerProcess(parsedArgs);//处理systemserver
            }
            return true;
        }
    

    step1:forkSystemServer(Zygote.java)——>step2:nativeForkSystemServer(Zygote.java) ——> (step3)(JNI)com_android_internal_os_Zygote_nativeForkSystemServer(com_android_internal_os_Zygote.cpp)
    ——>(step4)ForkAndSpecializeCommon——>(step5)fork();
    从Java世界到Native的fork();SystemServer进程被创建出来了;

    handleSystemServerProcess
    /**
         * Finish remaining work for the newly forked system server process.
         */
        private static void handleSystemServerProcess(
                ZygoteConnection.Arguments parsedArgs)
                throws ZygoteInit.MethodAndArgsCaller {
    
            closeServerSocket();//关闭父进程创建的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");//adb shell进终端,
                                                           //echo $SYSTEMSERVERCLASSPATH,有值输出,不为空
            if (systemServerClasspath != null) {
                performSystemServerDexOpt(systemServerClasspath);//预优化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.
                 */
                RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
                //最终会调用这里
            }
            /* should never reach here */
        }
    

    Zygote进程创建的子进程会继承Zygote进程中创建的Socket文件描述符,再加上子进程又不会使用,所以这里就调用closeServerSocket函数来关闭。这里最终会调用
    RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    Zygote-Java中讲到Zygote进程监听应用程序启动时也会执行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");
            redirectLogStreams();//重定向System.out和System.err到Android Log
            commonInit();//初始化UA,时区等
            nativeZygoteInit();//native初始化,在/frameworks/base/core/jni/AndroidRuntime.cpp中实现
            applicationInit(targetSdkVersion, argv, classLoader);
        }
    

    /frameworks/base/core/jni/AndroidRuntime.cpp

    
    static AndroidRuntime* gCurRuntime = NULL;//静态变量
    AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength)
    ......
    {  
          ......
          gCurRuntime = this;
    }
    static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
    {
        gCurRuntime->onZygoteInit();
    }
    /*
     * 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 },
    };
    

    gCurRuntime 在AndroidRuntime的构造函数中被初始化为this指针,而AndroidRuntime在Zygote进程的app_main.cpp中被AppRuntime继承并构造,所以此时的gCurRuntime指向AppRuntime ,所以nativeZygoteInit最终会调调到app_main.cpp中AppRuntime的onZygoteInit方法。

    /frameworks/base/cmds/app_process/app_main.cpp

        virtual void onZygoteInit()
        {
            sp<ProcessState> proc = ProcessState::self();//单列获取SystemServer的进程对象
            ALOGV("App process: starting thread pool.\n");
            proc->startThreadPool();//开启Binder线程池
        }
    

    这里创建了ProcessState对象,开启线程池用于Binder通信,标志这SystemServer具备了Binder通信的能力;因为后续会提到的AMS,PMS,PowerMS都是运行与SystemServer,ProcessState对象是单例对象,每个进程仅有一个,所以在这里初始化Binder,后续AMS,PMS等服务线程就可以直接使用。

    再来看看/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java 的applicationInit

    applicationInit
    private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
                throws ZygoteInit.MethodAndArgsCaller {
            // If the application calls System.exit(), terminate the process
            // immediately without running any shutdown hooks.  It is not possible to
            // shutdown an Android application gracefully.  Among other things, the
            // Android runtime shutdown hooks close the Binder driver, which can cause
            // leftover running threads to crash before the process actually exits.
            nativeSetExitWithoutCleanup(true);
    
            // We want to be fairly aggressive about heap utilization, to avoid
            // holding on to a lot of memory that isn't needed.
            VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
            VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);//设置SDK版本
    
            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
            invokeStaticMain(args.startClass, args.startArgs, classLoader);//核心,args.startClass就
                                                      //是ZygoteInit.java中startSystemServer方法传递过来的参数
        }
    
    invokeStaticMain
    /**
         * Invokes a static "main(argv[]) method on class "className".
         * Converts various failing exceptions into RuntimeExceptions, with
         * the assumption that they will then cause the VM instance to exit.
         *
         * @param className Fully-qualified class name
         * @param argv Argument vector for main()
         * @param classLoader the classLoader to load {@className} with
         */
        private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
                throws ZygoteInit.MethodAndArgsCaller {
            Class<?> cl;
    
            try {
                cl = Class.forName(className, true, classLoader);//利用反射获取得到SystemServer
            } 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();
            if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            //判断方法修饰符,必须是public和static
                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);//核心就是在此了,故意抛出这个异常,
                                                              //需要注意这个异常的参数
        }
    

    这里Method m=main(),argv从handleSystemServerProcess方法的parsedArgs.remainingArgs中传递过来;

    这里抛出的异常在什么位置处理呢???这里源码注释也有讲到,向上寻找,发现在调用startSystemServer的ZygoteInit的main方法中:

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

    main()——>>>>>>>>>
    try {
      ...
      if (startSystemServer) {
           startSystemServer(abiList, socketName);//启动SystemServer
      }
      ...
    } catch(MethodAndArgsCaller caller) {
           caller.run();          //核心调用,故意抛出异常来处理
    }
    

    没错,这就是文章开头说Zygote-Java章节中没有提到的—— caller.run()

    caller——>MethodAndArgsCaller——>ZygoteInit.java
        /**
         * Helper exception class which holds a method and arguments and
         * can call them. This is used as part of a trampoline to get rid of
         * the initial process setup stack frames.
         */
        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;
                mArgs = args;
            }
            public void run() {
                try {
                    mMethod.invoke(null, new Object[] { mArgs });//利用反射调用SystemServer的main方法
                } 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);
                }
            }
        }
    

    这里mMethod就是前面前面的Method m=main(),mArgs从handleSystemServerProcess方法的parsedArgs.remainingArgs中传递过来;利用反射调用SystemServer 类的main方法;下面我们直接到SystemServer.java 的main方法:

    /frameworks/base/services/java/com/android/server/SystemServer.java

        /**
         * The main entry point from zygote.
         */
        public static void main(String[] args) {
            new SystemServer().run();
        }
    
        public SystemServer() {
            // Check for factory test mode.
            mFactoryTestMode = FactoryTest.getMode();
        }
    
        private void run() {
            // If a device's clock is before 1970 (before 0), a lot of
            // APIs crash dealing with negative numbers, notably
            // java.io.File#setLastModified, so instead we fake it and
            // hope that time from cell towers or NTP fixes it shortly.
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }
            // If the system has "persist.sys.language" and friends set, replace them with
            // "persist.sys.locale". Note that the default locale at this point is calculated
            // using the "-Duser.locale" command line flag. That flag is usually populated by
            // AndroidRuntime using the same set of system properties, but only the system_server
            // and system apps are allowed to set them.
            //
            // NOTE: Most changes made here will need an equivalent change to
            // core/jni/AndroidRuntime.cpp
            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());
    
            // In case the runtime switched since last boot (such as when
            // the old runtime was removed in an OTA), set the system
            // property so that it is in sync. We can't do this in
            // libnativehelper's JniInvocation::Init code where we already
            // had to fallback to a different runtime because it is
            // running as root and we need to be the system user to set
            // the property. http://b/11463182
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
            //重新设置虚拟机
    
            // Enable the sampling profiler.
            if (SamplingProfilerIntegration.isEnabled()) {
                SamplingProfilerIntegration.start();
                mProfilerSnapshotTimer = new Timer();
                mProfilerSnapshotTimer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        SamplingProfilerIntegration.writeSnapshot("system_server", null);
                    }
                }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
            }
    
            // 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);
    
            // Some devices rely on runtime fingerprint generation, so make sure
            // we've defined it before booting further.
            Build.ensureFingerprintProperty();
    
            // Within the system server, it is an error to access Environment paths without
            // explicitly specifying a user.
            Environment.setUserRequired(true);
    
            // Ensure binder calls into the system always run at foreground priority.
            BinderInternal.disableBackgroundScheduling(true);
    
            // Prepare the main looper thread (this thread).
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            Looper.prepareMainLooper();//准备Main Looper
    
            // 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();//创建System Context;
    
            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    
            // Start services.
            try {
                startBootstrapServices();//核心:启动引导核心服务
                startCoreServices();     //核心:启动核心服务
                startOtherServices();    //核心:启动其他服务
            /**
            * 很多系统服务都是从这里启动,什么AMS,PMS等等,都是从这里启动;
            * 所以这些服务都是运行在SystemServer进程,只是不同的服务运行于不同的线程;
            */
            } catch (Throwable ex) {
                Slog.e("System", "******************************************");
                Slog.e("System", "************ Failure starting system services", ex);
                throw ex;
            }
    
            // For debug builds, log event loop stalls to dropbox for analysis.
            if (StrictMode.conditionallyEnableDebugLogging()) {
                Slog.i(TAG, "Enabled StrictMode for system server main thread.");
            }
            // Loop forever.
            Looper.loop();//进入无限循环
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    

    到这里SystemServer就启动完成,进入无限循环;对于系统服务的启动这里暂时不讲,后续讲到各个服务的时候会说道;这里我们知道Android 系统服务是如何启动:

    1. Linux 启动Init进程,Init进程通过解析init.rc脚本创建Zygote进程和相关服务端Socket;
    2. Zygote进程负责启动SystemServer进程和循环监听处理AMS启动应用进程的请求;
    3. SystemServer进程启动系统服务,如ActivityManagerService,PackageManagerService等;
    4. 启动Android应用程序时,ActivityManagerService会通过Socket向Zygote进程发送数据,由Zygote创建新的应用进程。

    相关文章

      网友评论

          本文标题:SystemServer

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