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

Commit 5409264c authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by android-build-merger
Browse files

Merge "Remove all static members from NetworkStatsFactory."

am: 63f94f41

Change-Id: I4657796f2c2083d11e8a0de75c6b61e0443a7015
parents 2778916c 63f94f41
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -67,7 +67,8 @@ interface INetworkStatsService {
    void forceUpdateIfaces(
         in Network[] defaultNetworks,
         in NetworkState[] networkStates,
         in String activeIface);
         in String activeIface,
         in VpnInfo[] vpnInfos);
    /** Force update of statistics. */
    @UnsupportedAppUsage
    void forceUpdate();
+4 −9
Original line number Diff line number Diff line
@@ -192,7 +192,6 @@ import com.android.server.net.BaseNetdEventCallback;
import com.android.server.net.BaseNetworkObserver;
import com.android.server.net.LockdownVpnTracker;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.net.NetworkStatsFactory;
import com.android.server.utils.PriorityDump;

import com.google.android.collect.Lists;
@@ -6800,8 +6799,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
    }

    /**
     * Notify NetworkStatsService and NetworkStatsFactory that the set of active ifaces has changed,
     * or that one of the active iface's trackedproperties has changed.
     * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
     * active iface's tracked properties has changed.
     */
    private void notifyIfacesChangedForNetworkStats() {
        ensureRunningOnConnectivityServiceThread();
@@ -6811,16 +6810,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
            activeIface = activeLinkProperties.getInterfaceName();
        }

        // CAUTION: Ordering matters between updateVpnInfos() and forceUpdateIfaces(), which
        // triggers a new poll. Trigger the poll first to ensure a snapshot is taken before
        // switching to the new state. This ensures that traffic does not get mis-attributed to
        // incorrect apps (including VPN app).
        final VpnInfo[] vpnInfos = getAllVpnInfo();
        try {
            mStatsService.forceUpdateIfaces(
                    getDefaultNetworks(), getAllNetworkState(), activeIface);
                    getDefaultNetworks(), getAllNetworkState(), activeIface, vpnInfos);
        } catch (Exception ignored) {
        }
        NetworkStatsFactory.updateVpnInfos(getAllVpnInfo());
    }

    @Override
