[Android][Framework] Android O SystemServer启动流程

SystemServer.main

SystemServer通过ZygoteInit.java反射启动,首先会进入main方法,main会构造一个新的SystemServer,然后运行run()方法

/frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
    /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }
}

SystemServer.run

private void run() {
    try {
        traceBeginAndSlog("InitBeforeStartServices");
        // 如果一个设备时间在1970年之前,很多API会crash,所以会将时间统一设置为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.
        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);

        // Here we go! 正式进入system server
        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
      	// 变更虚拟机的库文件
        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!
      	// 因为启动过程需要较多的虚拟机内存空间,清除vm内存增长上限
        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
        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);

        // Ensure binder calls into the system always run at foreground priority.
      	// 确保进入系统的binder调用运行高优先级
        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.prepareMainLooper();

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

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

        // Initialize the system context.
        createSystemContext();

        // Create the system service manager.
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
      	// 添加mSystemServiceManager到本地服务成员sLocalServiceObjects 见LocalServices.java
        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(); // 启动引导服务
        startCoreServices(); // 启动核心服务
        startOtherServices(); // 启动其他服务
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        traceEnd();
    }

    // For debug builds, log event loop stalls to dropbox for analysis.
    if (StrictMode.conditionallyEnableDebugLogging()) {
        Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    }
    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();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

下面看一下run函数用到的本地私有方法

SystemServer.performPendingShutdown

private void performPendingShutdown() {
  	// 通过检查ShutdownThread.SHUTDOWN_ACTION_PROPERTY来判断上次关机是否失败
    final String shutdownAction = SystemProperties.get(
            ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
    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;
                    }
                }
            }
        }
        ShutdownThread.rebootOrShutdown(null, reboot, reason);
    }
}

SystemServer.createSystemContext

