Android 9 (P)系统启动之SystemServer大揭秘下

      Android 9 系统启动之SystemServer大揭秘下



前言

  在前面的章节Android 9 系统启动之SystemServer大揭秘上中,我们细说了Android的system_server进程的出身及启动流程,在今天的篇章中我们将要看看system_server进程作为Android世界的肱骨大臣究竟有何功劳,能在Android世界享有如此美誉能和zygote同生共死。下面就让我们来看看system_serveer究竟有何丰功伟绩,让我们细品!

注意:本文演示的代码是Android P高通msm8953平台源码。其中涉及的源码路径如下:

frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/android/app/LoadedApk.java
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java


一. SystemServer彪悍的一生

  通过前面章节我们知道最后通过反射调用mMethod.invoke开启了SystemServer的彪悍人生,最终会调用到SystemServer.main()方法,还等什么让我们一探究竟。整个system_server进程启动流程图如下:
Android 9 (P)系统启动之SystemServer大揭秘下_第1张图片

SystemServer.main()启动流程图示意如下,这章主要详细分析如下几个流程.
Android 9 (P)系统启动之SystemServer大揭秘下_第2张图片


1.1 SystemServer.main

  无过多修饰,直接创建new一个SystemServer对象并调用其run方法。

    public static void main(String[] args) {
        new SystemServer().run();//就是这么简单,霸气有总裁范啊,直接创建并运行毫不拖泥带水的
    }

1.2 SystemServer.run

  前面霸道总裁装逼了一会儿,得开始干正事了,上来就是一堆代码啊!其主要逻辑无外乎前面总结的:

  • 初始化一些零碎事务
  • createSystemContext初始化system_server进程的context,这个是重点需要分析的
  • startBootstrapServices启动第一阶段服务
  • startCoreServices启动核心服务
  • startOtherServices启动其它服务
    private void run() {
        try {
        	//这个主要是为了调试使用,打日志
            traceBeginAndSlog("InitBeforeStartServices");
            // 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.
            //如果系统时钟早于1970,则系统强制设置从1970年开始
            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
            }

            //
            // Default the timezone property to GMT if not set.
            //
            //如果没有设置默认时区,则强制设置默认时区为GMT
            String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
            if (timezoneProperty == null || timezoneProperty.isEmpty()) {
                Slog.w(TAG, "Timezone not set; setting to GMT.");
                SystemProperties.set("persist.sys.timezone", "GMT");
            }

            // 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", "");
            }

            // The system server should never make non-oneway calls
            Binder.setWarnOnBlocking(true);//这几个暂时还没有搞清楚是干啥的主要,先忽略
            // The system server should always load safe labels
            PackageItemInfo.setForceSafeLabels(true);

            // Default to FULL within the system server.
            SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;

            // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
            SQLiteCompatibilityWalFlags.init(null);
            // Here we go!
            Slog.i(TAG, "Entered the Android system server!");
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
            if (!mRuntimeRestart) {
                MetricsLogger.histogram(null, "boot_system_server_init", 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 | xq oqi'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
            //变更虚拟机的库文件,这里默认使用的是libart.so
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

            // Mmmmmm... more memory!
            //由于system_server进程启动过程中消耗较多的虚拟机内存空间,所以先清除vm内存增长上限,供SystemServer正常启动
            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.
            //设置堆栈利用率为0.8,GC后会重新计算堆栈空间大小
            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);

            // Within the system server, any incoming Bundles should be defused
            // to avoid throwing BadParcelableException.
            BaseBundle.setShouldDefuse(true);//这个不是很明白,先忽略

            // Within the system server, when parceling exceptions, include the stack trace
            Parcel.setStackTraceParceling(true);//看英文意思是Parceling打包发生异常,会打印堆栈调试信息

            // Ensure binder calls into the system always run at foreground priority.
            //确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority),并且设置binder最大线程数位31
            BinderInternal.disableBackgroundScheduling(true);

            // 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
            Looper.prepareMainLooper();
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

            // Initialize native services.
            //加载android_servers.so库,该库就是frameworks/base/services/core/jni生成的
            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_server进程中创建Context,供后续启动的服务使用,具体将章节1.3

            // Create the system service manager.
            //构建SystemServiceManager对象,注意这个不是Android binder服务的大管家那个
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
                    
            // 将SystemServiceManager对象保存到SystemServer进程中的一个数据结构中   
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        // Start services.
        try {//启动各种层级服务
            traceBeginAndSlog("StartServices");
            startBootstrapServices();//启动系统Boot级别服务
            startCoreServices();//启动系统级别核心服务
            startOtherServices();//启动其它类型服务,主要是厂家可以根据实际情况配置的服务
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }

        StrictMode.initVmDefaults(null);

        if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
            int uptimeMillis = (int) SystemClock.elapsedRealtime();
            MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
            final int MAX_UPTIME_MILLIS = 60 * 1000;
            if (uptimeMillis > MAX_UPTIME_MILLIS) {
                Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                        "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
            }
        }

        // Loop forever.
        Looper.loop();//启动Looper循环
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

