Merge "Fix networktype on per process DNS setting"
diff --git a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
index 9403d95..242057c 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
@@ -23,16 +23,18 @@
 import static android.text.format.DateUtils.WEEK_IN_MILLIS;
 import static android.text.format.DateUtils.YEAR_IN_MILLIS;
 
+import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.test.suitebuilder.annotation.Suppress;
 import android.util.Log;
 
-import junit.framework.TestCase;
+import com.android.frameworks.coretests.R;
 
+import java.io.DataInputStream;
 import java.util.Random;
 
 @SmallTest
-public class NetworkStatsHistoryTest extends TestCase {
+public class NetworkStatsHistoryTest extends AndroidTestCase {
     private static final String TAG = "NetworkStatsHistoryTest";
 
     private static final long TEST_START = 1194220800000L;
@@ -47,6 +49,32 @@
         }
     }
 
+    public void testReadOriginalVersion() throws Exception {
+        final DataInputStream in = new DataInputStream(
+                getContext().getResources().openRawResource(R.raw.history_v1));
+
+        NetworkStatsHistory.Entry entry = null;
+        try {
+            final NetworkStatsHistory history = new NetworkStatsHistory(in);
+            assertEquals(15 * SECOND_IN_MILLIS, history.getBucketDuration());
+
+            entry = history.getValues(0, entry);
+            assertEquals(29143L, entry.rxBytes);
+            assertEquals(6223L, entry.txBytes);
+
+            entry = history.getValues(history.size() - 1, entry);
+            assertEquals(1476L, entry.rxBytes);
+            assertEquals(838L, entry.txBytes);
+
+            entry = history.getValues(Long.MIN_VALUE, Long.MAX_VALUE, entry);
+            assertEquals(332401L, entry.rxBytes);
+            assertEquals(64314L, entry.txBytes);
+
+        } finally {
+            in.close();
+        }
+    }
+
     public void testRecordSingleBucket() throws Exception {
         final long BUCKET_SIZE = HOUR_IN_MILLIS;
         stats = new NetworkStatsHistory(BUCKET_SIZE);
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index 2434e9f..69ad0f4 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -31,9 +31,9 @@
 
     public void testFindIndex() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L)
-                .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L);
+                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 10)
+                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 11)
+                .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L, 12);
 
         assertEquals(2, stats.findIndex(TEST_IFACE, 102, TAG_NONE));
         assertEquals(2, stats.findIndex(TEST_IFACE, 102, TAG_NONE));
@@ -47,95 +47,95 @@
         assertEquals(0, stats.size());
         assertEquals(2, stats.internalSize());
 
-        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L);
-        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L);
+        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L, 3);
+        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L, 4);
 
         assertEquals(2, stats.size());
         assertEquals(2, stats.internalSize());
 
-        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L);
-        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L);
-        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L);
+        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L, 7);
+        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L, 8);
+        stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L, 10);
 
         assertEquals(5, stats.size());
         assertTrue(stats.internalSize() >= 5);
 
-        assertEntry(stats, 0, TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L);
-        assertEntry(stats, 1, TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L);
-        assertEntry(stats, 2, TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L);
-        assertEntry(stats, 3, TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L);
-        assertEntry(stats, 4, TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L);
+        assertValues(stats, 0, TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L, 3);
+        assertValues(stats, 1, TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L, 4);
+        assertValues(stats, 2, TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L, 7);
+        assertValues(stats, 3, TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L, 8);
+        assertValues(stats, 4, TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L, 10);
     }
 
     public void testCombineExisting() throws Exception {
         final NetworkStats stats = new NetworkStats(TEST_START, 10);
 
-        stats.addValues(TEST_IFACE, 1001, TAG_NONE, 512L, 4L, 256L, 2L);
-        stats.addValues(TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L);
-        stats.combineValues(TEST_IFACE, 1001, TAG_NONE, -128L, -1L, -128L, -1L);
+        stats.addValues(TEST_IFACE, 1001, TAG_NONE, 512L, 4L, 256L, 2L, 10);
+        stats.addValues(TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L, 2);
+        stats.combineValues(TEST_IFACE, 1001, TAG_NONE, -128L, -1L, -128L, -1L, -1);
 
-        assertEntry(stats, 0, TEST_IFACE, 1001, TAG_NONE, 384L, 3L, 128L, 1L);
-        assertEntry(stats, 1, TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L);
+        assertValues(stats, 0, TEST_IFACE, 1001, TAG_NONE, 384L, 3L, 128L, 1L, 9);
+        assertValues(stats, 1, TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L, 2);
 
         // now try combining that should create row
-        stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L);
-        assertEntry(stats, 2, TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L);
-        stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L);
-        assertEntry(stats, 2, TEST_IFACE, 5005, TAG_NONE, 256L, 2L, 256L, 2L);
+        stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L, 3);
+        assertValues(stats, 2, TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L, 3);
+        stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L, 3);
+        assertValues(stats, 2, TEST_IFACE, 5005, TAG_NONE, 256L, 2L, 256L, 2L, 6);
     }
 
     public void testSubtractIdenticalData() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L);
