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

Commit c78da293 authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

Pass all default networks to NetworkStatsService

This will allow NetworkStatsService to treat traffic on these
networks differently from traffic where the app selects a network
that is not the default.

Bug: 35142602
Test: runtest frameworks-net
Change-Id: I5ea9d200d9fb153490c6108bb9390bf152f297da
parent a3bf36f0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.net;

import android.net.DataUsageRequest;
import android.net.INetworkStatsSession;
import android.net.Network;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
@@ -53,7 +54,7 @@ interface INetworkStatsService {
    void setUidForeground(int uid, boolean uidForeground);

    /** Force update of ifaces. */
    void forceUpdateIfaces();
    void forceUpdateIfaces(in Network[] defaultNetworks);
    /** Force update of statistics. */
    void forceUpdate();

+22 −2
Original line number Diff line number Diff line
@@ -4962,10 +4962,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
        } catch (Exception e) {
            loge("Exception setting default network :" + e);
        }

        notifyLockdownVpn(newNetwork);
        handleApplyDefaultProxy(newNetwork.linkProperties.getHttpProxy());
        updateTcpBufferSizes(newNetwork);
        mDnsManager.setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers());
        notifyIfacesChangedForNetworkStats();
    }

    private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) {
@@ -5538,13 +5540,31 @@ public class ConnectivityService extends IConnectivityManager.Stub
        notifyNetworkCallbacks(networkAgent, notifyType, 0);
    }

    /**
     * Returns the list of all interfaces that could be used by network traffic that does not
     * explicitly specify a network. This includes the default network, but also all VPNs that are
     * currently connected.
     *
     * Must be called on the handler thread.
     */
    private Network[] getDefaultNetworks() {
        ArrayList<Network> defaultNetworks = new ArrayList<>();
        NetworkAgentInfo defaultNetwork = getDefaultNetwork();
        for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
            if (nai.everConnected && (nai == defaultNetwork || nai.isVPN())) {
                defaultNetworks.add(nai.network);
            }
        }
        return defaultNetworks.toArray(new Network[0]);
    }

    /**
     * Notify NetworkStatsService that the set of active ifaces has changed, or that one of the
     * properties tracked by NetworkStatsService on an active iface has changed.
     */
    private void notifyIfacesChangedForNetworkStats() {
        try {
            mStatsService.forceUpdateIfaces();
            mStatsService.forceUpdateIfaces(getDefaultNetworks());
        } catch (Exception ignored) {
        }
    }
@@ -5576,7 +5596,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
            success = mVpns.get(user).setUnderlyingNetworks(networks);
        }
        if (success) {
            notifyIfacesChangedForNetworkStats();
            mHandler.post(() -> notifyIfacesChangedForNetworkStats());
        }
        return success;
    }
+21 −6
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ import android.net.INetworkManagementEventObserver;
import android.net.INetworkStatsService;
import android.net.INetworkStatsSession;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkIdentity;
import android.net.NetworkInfo;
@@ -231,14 +232,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    private final Object mStatsLock = new Object();

    /** Set of currently active ifaces. */
    @GuardedBy("mStatsLock")
    private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();

    /** Set of currently active ifaces for UID stats. */
    @GuardedBy("mStatsLock")
    private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();

    /** Current default active iface. */
    private String mActiveIface;

    /** Set of any ifaces associated with mobile networks since boot. */
    @GuardedBy("mStatsLock")
    private String[] mMobileIfaces = new String[0];

    /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
    @GuardedBy("mStatsLock")
    private Network[] mDefaultNetworks = new Network[0];

    private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
            new DropBoxNonMonotonicObserver();