1.2.1 performPendingShutdown

  这个地方不是很明白为啥要检测sys.shutdown.requested值是否为空,然后为空后需要重启终端。这个各位如果了解,也可以沟通沟通!

    private void performPendingShutdown() {
        final String shutdownAction = SystemProperties.get(
                ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
        //如果sys.shutdown.requested的值不为空则会重启终端
        if (shutdownAction != null && shutdownAction.length() > 0) {
            boolean reboot = (shutdownAction.charAt(0) == '1');

            final String reason;
            if (shutdownAction.length() > 1) {
                reason = shutdownAction.substring(1, shutdownAction.length());
            } else {
                reason = null;
            }

            // If it's a pending reboot into recovery to apply an update,
            // always make sure uncrypt gets executed properly when needed.
            // If '/cache/recovery/block.map' hasn't been created, stop the
            // reboot which will fail for sure, and get a chance to capture a
            // bugreport when that's still feasible. (Bug: 26444951)
            if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {
                File packageFile = new File(UNCRYPT_PACKAGE_FILE);
                if (packageFile.exists()) {
                    String filename = null;
                    try {
                        filename = FileUtils.readTextFile(packageFile, 0, null);
                    } catch (IOException e) {
                        Slog.e(TAG, "Error reading uncrypt package file", e);
                    }

                    if (filename != null && filename.startsWith("/data")) {
                        if (!new File(BLOCK_MAP_FILE).exists()) {
                            Slog.e(TAG, "Can't find block map file, uncrypt failed or " +
                                       "unexpected runtime restart?");
                            return;
                        }
                    }
                }
            }
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    synchronized (this) {
                        ShutdownThread.rebootOrShutdown(null, reboot, reason);
                    }
                }
            };

            // ShutdownThread must run on a looper capable of displaying the UI.
            //这个很常见不多说了
            Message msg = Message.obtain(UiThread.getHandler(), runnable);
            msg.setAsynchronous(true);
            UiThread.getHandler().sendMessage(msg);

        }
    }

1.3 createSystemContext初始化系统上下文

  这个知识点比较重要,我们分析分析该方法,其代码逻辑如下:

  • 创建system_server进程的上下文环境
  • 设置主题样式
    private void createSystemContext() {
    	//创建system_server进程上下文环境
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

		//设置主题
        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }

1.3.1 ActivityThread.systemMain

  该类定义在frameworks/base/core/java/android/app/ActivityThread.java中,这个类大伙因该比较熟悉或者耳闻过其大名。



    ActivityThread() {
        mResourcesManager = ResourcesManager.getInstance();//单例模式
    }
    public static ActivityThread systemMain() {
        // The system process on low-memory devices do not get to use hardware
        // accelerated drawing, since this can add too much overhead to the
        // process.
        if (!ActivityManager.isHighEndGfx()) {//判断是否是低内存设备,如果是低内存设备禁用硬件加速
            ThreadedRenderer.disable(true);
        } else {
            ThreadedRenderer.enableForegroundTrimming();
        }
        ActivityThread thread = new ActivityThread();
        thread.attach(true, 0);//这个在android app的启动过程中也会看到,也是这里需要重点分析的,注意这里传入的参数
        return thread;
    }

