/** Starts some essential services that are not tangled up in the bootstrap process. */
  private void startCoreServices() {
    // Tracks the battery level.  Requires LightService.
    mSystemServiceManager.startService(BatteryService.class);

    // Tracks application usage stats.
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
        LocalServices.getService(UsageStatsManagerInternal.class));
    // Update after UsageStatsService is available, needed before performBootDexOpt.
    mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();

    // Tracks whether the updatable WebView is in a ready state and watches for update installs.
    mSystemServiceManager.startService(WebViewUpdateService.class);
  }
  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);
    }

    // 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();

    // 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();

    // Create the system service manager.
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

    // Start services.
    try {
      startBootstrapServices();
      startCoreServices();
      startOtherServices();
    } 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");
  }