@@ -779,13 +790,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
    }

    @Override
    public void forceUpdateIfaces() {
    public void forceUpdateIfaces(Network[] defaultNetworks) {
        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
        assertBandwidthControlEnabled();

        final long token = Binder.clearCallingIdentity();
        try {
            updateIfaces();
            updateIfaces(defaultNetworks);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
@@ -996,11 +1007,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        }
    };

    private void updateIfaces() {
    private void updateIfaces(Network[] defaultNetworks) {
        synchronized (mStatsLock) {
            mWakeLock.acquire();
            try {
                updateIfacesLocked();
                updateIfacesLocked(defaultNetworks);
            } finally {
                mWakeLock.release();
            }
@@ -1013,7 +1024,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
     * are active on a single {@code iface}, they are combined under a single
     * {@link NetworkIdentitySet}.
     */
    private void updateIfacesLocked() {
    private void updateIfacesLocked(Network[] defaultNetworks) {
        if (!mSystemReady) return;
        if (LOGV) Slog.v(TAG, "updateIfacesLocked()");

@@ -1040,6 +1051,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
        // Rebuild active interfaces based on connected networks
        mActiveIfaces.clear();
        mActiveUidIfaces.clear();
        if (defaultNetworks != null) {
            // Caller is ConnectivityService. Update the list of default networks.
            mDefaultNetworks = defaultNetworks;
        }

        final ArraySet<String> mobileIfaces = new ArraySet<>();
        for (NetworkState state : states) {
@@ -1511,7 +1526,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
                    return true;
                }
                case MSG_UPDATE_IFACES: {
                    mService.updateIfaces();
                    mService.updateIfaces(null);
                    return true;
                }
                case MSG_REGISTER_GLOBAL_ALERT: {
+21 −5
Original line number Diff line number Diff line
@@ -3501,34 +3501,50 @@ public class ConnectivityServiceTest {
    @Test
    public void testStatsIfacesChanged() throws Exception {
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);

        Network[] onlyCell = new Network[]{mCellNetworkAgent.getNetwork()};
        Network[] onlyWifi = new Network[]{mWiFiNetworkAgent.getNetwork()};

        // Simple connection should have updated ifaces
        mCellNetworkAgent.connect(false);
        waitForIdle();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces(onlyCell);
        reset(mStatsService);

        // Default network switch should update ifaces.
        mWiFiNetworkAgent.connect(false);
        waitForIdle();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces(onlyWifi);
        reset(mStatsService);

        // Disconnect should update ifaces.
        mWiFiNetworkAgent.disconnect();
        waitForIdle();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces(onlyCell);
        reset(mStatsService);

        // Metered change should update ifaces
        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        waitForIdle();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces(onlyCell);
        reset(mStatsService);

        mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
        waitForIdle();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces(onlyCell);
        reset(mStatsService);

        // Captive portal change shouldn't update ifaces
        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
        waitForIdle();
        verify(mStatsService, never()).forceUpdateIfaces();
        verify(mStatsService, never()).forceUpdateIfaces(onlyCell);
        reset(mStatsService);

        // Roaming change should update ifaces
        mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
        waitForIdle();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces();
        verify(mStatsService, atLeastOnce()).forceUpdateIfaces(onlyCell);
        reset(mStatsService);
    }

+24 −17
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
import android.net.INetworkStatsSession;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
@@ -136,6 +137,12 @@ public class NetworkStatsServiceTest {
    private static final int UID_BLUE = 1002;
    private static final int UID_GREEN = 1003;


    private static final Network WIFI_NETWORK =  new Network(100);
    private static final Network MOBILE_NETWORK =  new Network(101);
    private static final Network[] NETWORKS_WIFI = new Network[]{ WIFI_NETWORK };
    private static final Network[] NETWORKS_MOBILE = new Network[]{ MOBILE_NETWORK };

    private static final long WAIT_TIMEOUT = 2 * 1000;  // 2 secs
    private static final int INVALID_TYPE = -1;

@@ -231,7 +238,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_WIFI);

        // verify service has empty history for wifi
        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -278,7 +285,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_WIFI);

        // verify service has empty history for wifi
        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -356,7 +363,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_WIFI);


        // modify some number on wifi, and trigger poll event
@@ -401,7 +408,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_MOBILE);


        // create some traffic on first network
@@ -439,7 +446,7 @@ public class NetworkStatsServiceTest {
                .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_MOBILE);
        forcePollAndWaitForIdle();


@@ -481,7 +488,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_WIFI);


        // create some traffic
@@ -543,7 +550,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_MOBILE);


        // create some traffic
@@ -573,7 +580,7 @@ public class NetworkStatsServiceTest {
                .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_MOBILE);
        forcePollAndWaitForIdle();


@@ -605,7 +612,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_WIFI);


        // create some traffic for two apps
@@ -667,7 +674,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_WIFI);


        // create some initial traffic
@@ -728,7 +735,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_WIFI);


        // create some initial traffic
@@ -770,7 +777,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_MOBILE);


        // Create some traffic
@@ -811,7 +818,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_MOBILE);


        // create some tethering traffic
@@ -856,7 +863,7 @@ public class NetworkStatsServiceTest {
        expectNetworkStatsUidDetail(buildEmptyStats());
        expectBandwidthControlCheck();

        mService.forceUpdateIfaces();
        mService.forceUpdateIfaces(NETWORKS_WIFI);

        // verify service has empty history for wifi
        assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -1161,7 +1168,7 @@ public class NetworkStatsServiceTest {
        final NetworkCapabilities capabilities = new NetworkCapabilities();
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, !isMetered);
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
        return new NetworkState(info, prop, capabilities, null, null, TEST_SSID);
        return new NetworkState(info, prop, capabilities, WIFI_NETWORK, null, TEST_SSID);
    }

    private static NetworkState buildMobile3gState(String subscriberId) {
@@ -1178,7 +1185,7 @@ public class NetworkStatsServiceTest {
        final NetworkCapabilities capabilities = new NetworkCapabilities();
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
        return new NetworkState(info, prop, capabilities, null, subscriberId, null);
        return new NetworkState(info, prop, capabilities, MOBILE_NETWORK, subscriberId, null);
    }

    private static NetworkState buildMobile4gState(String iface) {
@@ -1189,7 +1196,7 @@ public class NetworkStatsServiceTest {
        final NetworkCapabilities capabilities = new NetworkCapabilities();
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
        return new NetworkState(info, prop, capabilities, null, null, null);
        return new NetworkState(info, prop, capabilities, MOBILE_NETWORK, null, null);
    }

    private NetworkStats buildEmptyStats() {