+20 −29
Original line number Diff line number Diff line
@@ -78,17 +78,17 @@ public class NetworkStatsFactory {
     * <p>In order to prevent deadlocks, critical sections protected by this lock SHALL NOT call out
     * to other code that will acquire other locks within the system server. See b/134244752.
     */
    private static final Object sPersistentDataLock = new Object();
    private final Object mPersistentDataLock = new Object();

    /** Set containing info about active VPNs and their underlying networks. */
    private static volatile VpnInfo[] sVpnInfos = new VpnInfo[0];
    private volatile VpnInfo[] mVpnInfos = new VpnInfo[0];

    // A persistent snapshot of cumulative stats since device start
    @GuardedBy("sPersistentDataLock")
    @GuardedBy("mPersistentDataLock")
    private NetworkStats mPersistSnapshot;

    // The persistent snapshot of tun and 464xlat adjusted stats since device start
    @GuardedBy("sPersistentDataLock")
    @GuardedBy("mPersistentDataLock")
    private NetworkStats mTunAnd464xlatAdjustedStats;

    /**
@@ -97,12 +97,13 @@ public class NetworkStatsFactory {
     * Because counters must never roll backwards, once a given interface is stacked on top of an
     * underlying interface, the stacked interface can never be stacked on top of
     * another interface. */
    private static final ConcurrentHashMap<String, String> sStackedIfaces
    private final ConcurrentHashMap<String, String> mStackedIfaces
            = new ConcurrentHashMap<>();

    public static void noteStackedIface(String stackedIface, String baseIface) {
    /** Informs the factory of a new stacked interface. */
    public void noteStackedIface(String stackedIface, String baseIface) {
        if (stackedIface != null && baseIface != null) {
            sStackedIfaces.put(stackedIface, baseIface);
            mStackedIfaces.put(stackedIface, baseIface);
        }
    }

@@ -115,13 +116,8 @@ public class NetworkStatsFactory {
     *
     * @param vpnArray The snapshot of the currently-running VPNs.
     */
    public static void updateVpnInfos(VpnInfo[] vpnArray) {
        sVpnInfos = vpnArray.clone();
    }

    @VisibleForTesting
    public static VpnInfo[] getVpnInfos() {
        return sVpnInfos.clone();
    public void updateVpnInfos(VpnInfo[] vpnArray) {
        mVpnInfos = vpnArray.clone();
    }

    /**
@@ -132,7 +128,7 @@ public class NetworkStatsFactory {
     * {@link #noteStackedIface(String, String)}, but only interfaces noted before this method
     * is called are guaranteed to be included.
     */
    public static String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) {
    public String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) {
        if (requiredIfaces == NetworkStats.INTERFACES_ALL) {
            return null;
        }
@@ -142,7 +138,7 @@ public class NetworkStatsFactory {
        // elements as they existed upon construction exactly once, and may
        // (but are not guaranteed to) reflect any modifications subsequent to construction".
        // This is enough here.
        for (Map.Entry<String, String> entry : sStackedIfaces.entrySet()) {
        for (Map.Entry<String, String> entry : mStackedIfaces.entrySet()) {
            if (relatedIfaces.contains(entry.getKey())) {
                relatedIfaces.add(entry.getValue());
            } else if (relatedIfaces.contains(entry.getValue())) {
@@ -158,17 +154,12 @@ public class NetworkStatsFactory {
     * Applies 464xlat adjustments with ifaces noted with {@link #noteStackedIface(String, String)}.
     * @see NetworkStats#apply464xlatAdjustments(NetworkStats, NetworkStats, Map, boolean)
     */
    public static void apply464xlatAdjustments(NetworkStats baseTraffic,
    public void apply464xlatAdjustments(NetworkStats baseTraffic,
            NetworkStats stackedTraffic, boolean useBpfStats) {
        NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, sStackedIfaces,
        NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, mStackedIfaces,
                useBpfStats);
    }

    @VisibleForTesting
    public static void clearStackedIfaces() {
        sStackedIfaces.clear();
    }

    public NetworkStatsFactory() {
        this(new File("/proc/"), new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists());
    }
@@ -179,7 +170,7 @@ public class NetworkStatsFactory {
        mStatsXtIfaceFmt = new File(procRoot, "net/xt_qtaguid/iface_stat_fmt");
        mStatsXtUid = new File(procRoot, "net/xt_qtaguid/stats");
        mUseBpfStats = useBpfStats;
        synchronized (sPersistentDataLock) {
        synchronized (mPersistentDataLock) {
            mPersistSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), -1);
            mTunAnd464xlatAdjustedStats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
        }
@@ -304,7 +295,7 @@ public class NetworkStatsFactory {
        return readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
    }

    @GuardedBy("sPersistentDataLock")
    @GuardedBy("mPersistentDataLock")
    private void requestSwapActiveStatsMapLocked() throws RemoteException {
        // Ask netd to do a active map stats swap. When the binder call successfully returns,
        // the system server should be able to safely read and clean the inactive map
@@ -328,9 +319,9 @@ public class NetworkStatsFactory {
            int limitUid, String[] limitIfaces, int limitTag) throws IOException {
        // In order to prevent deadlocks, anything protected by this lock MUST NOT call out to other
        // code that will acquire other locks within the system server. See b/134244752.
        synchronized (sPersistentDataLock) {
        synchronized (mPersistentDataLock) {
            // Take a reference. If this gets swapped out, we still have the old reference.
            final VpnInfo[] vpnArray = sVpnInfos;
            final VpnInfo[] vpnArray = mVpnInfos;
            // Take a defensive copy. mPersistSnapshot is mutated in some cases below
            final NetworkStats prev = mPersistSnapshot.clone();

@@ -379,7 +370,7 @@ public class NetworkStatsFactory {
        }
    }

    @GuardedBy("sPersistentDataLock")
    @GuardedBy("mPersistentDataLock")
    private NetworkStats adjustForTunAnd464Xlat(
            NetworkStats uidDetailStats, NetworkStats previousStats, VpnInfo[] vpnArray) {
        // Calculate delta from last snapshot
@@ -389,7 +380,7 @@ public class NetworkStatsFactory {
        // network, the overhead is their fault.
        // No locking here: apply464xlatAdjustments behaves fine with an add-only
        // ConcurrentHashMap.
        delta.apply464xlatAdjustments(sStackedIfaces, mUseBpfStats);
        delta.apply464xlatAdjustments(mStackedIfaces, mUseBpfStats);

        // Migrate data usage over a VPN to the TUN network.
        for (VpnInfo info : vpnArray) {
+11 −4
Original line number Diff line number Diff line
@@ -130,6 +130,7 @@ import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FileRotator;
@@ -777,7 +778,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
        try {
            final String[] ifacesToQuery =
                    NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
                    mStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
            return getNetworkStatsUidDetail(ifacesToQuery);
        } catch (RemoteException e) {
            Log.wtf(TAG, "Error compiling UID stats", e);
@@ -829,7 +830,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    public void forceUpdateIfaces(
            Network[] defaultNetworks,
            NetworkState[] networkStates,
            String activeIface) {
            String activeIface,
            VpnInfo[] vpnInfos) {
        checkNetworkStackPermission(mContext);

        final long token = Binder.clearCallingIdentity();
@@ -838,6 +840,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        } finally {
            Binder.restoreCallingIdentity(token);
        }

        // Update the VPN underlying interfaces only after the poll is made and tun data has been
        // migrated. Otherwise the migration would use the new interfaces instead of the ones that
        // were current when the polled data was transferred.
        mStatsFactory.updateVpnInfos(vpnInfos);
    }

    @Override
@@ -1649,7 +1656,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        // fold tethering stats and operations into uid snapshot
        final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
        tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
        NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
        mStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
                mUseBpfTrafficStats);
        uidSnapshot.combineAllValues(tetherSnapshot);

@@ -1660,7 +1667,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
        if (vtStats != null) {
            vtStats.filter(UID_ALL, ifaces, TAG_ALL);
            NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats,
            mStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats,
                    mUseBpfTrafficStats);
            uidSnapshot.combineAllValues(vtStats);
        }
+14 −36
Original line number Diff line number Diff line
@@ -205,7 +205,6 @@ import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.android.server.net.NetworkPinner;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.net.NetworkStatsFactory;
import com.android.testutils.HandlerUtilsKt;
import com.android.testutils.ThrowingConsumer;

@@ -4882,11 +4881,8 @@ public class ConnectivityServiceTest {
        mCellNetworkAgent.sendLinkProperties(cellLp);
        waitForIdle();
        verify(mStatsService, atLeastOnce())
                .forceUpdateIfaces(
                        eq(onlyCell),
                        any(NetworkState[].class),
                        eq(MOBILE_IFNAME));
        assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
                        eq(new VpnInfo[0]));
        reset(mStatsService);

        // Default network switch should update ifaces.
@@ -4895,65 +4891,47 @@ public class ConnectivityServiceTest {
        waitForIdle();
        assertEquals(wifiLp, mService.getActiveLinkProperties());
        verify(mStatsService, atLeastOnce())
                .forceUpdateIfaces(
                        eq(onlyWifi),
                        any(NetworkState[].class),
                        eq(WIFI_IFNAME));
        assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
                .forceUpdateIfaces(eq(onlyWifi), any(NetworkState[].class), eq(WIFI_IFNAME),
                        eq(new VpnInfo[0]));
        reset(mStatsService);

        // Disconnect should update ifaces.
        mWiFiNetworkAgent.disconnect();
        waitForIdle();
        verify(mStatsService, atLeastOnce())
                .forceUpdateIfaces(
                        eq(onlyCell),
                        any(NetworkState[].class),
                        eq(MOBILE_IFNAME));
        assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class),
                        eq(MOBILE_IFNAME), eq(new VpnInfo[0]));
        reset(mStatsService);

        // Metered change should update ifaces
        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        waitForIdle();
        verify(mStatsService, atLeastOnce())
                .forceUpdateIfaces(
                        eq(onlyCell),
                        any(NetworkState[].class),
                        eq(MOBILE_IFNAME));
        assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
                        eq(new VpnInfo[0]));
        reset(mStatsService);

        mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        waitForIdle();
        verify(mStatsService, atLeastOnce())
                .forceUpdateIfaces(
                        eq(onlyCell),
                        any(NetworkState[].class),
                        eq(MOBILE_IFNAME));
        assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
                        eq(new VpnInfo[0]));
        reset(mStatsService);

        // Captive portal change shouldn't update ifaces
        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
        waitForIdle();
        verify(mStatsService, never())
                .forceUpdateIfaces(
                        eq(onlyCell),
                        any(NetworkState[].class),
                        eq(MOBILE_IFNAME));
        assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
                        eq(new VpnInfo[0]));
        reset(mStatsService);

        // Roaming change should update ifaces
        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
        waitForIdle();
        verify(mStatsService, atLeastOnce())
                .forceUpdateIfaces(
                        eq(onlyCell),
                        any(NetworkState[].class),
                        eq(MOBILE_IFNAME));
        assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
                .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
                        eq(new VpnInfo[0]));
        reset(mStatsService);
    }

Loading