Android10 启动之SystemServer源码分析

目录
  • 正文
  • createSystemContext
  • startBootstrapServices
  • startCoreServices
  • startOtherServices

正文

上一篇文章: # Android 10 启动分析之Zygote篇 (三)

紧接着上一篇文章的内容,我们从这篇文章开始来分析一下 SystemServer。

system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等80多个核心系统服务。这些服务以不同的线程方式存在于system_server这个进程中。

SystemServer的源码路径为 /frameworks/base/services/java/com/android/server/SystemServer.java,我们从这个类的main方法开始看起:

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

main方法里创建了一个SystemServer实例,并调用了run方法。SystemServer的构造方法里只是一些简单的变量初始化,我们直接从run方法继续阅读。

 private void run() {
        try {
           ...
            //准备主线程lopper
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            Looper.prepareMainLooper();
            Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
            // 加载libandroid_servers.so库
            System.loadLibrary("android_servers");
           //检测上次关机过程是否失败,这个调用可能不会返回
            performPendingShutdown();
             //初始化系统上下文
            createSystemContext();
           //创建系统服务管理者--SystemServiceManager
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setStartInfo(mRuntimeRestart,
                    mRuntimeStartElapsedTime, mRuntimeStartUptime);
             //将mSystemServiceManager添加到本地服务中,至于什么是LocalServices,它有什么作用,
             //以后再单独开一篇文章来讲解
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            //为可以并行化的init任务准备线程池
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }
        // 在这里开始启动一系列服务了
        try {
            traceBeginAndSlog("StartServices");
            // 启动引导服务
            startBootstrapServices();
            // 启动核心服务
            startCoreServices();
            // 启动其他服务
            startOtherServices();
            //停止init线程池
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
        ...
        // 死循环执行
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

我们来关注以下几个重点方法:

createSystemContext

private void createSystemContext() {
    //创建system_server进程的上下文信息
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    //设置主题
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    //获取systemui上下文信息,并设置主题
    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

在调用ActivityThread.systemMain方法时,这个过程会创建对象有ActivityThread,Instrumentation, ContextImpl,LoadedApk,Application。

为什么会要创建Application对象?就目前的源码来看,Application对象在systemserver进程并无实际作用,笔者只能猜测这是为将来的扩展做准备或者android版本迭代中的历史遗留代码。

startBootstrapServices

在这个方法中会启动系统的关键服务,这些服务是系统运行的基石。因为它们之间具有复杂的依赖关系,所以谷歌把它们放在一起初始化。

 private void startBootstrapServices() {
        // 尽早启动看门狗,这样我们在早期启动陷入死锁时就可以使system server崩溃重启。
        final Watchdog watchdog = Watchdog.getInstance();
        watchdog.start();
        //启动Installer Service,这个Service 通过binder与installd进程通讯,负责apk安装相关的工作
        Installer installer = mSystemServiceManager.startService(Installer.class);
        //设备标识符策略服务
        mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
        // 管理uri授权
        mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
        //启动ActivityTaskManagerService和ActivityManagerService
        ActivityTaskManagerService atm = mSystemServiceManager.startService(
                ActivityTaskManagerService.Lifecycle.class).getService();
        mActivityManagerService = ActivityManagerService.Lifecycle.startService(
                mSystemServiceManager, atm);
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        mWindowManagerGlobalLock = atm.getGlobalLock();
        //电源管理器需要尽早启动,因为其他服务需要它。
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
        //启动热缓解服务,目的是在手机开始过热时进行有效的热缓解
        mSystemServiceManager.startService(ThermalManagerService.class);
        // Now that the power manager has been started, let the activity manager
        // initialize power management features.
        mActivityManagerService.initPowerManagement();
        //启动系统恢复服务,负责协调设备上与恢复有关的功能。
        mSystemServiceManager.startService(RecoverySystemService.class);
        //到这里为止,系统启动的必须服务已经加载完毕
        RescueParty.noteBoot(mSystemContext);
        //管理LED和屏幕背光,我们需要它来显示
        mSystemServiceManager.startService(LightsService.class);
        //管理显示设备
        //在package manager 启动之前,需要启动display manager 提供display metrics
        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
     //只有DisplayManagerService会对PHASE_WAIT_FOR_DEFAULT_DISPLAY做处理
     //目的是在初始化包管理器之前,首先需要获取一个默认的显示设备
     mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
        // 启动 package manager.
        if (!mRuntimeRestart) {
            MetricsLogger.histogram(null, "boot_package_manager_init_start",
                    (int) SystemClock.elapsedRealtime());
        }
        try {
            Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        } finally {
            Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
        }
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
        //启动UserManager Service
        mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
       //为系统进程设置应用程序实例并启动
        mActivityManagerService.setSystemProcess();
        //使用ActivityManager实例完成看门狗设置并监听是否重启
        watchdog.init(mSystemContext, mActivityManagerService);
        // DisplayManagerService needs to setup android.display scheduling related policies
        // since setSystemProcess() would have overridden policies due to setProcessGroup
        mDisplayManagerService.setupSchedulerPolicies();
        //负责动态资源overlay
        mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
        mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext));
        if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {
            // DisplayManager needs the overlay immediately.
            mActivityManagerService.updateSystemUiContext();
            LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();
        }
          //传感器服务需要访问包管理器服务、app ops服务和权限服务,
         //因此我们在它们之后启动它。
         //在单独的线程中启动传感器服务。在使用它之前应该检查完成情况。
        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);
    }