1.3.2 ActivityThread.attach

  让我们接着继续分析attach函数,揭开其面纱看看其到底干了些啥!

    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {//这是Android app启动的分支,暂时不管
        	......
        }
        else {//分析Android app启动的时候,我还在想谁会走这条分支呢,原来是system_server进程启动会走
            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());//设置system_server进程在DDMS中的名称为system_process,system_server和system_process都是同一个进程只是套了不同的马甲,各位不要被蒙骗了
            try {
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
                // 先通过getSystemContext()创建系统上下文,然后通过createAppContext创建应用上下文
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                //创建Application
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                // 调用Application的onCreate()   
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }

        // add dropbox logging to libcore
        DropBox.setReporter(new DropBoxReporter());

        ViewRootImpl.ConfigChangedCallback configChangedCallback
                = (Configuration globalConfig) -> {
            synchronized (mResourcesManager) {
                // We need to apply this change to the resources immediately, because upon returning
                // the view hierarchy will be informed about it.
                if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
                        null /* compat */)) {
                    updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
                            mResourcesManager.getConfiguration().getLocales());

                    // This actually changed the resources! Tell everyone about it.
                    if (mPendingConfiguration == null
                            || mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
                        mPendingConfiguration = globalConfig;
                        sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
                    }
                }
            }
        };
		//设置ViewrOotImpl回调,譬如语言,横竖变化时回调
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

  通过上述的代码分析,我们可以归纳此时的attach主要干了如下几个事情:

  • 创建系统上下文:getSystemContext() -> createSystemContext() -> new ContextImpl()
  • 创建应用上下文:ContextImpl.createAppContext() -> new ContextImpl()
  • 添加回调configChangedCallback到ViewRootImpl

1.3.3 ActivityThread.getSystemContext

  让我们继续跟进getSystemContext,该函数比较简单直接调用ContextImpl.createSystemContext创建系统上下文。

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

1.3.4 ContextImpl.createSystemContext

  该方法定义在frameworks/base/core/java/android/app/ContextImpl.java中,代码如下:

    static ContextImpl createSystemContext(ActivityThread mainThread) {
    	// 这边new出来的LoadedApk将作为创建应用上下文的参数packageInfo
        LoadedApk packageInfo = new LoadedApk(mainThread);
        //通过ContextImpl创建系统上下文
        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;
    }

1.3.5 ContextImpl.createAppContext()创建应用上下文

    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        //通过ContextImpl创建应用上下文
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                null);
        context.setResources(packageInfo.getResources());
        return context;
    }

  不用怀疑你的眼睛,这里的new ContextImpl的参数创建系统上下文和应用上下文是一样的,这是不是多此一举呢?createAppContext()中的参数packageInfo,就是createSystemContext()中new的LoadedApk。创建完成之后,系统上下文赋值给了ActivityThread的成员变量mSystemContext,而应用上下文只是作为函数中的局部变量临时使用。这是我的理解,不知道谷歌的工程师是不是这么认为的,或者童靴们你们有另外的理解!

1.3.6 LoadedApk.makeApplication

  让我们回头看下ActivityThread.attach中创建上下文的内容:

            try {
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                //创建Application
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }

  接下来让我们继续分析makeApplication,该方法定义在frameworks/base/core/java/android/app/LoadedApk.java中,源码如下:

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

        Application app = null;

        String appClass = mApplicationInfo.className;
        //这里传入的参数forceDefaultAppClass为true 
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            // 此LoadedApk对象是createSystemContext时new的,mPackageName="android",大伙可以回看下
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            //有创建了一个局部应用上下文
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            //创建application
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        // 将前面创建的app添加到应用列表
        mActivityThread.mAllApplications.add(app);
        mApplication = app;
        ......
        return app;
}  

1.3.6 createSystemContext总结

  createSystemContext这一章节涉及的知识面比较多,且比较重要,我们分析总结一番。在这一章节里面我们主要是创建了一个ActivityThread对象,这个对象大伙应该都不会感到陌生,然后然后执行了该对象的attach()方法,attach()方法中创建了系统上下文mSystemContext(类型为ContextImpl),并创建Application对象。系统上下文中,new了一个LoadedApk的成员变量,并将ActivityThread对象传给LoadedApk成员,后面的Application对象就是LoadedApk使用ActivityThread创建的,LoadedApk创建了Application对象后,将Application添加到ActivityThread的应用列表中。关于这个章节的内容这里限于主题和篇幅就不过多解释了,如果想更加详细的了解可以参见gityuan的博客理解Application创建过程。


