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

Commit 63f94f41 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Gerrit Code Review
Browse files

Merge "Remove all static members from NetworkStatsFactory."

parents ecf4d593 4aa8760a
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