Merge "Fix the Preconditions dependency in EthernetNetworkSpecifier."
diff --git a/framework-t/src/android/net/TrafficStats.java b/framework-t/src/android/net/TrafficStats.java
index d8feb88..1af32bf 100644
--- a/framework-t/src/android/net/TrafficStats.java
+++ b/framework-t/src/android/net/TrafficStats.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -27,8 +28,8 @@
 import android.content.Context;
 import android.media.MediaPlayer;
 import android.os.Build;
+import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 
 import com.android.server.NetworkManagementSocketTagger;
 
@@ -36,6 +37,8 @@
 
 import java.io.FileDescriptor;
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.net.DatagramSocket;
 import java.net.Socket;
 import java.net.SocketException;
@@ -53,6 +56,7 @@
  * use {@link NetworkStatsManager} instead.
  */
 public class TrafficStats {
+    private static final String TAG = TrafficStats.class.getSimpleName();
     /**
      * The return value to indicate that the device does not support the statistic.
      */
@@ -173,12 +177,25 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
     private synchronized static INetworkStatsService getStatsService() {
         if (sStatsService == null) {
-            sStatsService = INetworkStatsService.Stub.asInterface(
-                    ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+            sStatsService = getStatsBinder();
         }
         return sStatsService;
     }
 
+    @Nullable
+    private static INetworkStatsService getStatsBinder() {
+        try {
+            final Method getServiceMethod = Class.forName("android.os.ServiceManager")
+                    .getDeclaredMethod("getService", new Class[]{String.class});
+            final IBinder binder = (IBinder) getServiceMethod.invoke(
+                    null, Context.NETWORK_STATS_SERVICE);
+            return INetworkStatsService.Stub.asInterface(binder);
+        } catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException
+                | InvocationTargetException e) {
+            throw new NullPointerException("Cannot get INetworkStatsService: " + e);
+        }
+    }
+
     /**
      * Snapshot of {@link NetworkStats} when the currently active profiling
      * session started, or {@code null} if no session active.
@@ -265,6 +282,18 @@
     }
 
     /**
+     * Set active tag to use when accounting {@link Socket} traffic originating
+     * from the current thread. The tag used internally is well-defined to
+     * distinguish all download provider traffic.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static void setThreadStatsTagDownload() {
+        setThreadStatsTag(TAG_SYSTEM_DOWNLOAD);
+    }
+
+    /**
      * Get the active tag used when accounting {@link Socket} traffic originating
      * from the current thread. Only one active tag per thread is supported.
      * {@link #tagSocket(Socket)}.