1.4 初始化SystemServiceManager系统服务管理类

  让我们收回思路,回到SystemServer中的run方法中看看创建系统服务管理类的代码。

	    // Create the system service manager.
	    //通过前面章节创建的系统上下文创建mSystemServiceManager 
	    mSystemServiceManager = new SystemServiceManager(mSystemContext);
	    //设置mSystemServiceManager 的启动相关信息
	    mSystemServiceManager.setStartInfo(mRuntimeRestart,
	            mRuntimeStartElapsedTime, mRuntimeStartUptime);
	    //将创建的mSystemServiceManager 添加到LocalServices中
	    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

  这一流程比较简单,主要逻辑有如下几点:

  • 以前面章节创建的系统上下文mSystemContext初始化SystemServiceManager对象
  • 设置mSystemServiceManager 对象启动信息,主要是时间和是否是重启等
  • 将构建的mSystemServiceManager 其添加到本地服务列表中,本地服务列表是以类为key保存的一个列表,即列表中某种类型的对象最多只能有一个

1.4.1 SystemServiceManager简单分析

  该类定义在frameworks/base/services/core/java/com/android/server/SystemServiceManager.java中,主要代码逻辑如下:

public class SystemServiceManager {
	......
	//系统服务列表,可以看到必须系统服务必须继承SystemService
    private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();

	//当前处于开机过程的哪个阶段,这个定义在SystemService中不是SystemServer中,后续会讲解
    private int mCurrentPhase = -1;
    ......

	//启动系统服务第一种方式,通过类名
    public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
            Slog.i(TAG, "Starting " + className);
            throw new RuntimeException("Failed to create service " + className
                    + ": service class not found, usually indicates that the caller should "
                    + "have called PackageManager.hasSystemFeature() to check whether the "
                    + "feature is available on this device before trying to start the "
                    + "services that implement it", ex);
        }
        return startService(serviceClass);
    }
    
    //第二种启动系统服务方式,创建并启动系统服务,系统服务类必须继承SystemService
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (InvocationTargetException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service constructor threw an exception", ex);
            }

            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
    //前面两种启动系统服务的方式,最后都会调用这个方法
    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }

    // 通知系统服务到了开机的哪个阶段,会遍历调用所有系统服务的onBootPhase()函数
    public void startBootPhase(final int phase) {
        if (phase <= mCurrentPhase) {
            throw new IllegalArgumentException("Next phase must be larger than previous");
        }
        mCurrentPhase = phase;

        Slog.i(TAG, "Starting phase " + mCurrentPhase);
        try {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase);
            final int serviceLen = mServices.size();
            for (int i = 0; i < serviceLen; i++) {
                final SystemService service = mServices.get(i);
                long time = SystemClock.elapsedRealtime();
                Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName());
                try {
                    service.onBootPhase(mCurrentPhase);
                } catch (Exception ex) {
                    throw new RuntimeException("Failed to boot service "
                            + service.getClass().getName()
                            + ": onBootPhase threw an exception during phase "
                            + mCurrentPhase, ex);
                }
                warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase");
                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }
}

  我们这里说mCurrentPhase表示当前处于开机过程的那个阶段,有如下几个阶段,定义在frameworks/base/services/core/java/com/android/server/SystemService.java中,如下所示:

public abstract class SystemService {
    /*
     * Boot Phases
     */
    public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?

    /**
     * After receiving this boot phase, services can obtain lock settings data.
     */
    public static final int PHASE_LOCK_SETTINGS_READY = 480;

    /**
     * After receiving this boot phase, services can safely call into core system services
     * such as the PowerManager or PackageManager.
     */
    public static final int PHASE_SYSTEM_SERVICES_READY = 500;

    /**
     * After receiving this boot phase, services can safely call into device specific services.
     */
    public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;

    /**
     * After receiving this boot phase, services can broadcast Intents.
     */
    public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

    /**
     * After receiving this boot phase, services can start/bind to third party apps.
     * Apps will be able to make Binder calls into services at this point.
     */
    public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;

    /**
     * After receiving this boot phase, services can allow user interaction with the device.
     * This phase occurs when boot has completed and the home application has started.
     * System services may prefer to listen to this phase rather than registering a
     * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.
     */
    public static final int PHASE_BOOT_COMPLETED = 1000;
	......
}

