Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de9cf339 authored by Junyu Lai's avatar Junyu Lai Committed by junyulai
Browse files

[MS66] Initialize TrafficStats with context

TrafficStats has static methods created in API level 8 that need
access to NetworkStatsManager but doesn't take a context.
Previously this was achieved by using ServiceManager, but
with TrafficStats moving to the connectivity module, this
is no longer possible.

Instead, make sure TrafficStats has an appropriate context by
the time any client code can call the relevant methods.
• In app code, this achieved by passing the application
  context from ActivityThread#handleBindApplication, before any
  app code can run.
• In the system server, this is achieved by passing the context
  right after creating service.

Test: atest TrafficStatsTest CtsWebkitTestCases
Bug: 204830222

Change-Id: I251bb8a4431ad12ff61929879ef1363cf06b9244
parent 139e007d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -317,6 +317,10 @@ package android.net {
    method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo);
  }

  public class TrafficStats {
    method public static void init(@NonNull android.content.Context);
  }

  public final class UnderlyingNetworkInfo implements android.os.Parcelable {
    ctor public UnderlyingNetworkInfo(int, @NonNull String, @NonNull java.util.List<java.lang.String>);
    method public int describeContents();
+8 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ import android.media.MediaFrameworkPlatformInitializer;
import android.media.MediaServiceManager;
import android.net.ConnectivityManager;
import android.net.Proxy;
import android.net.TrafficStats;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
@@ -6663,6 +6664,13 @@ public final class ActivityThread extends ClientTransactionHandler
        NetworkSecurityConfigProvider.install(appContext);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        // For backward compatibility, TrafficStats needs static access to the application context.
        // But for isolated apps which cannot access network related services, service discovery
        // is restricted. Hence, calling this would result in NPE.
        if (!Process.isIsolated()) {
            TrafficStats.init(appContext);
        }

        // Continue loading instrumentation.
        if (ii != null) {
            initInstrumentation(ii, data, appContext);
+5 −0
Original line number Diff line number Diff line
@@ -157,6 +157,11 @@ public class NetworkStatsManager {
        setAugmentWithSubscriptionPlan(true);
    }

    /** @hide */
    public INetworkStatsService getBinder() {
        return mService;
    }

    /**
     * Set poll on open flag to indicate the poll is needed before service gets statistics
     * result. This is default enabled. However, for any non-privileged caller, the poll might
+23 −19
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
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 +26,8 @@ import android.app.usage.NetworkStatsManager;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;

import com.android.server.NetworkManagementSocketTagger;
@@ -37,8 +36,6 @@ import dalvik.system.SocketTagger;

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;
@@ -177,25 +174,12 @@ public class TrafficStats {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
    private synchronized static INetworkStatsService getStatsService() {
        if (sStatsService == null) {
            sStatsService = getStatsBinder();
            throw new IllegalStateException("TrafficStats not initialized, uid="
                    + Binder.getCallingUid());
        }
        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.
@@ -209,6 +193,26 @@ public class TrafficStats {

    private static final String LOOPBACK_IFACE = "lo";

    /**
     * Initialization {@link TrafficStats} with the context, to
     * allow {@link TrafficStats} to fetch the needed binder.
     *
     * @param context a long-lived context, such as the application context or system
     *                server context.
     * @hide
     */
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @SuppressLint("VisiblySynchronized")
    public static synchronized void init(@NonNull final Context context) {
        if (sStatsService != null) {
            throw new IllegalStateException("TrafficStats is already initialized, uid="
                    + Binder.getCallingUid());
        }
        final NetworkStatsManager statsManager =
                context.getSystemService(NetworkStatsManager.class);
        sStatsService = statsManager.getBinder();
    }

    /**
     * Set active tag to use when accounting {@link Socket} traffic originating
     * from the current thread. Only one active tag per thread is supported.
+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import android.hardware.display.DisplayManagerInternal;
import android.net.ConnectivityManager;
import android.net.ConnectivityModuleConnector;
import android.net.NetworkStackClient;
import android.net.TrafficStats;
import android.os.BaseBundle;
import android.os.Binder;
import android.os.Build;
@@ -1838,6 +1839,7 @@ public final class SystemServer implements Dumpable {
            try {
                networkStats = NetworkStatsService.create(context);
                ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
                TrafficStats.init(context);
            } catch (Throwable e) {
                reportWtf("starting NetworkStats Service", e);
            }