总结一下,引导服务有以下15个:

服务名称 描述
Installer 负责apk安装相关的工作
DeviceIdentifiersPolicyService 设备标识符策略服务
UriGrantsManagerService Uri授权管理
ActivityTaskManagerService 用于管理Activity及其容器(task, stacks, displays,... )的系统服务
ActivityManagerService 管理Activity的启动,调度等工作
PowerManagerService 负责协调设备上的电源管理功能
ThermalManagerService 热缓解服务
RecoverySystemService 负责协调设备上与恢复有关的功能
LightsService 管理LED和屏幕背光
DisplayManagerService 管理显示设备
PackageManagerService 主要负责APK、jar包的管理
UserManagerService 管理用户的系统服务
OverlayManagerService 负责动态资源overlay工作,具体请搜索android RRO技术
SensorPrivacyService 和传感器有关,具体作用不明
SensorPrivacySere 传感器服务

startCoreServices

 private void startCoreServices() {
        // 追踪电池充电状态和电量。需要LightService
        mSystemServiceManager.startService(BatteryService.class);
         //跟踪应用程序使用状态
        mSystemServiceManager.startService(UsageStatsService.class);
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));
        // 跟踪可更新的WebView是否处于就绪状态,并监视更新安装。
        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
            traceBeginAndSlog("StartWebViewUpdateService");
            mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
            traceEnd();
        }
       //跟踪并缓存设备状态。
        mSystemServiceManager.startService(CachedDeviceStateService.class);
        // 跟踪在Binder调用中花费的cpu时间
        mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);
        // 跟踪handlers中处理messages所花费的时间。
        mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);
        //管理apk回滚
        mSystemServiceManager.startService(RollbackManagerService.class);
        // 用于捕获bugreport,adb bugreport 命令调用的就是这个服务
        mSystemServiceManager.startService(BugreportManagerService.class);
        // 管理Gpu和Gpu驱动的服务
        mSystemServiceManager.startService(GpuService.class);
    }

总结一下,核心服务共计9个:

服务名称 描述
BatteryService 追踪电池充电状态和电量
UsageStatsManagerInternal 跟踪应用程序使用状态
WebViewUpdateService 跟踪可更新的WebView是否处于就绪状态,并监视更新安装。
CachedDeviceStateService 跟踪并缓存设备状态
BinderCallsStatsService 跟踪在Binder调用中花费的cpu时间
LooperStatsService 跟踪handlers中处理messages所花费的时间。
RollbackManagerService 管理apk回滚
BugreportManagerService 用于捕获bugreport
GpuService 管理Gpu和Gpu驱动