1.4.2 LocalServices

  该类定义在frameworks/base/core/java/com/android/server/LocalServices.java中,逻辑so easy就是将SystemService 存放在hash表中,供后续使用。

public final class LocalServices {
    private LocalServices() {}

    private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
            new ArrayMap<Class<?>, Object>();

    /**
     * Returns a local service instance that implements the specified interface.
     *
     * @param type The type of service.
     * @return The service object.
     */
    @SuppressWarnings("unchecked")
    public static <T> T getService(Class<T> type) {
        synchronized (sLocalServiceObjects) {
            return (T) sLocalServiceObjects.get(type);
        }
    }

    /**
     * Adds a service instance of the specified interface to the global registry of local services.
     */
    public static <T> void addService(Class<T> type, T service) {
        synchronized (sLocalServiceObjects) {
            if (sLocalServiceObjects.containsKey(type)) {
                throw new IllegalStateException("Overriding service registration");
            }
            sLocalServiceObjects.put(type, service);
        }
    }
}

1.5 startBootstrapServices启动引导服务

  能被称为引导的东西个人感觉都是牛逼的东西,譬如windows下的BIOS引导程序,当然这里的引导服务也不例外,基本都是Android界的实干家,牛逼的很。

	//代码量有点多,所以把默认注释和无关紧要的代码给删掉了
    private void startBootstrapServices() {

        ......
        //通过mSystemServiceManager启动Installer,并且是阻塞等待与installd建立socket通道
        Installer installer = mSystemServiceManager.startService(Installer.class);
        

		//这个服务暂时不清楚是干啥的
        mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
        

		//好吗,这个服务无需多言了,我是AMS重要你懂的
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
      
		//PowerManagerService服务,牵涉到电源管理等等方面
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
        

		//mPowerManagerService 已经准备就绪,AMS
        mActivityManagerService.initPowerManagement();
        

		//启动RecoverySystemService
        mSystemServiceManager.startService(RecoverySystemService.class);
        

		//不知是啥,那就只能忽略了
        RescueParty.noteBoot(mSystemContext);

       	//启动LightsService服务
        mSystemServiceManager.startService(LightsService.class);

		//这个服务不知是啥,暂时不管了
        if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) {
            mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS);
        }
        

		// 启动DisplayManagerService(必须咋PMS服务启动之前)
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

		//划重点,初始化package manager之前,需要默认显示。阻塞,10s超时,see DisplayManagerService.onBootPhase()
        mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
        traceEnd();

        //当设备正在加密时,仅运行核心
        String cryptState = SystemProperties.get("vold.decrypt");
        if (ENCRYPTING_STATE.equals(cryptState)) {
            Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
            mOnlyCore = true;
        } else if (ENCRYPTED_STATE.equals(cryptState)) {
            Slog.w(TAG, "Device encrypted - only parsing core apps");
            mOnlyCore = true;
        }

        // Start Carrier regionalization service
        //开启运营商区域化服务,先放着
        if (RegionalizationEnvironment.isSupported()) {
            Slog.i(TAG, "Regionalization Service");
            RegionalizationService regionalizationService = new RegionalizationService();
            ServiceManager.addService("regionalization", regionalizationService);
        }

		//启动PMS服务
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();

        if (!mOnlyCore) {
            boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                    false);
            if (!disableOtaDexopt) {
                traceBeginAndSlog("StartOtaDexOptService");
                try {
                    OtaDexoptService.main(mSystemContext, mPackageManagerService);
                } catch (Throwable e) {
                    reportWtf("starting OtaDexOptService", e);
                } finally {
                    traceEnd();
                }
            }
        }

        //启动多用户服务,新建目录/data/user/
        mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
        

        // 初始化用来缓存包资源的属性缓存,不要问我怎么知道的,按照注释翻译的
        AttributeCache.init(mSystemContext);
        

		//设置AMS
        mActivityManagerService.setSystemProcess();
       

   		//直接过
        mDisplayManagerService.setupSchedulerPolicies();

  		//直接过
        OverlayManagerService overlayManagerService = new OverlayManagerService(
                mSystemContext, installer);
        mSystemServiceManager.startService(overlayManagerService);
        

        if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {
            // DisplayManager needs the overlay immediately.
            overlayManagerService.updateSystemUiContext();
            LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();
        }

		//启动sensor服务
        mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
            TimingsTraceLog traceLog = new TimingsTraceLog(
                    SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
            traceLog.traceBegin(START_SENSOR_SERVICE);
            startSensorService();
            traceLog.traceEnd();
        }, START_SENSOR_SERVICE);
    }

  这里可以看到startBootstrapServices会首先等待installd启动完成,然后阻塞等待和建立连接。接着会启动一系列相关联的重要服务,其中比较常见的和经常会用到的如下表格所示:

