public void testStatsBucketResize() throws Exception {
    NetworkStatsHistory history = null;

    assertStatsFilesExist(false);

    // pretend that wifi network comes online; service should ask about full
    // network state, and poll any existing interfaces before updating.
    expectCurrentTime();
    expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
    expectNetworkState(buildWifiState());
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    verifyAndReset();

    // modify some number on wifi, and trigger poll event
    incrementCurrentTime(2 * HOUR_IN_MILLIS);
    expectCurrentTime();
    expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
    expectNetworkStatsSummary(
        new NetworkStats(getElapsedRealtime(), 1).addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L));
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify service recorded history
    history = mService.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
    assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
    assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
    assertEquals(2, history.size());
    verifyAndReset();

    // now change bucket duration setting and trigger another poll with
    // exact same values, which should resize existing buckets.
    expectCurrentTime();
    expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify identical stats, but spread across 4 buckets now
    history = mService.getHistoryForNetwork(sTemplateWifi, FIELD_ALL);
    assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
    assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
    assertEquals(4, history.size());
    verifyAndReset();
  }
  public void testUidRemovedIsMoved() throws Exception {
    // pretend that network comes online
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkState(buildWifiState());
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    verifyAndReset();

    // create some traffic
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(
        new NetworkStats(getElapsedRealtime(), 1)
            .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L));
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 1)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
            .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L)
            .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L));
    expectNetworkStatsPoll();

    mService.incrementOperationCount(UID_RED, 0xFAAD, 10);

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify service recorded history
    assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
    assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
    assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
    assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
    verifyAndReset();

    // now pretend two UIDs are uninstalled, which should migrate stats to
    // special "removed" bucket.
    expectCurrentTime();
    expectDefaultSettings();
    replay();
    final Intent intent = new Intent(ACTION_UID_REMOVED);
    intent.putExtra(EXTRA_UID, UID_BLUE);
    mServiceContext.sendBroadcast(intent);
    intent.putExtra(EXTRA_UID, UID_RED);
    mServiceContext.sendBroadcast(intent);

    // existing uid and total should remain unchanged; but removed UID
    // should be gone completely.
    assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
    assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
    assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
    assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
    assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 10);
    verifyAndReset();
  }
  @Override
  public void setUp() throws Exception {
    super.setUp();

    mServiceContext = new BroadcastInterceptingContext(getContext());
    mStatsDir = getContext().getFilesDir();
    if (mStatsDir.exists()) {
      IoUtils.deleteContents(mStatsDir);
    }

    mNetManager = createMock(INetworkManagementService.class);
    mAlarmManager = createMock(IAlarmManager.class);
    mTime = createMock(TrustedTime.class);
    mSettings = createMock(NetworkStatsSettings.class);
    mConnManager = createMock(IConnectivityManager.class);

    mService =
        new NetworkStatsService(
            mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings);
    mService.bindConnectivityManager(mConnManager);

    mElapsedRealtime = 0L;

    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectSystemReady();

    // catch INetworkManagementEventObserver during systemReady()
    final Capture<INetworkManagementEventObserver> networkObserver =
        new Capture<INetworkManagementEventObserver>();
    mNetManager.registerObserver(capture(networkObserver));
    expectLastCall().atLeastOnce();

    replay();
    mService.systemReady();
    verifyAndReset();

    mNetworkObserver = networkObserver.getValue();
  }
 private void assertNetworkTotal(
     NetworkTemplate template,
     long rxBytes,
     long rxPackets,
     long txBytes,
     long txPackets,
     int operations) {
   final NetworkStatsHistory history = mService.getHistoryForNetwork(template, FIELD_ALL);
   assertValues(
       history,
       Long.MIN_VALUE,
       Long.MAX_VALUE,
       rxBytes,
       rxPackets,
       txBytes,
       txPackets,
       operations);
 }
 private void assertUidTotal(
     NetworkTemplate template,
     int uid,
     int set,
     long rxBytes,
     long rxPackets,
     long txBytes,
     long txPackets,
     int operations) {
   final NetworkStatsHistory history =
       mService.getHistoryForUid(template, uid, set, TAG_NONE, FIELD_ALL);
   assertValues(
       history,
       Long.MIN_VALUE,
       Long.MAX_VALUE,
       rxBytes,
       rxPackets,
       txBytes,
       txPackets,
       operations);
 }
  public void testForegroundBackground() throws Exception {
    // pretend that network comes online
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkState(buildWifiState());
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    verifyAndReset();

    // create some initial traffic
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 1)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
    expectNetworkStatsPoll();

    mService.incrementOperationCount(UID_RED, 0xF00D, 1);

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify service recorded history
    assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
    verifyAndReset();

    // now switch to foreground
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 1)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
    expectNetworkStatsPoll();

    mService.setUidForeground(UID_RED, true);
    mService.incrementOperationCount(UID_RED, 0xFAAD, 1);

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // test that we combined correctly
    assertUidTotal(sTemplateWifi, UID_RED, 160L, 4L, 160L, 4L, 2);

    // verify entire history present
    final NetworkStats stats =
        mService.getSummaryForAllUid(sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
    assertEquals(4, stats.size());
    assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 1);
    assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 1);
    assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 1);
    assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 1);

    verifyAndReset();
  }
  public void testSummaryForAllUid() throws Exception {
    // pretend that network comes online
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkState(buildWifiState());
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    verifyAndReset();

    // create some traffic for two apps
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 1)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
            .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
    expectNetworkStatsPoll();

    mService.incrementOperationCount(UID_RED, 0xF00D, 1);

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify service recorded history
    assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 1);
    assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 0);
    verifyAndReset();

    // now create more traffic in next hour, but only for one app
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 1)
            .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L));
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // first verify entire history present
    NetworkStats stats =
        mService.getSummaryForAllUid(sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
    assertEquals(3, stats.size());
    assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 1);
    assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 1);
    assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0);

    // now verify that recent history only contains one uid
    final long currentTime = currentTimeMillis();
    stats =
        mService.getSummaryForAllUid(
            sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
    assertEquals(1, stats.size());
    assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0);

    verifyAndReset();
  }
  public void testUid3g4gCombinedByTemplate() throws Exception {
    // pretend that network comes online
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkState(buildMobile3gState(IMSI_1));
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    verifyAndReset();

    // create some traffic
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 1)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
    expectNetworkStatsPoll();

    mService.incrementOperationCount(UID_RED, 0xF00D, 5);

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify service recorded history
    assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5);
    verifyAndReset();

    // now switch over to 4g network
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkState(buildMobile4gState());
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
    verifyAndReset();

    // create traffic on second network
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 1)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L));
    expectNetworkStatsPoll();

    mService.incrementOperationCount(UID_RED, 0xFAAD, 5);

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify that ALL_MOBILE template combines both
    assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10);

    verifyAndReset();
  }
  public void testUidStatsAcrossNetworks() throws Exception {
    // pretend first mobile network comes online
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkState(buildMobile3gState(IMSI_1));
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    verifyAndReset();

    // create some traffic on first network
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(
        new NetworkStats(getElapsedRealtime(), 1).addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L));
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 3)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
            .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
    expectNetworkStatsPoll();

    mService.incrementOperationCount(UID_RED, 0xF00D, 10);

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify service recorded history
    assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
    assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
    assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
    assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);
    verifyAndReset();

    // now switch networks; this also tests that we're okay with interfaces
    // disappearing, to verify we don't count backwards.
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkState(buildMobile3gState(IMSI_2));
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
    verifyAndReset();

    // create traffic on second network
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(
        new NetworkStats(getElapsedRealtime(), 1).addIfaceValues(TEST_IFACE, 128L, 1L, 1024L, 8L));
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 1)
            .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 1024L, 8L, 0L)
            .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L));
    expectNetworkStatsPoll();

    mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10);

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify original history still intact
    assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
    assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10);
    assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0);

    // and verify new history also recorded under different template, which
    // verifies that we didn't cross the streams.
    assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
    assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
    assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
    verifyAndReset();
  }
  public void testStatsRebootPersist() throws Exception {
    assertStatsFilesExist(false);

    // pretend that wifi network comes online; service should ask about full
    // network state, and poll any existing interfaces before updating.
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkState(buildWifiState());
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectNetworkStatsPoll();

    replay();
    mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION_IMMEDIATE));

    // verify service has empty history for wifi
    assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
    verifyAndReset();

    // modify some number on wifi, and trigger poll event
    incrementCurrentTime(HOUR_IN_MILLIS);
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(
        new NetworkStats(getElapsedRealtime(), 1)
            .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L));
    expectNetworkStatsUidDetail(
        new NetworkStats(getElapsedRealtime(), 2)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
            .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
            .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
    expectNetworkStatsPoll();

    mService.setUidForeground(UID_RED, false);
    mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
    mService.setUidForeground(UID_RED, true);
    mService.incrementOperationCount(UID_RED, 0xFAAD, 6);

    replay();
    mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));

    // verify service recorded history
    assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
    assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
    assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
    assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
    assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
    verifyAndReset();

    // graceful shutdown system, which should trigger persist of stats, and
    // clear any values in memory.
    expectCurrentTime();
    expectDefaultSettings();
    replay();
    mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
    verifyAndReset();

    // talk with zombie service to assert stats have gone; and assert that
    // we persisted them to file.
    expectDefaultSettings();
    replay();
    assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
    verifyAndReset();

    assertStatsFilesExist(true);

    // boot through serviceReady() again
    expectCurrentTime();
    expectDefaultSettings();
    expectNetworkStatsSummary(buildEmptyStats());
    expectNetworkStatsUidDetail(buildEmptyStats());
    expectSystemReady();

    // catch INetworkManagementEventObserver during systemReady()
    final Capture<INetworkManagementEventObserver> networkObserver =
        new Capture<INetworkManagementEventObserver>();
    mNetManager.registerObserver(capture(networkObserver));
    expectLastCall().atLeastOnce();

    replay();
    mService.systemReady();

    mNetworkObserver = networkObserver.getValue();

    // after systemReady(), we should have historical stats loaded again
    assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
    assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
    assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4);
    assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6);
    assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
    verifyAndReset();
  }
  /** Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized. */
  private void startOtherServices() {
    final Context context = mSystemContext;
    AccountManagerService accountManager = null;
    ContentService contentService = null;
    VibratorService vibrator = null;
    IAlarmManager alarm = null;
    IMountService mountService = null;
    NetworkManagementService networkManagement = null;
    NetworkStatsService networkStats = null;
    NetworkPolicyManagerService networkPolicy = null;
    ConnectivityService connectivity = null;
    NetworkScoreService networkScore = null;
    NsdService serviceDiscovery = null;
    WindowManagerService wm = null;
    BluetoothManagerService bluetooth = null;
    UsbService usb = null;
    SerialService serial = null;
    NetworkTimeUpdateService networkTimeUpdater = null;
    CommonTimeManagementService commonTimeMgmtService = null;
    InputManagerService inputManager = null;
    TelephonyRegistry telephonyRegistry = null;
    ConsumerIrService consumerIr = null;
    AudioService audioService = null;
    MmsServiceBroker mmsService = null;
    EntropyMixer entropyMixer = null;
    CameraService cameraService = null;

    boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
    boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
    boolean disableLocation = SystemProperties.getBoolean("config.disable_location", false);
    boolean disableSystemUI = SystemProperties.getBoolean("config.disable_systemui", false);
    boolean disableNonCoreServices = SystemProperties.getBoolean("config.disable_noncore", false);
    boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);
    boolean disableNetworkTime = SystemProperties.getBoolean("config.disable_networktime", false);
    boolean isEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");

    try {
      Slog.i(TAG, "Reading configuration...");
      SystemConfig.getInstance();

      Slog.i(TAG, "Scheduling Policy");
      ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());

      mSystemServiceManager.startService(TelecomLoaderService.class);

      Slog.i(TAG, "Telephony Registry");
      telephonyRegistry = new TelephonyRegistry(context);
      ServiceManager.addService("telephony.registry", telephonyRegistry);

      Slog.i(TAG, "Entropy Mixer");
      entropyMixer = new EntropyMixer(context);

      mContentResolver = context.getContentResolver();

      Slog.i(TAG, "Camera Service");
      mSystemServiceManager.startService(CameraService.class);

      // The AccountManager must come before the ContentService
      try {
        // TODO: seems like this should be disable-able, but req'd by ContentService
        Slog.i(TAG, "Account Manager");
        accountManager = new AccountManagerService(context);
        ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
      } catch (Throwable e) {
        Slog.e(TAG, "Failure starting Account Manager", e);
      }

      Slog.i(TAG, "Content Manager");
      contentService =
          ContentService.main(context, mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL);

      Slog.i(TAG, "System Content Providers");
      mActivityManagerService.installSystemProviders();

      Slog.i(TAG, "Vibrator Service");
      vibrator = new VibratorService(context);
      ServiceManager.addService("vibrator", vibrator);

      Slog.i(TAG, "Consumer IR Service");
      consumerIr = new ConsumerIrService(context);
      ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);

      mSystemServiceManager.startService(AlarmManagerService.class);
      alarm = IAlarmManager.Stub.asInterface(ServiceManager.getService(Context.ALARM_SERVICE));

      Slog.i(TAG, "Init Watchdog");
      final Watchdog watchdog = Watchdog.getInstance();
      watchdog.init(context, mActivityManagerService);

      Slog.i(TAG, "Input Manager");
      inputManager = new InputManagerService(context);

      Slog.i(TAG, "Window Manager");
      wm =
          WindowManagerService.main(
              context,
              inputManager,
              mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
              !mFirstBoot,
              mOnlyCore);
      ServiceManager.addService(Context.WINDOW_SERVICE, wm);
      ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

      mActivityManagerService.setWindowManager(wm);

      inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
      inputManager.start();

      // TODO: Use service dependencies instead.
      mDisplayManagerService.windowManagerAndInputReady();

      // Skip Bluetooth if we have an emulator kernel
      // TODO: Use a more reliable check to see if this product should
      // support Bluetooth - see bug 988521
      if (isEmulator) {
        Slog.i(TAG, "No Bluetooh Service (emulator)");
      } else if (mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        Slog.i(TAG, "No Bluetooth Service (factory test)");
      } else if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
        Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)");
      } else if (disableBluetooth) {
        Slog.i(TAG, "Bluetooth Service disabled by config");
      } else {
        Slog.i(TAG, "Bluetooth Manager Service");
        bluetooth = new BluetoothManagerService(context);
        ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
      }
    } catch (RuntimeException e) {
      Slog.e("System", "******************************************");
      Slog.e("System", "************ Failure starting core service", e);
    }

    StatusBarManagerService statusBar = null;
    INotificationManager notification = null;
    InputMethodManagerService imm = null;
    WallpaperManagerService wallpaper = null;
    LocationManagerService location = null;
    CountryDetectorService countryDetector = null;
    TextServicesManagerService tsms = null;
    LockSettingsService lockSettings = null;
    AssetAtlasService atlas = null;
    MediaRouterService mediaRouter = null;

    // Bring up services needed for UI.
    if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
      try {
        Slog.i(TAG, "Input Method Service");
        imm = new InputMethodManagerService(context, wm);
        ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
      } catch (Throwable e) {
        reportWtf("starting Input Manager Service", e);
      }

      try {
        Slog.i(TAG, "Accessibility Manager");
        ServiceManager.addService(
            Context.ACCESSIBILITY_SERVICE, new AccessibilityManagerService(context));
      } catch (Throwable e) {
        reportWtf("starting Accessibility Manager", e);
      }
    }

    try {
      wm.displayReady();
    } catch (Throwable e) {
      reportWtf("making display ready", e);
    }

    if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
      if (!disableStorage && !"0".equals(SystemProperties.get("system_init.startmountservice"))) {
        try {
          /*
           * NotificationManagerService is dependant on MountService,
           * (for media / usb notifications) so we must start MountService first.
           */
          mSystemServiceManager.startService(MOUNT_SERVICE_CLASS);
          mountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
        } catch (Throwable e) {
          reportWtf("starting Mount Service", e);
        }
      }
    }

    // We start this here so that we update our configuration to set watch or television
    // as appropriate.
    mSystemServiceManager.startService(UiModeManagerService.class);

    try {
      mPackageManagerService.performBootDexOpt();
    } catch (Throwable e) {
      reportWtf("performing boot dexopt", e);
    }

    try {
      ActivityManagerNative.getDefault()
          .showBootMessage(
              context
                  .getResources()
                  .getText(com.android.internal.R.string.android_upgrading_starting_apps),
              false);
    } catch (RemoteException e) {
    }

    if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
      if (!disableNonCoreServices) {
        try {
          Slog.i(TAG, "LockSettingsService");
          lockSettings = new LockSettingsService(context);
          ServiceManager.addService("lock_settings", lockSettings);
        } catch (Throwable e) {
          reportWtf("starting LockSettingsService service", e);
        }

        if (!SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("")) {
          mSystemServiceManager.startService(PersistentDataBlockService.class);
        }

        mSystemServiceManager.startService(DeviceIdleController.class);

        // Always start the Device Policy Manager, so that the API is compatible with
        // API8.
        mSystemServiceManager.startService(DevicePolicyManagerService.Lifecycle.class);
      }

      if (!disableSystemUI) {
        try {
          Slog.i(TAG, "Status Bar");
          statusBar = new StatusBarManagerService(context, wm);
          ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
        } catch (Throwable e) {
          reportWtf("starting StatusBarManagerService", e);
        }
      }

      if (!disableNonCoreServices) {
        try {
          Slog.i(TAG, "Clipboard Service");
          ServiceManager.addService(Context.CLIPBOARD_SERVICE, new ClipboardService(context));
        } catch (Throwable e) {
          reportWtf("starting Clipboard Service", e);
        }
      }

      if (!disableNetwork) {
        try {
          Slog.i(TAG, "NetworkManagement Service");
          networkManagement = NetworkManagementService.create(context);
          ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
        } catch (Throwable e) {
          reportWtf("starting NetworkManagement Service", e);
        }
      }

      if (!disableNonCoreServices) {
        try {
          Slog.i(TAG, "Text Service Manager Service");
          tsms = new TextServicesManagerService(context);
          ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
        } catch (Throwable e) {
          reportWtf("starting Text Service Manager Service", e);
        }
      }

      if (!disableNetwork) {
        try {
          Slog.i(TAG, "Network Score Service");
          networkScore = new NetworkScoreService(context);
          ServiceManager.addService(Context.NETWORK_SCORE_SERVICE, networkScore);
        } catch (Throwable e) {
          reportWtf("starting Network Score Service", e);
        }

        try {
          Slog.i(TAG, "NetworkStats Service");
          networkStats = new NetworkStatsService(context, networkManagement, alarm);
          ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
        } catch (Throwable e) {
          reportWtf("starting NetworkStats Service", e);
        }

        try {
          Slog.i(TAG, "NetworkPolicy Service");
          networkPolicy =
              new NetworkPolicyManagerService(
                  context,
                  mActivityManagerService,
                  (IPowerManager) ServiceManager.getService(Context.POWER_SERVICE),
                  networkStats,
                  networkManagement);
          ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
        } catch (Throwable e) {
          reportWtf("starting NetworkPolicy Service", e);
        }

        mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
        mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
        mSystemServiceManager.startService("com.android.server.wifi.WifiScanningService");

        mSystemServiceManager.startService("com.android.server.wifi.RttService");

        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET)
            || mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) {
          mSystemServiceManager.startService(ETHERNET_SERVICE_CLASS);
        }

        try {
          Slog.i(TAG, "Connectivity Service");
          connectivity =
              new ConnectivityService(context, networkManagement, networkStats, networkPolicy);
          ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
          networkStats.bindConnectivityManager(connectivity);
          networkPolicy.bindConnectivityManager(connectivity);
        } catch (Throwable e) {
          reportWtf("starting Connectivity Service", e);
        }

        try {
          Slog.i(TAG, "Network Service Discovery Service");
          serviceDiscovery = NsdService.create(context);
          ServiceManager.addService(Context.NSD_SERVICE, serviceDiscovery);
        } catch (Throwable e) {
          reportWtf("starting Service Discovery Service", e);
        }
      }

      if (!disableNonCoreServices) {
        try {
          Slog.i(TAG, "UpdateLock Service");
          ServiceManager.addService(Context.UPDATE_LOCK_SERVICE, new UpdateLockService(context));
        } catch (Throwable e) {
          reportWtf("starting UpdateLockService", e);
        }
      }

      /*
       * MountService has a few dependencies: Notification Manager and
       * AppWidget Provider. Make sure MountService is completely started
       * first before continuing.
       */
      if (mountService != null && !mOnlyCore) {
        try {
          mountService.waitForAsecScan();
        } catch (RemoteException ignored) {
        }
      }

      try {
        if (accountManager != null) accountManager.systemReady();
      } catch (Throwable e) {
        reportWtf("making Account Manager Service ready", e);
      }

      try {
        if (contentService != null) contentService.systemReady();
      } catch (Throwable e) {
        reportWtf("making Content Service ready", e);
      }

      mSystemServiceManager.startService(NotificationManagerService.class);
      notification =
          INotificationManager.Stub.asInterface(
              ServiceManager.getService(Context.NOTIFICATION_SERVICE));
      networkPolicy.bindNotificationManager(notification);

      mSystemServiceManager.startService(DeviceStorageMonitorService.class);

      if (!disableLocation) {
        try {
          Slog.i(TAG, "Location Manager");
          location = new LocationManagerService(context);
          ServiceManager.addService(Context.LOCATION_SERVICE, location);
        } catch (Throwable e) {
          reportWtf("starting Location Manager", e);
        }

        try {
          Slog.i(TAG, "Country Detector");
          countryDetector = new CountryDetectorService(context);
          ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
        } catch (Throwable e) {
          reportWtf("starting Country Detector", e);
        }
      }

      if (!disableNonCoreServices) {
        try {
          Slog.i(TAG, "Search Service");
          ServiceManager.addService(Context.SEARCH_SERVICE, new SearchManagerService(context));
        } catch (Throwable e) {
          reportWtf("starting Search Service", e);
        }
      }

      try {
        Slog.i(TAG, "DropBox Service");
        ServiceManager.addService(
            Context.DROPBOX_SERVICE,
            new DropBoxManagerService(context, new File("/data/system/dropbox")));
      } catch (Throwable e) {
        reportWtf("starting DropBoxManagerService", e);
      }

      if (!disableNonCoreServices
          && context.getResources().getBoolean(R.bool.config_enableWallpaperService)) {
        try {
          Slog.i(TAG, "Wallpaper Service");
          wallpaper = new WallpaperManagerService(context);
          ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
        } catch (Throwable e) {
          reportWtf("starting Wallpaper Service", e);
        }
      }

      try {
        Slog.i(TAG, "Audio Service");
        audioService = new AudioService(context);
        ServiceManager.addService(Context.AUDIO_SERVICE, audioService);
      } catch (Throwable e) {
        reportWtf("starting Audio Service", e);
      }

      if (!disableNonCoreServices) {
        mSystemServiceManager.startService(DockObserver.class);
      }

      try {
        Slog.i(TAG, "Wired Accessory Manager");
        // Listen for wired headset changes
        inputManager.setWiredAccessoryCallbacks(new WiredAccessoryManager(context, inputManager));
      } catch (Throwable e) {
        reportWtf("starting WiredAccessoryManager", e);
      }

      if (!disableNonCoreServices) {
        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
          // Start MIDI Manager service
          mSystemServiceManager.startService(MIDI_SERVICE_CLASS);
        }

        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)
            || mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY)) {
          // Manage USB host and device support
          mSystemServiceManager.startService(USB_SERVICE_CLASS);
        }

        try {
          Slog.i(TAG, "Serial Service");
          // Serial port support
          serial = new SerialService(context);
          ServiceManager.addService(Context.SERIAL_SERVICE, serial);
        } catch (Throwable e) {
          Slog.e(TAG, "Failure starting SerialService", e);
        }
      }

      mSystemServiceManager.startService(TwilightService.class);

      mSystemServiceManager.startService(JobSchedulerService.class);

      if (!disableNonCoreServices) {
        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BACKUP)) {
          mSystemServiceManager.startService(BACKUP_MANAGER_SERVICE_CLASS);
        }

        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)) {
          mSystemServiceManager.startService(APPWIDGET_SERVICE_CLASS);
        }

        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_VOICE_RECOGNIZERS)) {
          mSystemServiceManager.startService(VOICE_RECOGNITION_MANAGER_SERVICE_CLASS);
        }
      }

      try {
        Slog.i(TAG, "DiskStats Service");
        ServiceManager.addService("diskstats", new DiskStatsService(context));
      } catch (Throwable e) {
        reportWtf("starting DiskStats Service", e);
      }

      try {
        // need to add this service even if SamplingProfilerIntegration.isEnabled()
        // is false, because it is this service that detects system property change and
        // turns on SamplingProfilerIntegration. Plus, when sampling profiler doesn't work,
        // there is little overhead for running this service.
        Slog.i(TAG, "SamplingProfiler Service");
        ServiceManager.addService("samplingprofiler", new SamplingProfilerService(context));
      } catch (Throwable e) {
        reportWtf("starting SamplingProfiler Service", e);
      }

      if (!disableNetwork && !disableNetworkTime) {
        try {
          Slog.i(TAG, "NetworkTimeUpdateService");
          networkTimeUpdater = new NetworkTimeUpdateService(context);
        } catch (Throwable e) {
          reportWtf("starting NetworkTimeUpdate service", e);
        }
      }

      try {
        Slog.i(TAG, "CommonTimeManagementService");
        commonTimeMgmtService = new CommonTimeManagementService(context);
        ServiceManager.addService("commontime_management", commonTimeMgmtService);
      } catch (Throwable e) {
        reportWtf("starting CommonTimeManagementService service", e);
      }

      if (!disableNetwork) {
        try {
          Slog.i(TAG, "CertBlacklister");
          CertBlacklister blacklister = new CertBlacklister(context);
        } catch (Throwable e) {
          reportWtf("starting CertBlacklister", e);
        }
      }

      if (!disableNonCoreServices) {
        // Dreams (interactive idle-time views, a/k/a screen savers, and doze mode)
        mSystemServiceManager.startService(DreamManagerService.class);
      }

      if (!disableNonCoreServices) {
        try {
          Slog.i(TAG, "Assets Atlas Service");
          atlas = new AssetAtlasService(context);
          ServiceManager.addService(AssetAtlasService.ASSET_ATLAS_SERVICE, atlas);
        } catch (Throwable e) {
          reportWtf("starting AssetAtlasService", e);
        }
      }

      if (!disableNonCoreServices) {
        ServiceManager.addService(
            GraphicsStatsService.GRAPHICS_STATS_SERVICE, new GraphicsStatsService(context));
      }

      if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
        mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);
      }

      mSystemServiceManager.startService(RestrictionsManagerService.class);

      mSystemServiceManager.startService(MediaSessionService.class);

      if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_HDMI_CEC)) {
        mSystemServiceManager.startService(HdmiControlService.class);
      }

      if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_LIVE_TV)) {
        mSystemServiceManager.startService(TvInputManagerService.class);
      }

      if (!disableNonCoreServices) {
        try {
          Slog.i(TAG, "Media Router Service");
          mediaRouter = new MediaRouterService(context);
          ServiceManager.addService(Context.MEDIA_ROUTER_SERVICE, mediaRouter);
        } catch (Throwable e) {
          reportWtf("starting MediaRouterService", e);
        }

        mSystemServiceManager.startService(TrustManagerService.class);

        mSystemServiceManager.startService(FingerprintService.class);

        try {
          Slog.i(TAG, "BackgroundDexOptService");
          BackgroundDexOptService.schedule(context);
        } catch (Throwable e) {
          reportWtf("starting BackgroundDexOptService", e);
        }
      }

      mSystemServiceManager.startService(LauncherAppsService.class);
    }

    if (!disableNonCoreServices) {
      mSystemServiceManager.startService(MediaProjectionManagerService.class);
    }

    // Before things start rolling, be sure we have decided whether
    // we are in safe mode.
    final boolean safeMode = wm.detectSafeMode();
    if (safeMode) {
      mActivityManagerService.enterSafeMode();
      // Disable the JIT for the system_server process
      VMRuntime.getRuntime().disableJitCompilation();
    } else {
      // Enable the JIT for the system_server process
      VMRuntime.getRuntime().startJitCompilation();
    }

    // MMS service broker
    mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);

    // It is now time to start up the app processes...

    try {
      vibrator.systemReady();
    } catch (Throwable e) {
      reportWtf("making Vibrator Service ready", e);
    }

    if (lockSettings != null) {
      try {
        lockSettings.systemReady();
      } catch (Throwable e) {
        reportWtf("making Lock Settings Service ready", e);
      }
    }

    // Needed by DevicePolicyManager for initialization
    mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);

    mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);

    try {
      wm.systemReady();
    } catch (Throwable e) {
      reportWtf("making Window Manager Service ready", e);
    }

    if (safeMode) {
      mActivityManagerService.showSafeModeOverlay();
    }

    // Update the configuration for this context by hand, because we're going
    // to start using it before the config change done in wm.systemReady() will
    // propagate to it.
    Configuration config = wm.computeNewConfiguration();
    DisplayMetrics metrics = new DisplayMetrics();
    WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    w.getDefaultDisplay().getMetrics(metrics);
    context.getResources().updateConfiguration(config, metrics);

    // The system context's theme may be configuration-dependent.
    final Theme systemTheme = context.getTheme();
    if (systemTheme.getChangingConfigurations() != 0) {
      systemTheme.rebase();
    }

    try {
      // TODO: use boot phase
      mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
    } catch (Throwable e) {
      reportWtf("making Power Manager Service ready", e);
    }

    try {
      mPackageManagerService.systemReady();
    } catch (Throwable e) {
      reportWtf("making Package Manager Service ready", e);
    }

    try {
      // TODO: use boot phase and communicate these flags some other way
      mDisplayManagerService.systemReady(safeMode, mOnlyCore);
    } catch (Throwable e) {
      reportWtf("making Display Manager Service ready", e);
    }

    // These are needed to propagate to the runnable below.
    final NetworkManagementService networkManagementF = networkManagement;
    final NetworkStatsService networkStatsF = networkStats;
    final NetworkPolicyManagerService networkPolicyF = networkPolicy;
    final ConnectivityService connectivityF = connectivity;
    final NetworkScoreService networkScoreF = networkScore;
    final WallpaperManagerService wallpaperF = wallpaper;
    final InputMethodManagerService immF = imm;
    final LocationManagerService locationF = location;
    final CountryDetectorService countryDetectorF = countryDetector;
    final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
    final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
    final TextServicesManagerService textServiceManagerServiceF = tsms;
    final StatusBarManagerService statusBarF = statusBar;
    final AssetAtlasService atlasF = atlas;
    final InputManagerService inputManagerF = inputManager;
    final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
    final MediaRouterService mediaRouterF = mediaRouter;
    final AudioService audioServiceF = audioService;
    final MmsServiceBroker mmsServiceF = mmsService;

    // 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(
        new Runnable() {
          @Override
          public void run() {
            Slog.i(TAG, "Making services ready");
            mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);

            try {
              mActivityManagerService.startObservingNativeCrashes();
            } catch (Throwable e) {
              reportWtf("observing native crashes", e);
            }

            Slog.i(TAG, "WebViewFactory preparation");
            WebViewFactory.prepareWebViewInSystemServer();

            try {
              startSystemUi(context);
            } catch (Throwable e) {
              reportWtf("starting System UI", e);
            }
            try {
              if (networkScoreF != null) networkScoreF.systemReady();
            } catch (Throwable e) {
              reportWtf("making Network Score Service ready", e);
            }
            try {
              if (networkManagementF != null) networkManagementF.systemReady();
            } catch (Throwable e) {
              reportWtf("making Network Managment Service ready", e);
            }
            try {
              if (networkStatsF != null) networkStatsF.systemReady();
            } catch (Throwable e) {
              reportWtf("making Network Stats Service ready", e);
            }
            try {
              if (networkPolicyF != null) networkPolicyF.systemReady();
            } catch (Throwable e) {
              reportWtf("making Network Policy Service ready", e);
            }
            try {
              if (connectivityF != null) connectivityF.systemReady();
            } catch (Throwable e) {
              reportWtf("making Connectivity Service ready", e);
            }
            try {
              if (audioServiceF != null) audioServiceF.systemReady();
            } catch (Throwable e) {
              reportWtf("Notifying AudioService running", e);
            }
            Watchdog.getInstance().start();

            // It is now okay to let the various system services start their
            // third party code...
            mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

            try {
              if (wallpaperF != null) wallpaperF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying WallpaperService running", e);
            }
            try {
              if (immF != null) immF.systemRunning(statusBarF);
            } catch (Throwable e) {
              reportWtf("Notifying InputMethodService running", e);
            }
            try {
              if (locationF != null) locationF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying Location Service running", e);
            }
            try {
              if (countryDetectorF != null) countryDetectorF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying CountryDetectorService running", e);
            }
            try {
              if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying NetworkTimeService running", e);
            }
            try {
              if (commonTimeMgmtServiceF != null) {
                commonTimeMgmtServiceF.systemRunning();
              }
            } catch (Throwable e) {
              reportWtf("Notifying CommonTimeManagementService running", e);
            }
            try {
              if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying TextServicesManagerService running", e);
            }
            try {
              if (atlasF != null) atlasF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying AssetAtlasService running", e);
            }
            try {
              // TODO(BT) Pass parameter to input manager
              if (inputManagerF != null) inputManagerF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying InputManagerService running", e);
            }
            try {
              if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying TelephonyRegistry running", e);
            }
            try {
              if (mediaRouterF != null) mediaRouterF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying MediaRouterService running", e);
            }

            try {
              if (mmsServiceF != null) mmsServiceF.systemRunning();
            } catch (Throwable e) {
              reportWtf("Notifying MmsService running", e);
            }
          }
        });
  }