+                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats after = new NetworkStats(TEST_START, 2)
-                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L);
+                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats result = after.subtract(before);
 
         // identical data should result in zero delta
-        assertEntry(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L);
-        assertEntry(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L);
+        assertValues(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L, 0);
+        assertValues(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L, 0);
     }
 
     public void testSubtractIdenticalRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L);
+                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats after = new NetworkStats(TEST_START, 2)
-                .addValues(TEST_IFACE, 100, TAG_NONE, 1025L, 9L, 2L, 1L)
-                .addValues(TEST_IFACE, 101, TAG_NONE, 3L, 1L, 1028L, 9L);
+                .addValues(TEST_IFACE, 100, TAG_NONE, 1025L, 9L, 2L, 1L, 15)
+                .addValues(TEST_IFACE, 101, TAG_NONE, 3L, 1L, 1028L, 9L, 20);
 
         final NetworkStats result = after.subtract(before);
 
         // expect delta between measurements
-        assertEntry(result, 0, TEST_IFACE, 100, TAG_NONE, 1L, 1L, 2L, 1L);
-        assertEntry(result, 1, TEST_IFACE, 101, TAG_NONE, 3L, 1L, 4L, 1L);
+        assertValues(result, 0, TEST_IFACE, 100, TAG_NONE, 1L, 1L, 2L, 1L, 4);
+        assertValues(result, 1, TEST_IFACE, 101, TAG_NONE, 3L, 1L, 4L, 1L, 8);
     }
 
     public void testSubtractNewRows() throws Exception {
         final NetworkStats before = new NetworkStats(TEST_START, 2)
-                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L);
+                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12);
 
         final NetworkStats after = new NetworkStats(TEST_START, 3)
-                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L)
-                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L)
-                .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L);
+                .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11)
+                .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12)
+                .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
 
         final NetworkStats result = after.subtract(before);
 
         // its okay to have new rows
-        assertEntry(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L);
-        assertEntry(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L);
-        assertEntry(result, 2, TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L);
+        assertValues(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L, 0);
+        assertValues(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L, 0);
+        assertValues(result, 2, TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L, 20);
     }
 
-    private static void assertEntry(NetworkStats stats, int index, String iface, int uid, int tag,
-            long rxBytes, long rxPackets, long txBytes, long txPackets) {
+    private static void assertValues(NetworkStats stats, int index, String iface, int uid, int tag,
+            long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
         final NetworkStats.Entry entry = stats.getValues(index, null);
         assertEquals(iface, entry.iface);
         assertEquals(uid, entry.uid);
@@ -144,6 +144,7 @@
         assertEquals(rxPackets, entry.rxPackets);
         assertEquals(txBytes, entry.txBytes);
         assertEquals(txPackets, entry.txPackets);
+        assertEquals(operations, entry.operations);
     }
 
 }
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index 56ef995..f628977 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -50,10 +50,9 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        final File canonicalFilesDir = getContext().getFilesDir().getCanonicalFile();
-        mTestProc = new File(canonicalFilesDir, "proc");
+        mTestProc = new File(getContext().getFilesDir(), "proc");
         if (mTestProc.exists()) {
-            Files.deleteRecursively(mTestProc);
+            IoUtils.deleteContents(mTestProc);
         }
 
         mService = NetworkManagementService.createForTest(mContext, mTestProc, true);
@@ -64,7 +63,7 @@
         mService = null;
 
         if (mTestProc.exists()) {
-            Files.deleteRecursively(mTestProc);
+            IoUtils.deleteContents(mTestProc);
         }
 
         super.tearDown();
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index bd80af9..cf69fd5 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -160,22 +160,25 @@
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
 
         // verify service has empty history for wifi
-        assertNetworkTotal(sTemplateWifi, 0L, 0L);
+        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
         verifyAndReset();
 