引导服务 功能
Installer 注意和installd的关联,这个是在系统安装apk时的一个服务类, 启动完成installer服务之后才能启动其它的系统服务,是installd的客户端和installd是C-S端架构
ActivityManagerService 牛逼的AMS服务,负责四大组件的启动,切换,调度等相关工作
PowerManagerService 负责Android系统中和Power相关的计算,决策系统的电源策略
LightsService 管理和显示Android相关指示灯服务
DisplayManagerService 用来管理Android所有显示设备服务
PackageManagerService 牛逼的PKMS服务,主要用来管理apk的安装,解析,验签,删除,升级等功能
UserManagerService 多用户模式管理服务
SensorService Android各种感应器管理服务!

1.6 startCoreServices启动核心服务

  无需多言,主要是启动Android系统各种核心服务,核心是啥各位应该都懂!

    private void startCoreServices() {
		// 启动BatteryService,用于管理电池各种状态情况
        mSystemServiceManager.startService(BatteryService.class);
        

		//启动UsageStatsService服务,该服务主要用于统计应用使用情况
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));
        

        //启动WebViewUpdateService
        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
            mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
        }

        // Tracks cpu time spent in binder calls
        BinderCallsStatsService.start();
    }

  其中核心服务中常见的和其作用如下表格所示:

核心服务 功能
BatteryService 电源管理服务,管理电池的各种状态
UsageStatsService 主要用于统计应用的使用情况,如时长,使用频率等
WebViewUpdateService 用于管理webview的更新

1.7 startOtherServices启动其它服务

  好吗其它,你懂的!就好像各种排名,通常是以其它结束的。这里的代码比较多,没有什么难点,就是启动各种服务。

    private void startOtherServices() {
		......
		mSystemServiceManager.startService(KeyChainSystemService.class);
		//启动调度策略服务
		ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
		mSystemServiceManager.startService(TelecomLoaderService.class);
	
		telephonyRegistry = new TelephonyRegistry(context);// 提供电话注册、管理服务,可以获取电话的链接状态、信号强度等
        ServiceManager.addService("telephony.registry", telephonyRegistry);
        
		mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);//启动账号管理,密码,认证等相关的服务
		
		mSystemServiceManager.startService(CONTENT_SERVICE_CLASS);

		mActivityManagerService.installSystemProviders();//启动provider服务
		
		mSystemServiceManager.startService(DropBoxManagerService.class);
		
		vibrator = new VibratorService(context);
        ServiceManager.addService("vibrator", vibrator);
        
		mSystemServiceManager.startService(AlarmManagerService.class);//Alarm服务

		watchdog.init(context, mActivityManagerService);//启动看门狗服务
		
		inputManager = new InputManagerService(context);//启动input输入管理服务
		wm = WindowManagerService.main(context, inputManager,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                    !mFirstBoot, mOnlyCore, new PhoneWindowManager());//WMS服务,这个也很重要
        ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
                DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
        ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
        mActivityManagerService.setWindowManager(wm);
        
		startHidlServices();//启动HIDL服务

		mSystemServiceManager.startService(VrManagerService.class);//启动vr服务

		inputManager.setWindowManagerCallbacks(wm.getInputMonitor());//启动inputManager
        inputManager.start();

		mDisplayManagerService.windowManagerAndInputReady();

		//SystemServer启动的480阶段
		mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
		
		//SystemServer启动的500阶段
		mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);

		//SystemServer启动的520阶段
		mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);

		mActivityManagerService.systemReady(() -> {
			
			mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY);

	       try {
	                startSystemUi(context, windowManagerF);
	            } catch (Throwable e) {
	                reportWtf("starting System UI", e);
	            }
			}

            mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
}

  在这一阶段启动的服务太多了,就不一一列举出来,在该阶段的最后调用AMS.systemReady()启动默认Lancher进而完成了整个的开机流程。到此, System_server主线程的启动工作总算完成, 进入Looper.loop()状态,等待其他线程通过handler发送消息到主线再处理.。最后附上该阶段启动的相关服务常见列表!