private void createSystemContext() {
  	// 创建系统上下文并设置主题
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

SystemServer.startBootstrapServices

/**
 * Starts the small tangle of critical services that are needed to get
 * the system off the ground.  These services have complex mutual dependencies
 * which is why we initialize them all in one place here.  Unless your service
 * is also entwined in these dependencies, it should be initialized in one of
 * the other functions.
 * 这里的服务都是有复杂的依赖性,所以放在这里统一初始化。如果有与这些服务不相关的服务需要启动,应该放在其他地方去做
 */
private void startBootstrapServices() {
    Slog.i(TAG, "Reading configuration...");
    final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
    traceBeginAndSlog(TAG_SYSTEM_CONFIG);
    SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
    traceEnd();

    // 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.
    traceBeginAndSlog("StartInstaller");
  	// 等待installd启动,使其有时间建立正确权限的目录。之后才可以初始化其他服务
    Installer installer = mSystemServiceManager.startService(Installer.class);
    traceEnd();

    // In some cases after launching an app we need to access device identifiers,
    // therefore register the device identifier policy before the activity manager.
    traceBeginAndSlog("DeviceIdentifiersPolicyService");
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
    traceEnd();

    // Activity manager runs the show.
    traceBeginAndSlog("StartActivityManager");
  	// 启动ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    traceEnd();

    // 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,因为其他服务需要使用它,所以需要早期创建
    traceBeginAndSlog("StartPowerManager");
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
    traceEnd();

    // Now that the power manager has been started, let the activity manager
    // initialize power management features.
    traceBeginAndSlog("InitPowerManagement");
    mActivityManagerService.initPowerManagement();
    traceEnd();

    // Bring up recovery system in case a rescue party needs a reboot
  	// 如果一个rescure party需要重启,则启动recovery
  	// rescure party是Android O的新特性,代码位于/services/core/java/com/android/server/RescueParty.java
    if (!SystemProperties.getBoolean("config.disable_noncore", false)) {
        traceBeginAndSlog("StartRecoverySystemService");
        mSystemServiceManager.startService(RecoverySystemService.class);
        traceEnd();
    }

    // Now that we have the bare essentials of the OS up and running, take
    // note that we just booted, which might send out a rescue party if
    // we're stuck in a runtime restart loop.
  	// 正常启动系统做一个标记,如果开机重启循环,就会发出一个rescure party
    RescueParty.noteBoot(mSystemContext);

    // Manages LEDs and display backlight so we need it to bring up the display.
  	// 点亮display
    traceBeginAndSlog("StartLightsService");
    mSystemServiceManager.startService(LightsService.class);
    traceEnd();

    // Display manager is needed to provide display metrics before package manager
    // starts up.
  	// 要在package manager之前启动display manager,这样可以提供display metrics数据下去
    traceBeginAndSlog("StartDisplayManager");
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
    traceEnd();

    // We need the default display before we can initialize the package manager.
  	// 初始化package manager前需要default display
    traceBeginAndSlog("WaitForDisplay");
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
    traceEnd();

    // Only run "core" apps if we're encrypting the device.
  	// 设备在加密时,运行核心app
    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 the package manager.
  	// 开始启动PMS
    if (!mRuntimeRestart) {
        MetricsLogger.histogram(null, "boot_package_manager_init_start",
                (int) SystemClock.elapsedRealtime());
    }
    traceBeginAndSlog("StartPackageManagerService");
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();
    traceEnd();
    if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
        MetricsLogger.histogram(null, "boot_package_manager_init_ready",
                (int) SystemClock.elapsedRealtime());
    }
    // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
    // A/B artifacts after boot, before anything else might touch/need them.
    // Note: this isn't needed during decryption (we don't have /data anyways).
    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();
            }
        }
    }

    traceBeginAndSlog("StartUserManagerService");
  	// UserManagerService 新建目录/data/user/
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
    traceEnd();

    // Initialize attribute cache used to cache resources from packages.
    traceBeginAndSlog("InitAttributerCache");
    AttributeCache.init(mSystemContext);
    traceEnd();

    // Set up the Application instance for the system process and get started.
  	// 设置AMS
    traceBeginAndSlog("SetSystemProcess");
    mActivityManagerService.setSystemProcess();
    traceEnd();

    // DisplayManagerService needs to setup android.display scheduling related policies
    // since setSystemProcess() would have overridden policies due to setProcessGroup
  	// 配置displayManagerService
    mDisplayManagerService.setupSchedulerPolicies();

    // Manages Overlay packages
  	// 启动OverlayManagerService
    traceBeginAndSlog("StartOverlayManagerService");
    mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
    traceEnd();

    // The sensor service needs access to package manager service, app ops
    // service, and permissions service, therefore we start it after them.
    // Start sensor service in a separate thread. Completion should be checked
    // before using it.
  	// sensor service需要访问PMS,app ops service和permission service。所以基本上在最后启动。
  	// sensor在线程启动,访问前需要检查是否启动完成
    mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
        BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
                SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
        traceLog.traceBegin(START_SENSOR_SERVICE);
        startSensorService();
        traceLog.traceEnd();
    }, START_SENSOR_SERVICE);
}

BootstrapService整理:

  1. Installer.class 等待installd启动,使其有时间建立正确权限的目录。之后才可以初始化其他服务。
  2. DeviceIdentifiersPolicyService.class 在activity manager之前启动该服务,提供app访问设备identifier。
  3. ActivityManagerService.Lifecycle.class 启动AMS
  4. PowerManagerService.class 启动PowerManagerService,因为其他服务需要使用它,所以需要早期创建。
  5. mActivityManagerService.initPowerManagement(); 由AMS初始化PowerManagerService
  6. RecoverySystemService.class 准备rescue party相关
  7. LightsService.class 点亮display
  8. DisplayManagerService.class 上一步点亮屏幕后,启动displayManagerService,准备display metrics数据
  9. mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); systemServiceManager等待display
  10. PackageManagerService.main 启动PMS
  11. UserManagerService.LifeCycle.class 启动UserManagerService,管理多用户,创建/data/user目录
  12. AttributeCache.init(mSystemContext); 初始化attribute cache,用来缓存从packages拿到的资源
  13. mActivityManagerService.setSystemProcess(); 设置AMS
  14. mDisplayManagerService.setupSchedulerPolicies(); 设置DisplayManagerService的schedule
  15. new OverlayManagerService 启动OverlayManagerService
  16. startSensorService(); 启动sensor服务,最后启动它,而且是在线程中启动,所以使用时需要检查完整性