+        // bootstrap with full polling event to prime stats
+        performBootstrapPoll(TEST_START, elapsedRealtime);
+
         // modify some number on wifi, and trigger poll event
         elapsedRealtime += HOUR_IN_MILLIS;
         expectTime(TEST_START + elapsedRealtime);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 1L, 2048L, 2L));
-        expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+        expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
 
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify service recorded history
-        assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
+        assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
         verifyAndReset();
 
         // and bump forward again, with counters going higher. this is
@@ -185,13 +188,13 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4096L, 4L, 8192L, 8L));
-        expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+        expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
 
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify service recorded history
-        assertNetworkTotal(sTemplateWifi, 4096L, 8192L);
+        assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
         verifyAndReset();
 
     }
@@ -211,26 +214,32 @@
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
 
         // verify service has empty history for wifi
-        assertNetworkTotal(sTemplateWifi, 0L, 0L);
+        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
         verifyAndReset();
 
+        // bootstrap with full polling event to prime stats
+        performBootstrapPoll(TEST_START, elapsedRealtime);
+
         // modify some number on wifi, and trigger poll event
         elapsedRealtime += HOUR_IN_MILLIS;
         expectTime(TEST_START + elapsedRealtime);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 8L, 2048L, 16L));
-        expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2)
+        expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 2)
                 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L)
                 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 128L, 1L));
 
+        mService.incrementOperationCount(UID_RED, TAG_NONE, 20);
+        mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10);
+
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify service recorded history
-        assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
-        assertUidTotal(sTemplateWifi, UID_RED, 512L, 256L);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 128L);
+        assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
+        assertUidTotal(sTemplateWifi, UID_RED, 512L, 4L, 256L, 2L, 20);
+        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 10);
         verifyAndReset();
 
         // graceful shutdown system, which should trigger persist of stats, and
@@ -241,7 +250,7 @@
         // we persisted them to file.
         expectDefaultSettings();
         replay();
-        assertNetworkTotal(sTemplateWifi, 0L, 0L);
+        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
         verifyAndReset();
 
         assertStatsFilesExist(true);
@@ -254,9 +263,9 @@
         mService.systemReady();
 
         // after systemReady(), we should have historical stats loaded again
-        assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
-        assertUidTotal(sTemplateWifi, UID_RED, 512L, 256L);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 128L);
+        assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
+        assertUidTotal(sTemplateWifi, UID_RED, 512L, 4L, 256L, 2L, 20);
+        assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 10);
         verifyAndReset();
 
     }
@@ -278,20 +287,23 @@
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
         verifyAndReset();
 
+        // bootstrap with full polling event to prime stats
+        performBootstrapPoll(TEST_START, elapsedRealtime);
+
         // modify some number on wifi, and trigger poll event
         elapsedRealtime += 2 * HOUR_IN_MILLIS;
         expectTime(TEST_START + elapsedRealtime);
         expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
         expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 512L, 4L, 512L, 4L));
-        expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+        expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
 
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify service recorded history
         history = mService.getHistoryForNetwork(sTemplateWifi);
-        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
+        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
         assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
         assertEquals(2, history.size());
         verifyAndReset();
@@ -301,14 +313,14 @@
         expectTime(TEST_START + elapsedRealtime);
         expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
         expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
-        expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+        expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
 
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify identical stats, but spread across 4 buckets now
         history = mService.getHistoryForNetwork(sTemplateWifi);
-        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
+        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();
@@ -328,25 +340,32 @@
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
         verifyAndReset();
 
+        // bootstrap with full polling event to prime stats
+        performBootstrapPoll(TEST_START, elapsedRealtime);
+
         // create some traffic on first network
         elapsedRealtime += HOUR_IN_MILLIS;
         expectTime(TEST_START + elapsedRealtime);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 2048L, 16L, 512L, 4L));
-        expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 3)
+        expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 3)
                 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 1536L, 12L, 512L, 4L)
                 .addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L)
                 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 512L, 4L, 0L, 0L));
 
+        mService.incrementOperationCount(UID_RED, TAG_NONE, 15);
+        mService.incrementOperationCount(UID_RED, 0xF00D, 10);
+        mService.incrementOperationCount(UID_BLUE, TAG_NONE, 5);
+
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify service recorded history
-        assertNetworkTotal(sTemplateImsi1, 2048L, 512L);
-        assertNetworkTotal(sTemplateWifi, 0L, 0L);
-        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 512L);
-        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 0L);
+        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
+        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 15);
+        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 5);
         verifyAndReset();
 
         // now switch networks; this also tests that we're okay with interfaces