startOtherServices

这个方法负责启动剩下的服务,共计有70多个,限于篇幅的原因,在此不再一一列举,贴一张从网上找到的图片大家简单的了解一下就行了:

需要注意的是在startOtherServices结尾处调用了AMS的systemReady方法,AMS的systemReady里有这样一条语句:

 mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");

这条语句会启动如下的Intent:

Intent getHomeIntent() {
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;
    }

注意到Intent.CATEGORY_HOME没,这意味着startHomeOnAllDisplays最终启动的是android的launcher app,android的启动已经进入了结尾。

至此,我们从按下电源键开始,到最终呈现launcher页面,整个启动流程做了一个简单的介绍。Android 10的启动分析系列正篇到此结束,其中启动过程中的一些细节知识点,我们今后再以番外的形式补充介绍,感谢大家的收看!!!

更多关于Android10 启动SystemServer的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android10 App 启动分析进程创建源码解析

    目录 正文 RootActivityContainer ActivityStartController 调用startActivityUnchecked方法 ActivityStackSupervisor 启动进程 RuntimeInit.applicationInit这个方法 正文 从前文# Android 10 启动分析之SystemServer篇 (四)中可以得知,系统在完成所有的初始化工作后,会通过 mAtmInternal.startHomeOnAllDisplays(currentU

  • Android 10 启动Init进程解析

    目录 按下电源键时,android做了啥? init进程解析 FirstStageMain SetupSelinux SecondStageMain init.rc 解析 按下电源键时,android做了啥? 当我们按下电源键时,手机开始上电,并从地址0x00000000处开始执行,而这个地址通常是Bootloader程序的首地址. bootloader是一段裸机程序,是直接与硬件打交道的,其最终目的是“初始化并检测硬件设备,准备好软件环境,最后调用操作系统内核”.除此之外,bootloader

  • Android10 客户端事务管理ClientLifecycleManager源码解析

    目录 正文 ClientLifecycleManager ClientTransaction TransactionExecutor executeLifecycleState 正文 在Android 10 App启动分析之Activity启动篇(二)一文中,简单地介绍了Activity的生命周期管理器是如何调度Activity进入onCreate生命周期的流程.这篇文章,我们将详细地分析framework中activity的生命周期管理功能,从更宏观的角度来更全面地了解生命周期及相关事务的工作

  • Android10 App启动Activity源码分析

    目录 正文 ActivityThread的main方法 Application Context对象 LaunchActivityItem ClientLifecycleManager ClientTransaction TransactionExecutor executeLifecycleState方法 正文 上一篇: Android 10 App启动分析之进程创建篇(一) 上一篇文章,我们探讨了App启动过程中进程创建及初始化的流程,这篇文章我们接着上篇的内容,继续探讨App的Applica

  • Android10 启动Zygote源码解析

    目录 app_main ZygoteInit preload preloadClasses preloadResources preloadSharedLibraries forkSystemServer app_main 上一篇文章: # Android 10 启动分析之servicemanager篇 (二) 在init篇中有提到,init进程会在在Trigger 为late-init的Action中,启动Zygote服务,这篇文章我们就来具体分析一下Zygote服务,去挖掘一下Zygote负

  • Android 10 启动之servicemanager源码解析

    目录 正文 获取服务 注册服务 正文 上一篇文章: Android 10 启动分析之Init篇 (一) 在前文提到,init进程会在在Trigger 为init的Action中,启动servicemanager服务,这篇文章我们就来具体分析一下servicemanager服务,它到底做了哪些事情. servicemanager服务的源码位于/frameworks/native/cmds/servicemanager/service_manager.c,我们将从这个类的入口开始看起. int ma

  • Android10 启动之SystemServer源码分析

    目录 正文 createSystemContext startBootstrapServices startCoreServices startOtherServices 正文 上一篇文章: # Android 10 启动分析之Zygote篇 (三) 紧接着上一篇文章的内容,我们从这篇文章开始来分析一下 SystemServer. system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService.PowerManagerService

  • Hadoop源码分析六启动文件namenode原理详解

    1. namenode启动 在本系列文章三中分析了hadoop的启动文件,其中提到了namenode启动的时候调用的类为 org.apache.hadoop.hdfs.server.namenode.NameNode 其main方法的内容如下: public static void main(String argv[]) throws Exception { if (DFSUtil.parseHelpArgument(argv, NameNode.USAGE, System.out, true)

  • Hadoop源码分析三启动及脚本剖析

    1. 启动 hadoop的启动是通过其sbin目录下的脚本来启动的.与启动相关的叫脚本有以下几个: start-all.sh.start-dfs.sh.start-yarn.sh.hadoop-daemon.sh.yarn-daemon.sh. hadoop-daemon.sh是用来启动与hdfs相关的服务的 yarn-daemon.sh是用来启动和yarn相关的服务 start-dfs.sh是用来启动hdfs集群的 start-yarn.sh是用来启动yarn集群 start-all.sh是用

  • Netty启动流程服务端channel初始化源码分析

    目录 服务端channel初始化 回顾上一小节initAndRegister()方法 init(Channel)方法 前文传送门 Netty分布式server启动流程 服务端channel初始化 回顾上一小节initAndRegister()方法 final ChannelFuture initAndRegister() { Channel channel = null; try { //创建channel channel = channelFactory.newChannel(); //初始化

  • Netty分布式server启动流程Nio创建源码分析

    目录 NioServerSocketChannel创建 继承关系 绑定端口 端口封装成socket地址对象 跟进initAndRegister()方法 创建channel 父类的构造方法 将jdk的channel设置为非阻塞模式 前文传送门 Netty分布式Server启动流程服务端初始化源码分析 NioServerSocketChannel创建 我们如果熟悉Nio, 则对channel的概念则不会陌生, channel在相当于一个通道, 用于数据的传输 Netty将jdk的channel进行了

  • Netty分布式Server启动流程服务端初始化源码分析

    目录 第一节:服务端初始化 group方法 初始化成员变量 初始化客户端Handler 第一节:服务端初始化 首先看下在我们用户代码中netty的使用最简单的一个demo: //创建boss和worker线程(1) EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); //创建ServerBootstrap(2) ServerBootst

  • Netty源码分析NioEventLoop线程的启动

    目录 之前的小节我们学习了NioEventLoop的创建以及线程分配器的初始化, 那么NioEventLoop是如何开启的呢, 我们这一小节继续学习 NioEventLoop的开启方法在其父类SingleThreadEventExecutor中的execute(Runnable task)方法中, 我们跟到这个方法: @Override public void execute(Runnable task) { if (task == null) { throw new NullPointerEx

  • 详解SpringBoot启动代码和自动装配源码分析

    目录 一.SpringBoot启动代码主线分析 二.SpringBoot自动装配原理分析 1.自动装配的前置知识@Import 2.@SpringApplication注解分析 2.1@SpringBootConfiguration 2.2@EnableAutoConfiguration ​随着互联网的快速发展,各种组件层出不穷,需要框架集成的组件越来越多.每一种组件与Spring容器整合需要实现相关代码.SpringMVC框架配置由于太过于繁琐和依赖XML文件:为了方便快速集成第三方组件和减少

  • Netty启动步骤绑定端口示例方法源码分析

    目录 绑定端口 我们继续跟第一小节的最初的doBind()方法 第二步, 获得channel 重点关注下doBind(localAddress)方法 最终会走到这一步, pipeline.fireChannelActive() 章节总结 前文传送门:Netty启动流程注册多路复用源码解析 绑定端口 上一小节我们学习了channel注册在selector的步骤, 仅仅做了注册但并没有监听事件, 事件是如何监听的呢? 我们继续跟第一小节的最初的doBind()方法 private ChannelFu

随机推荐