其它服务 功能
CameraServiceProxy 顾名思义摄像相关服务
AlarmManagerService 定时器管理服务
InputManagerservice 输入事件管理服务
WindowManagerService WMS窗口管理服务
VrManagerService VR管理服务
BluetoothService 蓝牙管理服务
NotificationManagerService 通知栏管理服务
DeviceStorageMonitorService 存储管理相关服务
LocationManagerService 定位管理服务
AudioService 音频相关管理服务
LockSettingsService 屏幕锁定服务,管理每个用户的相关锁屏信息
DeviceIdleController Doze模式的主要驱动,参考“深入Android ‘M’ Doze”
DevicePolicyManagerService 提供一些系统级别的设置及属性
StatusBarManagerService 状态栏管理服务
ClipboardService 系统剪切板服务
NetworkManagementService 网络管理服务
TextServicesManagerService 文本服务,例如文本检查等
NetworkScoreService 网络评分服务
NetworkStatsService 网络状态服务
NetworkPolicyManagerService 网络策略服务
WifiP2pService Wifi Direct服务
WifiService Wifi服务
WifiScanningService Wifi扫描服务
RttService Wifi相关
EthernetService 以太网服务
ConnectivityService 网络连接管理服务
NsdService 网络发现服务
NotificationManagerService 通知栏管理服务
DeviceStorageMonitorService 磁盘空间状态检测服务
LocationManagerService 位置服务,GPS、定位等
CountryDetectorService 检测用户国家
SearchManagerService 搜索管理服务
DropBoxManagerService 用于系统运行时日志的存储于管理
WallpaperManagerService 壁纸管理服务
AudioService AudioFlinger的上层管理封装,主要是音量、音效、声道及铃声等的管理
DockObserver 如果系统有个座子,当手机装上或拔出这个座子的话,就得靠他来管理了
WiredAccessoryManager 监视手机和底座上的耳机
UsbService USB服务
SerialService 串口服务
TwilightService 指出用户当前所在位置是否为晚上,被UiModeManager等用来调整夜间模式。
BackupManagerService 备份服务
AppWidgetService 提供Widget的管理和相关服务
VoiceInteractionManagerService 语音交互管理服务
DiskStatsService 磁盘统计服务,供dumpsys使用
SamplingProfilerService 用于耗时统计等
NetworkTimeUpdateService 监视网络时间,当网络时间变化时更新本地时间。
CommonTimeManagementService 管理本地常见的时间服务的配置,在网络配置变化时重新配置本地服务。
CertBlacklister 提供一种机制更新SSL certificate blacklist
DreamManagerService 屏幕保护
AssetAtlasService 负责将预加载的bitmap组装成纹理贴图,生成的纹理贴图可以被用来跨进程使用,以减少内存。
PrintManagerService 打印服务
HdmiControlService HDMI控制服务
FingerprintService 指纹服务


二. SystemServer服务启动阶段概括

  通过前面的章节我们发现在SystemServer启动服务的三个阶段过程中,SystemServiceManager的startBootPhase()贯穿system_server进程以及服务的整个启动过程,基本示意图如下所示:

Android 9 (P)系统启动之SystemServer大揭秘下_第3张图片

  其中最后的PHASE_BOOT_COMPLETED=1000,该阶段是发生在Boot完成和home应用启动完毕,从而完成了真正意义上的Android终端开机启动流程。系统服务更倾向于监听该阶段,而不是注册广播ACTION_BOOT_COMPLETED,从而降低系统延迟。

  其中各个启动阶段在system_server进程启动中的源码位置如下所示:

public final class SystemServer {

    private void startBootstrapServices() {
      ...
      //phase100
      mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
      ...
    }

	//重点注意,在该阶段是没有设置启动阶段标志的相关设置
    private void startCoreServices() {
      ...
    }

    private void startOtherServices() {
      ...
      //phase480 && 500
      mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
      mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
      
      //520
      mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
      ...
	mActivityManagerService.systemReady(() -> {
		......
		//550
		mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);
		
		//600
        mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
		......
	}, BOOT_TIMINGS_TRACE_LOG);
}