@@ -356,7 +375,7 @@
         expectDefaultSettings();
         expectNetworkState(buildMobile3gState(IMSI_2));
         expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
-        expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+        expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -369,22 +388,24 @@
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 128L, 1L, 1024L, 8L));
-        expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+        expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 1024L, 8L));
 
+        mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10);
+
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify original history still intact
-        assertNetworkTotal(sTemplateImsi1, 2048L, 512L);
-        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 512L);
-        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 0L);
+        assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
+        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 15);
+        assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 5);
 
         // and verify new history also recorded under different template, which
         // verifies that we didn't cross the streams.
-        assertNetworkTotal(sTemplateImsi2, 128L, 1024L);
-        assertNetworkTotal(sTemplateWifi, 0L, 0L);
-        assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1024L);
+        assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
+        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+        assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
         verifyAndReset();
 
     }
@@ -402,25 +423,32 @@
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
         verifyAndReset();
 
+        // bootstrap with full polling event to prime stats
+        performBootstrapPoll(TEST_START, elapsedRealtime);
+
         // create some traffic
         elapsedRealtime += HOUR_IN_MILLIS;
         expectTime(TEST_START + elapsedRealtime);
         expectDefaultSettings();
         expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4128L, 258L, 544L, 34L));
-        expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+        expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 16L, 1L, 16L, 1L)
                 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 4096L, 258L, 512L, 32L)
                 .addValues(TEST_IFACE, UID_GREEN, TAG_NONE, 16L, 1L, 16L, 1L));
 
+        mService.incrementOperationCount(UID_RED, TAG_NONE, 10);
+        mService.incrementOperationCount(UID_BLUE, TAG_NONE, 15);
+        mService.incrementOperationCount(UID_GREEN, TAG_NONE, 5);
+
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify service recorded history
-        assertNetworkTotal(sTemplateWifi, 4128L, 544L);
-        assertUidTotal(sTemplateWifi, UID_RED, 16L, 16L);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 512L);
-        assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 16L);
+        assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
+        assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
+        assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 15);
+        assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 5);
         verifyAndReset();
 
         // now pretend two UIDs are uninstalled, which should migrate stats to
@@ -435,11 +463,11 @@
 
         // existing uid and total should remain unchanged; but removed UID
         // should be gone completely.
-        assertNetworkTotal(sTemplateWifi, 4128L, 544L);
-        assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L);
-        assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 16L);
-        assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 528L);
+        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, 5);
+        assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 25);
         verifyAndReset();
 
     }
@@ -457,20 +485,26 @@
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
         verifyAndReset();
 
+        // bootstrap with full polling event to prime stats
+        performBootstrapPoll(TEST_START, elapsedRealtime);
+
         // create some traffic
         elapsedRealtime += HOUR_IN_MILLIS;
         expectTime(TEST_START + elapsedRealtime);
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
-        expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+        expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 1024L, 8L, 1024L, 8L)
                 .addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L));
 
+        mService.incrementOperationCount(UID_RED, TAG_NONE, 10);
+        mService.incrementOperationCount(UID_RED, 0xF00D, 5);
+
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify service recorded history
-        assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 1024L);
+        assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 10);
         verifyAndReset();
 
         // now switch over to 4g network
@@ -479,7 +513,7 @@
         expectDefaultSettings();
         expectNetworkState(buildMobile4gState());
         expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
-        expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+        expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
 
         replay();
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -491,14 +525,16 @@
         expectTime(TEST_START + elapsedRealtime);
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
-        expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+        expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L));
 
+        mService.incrementOperationCount(UID_RED, TAG_NONE, 5);
+
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify that ALL_MOBILE template combines both
-        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 1280L);
+        assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 15);
 
         verifyAndReset();
 
@@ -537,32 +573,41 @@
         mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
         verifyAndReset();
 
+        // bootstrap with full polling event to prime stats
+        performBootstrapPoll(TEST_START, elapsedRealtime);
+
         // create some traffic for two apps
         elapsedRealtime += HOUR_IN_MILLIS;
         expectTime(TEST_START + elapsedRealtime);
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
-        expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+        expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L)
                 .addValues(TEST_IFACE, UID_RED, 0xF00D, 10L, 1L, 10L, 1L)
                 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L));
 
