Network stats with varint, omit parcel fields.

Persist NetworkStatsHistory using variable-length encoding; since
most buckets have small numbers, we can encode them tighter. Initial
test showed 44% space savings. Also persist packet and operation
counters.

Let NetworkStatsHistory consumers request which fields they actually
need to reduce parcel overhead.

Tests for verify varint and history field requests, also verify end-
to-end by persisting history into byte[] and restoring. Expose
bandwidth control enabled state. Extend random generation to create
packet and operation counts. Moved operation counts to long.

Fix bug that miscalculated bytes since last persist, which would
cause partial stats loss when battery pulled.

Bug: 4581977, 5023706, 5023635, 5096903
Change-Id: If61e89f681ffa11fe5711471fd9f7c238d3d37b0
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 0e8e7fc..f2fcb8f 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -58,7 +58,7 @@
     private long[] rxPackets;
     private long[] txBytes;
     private long[] txPackets;
-    private int[] operations;
+    private long[] operations;
 
     public static class Entry {
         public String iface;
@@ -68,13 +68,18 @@
         public long rxPackets;
         public long txBytes;
         public long txPackets;
-        public int operations;
+        public long operations;
 
         public Entry() {
+            this(IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
+        }
+
+        public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
+            this(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, operations);
         }
 
         public Entry(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes,
-                long txPackets, int operations) {
+                long txPackets, long operations) {
             this.iface = iface;
             this.uid = uid;
             this.tag = tag;
@@ -96,7 +101,7 @@
         this.rxPackets = new long[initialSize];
         this.txBytes = new long[initialSize];
         this.txPackets = new long[initialSize];
-        this.operations = new int[initialSize];
+        this.operations = new long[initialSize];
     }
 
     public NetworkStats(Parcel parcel) {
@@ -109,7 +114,7 @@
         rxPackets = parcel.createLongArray();
         txBytes = parcel.createLongArray();
         txPackets = parcel.createLongArray();
-        operations = parcel.createIntArray();
+        operations = parcel.createLongArray();
     }
 
     /** {@inheritDoc} */
@@ -123,16 +128,16 @@
         dest.writeLongArray(rxPackets);
         dest.writeLongArray(txBytes);
         dest.writeLongArray(txPackets);
-        dest.writeIntArray(operations);
+        dest.writeLongArray(operations);
     }
 
     public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
             long txBytes, long txPackets) {
-        return addValues(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, 0);
+        return addValues(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, 0L);
     }
 
     public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
-            long txBytes, long txPackets, int operations) {
+            long txBytes, long txPackets, long operations) {
         return addValues(
                 new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
     }
@@ -197,7 +202,7 @@
     }
 
     public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
-            long txBytes, long txPackets, int operations) {
+            long txBytes, long txPackets, long operations) {
         return combineValues(
                 new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
     }