Better network stats parsing, integer tags, async.

Change NMS parsing to handle extended /proc/ stats formats by pairing
values with header keys.  Move TrafficStats to integer tags to match
kernel internals, and offer well-known tags for system services.

Async policy event dispatch from NPMS, and update tests to block for
event dispatch.  Narrow app policy to exclude apps signed with system
key, which are usually critical.

Bug: 4948913, 4903489, 4585280

Change-Id: Idb357227ccaa617906411f309371cea18d7bc519
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index cb47193..040489e 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -16,7 +16,10 @@
 
 package android.net;
 
+import android.app.DownloadManager;
+import android.app.backup.BackupManager;
 import android.content.Context;
+import android.media.MediaPlayer;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.RemoteException;
@@ -50,6 +53,27 @@
     public static final int UID_REMOVED = -4;
 
     /**
+     * Default tag value for {@link DownloadManager} traffic.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_DOWNLOAD = 0xFFFF0001;
+
+    /**
+     * Default tag value for {@link MediaPlayer} traffic.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_MEDIA = 0xFFFF0002;
+
+    /**
+     * Default tag value for {@link BackupManager} traffic.
+     *
+     * @hide
+     */
+    public static final int TAG_SYSTEM_BACKUP = 0xFFFF0003;
+
+    /**
      * Snapshot of {@link NetworkStats} when the currently active profiling
      * session started, or {@code null} if no session active.
      *
@@ -67,12 +91,20 @@
      * Changes only take effect during subsequent calls to
      * {@link #tagSocket(Socket)}.
      */
-    public static void setThreadStatsTag(String tag) {
+    public static void setThreadStatsTag(int tag) {
         BlockGuard.setThreadSocketStatsTag(tag);
     }
 
+    /**
+     * @deprecated unsupported, will eventually be removed
+     */
+    @Deprecated
+    public static void setThreadStatsTag(String tag) {
+        setThreadStatsTag(tag.hashCode());
+    }
+
     public static void clearThreadStatsTag() {
-        BlockGuard.setThreadSocketStatsTag(null);
+        BlockGuard.setThreadSocketStatsTag(-1);
     }
 
     /**
@@ -103,7 +135,7 @@
      * parameters. When finished, call {@link #untagSocket(Socket)} to remove
      * statistics parameters.
      *
-     * @see #setThreadStatsTag(String)
+     * @see #setThreadStatsTag(int)
      * @see #setThreadStatsUid(int)
      */
     public static void tagSocket(Socket socket) throws SocketException {
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 4a79d17..7610a11 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -124,8 +124,6 @@
     private PendingIntent mPollIntent;
 
     // TODO: listen for kernel push events through netd instead of polling
-    // TODO: watch for UID uninstall, and transfer stats into single bucket
-
     // TODO: trim empty history objects entirely
 
     private static final long KB_IN_BYTES = 1024;
@@ -506,8 +504,11 @@
         try {
             networkSnapshot = mNetworkManager.getNetworkStatsSummary();
             uidSnapshot = detailedPoll ? mNetworkManager.getNetworkStatsDetail() : null;
+        } catch (IllegalStateException e) {
+            Slog.w(TAG, "problem reading network stats: " + e);
+            return;
         } catch (RemoteException e) {
-            Slog.w(TAG, "problem reading network stats");
+            Slog.w(TAG, "problem reading network stats: " + e);
             return;
         }