+        mService.incrementOperationCount(UID_RED, TAG_NONE, 5);
+        mService.incrementOperationCount(UID_RED, 0xF00D, 1);
+        mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10);
+
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
         // verify service recorded history
-        assertUidTotal(sTemplateWifi, UID_RED, 50L, 50L);
-        assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 512L);
+        assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 5);
+        assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 10);
         verifyAndReset();
-        
+
         // now create more traffic in next hour, but only for one app
         elapsedRealtime += HOUR_IN_MILLIS;
         expectTime(TEST_START + elapsedRealtime);
         expectDefaultSettings();
         expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
-        expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+        expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
                 .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L));
 
+        mService.incrementOperationCount(UID_BLUE, TAG_NONE, 15);
+
         replay();
         mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
 
@@ -570,28 +615,32 @@
         NetworkStats stats = mService.getSummaryForAllUid(
                 sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
         assertEquals(3, stats.size());
-        assertValues(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L);
-        assertValues(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L);
-        assertValues(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L);
+        assertValues(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L, 5);
+        assertValues(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L, 1);
+        assertValues(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L, 15);
 
         // now verify that recent history only contains one uid
         final long currentTime = TEST_START + elapsedRealtime;
         stats = mService.getSummaryForAllUid(
                 sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
         assertEquals(1, stats.size());
-        assertValues(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L);
+        assertValues(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L, 5);
 
         verifyAndReset();
     }
 
-    private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long txBytes) {
+    private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
+            long txBytes, long txPackets, int operations) {
         final NetworkStatsHistory history = mService.getHistoryForNetwork(template);
-        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, txBytes);
+        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
+                txPackets, operations);
     }
 
-    private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long txBytes) {
+    private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
+            long txBytes, long txPackets, int operations) {
         final NetworkStatsHistory history = mService.getHistoryForUid(template, uid, TAG_NONE);
-        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, txBytes);
+        assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
+                txPackets, operations);
     }
 
     private void expectSystemReady() throws Exception {
@@ -611,8 +660,8 @@
         expect(mNetManager.getNetworkStatsSummary()).andReturn(summary).atLeastOnce();
     }
 
-    private void expectNetworkStatsDetail(NetworkStats detail) throws Exception {
-        expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
+    private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
+        expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
     }
 
     private void expectDefaultSettings() throws Exception {
@@ -639,6 +688,17 @@
         expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
     }
 
+    private void performBootstrapPoll(long testStart, long elapsedRealtime) throws Exception {
+        expectTime(testStart + elapsedRealtime);
+        expectDefaultSettings();
+        expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
+        expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
+
+        replay();
+        mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+        verifyAndReset();
+    }
+
     private void assertStatsFilesExist(boolean exist) {
         final File networkFile = new File(mStatsDir, "netstats.bin");
         final File uidFile = new File(mStatsDir, "netstats_uid.bin");
@@ -652,23 +712,26 @@
     }
 
     private static void assertValues(NetworkStats stats, int i, String iface, int uid, int tag,
-            long rxBytes, long rxPackets, long txBytes, long txPackets) {
+            long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
         final NetworkStats.Entry entry = stats.getValues(i, null);
-        assertEquals(iface, entry.iface);
-        assertEquals(uid, entry.uid);
-        assertEquals(tag, entry.tag);
-        assertEquals(rxBytes, entry.rxBytes);
-        // TODO: enable testing packet counts once stored in history
-//        assertEquals(rxPackets, entry.rxPackets);
-        assertEquals(txBytes, entry.txBytes);
-//        assertEquals(txPackets, entry.txPackets);
+        assertEquals("unexpected iface", iface, entry.iface);
+        assertEquals("unexpected uid", uid, entry.uid);
+        assertEquals("unexpected tag", tag, entry.tag);
+        assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
+        assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+        assertEquals("unexpected operations", operations, entry.operations);
     }
 
-    private static void assertValues(
-            NetworkStatsHistory stats, long start, long end, long rxBytes, long txBytes) {
+    private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
+            long rxPackets, long txBytes, long txPackets, int operations) {
         final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
         assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+        assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
         assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+        assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+        assertEquals("unexpected operations", operations, entry.operations);
     }
 
     private static NetworkState buildWifiState() {