public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        ......
        final void finishBooting() {
        	......
        // Let system services know.10000
        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
        	......
        }
        ......
}

  如上就是Systemserver启动服务的各个阶段相关标志的设置,那么下面我们简单分析分析各个阶段主要完成的相关工作。


2.1 PHASE_START(0)

  在源码中是没有这个阶阶段的,这个是我们让更好的理解,本人强行加上去的,可以理解为system_server进程启动之后并启动SystemSever的开始阶段,在这一阶段主要创建了如下几个引导服务:

  • installer服务,主要是提供给其它服务使用
  • ActivityManagerService
  • PowerManagerService
  • RecoverySystemService
  • DisplayManagerService

2.2 PHASE_WAIT_FOR_DEFAULT_DISPLAY(100)

  进入该阶段后,将会回调2.1阶段创建的相关服务的onBootPhase(100)方法,然后继续创建下列相关的服务:

  • PackageManagerService
  • UserManagerService
  • OverlayManagerService
  • BatteryService
  • UsageStatsService
  • InputManagerService
  • WindowManagerService
  • NetworkWatchlistService

2.3 PHASE_LOCK_SETTINGS_READY(480)

  进入该阶段后会回调前面阶段创建服务的onBootPhase(480)方法,该阶段非常短调用完上述方法后会直接进入PHASE_SYSTEM_SERVICES_READY(500)阶段。


2.4 PHASE_SYSTEM_SERVICES_READY(500)

  进入该阶段后会回调前面阶段创建服务的onBootPhase(500)方法,并依次执行如下服务的systemReady方法:

  • WindowManagerService.systemReady():
  • PowerManagerService.systemReady():
  • PackageManagerService.systemReady():
  • DisplayManagerService.systemReady():

接下来就绪AMS.systemReady方法,这个方法非常重要!


2.5 PHASE_ACTIVITY_MANAGER_READY(550)

  该阶段中将设置AMS的mSystemReady为true表明AMS已准备就绪,进入该阶段服务能广播Intent;但是system_server主线程并没有就绪,然后继续会调用前面创建服务的onBootPhase(550)方法!接下来执行: (AMS启动native crash监控, 加载WebView,启动SystemUi等),如下:

  • mActivityManagerService.startObservingNativeCrashes()

  • mWebViewUpdateService.prepareWebViewInSystemServer

  • startSystemUi(context)

  • networkManagementF.systemReady

  • pSecServiceF.systemReady

  • networkStatsF.systemRead

  • connectivityF.systemReady

  • networkPolicyF.systemReady

  • Watchdog.getInstance().start()


2.6 PHASE_THIRD_PARTY_APPS_CAN_START(600)

  该阶段依次会调用前面阶段创建服务的onBootPhase(600),接着调用如下服务的systemRunning方法:

  • locationF.systemRunning
  • countryDetectorF.systemRunning
  • networkTimeUpdaterF.systemRunning
  • commonTimeMgmtServiceF.systemRunning
  • inputManagerF.systemRunning
  • telephonyRegistryF.systemRunning
  • mediaRouterF.systemRunning
  • mmsServiceF.systemRunning
  • incident.systemRunning

2.7 PHASE_BOOT_COMPLETED(1000)

  在经过如上一系列流程,最终调用AMS.finishBooting()时,则进入阶段PHASE_BOOT_COMPLETED(1000)。
到此,系统服务启动阶段完成就绪,system_server进程启动完成则进入Looper.loop()状态,随时待命,等待消息队列MessageQueue中的消息到来,则马上进入执行状态。



结语

  经过层层的拨山涉水,我们终于system_server进程的启动以及其启动过程中的丰功伟绩介绍完成了,到这里大伙应该明白了为啥system_server进程可以做到和zygote进程生死与共了,这个哥们是有实力的人不是靠吹牛皮来的。



写在最后

  system_server进程启动篇章终于告一段落了,在后续篇章中我们将要讲述zygote进程怎么否孵化普通App进程的,这个也是后续篇章的重点。好了,如果今天的文章对大伙有帮助,希望能点个赞,求个关注!各位江湖见!

你可能感兴趣的:(Android,P开机启动流程分析)