Collect historical network stats.

Periodically records delta network traffic into historical buckets to
support other services, such NetworkPolicyManager and Settings UI.

Introduces NetworkStatsHistory structure which contains sparse, uniform
buckets of data usage defined by timestamps.  Service periodically
polls NetworkStats and records changes into buckets.  It only persists
to disk when substantial changes have occured.  Current parameters
create 4 buckets each day, and persist for 90 days, resulting in about
8kB of data per network.

Only records stats for "well known" network interfaces that have been
claimed by Telephony or Wi-Fi subsystems.  Historical stats are also
keyed off identity (such as IMSI) to support SIM swapping.

Change-Id: Ia27d1289556a2bf9545fbc4f3b789425a01be53a
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4cd601f..596cbac 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -49,6 +49,7 @@
 import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.net.NetworkPolicyManagerService;
+import com.android.server.net.NetworkStatsService;
 import com.android.server.pm.PackageManagerService;
 import com.android.server.usb.UsbService;
 import com.android.server.wm.WindowManagerService;
@@ -116,7 +117,9 @@
         LightsService lights = null;
         PowerManagerService power = null;
         BatteryService battery = null;
+        AlarmManagerService alarm = null;
         NetworkManagementService networkManagement = null;
+        NetworkStatsService networkStats = null;
         NetworkPolicyManagerService networkPolicy = null;
         ConnectivityService connectivity = null;
         IPackageManager pm = null;
@@ -188,7 +191,7 @@
             power.init(context, lights, ActivityManagerService.getDefault(), battery);
 
             Slog.i(TAG, "Alarm Manager");
-            AlarmManagerService alarm = new AlarmManagerService(context);
+            alarm = new AlarmManagerService(context);
             ServiceManager.addService(Context.ALARM_SERVICE, alarm);
 
             Slog.i(TAG, "Init Watchdog");
@@ -274,22 +277,6 @@
             }
 
             try {
-                Slog.i(TAG, "NetStat Service");
-                ServiceManager.addService("netstat", new NetStatService(context));
-            } catch (Throwable e) {
-                Slog.e(TAG, "Failure starting NetStat Service", e);
-            }
-
-            try {
-                Slog.i(TAG, "NetworkPolicy Service");
-                networkPolicy = new NetworkPolicyManagerService(
-                        context, ActivityManagerService.self(), power);
-                ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
-            } catch (Throwable e) {
-                Slog.e(TAG, "Failure starting Connectivity Service", e);
-            }
-
-            try {
                 Slog.i(TAG, "NetworkManagement Service");
                 networkManagement = NetworkManagementService.create(context);
                 ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
@@ -298,6 +285,23 @@
             }
 
             try {
+                Slog.i(TAG, "NetworkStats Service");
+                networkStats = new NetworkStatsService(context, networkManagement, alarm);
+                ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
+            } catch (Throwable e) {
+                Slog.e(TAG, "Failure starting NetworkStats Service", e);
+            }
+
+            try {
+                Slog.i(TAG, "NetworkPolicy Service");
+                networkPolicy = new NetworkPolicyManagerService(
+                        context, ActivityManagerService.self(), power, networkStats);
+                ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
+            } catch (Throwable e) {
+                Slog.e(TAG, "Failure starting NetworkPolicy Service", e);
+            }
+
+            try {
                 Slog.i(TAG, "Connectivity Service");
                 connectivity = new ConnectivityService(context, networkManagement, networkPolicy);
                 ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
@@ -535,6 +539,7 @@
         // These are needed to propagate to the runnable below.
         final Context contextF = context;
         final BatteryService batteryF = battery;
+        final NetworkStatsService networkStatsF = networkStats;
         final NetworkPolicyManagerService networkPolicyF = networkPolicy;
         final ConnectivityService connectivityF = connectivity;
         final DockObserver dockF = dock;
@@ -561,6 +566,7 @@
 
                 startSystemUi(contextF);
                 if (batteryF != null) batteryF.systemReady();
+                if (networkStatsF != null) networkStatsF.systemReady();
                 if (networkPolicyF != null) networkPolicyF.systemReady();
                 if (connectivityF != null) connectivityF.systemReady();
                 if (dockF != null) dockF.systemReady();