SystemServer.startCoreServices

来了解一下核心服务,核心的也就是最基本的。这些服务不会和启动阶段的进程产生影响。

/**
 * Starts some essential services that are not tangled up in the bootstrap process.
 */
private void startCoreServices() {
    // Records errors and logs, for example wtf()
  	// 记录error和log的服务,经典的wtf的log...
    traceBeginAndSlog("StartDropBoxManager");
    mSystemServiceManager.startService(DropBoxManagerService.class);
    traceEnd();

    traceBeginAndSlog("StartBatteryService");
    // Tracks the battery level.  Requires LightService.
  	// 统计电池的服务,需要LightService
    mSystemServiceManager.startService(BatteryService.class);
    traceEnd();

    // Tracks application usage stats.
  	// 统计应用使用情况的服务
    traceBeginAndSlog("StartUsageService");
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));
    traceEnd();

    // Tracks whether the updatable WebView is in a ready state and watches for update installs.
    traceBeginAndSlog("StartWebViewUpdateService");
    mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
    traceEnd();
}
  1. DropBoxManagerService.class 记录error和log的服务
  2. BatteryService.class 记录电池使用的服务
  3. UsageStatsService.class 应用使用情况的服务
  4. WebViewUpdateService.class WebView更新的服务

SystemServer.startOtherServices

启动一些没有被重构和管理的杂项。

这个代码很长,有一千多行就不贴了。基本上如果遇到一些前面过程没提到的服务,就可以到这里面找。

这个方法内最后的代码是:

// We now tell the activity manager it is okay to run third party
// code.  It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(() -> {
  ...
}

这时候AMS已经启动完成,可以运行三方代码了。

参考

http://gityuan.com/2016/02/20/android-system-server-2/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

spring-boot 速成(8) 集成druid+mybatis

spring-boot与druid、mybatis集成(包括pageHelper分页插件), 要添加以下几个依赖项: compile('mysql:my...

9299
来自专栏逍遥剑客的游戏开发

做了Nebula3的应用程序向导

1233
来自专栏王小雷

超详细讲解Sqoop2应用与实践

摘要:超详细讲解Sqoop2应用与实践,从hdfs上的数据导入到postgreSQL中,再从postgreSQL数据库导入到hdfs上。详细讲解创建link和创...

45110
来自专栏Android 研究

Android系统启动——6 SystemServer启动

SystemServer是Android系统的核心之一,大部分Android提供的服务都运行在这个进程里,SystemServer中运行的服务总共有60多种。为...

5823
来自专栏技术博文

Linux命令英文全称

su:Swith user  切换用户,切换到root用户 cat: Concatenate  串联 uname: Unix name  系统名称 df: Di...

3915
来自专栏杨建荣的学习笔记

rac节点无法启动ORA-29702的问题及分析(70天)

今天在虚拟机上启动rac,发现有一个节点怎么都起不了。另外一个节点没问题。 SQL> startup nomount ORA-29702: error occ...

5766
来自专栏ImportSource

Spring5以来注册Bean的各种姿势,特别最后的纯编码注册值得尝试

各位好,今天我们的内容是有关Spring 5以来有关注册bean的几种方式。前面两三个是比较常用的方式,最后两种是只有在特殊的场合下才会被用到和想到。我们会分别...

1.5K7
来自专栏杨建荣的学习笔记

11g Dataguard中的snapshot standby特性(r8笔记第49天)

11g中的ADG特性本身已经非常有特色,促使很多对于10g中不太灵便的备库升级到11g,对于DBA是一大福利,那么还有一个福利就是snapshot standb...

2975
来自专栏bboysoul

linux编译安装apache

wget http://mirrors.ustc.edu.cn/apache/httpd/httpd-2.4.25.tar.gz tar -zxvf http...

2503
来自专栏黑泽君的专栏

常用的 default.properties 文件 + 常用的 struts-default.xml 文件 + 常用的 struts-plugin.xml 文件 + 常用的 struts.xml 文件

常用的 default.properties 文件,所在位置:\struts-2.3.15.3-all\struts-2.3.15.3\apps\struts2...

914

扫码关注云+社区

领取腾讯云代金券