Merge changes Ieb8645ac,I6466ec14,I87deb82b,I995b108e,Ib6521459 am: 2ce04660f6

am: 48f59a0fdf

Change-Id: I960e94b03b29282ae2b03f78a19ed2692bd88e05
This commit is contained in:
Varun Anand
2019-06-17 10:33:53 -07:00
committed by android-build-merger
17 changed files with 539 additions and 277 deletions

View File

@@ -193,6 +193,7 @@ import com.android.server.net.BaseNetdEventCallback;
import com.android.server.net.BaseNetworkObserver; import com.android.server.net.BaseNetworkObserver;
import com.android.server.net.LockdownVpnTracker; import com.android.server.net.LockdownVpnTracker;
import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.net.NetworkStatsFactory;
import com.android.server.utils.PriorityDump; import com.android.server.utils.PriorityDump;
import com.google.android.collect.Lists; import com.google.android.collect.Lists;
@@ -4382,7 +4383,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
/** /**
* @return VPN information for accounting, or null if we can't retrieve all required * @return VPN information for accounting, or null if we can't retrieve all required
* information, e.g primary underlying iface. * information, e.g underlying ifaces.
*/ */
@Nullable @Nullable
private VpnInfo createVpnInfo(Vpn vpn) { private VpnInfo createVpnInfo(Vpn vpn) {
@@ -4394,17 +4395,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
// see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret // see VpnService.setUnderlyingNetworks()'s javadoc about how to interpret
// the underlyingNetworks list. // the underlyingNetworks list.
if (underlyingNetworks == null) { if (underlyingNetworks == null) {
NetworkAgentInfo defaultNetwork = getDefaultNetwork(); NetworkAgentInfo defaultNai = getDefaultNetwork();
if (defaultNetwork != null && defaultNetwork.linkProperties != null) { if (defaultNai != null) {
info.primaryUnderlyingIface = getDefaultNetwork().linkProperties.getInterfaceName(); underlyingNetworks = new Network[] { defaultNai.network };
}
} else if (underlyingNetworks.length > 0) {
LinkProperties linkProperties = getLinkProperties(underlyingNetworks[0]);
if (linkProperties != null) {
info.primaryUnderlyingIface = linkProperties.getInterfaceName();
} }
} }
return info.primaryUnderlyingIface == null ? null : info; if (underlyingNetworks != null && underlyingNetworks.length > 0) {
List<String> interfaces = new ArrayList<>();
for (Network network : underlyingNetworks) {
LinkProperties lp = getLinkProperties(network);
if (lp != null) {
for (String iface : lp.getAllInterfaceNames()) {
if (!TextUtils.isEmpty(iface)) {
interfaces.add(iface);
}
}
}
}
if (!interfaces.isEmpty()) {
info.underlyingIfaces = interfaces.toArray(new String[interfaces.size()]);
}
}
return info.underlyingIfaces == null ? null : info;
} }
/** /**
@@ -6784,8 +6796,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
/** /**
* Notify NetworkStatsService that the set of active ifaces has changed, or that one of the * Notify NetworkStatsService and NetworkStatsFactory that the set of active ifaces has changed,
* properties tracked by NetworkStatsService on an active iface has changed. * or that one of the active iface's trackedproperties has changed.
*/ */
private void notifyIfacesChangedForNetworkStats() { private void notifyIfacesChangedForNetworkStats() {
ensureRunningOnConnectivityServiceThread(); ensureRunningOnConnectivityServiceThread();
@@ -6794,11 +6806,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (activeLinkProperties != null) { if (activeLinkProperties != null) {
activeIface = activeLinkProperties.getInterfaceName(); 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).
try { try {
mStatsService.forceUpdateIfaces( mStatsService.forceUpdateIfaces(
getDefaultNetworks(), getAllVpnInfo(), getAllNetworkState(), activeIface); getDefaultNetworks(), getAllNetworkState(), activeIface);
} catch (Exception ignored) { } catch (Exception ignored) {
} }
NetworkStatsFactory.updateVpnInfos(getAllVpnInfo());
} }
@Override @Override

View File

@@ -569,7 +569,7 @@ public class NetworkStatsTest {
.addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, .addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L); DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 0L);
assertTrue(delta.toString(), delta.migrateTun(tunUid, tunIface, underlyingIface)); delta.migrateTun(tunUid, tunIface, new String[] {underlyingIface});
assertEquals(20, delta.size()); assertEquals(20, delta.size());
// tunIface and TEST_IFACE entries are not changed. // tunIface and TEST_IFACE entries are not changed.
@@ -650,7 +650,7 @@ public class NetworkStatsTest {
.addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L); DEFAULT_NETWORK_NO, 75500L, 37L, 130000L, 70L, 0L);
assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface)); delta.migrateTun(tunUid, tunIface, new String[]{underlyingIface});
assertEquals(9, delta.size()); assertEquals(9, delta.size());
// tunIface entries should not be changed. // tunIface entries should not be changed.
@@ -812,6 +812,37 @@ public class NetworkStatsTest {
assertEquals(entry2, stats.getValues(1, null)); assertEquals(entry2, stats.getValues(1, null));
} }
@Test
public void testFilterDebugEntries() {
NetworkStats.Entry entry1 = new NetworkStats.Entry(
"test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats.Entry entry2 = new NetworkStats.Entry(
"test2", 10101, SET_DBG_VPN_IN, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats.Entry entry3 = new NetworkStats.Entry(
"test2", 10101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats.Entry entry4 = new NetworkStats.Entry(
"test2", 10101, SET_DBG_VPN_OUT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 50000L, 25L, 100000L, 50L, 0L);
NetworkStats stats = new NetworkStats(TEST_START, 4)
.addValues(entry1)
.addValues(entry2)
.addValues(entry3)
.addValues(entry4);
stats.filterDebugEntries();
assertEquals(2, stats.size());
assertEquals(entry1, stats.getValues(0, null));
assertEquals(entry3, stats.getValues(1, null));
}
@Test @Test
public void testApply464xlatAdjustments() { public void testApply464xlatAdjustments() {
final String v4Iface = "v4-wlan0"; final String v4Iface = "v4-wlan0";

View File

@@ -192,6 +192,7 @@ import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn; import com.android.server.connectivity.Vpn;
import com.android.server.net.NetworkPinner; import com.android.server.net.NetworkPinner;
import com.android.server.net.NetworkPolicyManagerInternal; import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.net.NetworkStatsFactory;
import com.android.testutils.HandlerUtilsKt; import com.android.testutils.HandlerUtilsKt;
import org.junit.After; import org.junit.After;
@@ -4901,9 +4902,9 @@ public class ConnectivityServiceTest {
verify(mStatsService, atLeastOnce()) verify(mStatsService, atLeastOnce())
.forceUpdateIfaces( .forceUpdateIfaces(
eq(onlyCell), eq(onlyCell),
eq(new VpnInfo[0]),
any(NetworkState[].class), any(NetworkState[].class),
eq(MOBILE_IFNAME)); eq(MOBILE_IFNAME));
assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
reset(mStatsService); reset(mStatsService);
// Default network switch should update ifaces. // Default network switch should update ifaces.
@@ -4914,9 +4915,9 @@ public class ConnectivityServiceTest {
verify(mStatsService, atLeastOnce()) verify(mStatsService, atLeastOnce())
.forceUpdateIfaces( .forceUpdateIfaces(
eq(onlyWifi), eq(onlyWifi),
eq(new VpnInfo[0]),
any(NetworkState[].class), any(NetworkState[].class),
eq(WIFI_IFNAME)); eq(WIFI_IFNAME));
assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
reset(mStatsService); reset(mStatsService);
// Disconnect should update ifaces. // Disconnect should update ifaces.
@@ -4925,9 +4926,9 @@ public class ConnectivityServiceTest {
verify(mStatsService, atLeastOnce()) verify(mStatsService, atLeastOnce())
.forceUpdateIfaces( .forceUpdateIfaces(
eq(onlyCell), eq(onlyCell),
eq(new VpnInfo[0]),
any(NetworkState[].class), any(NetworkState[].class),
eq(MOBILE_IFNAME)); eq(MOBILE_IFNAME));
assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
reset(mStatsService); reset(mStatsService);
// Metered change should update ifaces // Metered change should update ifaces
@@ -4936,9 +4937,9 @@ public class ConnectivityServiceTest {
verify(mStatsService, atLeastOnce()) verify(mStatsService, atLeastOnce())
.forceUpdateIfaces( .forceUpdateIfaces(
eq(onlyCell), eq(onlyCell),
eq(new VpnInfo[0]),
any(NetworkState[].class), any(NetworkState[].class),
eq(MOBILE_IFNAME)); eq(MOBILE_IFNAME));
assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
reset(mStatsService); reset(mStatsService);
mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
@@ -4946,9 +4947,9 @@ public class ConnectivityServiceTest {
verify(mStatsService, atLeastOnce()) verify(mStatsService, atLeastOnce())
.forceUpdateIfaces( .forceUpdateIfaces(
eq(onlyCell), eq(onlyCell),
eq(new VpnInfo[0]),
any(NetworkState[].class), any(NetworkState[].class),
eq(MOBILE_IFNAME)); eq(MOBILE_IFNAME));
assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
reset(mStatsService); reset(mStatsService);
// Captive portal change shouldn't update ifaces // Captive portal change shouldn't update ifaces
@@ -4957,9 +4958,9 @@ public class ConnectivityServiceTest {
verify(mStatsService, never()) verify(mStatsService, never())
.forceUpdateIfaces( .forceUpdateIfaces(
eq(onlyCell), eq(onlyCell),
eq(new VpnInfo[0]),
any(NetworkState[].class), any(NetworkState[].class),
eq(MOBILE_IFNAME)); eq(MOBILE_IFNAME));
assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
reset(mStatsService); reset(mStatsService);
// Roaming change should update ifaces // Roaming change should update ifaces
@@ -4968,9 +4969,9 @@ public class ConnectivityServiceTest {
verify(mStatsService, atLeastOnce()) verify(mStatsService, atLeastOnce())
.forceUpdateIfaces( .forceUpdateIfaces(
eq(onlyCell), eq(onlyCell),
eq(new VpnInfo[0]),
any(NetworkState[].class), any(NetworkState[].class),
eq(MOBILE_IFNAME)); eq(MOBILE_IFNAME));
assertEquals(new VpnInfo[0], NetworkStatsFactory.getVpnInfos());
reset(mStatsService); reset(mStatsService);
} }

View File

@@ -0,0 +1,117 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.net;
import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
import static android.net.NetworkStats.METERED_ALL;
import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkStats.ROAMING_ALL;
import static android.net.NetworkStats.ROAMING_NO;
import static android.net.NetworkStats.ROAMING_YES;
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.SET_FOREGROUND;
import static android.net.NetworkStats.TAG_NONE;
import static org.junit.Assert.assertEquals;
import android.net.NetworkStats;
import com.android.internal.net.VpnInfo;
/** Superclass with utilities for NetworkStats(Service|Factory)Test */
abstract class NetworkStatsBaseTest {
static final String TEST_IFACE = "test0";
static final String TEST_IFACE2 = "test1";
static final String TUN_IFACE = "test_nss_tun0";
static final int UID_RED = 1001;
static final int UID_BLUE = 1002;
static final int UID_GREEN = 1003;
static final int UID_VPN = 1004;
void assertValues(NetworkStats stats, String iface, int uid, long rxBytes,
long rxPackets, long txBytes, long txPackets) {
assertValues(
stats, iface, uid, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
rxBytes, rxPackets, txBytes, txPackets, 0);
}
void assertValues(NetworkStats stats, String iface, int uid, int set, int tag,
int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets,
long txBytes, long txPackets, long operations) {
final NetworkStats.Entry entry = new NetworkStats.Entry();
final int[] sets;
if (set == SET_ALL) {
sets = new int[] {SET_ALL, SET_DEFAULT, SET_FOREGROUND};
} else {
sets = new int[] {set};
}
final int[] roamings;
if (roaming == ROAMING_ALL) {
roamings = new int[] {ROAMING_ALL, ROAMING_YES, ROAMING_NO};
} else {
roamings = new int[] {roaming};
}
final int[] meterings;
if (metered == METERED_ALL) {
meterings = new int[] {METERED_ALL, METERED_YES, METERED_NO};
} else {
meterings = new int[] {metered};
}
final int[] defaultNetworks;
if (defaultNetwork == DEFAULT_NETWORK_ALL) {
defaultNetworks =
new int[] {DEFAULT_NETWORK_ALL, DEFAULT_NETWORK_YES, DEFAULT_NETWORK_NO};
} else {
defaultNetworks = new int[] {defaultNetwork};
}
for (int s : sets) {
for (int r : roamings) {
for (int m : meterings) {
for (int d : defaultNetworks) {
final int i = stats.findIndex(iface, uid, s, tag, m, r, d);
if (i != -1) {
entry.add(stats.getValues(i, null));
}
}
}
}
}
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
assertEquals("unexpected txPackets", txPackets, entry.txPackets);
assertEquals("unexpected operations", operations, entry.operations);
}
VpnInfo createVpnInfo(String[] underlyingIfaces) {
VpnInfo info = new VpnInfo();
info.ownerUid = UID_VPN;
info.vpnIface = TUN_IFACE;
info.underlyingIfaces = underlyingIfaces;
return info;
}
}

View File

@@ -16,8 +16,11 @@
package com.android.server.net; package com.android.server.net;
import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
import static android.net.NetworkStats.DEFAULT_NETWORK_NO; import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.METERED_ALL;
import static android.net.NetworkStats.METERED_NO; import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.ROAMING_ALL;
import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_NO;
import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_DEFAULT;
@@ -39,6 +42,7 @@ import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.tests.net.R; import com.android.frameworks.tests.net.R;
import com.android.internal.net.VpnInfo;
import libcore.io.IoUtils; import libcore.io.IoUtils;
import libcore.io.Streams; import libcore.io.Streams;
@@ -54,12 +58,12 @@ import java.io.FileWriter;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
/** /** Tests for {@link NetworkStatsFactory}. */
* Tests for {@link NetworkStatsFactory}.
*/
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@SmallTest @SmallTest
public class NetworkStatsFactoryTest { public class NetworkStatsFactoryTest extends NetworkStatsBaseTest {
private static final String CLAT_PREFIX = "v4-";
private File mTestProc; private File mTestProc;
private NetworkStatsFactory mFactory; private NetworkStatsFactory mFactory;
@@ -75,6 +79,8 @@ public class NetworkStatsFactoryTest {
// related to networkStatsFactory is compiled to a minimal native library and loaded here. // related to networkStatsFactory is compiled to a minimal native library and loaded here.
System.loadLibrary("networkstatsfactorytestjni"); System.loadLibrary("networkstatsfactorytestjni");
mFactory = new NetworkStatsFactory(mTestProc, false); mFactory = new NetworkStatsFactory(mTestProc, false);
NetworkStatsFactory.updateVpnInfos(new VpnInfo[0]);
NetworkStatsFactory.clearStackedIfaces();
} }
@After @After
@@ -98,6 +104,236 @@ public class NetworkStatsFactoryTest {
assertStatsEntry(stats, "rmnet2", 10001, SET_DEFAULT, 0x0, 1125899906842624L, 984L); assertStatsEntry(stats, "rmnet2", 10001, SET_DEFAULT, 0x0, 1125899906842624L, 984L);
} }
@Test
public void vpnRewriteTrafficThroughItself() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
NetworkStatsFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
//
// 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
// over VPN.
// 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
// over VPN.
//
// VPN UID rewrites packets read from TUN back to TUN, plus some of its own traffic
final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_rewrite_through_self);
assertValues(tunStats, TUN_IFACE, UID_RED, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
DEFAULT_NETWORK_ALL, 2000L, 200L, 1000L, 100L, 0);
assertValues(tunStats, TUN_IFACE, UID_BLUE, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
DEFAULT_NETWORK_ALL, 1000L, 100L, 500L, 50L, 0);
assertValues(tunStats, TUN_IFACE, UID_VPN, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
DEFAULT_NETWORK_ALL, 0L, 0L, 1600L, 160L, 0);
assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L);
assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 260L, 26L);
}
@Test
public void vpnWithClat() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {CLAT_PREFIX + TEST_IFACE})};
NetworkStatsFactory.updateVpnInfos(vpnInfos);
NetworkStatsFactory.noteStackedIface(CLAT_PREFIX + TEST_IFACE, TEST_IFACE);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
// over VPN.
// 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
// over VPN.
// VPN sent 1650 bytes (150 packets), and received 3300 (300 packets) over v4-WiFi, and clat
// added 20 bytes per packet of extra overhead
//
// For 1650 bytes sent over v4-WiFi, 4650 bytes were actually sent over WiFi, which is
// expected to be split as follows:
// UID_RED: 1000 bytes, 100 packets
// UID_BLUE: 500 bytes, 50 packets
// UID_VPN: 3150 bytes, 0 packets
//
// For 3300 bytes received over v4-WiFi, 9300 bytes were actually sent over WiFi, which is
// expected to be split as follows:
// UID_RED: 2000 bytes, 200 packets
// UID_BLUE: 1000 bytes, 100 packets
// UID_VPN: 6300 bytes, 0 packets
final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_with_clat);
assertValues(tunStats, CLAT_PREFIX + TEST_IFACE, UID_RED, 2000L, 200L, 1000, 100L);
assertValues(tunStats, CLAT_PREFIX + TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
assertValues(tunStats, CLAT_PREFIX + TEST_IFACE, UID_VPN, 6300L, 0L, 3150L, 0L);
}
@Test
public void vpnWithOneUnderlyingIface() throws Exception {
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
NetworkStatsFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
// over VPN.
// 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
// over VPN.
// VPN sent 1650 bytes (150 packets), and received 3300 (300 packets) over WiFi.
// Of 1650 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
// attributed to UID_BLUE, and 150 bytes attributed to UID_VPN.
// Of 3300 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
// attributed to UID_BLUE, and 300 bytes attributed to UID_VPN.
final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying);
assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L);
assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
assertValues(tunStats, TEST_IFACE, UID_VPN, 300L, 0L, 150L, 0L);
}
@Test
public void vpnWithOneUnderlyingIfaceAndOwnTraffic() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
NetworkStatsFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent, and 2000 bytes (200 packets) were received by UID_RED
// over VPN.
// 500 bytes (50 packets) were sent, and 1000 bytes (100 packets) were received by UID_BLUE
// over VPN.
// Additionally, the VPN sends 6000 bytes (600 packets) of its own traffic into the tun
// interface (passing that traffic to the VPN endpoint), and receives 5000 bytes (500
// packets) from it. Including overhead that is 6600/5500 bytes.
// VPN sent 8250 bytes (750 packets), and received 8800 (800 packets) over WiFi.
// Of 8250 bytes sent over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes
// attributed to UID_BLUE, and 6750 bytes attributed to UID_VPN.
// Of 8800 bytes received over WiFi, expect 2000 bytes attributed to UID_RED, 1000 bytes
// attributed to UID_BLUE, and 5800 bytes attributed to UID_VPN.
final NetworkStats tunStats =
parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_own_traffic);
assertValues(tunStats, TEST_IFACE, UID_RED, 2000L, 200L, 1000L, 100L);
assertValues(tunStats, TEST_IFACE, UID_BLUE, 1000L, 100L, 500L, 50L);
assertValues(tunStats, TEST_IFACE, UID_VPN, 5800L, 500L, 6750L, 600L);
}
@Test
public void vpnWithOneUnderlyingIface_withCompression() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
NetworkStatsFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
// 3000 bytes (300 packets) were sent/received by UID_BLUE over VPN.
// VPN sent/received 1000 bytes (100 packets) over WiFi.
// Of 1000 bytes over WiFi, expect 250 bytes attributed UID_RED and 750 bytes to UID_BLUE,
// with nothing attributed to UID_VPN for both rx/tx traffic.
final NetworkStats tunStats =
parseDetailedStats(R.raw.xt_qtaguid_vpn_one_underlying_compression);
assertValues(tunStats, TEST_IFACE, UID_RED, 250L, 25L, 250L, 25L);
assertValues(tunStats, TEST_IFACE, UID_BLUE, 750L, 75L, 750L, 75L);
assertValues(tunStats, TEST_IFACE, UID_VPN, 0L, 0L, 0L, 0L);
}
@Test
public void vpnWithTwoUnderlyingIfaces_packetDuplication() throws Exception {
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is duplicating traffic across both WiFi and Cell.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
NetworkStatsFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent/received by UID_RED and UID_BLUE over VPN.
// VPN sent/received 4400 bytes (400 packets) over both WiFi and Cell (8800 bytes in total).
// Of 8800 bytes over WiFi/Cell, expect:
// - 500 bytes rx/tx each over WiFi/Cell attributed to both UID_RED and UID_BLUE.
// - 1200 bytes rx/tx each over WiFi/Cell for VPN_UID.
final NetworkStats tunStats =
parseDetailedStats(R.raw.xt_qtaguid_vpn_two_underlying_duplication);
assertValues(tunStats, TEST_IFACE, UID_RED, 500L, 50L, 500L, 50L);
assertValues(tunStats, TEST_IFACE, UID_BLUE, 500L, 50L, 500L, 50L);
assertValues(tunStats, TEST_IFACE, UID_VPN, 1200L, 100L, 1200L, 100L);
assertValues(tunStats, TEST_IFACE2, UID_RED, 500L, 50L, 500L, 50L);
assertValues(tunStats, TEST_IFACE2, UID_BLUE, 500L, 50L, 500L, 50L);
assertValues(tunStats, TEST_IFACE2, UID_VPN, 1200L, 100L, 1200L, 100L);
}
@Test
public void vpnWithTwoUnderlyingIfaces_splitTraffic() throws Exception {
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting traffic across WiFi and Cell.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
NetworkStatsFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent, and 500 bytes (50 packets) received by UID_RED over
// VPN.
// VPN sent 660 bytes (60 packets) over WiFi and 440 bytes (40 packets) over Cell.
// And, it received 330 bytes (30 packets) over WiFi and 220 bytes (20 packets) over Cell.
// For UID_RED, expect 600 bytes attributed over WiFi and 400 bytes over Cell for sent (tx)
// traffic. For received (rx) traffic, expect 300 bytes over WiFi and 200 bytes over Cell.
//
// For UID_VPN, expect 60 bytes attributed over WiFi and 40 bytes over Cell for tx traffic.
// And, 30 bytes over WiFi and 20 bytes over Cell for rx traffic.
final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_two_underlying_split);
assertValues(tunStats, TEST_IFACE, UID_RED, 300L, 30L, 600L, 60L);
assertValues(tunStats, TEST_IFACE, UID_VPN, 30L, 0L, 60L, 0L);
assertValues(tunStats, TEST_IFACE2, UID_RED, 200L, 20L, 400L, 40L);
assertValues(tunStats, TEST_IFACE2, UID_VPN, 20L, 0L, 40L, 0L);
}
@Test
public void vpnWithTwoUnderlyingIfaces_splitTrafficWithCompression() throws Exception {
// WiFi and Cell networks are connected and VPN is using WiFi (which has TEST_IFACE) and
// Cell (which has TEST_IFACE2) and has declared both of them in its underlying network set.
// Additionally, VPN is arbitrarily splitting compressed traffic across WiFi and Cell.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE, TEST_IFACE2})};
NetworkStatsFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface:
// 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
// VPN sent/received 600 bytes (60 packets) over WiFi and 200 bytes (20 packets) over Cell.
// For UID_RED, expect 600 bytes attributed over WiFi and 200 bytes over Cell for both
// rx/tx.
// UID_VPN gets nothing attributed to it (avoiding negative stats).
final NetworkStats tunStats =
parseDetailedStats(R.raw.xt_qtaguid_vpn_two_underlying_split_compression);
assertValues(tunStats, TEST_IFACE, UID_RED, 600L, 60L, 600L, 60L);
assertValues(tunStats, TEST_IFACE, UID_VPN, 0L, 0L, 0L, 0L);
assertValues(tunStats, TEST_IFACE2, UID_RED, 200L, 20L, 200L, 20L);
assertValues(tunStats, TEST_IFACE2, UID_VPN, 0L, 0L, 0L, 0L);
}
@Test
public void vpnWithIncorrectUnderlyingIface() throws Exception {
// WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
// but has declared only WiFi (TEST_IFACE) in its underlying network set.
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(new String[] {TEST_IFACE})};
NetworkStatsFactory.updateVpnInfos(vpnInfos);
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
// VPN sent/received 1100 bytes (100 packets) over Cell.
// Of 1100 bytes over Cell, expect all of it attributed to UID_VPN for both rx/tx traffic.
final NetworkStats tunStats = parseDetailedStats(R.raw.xt_qtaguid_vpn_incorrect_iface);
assertValues(tunStats, TEST_IFACE, UID_RED, 0L, 0L, 0L, 0L);
assertValues(tunStats, TEST_IFACE, UID_VPN, 0L, 0L, 0L, 0L);
assertValues(tunStats, TEST_IFACE2, UID_RED, 0L, 0L, 0L, 0L);
assertValues(tunStats, TEST_IFACE2, UID_VPN, 1100L, 100L, 1100L, 100L);
}
@Test @Test
public void testKernelTags() throws Exception { public void testKernelTags() throws Exception {
assertEquals(0, kernelToTag("0x0000000000000000")); assertEquals(0, kernelToTag("0x0000000000000000"));
@@ -146,7 +382,7 @@ public class NetworkStatsFactoryTest {
} }
@Test @Test
public void testDoubleClatAccounting() throws Exception { public void testDoubleClatAccountingSimple() throws Exception {
NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0"); NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
// xt_qtaguid_with_clat_simple is a synthetic file that simulates // xt_qtaguid_with_clat_simple is a synthetic file that simulates
@@ -154,12 +390,17 @@ public class NetworkStatsFactoryTest {
// - 41 sent 464xlat packets of size 100 bytes // - 41 sent 464xlat packets of size 100 bytes
// - no other traffic on base interface for root uid. // - no other traffic on base interface for root uid.
NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_simple); NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat_simple);
assertEquals(4, stats.size()); assertEquals(3, stats.size());
assertStatsEntry(stats, "v4-wlan0", 10060, SET_DEFAULT, 0x0, 46860L, 4920L); assertStatsEntry(stats, "v4-wlan0", 10060, SET_DEFAULT, 0x0, 46860L, 4920L);
assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 0L, 0L); assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0x0, 0L, 0L);
}
stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat); @Test
public void testDoubleClatAccounting() throws Exception {
NetworkStatsFactory.noteStackedIface("v4-wlan0", "wlan0");
NetworkStats stats = parseDetailedStats(R.raw.xt_qtaguid_with_clat);
assertEquals(42, stats.size()); assertEquals(42, stats.size());
assertStatsEntry(stats, "v4-wlan0", 0, SET_DEFAULT, 0x0, 356L, 276L); assertStatsEntry(stats, "v4-wlan0", 0, SET_DEFAULT, 0x0, 356L, 276L);
@@ -272,11 +513,19 @@ public class NetworkStatsFactoryTest {
private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set, private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO, assertStatsEntry(stats, iface, uid, set, tag, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO,
DEFAULT_NETWORK_NO); rxBytes, rxPackets, txBytes, txPackets);
}
private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets,
long txBytes, long txPackets) {
final int i = stats.findIndex(iface, uid, set, tag, metered, roaming, defaultNetwork);
if (i < 0) { if (i < 0) {
fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d)", fail(String.format("no NetworkStats for (iface: %s, uid: %d, set: %d, tag: %d, metered:"
iface, uid, set, tag)); + " %d, roaming: %d, defaultNetwork: %d)",
iface, uid, set, tag, metered, roaming, defaultNetwork));
} }
final NetworkStats.Entry entry = stats.getValues(i, null); final NetworkStats.Entry entry = stats.getValues(i, null);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);

View File

@@ -52,7 +52,6 @@ import android.util.ArrayMap;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4;
import com.android.internal.net.VpnInfo;
import com.android.server.net.NetworkStatsServiceTest.LatchedHandler; import com.android.server.net.NetworkStatsServiceTest.LatchedHandler;
import com.android.testutils.HandlerUtilsKt; import com.android.testutils.HandlerUtilsKt;
@@ -93,8 +92,6 @@ public class NetworkStatsObserversTest {
private static final long BASE_BYTES = 7 * MB_IN_BYTES; private static final long BASE_BYTES = 7 * MB_IN_BYTES;
private static final int INVALID_TYPE = -1; private static final int INVALID_TYPE = -1;
private static final VpnInfo[] VPN_INFO = new VpnInfo[0];
private long mElapsedRealtime; private long mElapsedRealtime;
private HandlerThread mObserverHandlerThread; private HandlerThread mObserverHandlerThread;
@@ -247,8 +244,7 @@ public class NetworkStatsObserversTest {
NetworkStats uidSnapshot = null; NetworkStats uidSnapshot = null;
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
waitForObserverToIdle(); waitForObserverToIdle();
} }
@@ -271,15 +267,13 @@ public class NetworkStatsObserversTest {
.addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
NetworkStats uidSnapshot = null; NetworkStats uidSnapshot = null;
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
// Delta // Delta
xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */) xtSnapshot = new NetworkStats(TEST_START, 1 /* initialSize */)
.addIfaceValues(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L); .addIfaceValues(TEST_IFACE, BASE_BYTES + 1024L, 10L, BASE_BYTES + 2048L, 20L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
waitForObserverToIdle(); waitForObserverToIdle();
} }
@@ -303,16 +297,14 @@ public class NetworkStatsObserversTest {
.addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L); .addIfaceValues(TEST_IFACE, BASE_BYTES, 8L, BASE_BYTES, 16L);
NetworkStats uidSnapshot = null; NetworkStats uidSnapshot = null;
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
// Delta // Delta
xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */) xtSnapshot = new NetworkStats(TEST_START + MINUTE_IN_MILLIS, 1 /* initialSize */)
.addIfaceValues(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L, .addIfaceValues(TEST_IFACE, BASE_BYTES + THRESHOLD_BYTES, 12L,
BASE_BYTES + THRESHOLD_BYTES, 22L); BASE_BYTES + THRESHOLD_BYTES, 22L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
waitForObserverToIdle(); waitForObserverToIdle();
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType); assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
} }
@@ -337,8 +329,7 @@ public class NetworkStatsObserversTest {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
// Delta // Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
@@ -346,8 +337,7 @@ public class NetworkStatsObserversTest {
DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
waitForObserverToIdle(); waitForObserverToIdle();
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType); assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
} }
@@ -372,8 +362,7 @@ public class NetworkStatsObserversTest {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); DEFAULT_NETWORK_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
// Delta // Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
@@ -381,8 +370,7 @@ public class NetworkStatsObserversTest {
DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
waitForObserverToIdle(); waitForObserverToIdle();
} }
@@ -406,8 +394,7 @@ public class NetworkStatsObserversTest {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
// Delta // Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
@@ -415,8 +402,7 @@ public class NetworkStatsObserversTest {
DEFAULT_NETWORK_YES, BASE_BYTES + THRESHOLD_BYTES, 2L, DEFAULT_NETWORK_YES, BASE_BYTES + THRESHOLD_BYTES, 2L,
BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
waitForObserverToIdle(); waitForObserverToIdle();
assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType); assertEquals(NetworkStatsManager.CALLBACK_LIMIT_REACHED, mHandler.lastMessageType);
} }
@@ -441,8 +427,7 @@ public class NetworkStatsObserversTest {
.addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO, .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); ROAMING_NO, DEFAULT_NETWORK_YES, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
// Delta // Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
@@ -450,8 +435,7 @@ public class NetworkStatsObserversTest {
ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, ROAMING_NO, DEFAULT_NETWORK_NO, BASE_BYTES + THRESHOLD_BYTES, 2L,
BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, TEST_START);
VPN_INFO, TEST_START);
waitForObserverToIdle(); waitForObserverToIdle();
} }

View File

@@ -23,7 +23,6 @@ import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.TYPE_WIMAX; import static android.net.ConnectivityManager.TYPE_WIMAX;
import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.DEFAULT_NETWORK_YES; import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.INTERFACES_ALL; import static android.net.NetworkStats.INTERFACES_ALL;
@@ -42,7 +41,6 @@ import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
import static android.net.NetworkTemplate.buildTemplateWifiWildcard; import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
import static android.net.TrafficStats.MB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.TrafficStats.UID_REMOVED; import static android.net.TrafficStats.UID_REMOVED;
@@ -60,7 +58,6 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -98,7 +95,6 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4;
import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings; import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
@@ -129,13 +125,9 @@ import java.util.Objects;
*/ */
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@SmallTest @SmallTest
public class NetworkStatsServiceTest { public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
private static final String TAG = "NetworkStatsServiceTest"; private static final String TAG = "NetworkStatsServiceTest";
private static final String TEST_IFACE = "test0";
private static final String TEST_IFACE2 = "test1";
private static final String TUN_IFACE = "test_nss_tun0";
private static final long TEST_START = 1194220800000L; private static final long TEST_START = 1194220800000L;
private static final String IMSI_1 = "310004"; private static final String IMSI_1 = "310004";
@@ -146,11 +138,6 @@ public class NetworkStatsServiceTest {
private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1); private static NetworkTemplate sTemplateImsi1 = buildTemplateMobileAll(IMSI_1);
private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2); private static NetworkTemplate sTemplateImsi2 = buildTemplateMobileAll(IMSI_2);
private static final int UID_RED = 1001;
private static final int UID_BLUE = 1002;
private static final int UID_GREEN = 1003;
private static final int UID_VPN = 1004;
private static final Network WIFI_NETWORK = new Network(100); private static final Network WIFI_NETWORK = new Network(100);
private static final Network MOBILE_NETWORK = new Network(101); private static final Network MOBILE_NETWORK = new Network(101);
private static final Network VPN_NETWORK = new Network(102); private static final Network VPN_NETWORK = new Network(102);
@@ -217,10 +204,12 @@ public class NetworkStatsServiceTest {
expectSystemReady(); expectSystemReady();
mService.systemReady(); mService.systemReady();
// Verify that system ready fetches realtime stats
verify(mNetManager).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
mSession = mService.openSession(); mSession = mService.openSession();
assertNotNull("openSession() failed", mSession); assertNotNull("openSession() failed", mSession);
// catch INetworkManagementEventObserver during systemReady() // catch INetworkManagementEventObserver during systemReady()
ArgumentCaptor<INetworkManagementEventObserver> networkObserver = ArgumentCaptor<INetworkManagementEventObserver> networkObserver =
ArgumentCaptor.forClass(INetworkManagementEventObserver.class); ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
@@ -252,7 +241,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
// verify service has empty history for wifi // verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -296,7 +285,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
// verify service has empty history for wifi // verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -370,8 +359,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
// modify some number on wifi, and trigger poll event // modify some number on wifi, and trigger poll event
incrementCurrentTime(2 * HOUR_IN_MILLIS); incrementCurrentTime(2 * HOUR_IN_MILLIS);
@@ -412,8 +400,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
// create some traffic on first network // create some traffic on first network
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -448,7 +435,7 @@ public class NetworkStatsServiceTest {
.addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
forcePollAndWaitForIdle(); forcePollAndWaitForIdle();
@@ -488,8 +475,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
// create some traffic // create some traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -547,8 +533,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
// create some traffic // create some traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -575,7 +560,7 @@ public class NetworkStatsServiceTest {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L));
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
forcePollAndWaitForIdle(); forcePollAndWaitForIdle();
@@ -605,8 +590,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
// create some traffic for two apps // create some traffic for two apps
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -664,7 +648,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
NetworkStats.Entry entry1 = new NetworkStats.Entry( NetworkStats.Entry entry1 = new NetworkStats.Entry(
TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L); TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L);
@@ -708,7 +692,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
NetworkStats.Entry uidStats = new NetworkStats.Entry( NetworkStats.Entry uidStats = new NetworkStats.Entry(
TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L); TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xF00D, 1024L, 8L, 512L, 4L, 0L);
@@ -733,11 +717,17 @@ public class NetworkStatsServiceTest {
NetworkStats stats = mService.getDetailedUidStats(ifaceFilter); NetworkStats stats = mService.getDetailedUidStats(ifaceFilter);
verify(mNetManager, times(1)).getNetworkStatsUidDetail(eq(UID_ALL), argThat(ifaces -> // mNetManager#getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL) has following invocations:
ifaces != null && ifaces.length == 2 // 1) NetworkStatsService#systemReady from #setUp.
&& ArrayUtils.contains(ifaces, TEST_IFACE) // 2) mService#forceUpdateIfaces in the test above.
&& ArrayUtils.contains(ifaces, stackedIface))); //
// Additionally, we should have one call from the above call to mService#getDetailedUidStats
// with the augmented ifaceFilter
verify(mNetManager, times(2)).getNetworkStatsUidDetail(UID_ALL, INTERFACES_ALL);
verify(mNetManager, times(1)).getNetworkStatsUidDetail(
eq(UID_ALL), eq(NetworkStatsFactory.augmentWithStackedInterfaces(ifaceFilter)));
assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), TEST_IFACE));
assertTrue(ArrayUtils.contains(stats.getUniqueIfaces(), stackedIface));
assertEquals(2, stats.size()); assertEquals(2, stats.size());
assertEquals(uidStats, stats.getValues(0, null)); assertEquals(uidStats, stats.getValues(0, null));
assertEquals(tetheredStats1, stats.getValues(1, null)); assertEquals(tetheredStats1, stats.getValues(1, null));
@@ -752,8 +742,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
// create some initial traffic // create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -810,8 +799,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
// create some initial traffic // create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -851,8 +839,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
// Create some traffic // Create some traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -890,8 +877,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_MOBILE, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states));
// create some tethering traffic // create some tethering traffic
incrementCurrentTime(HOUR_IN_MILLIS); incrementCurrentTime(HOUR_IN_MILLIS);
@@ -922,113 +908,6 @@ public class NetworkStatsServiceTest {
assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0); assertUidTotal(sTemplateImsi1, UID_TETHERING, 1920L, 14L, 384L, 2L, 0);
} }
@Test
public void vpnWithOneUnderlyingIface() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
expectDefaultSettings();
NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck();
mService.forceUpdateIfaces(
new Network[] {WIFI_NETWORK, VPN_NETWORK},
vpnInfos,
networkStates,
getActiveIface(networkStates));
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
// 500 bytes (50 packets) were sent/received by UID_BLUE over VPN.
// VPN sent/received 1650 bytes (150 packets) over WiFi.
// Of 1650 bytes over WiFi, expect 1000 bytes attributed to UID_RED, 500 bytes attributed to
// UID_BLUE, and 150 bytes attributed to UID_VPN for both rx/tx traffic.
incrementCurrentTime(HOUR_IN_MILLIS);
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
.addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
.addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 500L, 50L, 500L, 50L, 1L)
.addValues(
TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1650L, 150L, 1650L, 150L, 2L));
forcePollAndWaitForIdle();
assertUidTotal(sTemplateWifi, UID_RED, 1000L, 100L, 1000L, 100L, 1);
assertUidTotal(sTemplateWifi, UID_BLUE, 500L, 50L, 500L, 50L, 1);
assertUidTotal(sTemplateWifi, UID_VPN, 150L, 0L, 150L, 0L, 2);
}
@Test
public void vpnWithOneUnderlyingIface_withCompression() throws Exception {
// WiFi network is connected and VPN is using WiFi (which has TEST_IFACE).
expectDefaultSettings();
NetworkState[] networkStates = new NetworkState[] {buildWifiState(), buildVpnState()};
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck();
mService.forceUpdateIfaces(
new Network[] {WIFI_NETWORK, VPN_NETWORK},
vpnInfos,
networkStates,
getActiveIface(networkStates));
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
// 3000 bytes (300 packets) were sent/received by UID_BLUE over VPN.
// VPN sent/received 1000 bytes (100 packets) over WiFi.
// Of 1000 bytes over WiFi, expect 250 bytes attributed UID_RED and 750 bytes to UID_BLUE,
// with nothing attributed to UID_VPN for both rx/tx traffic.
incrementCurrentTime(HOUR_IN_MILLIS);
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
.addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
.addValues(TUN_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 3000L, 300L, 3000L, 300L, 1L)
.addValues(
TEST_IFACE, UID_VPN, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 0L));
forcePollAndWaitForIdle();
assertUidTotal(sTemplateWifi, UID_RED, 250L, 25L, 250L, 25L, 0);
assertUidTotal(sTemplateWifi, UID_BLUE, 750L, 75L, 750L, 75L, 0);
assertUidTotal(sTemplateWifi, UID_VPN, 0L, 0L, 0L, 0L, 0);
}
@Test
public void vpnWithIncorrectUnderlyingIface() throws Exception {
// WiFi and Cell networks are connected and VPN is using Cell (which has TEST_IFACE2),
// but has declared only WiFi (TEST_IFACE) in its underlying network set.
expectDefaultSettings();
NetworkState[] networkStates =
new NetworkState[] {
buildWifiState(), buildMobile4gState(TEST_IFACE2), buildVpnState()
};
VpnInfo[] vpnInfos = new VpnInfo[] {createVpnInfo(TEST_IFACE)};
expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck();
mService.forceUpdateIfaces(
new Network[] {WIFI_NETWORK, VPN_NETWORK},
vpnInfos,
networkStates,
getActiveIface(networkStates));
// create some traffic (assume 10 bytes of MTU for VPN interface and 1 byte encryption
// overhead per packet):
// 1000 bytes (100 packets) were sent/received by UID_RED over VPN.
// VPN sent/received 1100 bytes (100 packets) over Cell.
// Of 1100 bytes over Cell, expect all of it attributed to UID_VPN for both rx/tx traffic.
incrementCurrentTime(HOUR_IN_MILLIS);
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
.addValues(TUN_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1000L, 100L, 1000L, 100L, 1L)
.addValues(
TEST_IFACE2, UID_VPN, SET_DEFAULT, TAG_NONE, 1100L, 100L, 1100L, 100L, 1L));
forcePollAndWaitForIdle();
assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
assertUidTotal(sTemplateWifi, UID_VPN, 0L, 0L, 0L, 0L, 0);
assertUidTotal(buildTemplateMobileWildcard(), UID_RED, 0L, 0L, 0L, 0L, 0);
assertUidTotal(buildTemplateMobileWildcard(), UID_VPN, 1100L, 100L, 1100L, 100L, 1);
}
@Test @Test
public void testRegisterUsageCallback() throws Exception { public void testRegisterUsageCallback() throws Exception {
// pretend that wifi network comes online; service should ask about full // pretend that wifi network comes online; service should ask about full
@@ -1039,7 +918,7 @@ public class NetworkStatsServiceTest {
expectNetworkStatsUidDetail(buildEmptyStats()); expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck(); expectBandwidthControlCheck();
mService.forceUpdateIfaces(NETWORKS_WIFI, new VpnInfo[0], states, getActiveIface(states)); mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states));
// verify service has empty history for wifi // verify service has empty history for wifi
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
@@ -1259,59 +1138,6 @@ public class NetworkStatsServiceTest {
} }
} }
private static void assertValues(NetworkStats stats, String iface, int uid, int set,
int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets,
long txBytes, long txPackets, int operations) {
final NetworkStats.Entry entry = new NetworkStats.Entry();
final int[] sets;
if (set == SET_ALL) {
sets = new int[] { SET_ALL, SET_DEFAULT, SET_FOREGROUND };
} else {
sets = new int[] { set };
}
final int[] roamings;
if (roaming == ROAMING_ALL) {
roamings = new int[] { ROAMING_ALL, ROAMING_YES, ROAMING_NO };
} else {
roamings = new int[] { roaming };
}
final int[] meterings;
if (metered == METERED_ALL) {
meterings = new int[] { METERED_ALL, METERED_YES, METERED_NO };
} else {
meterings = new int[] { metered };
}
final int[] defaultNetworks;
if (defaultNetwork == DEFAULT_NETWORK_ALL) {
defaultNetworks = new int[] { DEFAULT_NETWORK_ALL, DEFAULT_NETWORK_YES,
DEFAULT_NETWORK_NO };
} else {
defaultNetworks = new int[] { defaultNetwork };
}
for (int s : sets) {
for (int r : roamings) {
for (int m : meterings) {
for (int d : defaultNetworks) {
final int i = stats.findIndex(iface, uid, s, tag, m, r, d);
if (i != -1) {
entry.add(stats.getValues(i, null));
}
}
}
}
}
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
assertEquals("unexpected txPackets", txPackets, entry.txPackets);
assertEquals("unexpected operations", operations, entry.operations);
}
private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes, private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
long rxPackets, long txBytes, long txPackets, int operations) { long rxPackets, long txBytes, long txPackets, int operations) {
final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null); final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
@@ -1377,14 +1203,6 @@ public class NetworkStatsServiceTest {
return new NetworkState(info, prop, new NetworkCapabilities(), VPN_NETWORK, null, null); return new NetworkState(info, prop, new NetworkCapabilities(), VPN_NETWORK, null, null);
} }
private static VpnInfo createVpnInfo(String underlyingIface) {
VpnInfo info = new VpnInfo();
info.ownerUid = UID_VPN;
info.vpnIface = TUN_IFACE;
info.primaryUnderlyingIface = underlyingIface;
return info;
}
private long getElapsedRealtime() { private long getElapsedRealtime() {
return mElapsedRealtime; return mElapsedRealtime;
} }

View File

@@ -0,0 +1,3 @@
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
3 test1 0x0 1004 0 1100 100 1100 100 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,5 @@
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
4 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,4 @@
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
3 test_nss_tun0 0x0 1002 0 3000 300 3000 300 0 0 0 0 0 0 0 0 0 0 0 0
4 test0 0x0 1004 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,6 @@
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
4 test_nss_tun0 0x0 1004 0 5000 500 6000 600 0 0 0 0 0 0 0 0 0 0 0 0
5 test0 0x0 1004 0 8800 800 0 0 0 0 0 0 0 0 0 0 0 0 0 0
6 test0 0x0 1004 1 0 0 8250 750 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,6 @@
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
4 test_nss_tun0 0x0 1004 0 0 0 1600 160 0 0 0 0 0 0 0 0 0 0 0 0
5 test0 0x0 1004 1 0 0 1760 176 0 0 0 0 0 0 0 0 0 0 0 0
6 test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,5 @@
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
3 test_nss_tun0 0x0 1002 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
4 test0 0x0 1004 0 2200 200 2200 200 0 0 0 0 0 0 0 0 0 0 0 0
5 test1 0x0 1004 0 2200 200 2200 200 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,4 @@
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
2 test_nss_tun0 0x0 1001 0 500 50 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
3 test0 0x0 1004 0 330 30 660 60 0 0 0 0 0 0 0 0 0 0 0 0
4 test1 0x0 1004 0 220 20 440 40 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,4 @@
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
2 test_nss_tun0 0x0 1001 0 1000 100 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
3 test0 0x0 1004 0 600 60 600 60 0 0 0 0 0 0 0 0 0 0 0 0
4 test1 0x0 1004 0 200 20 200 20 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -0,0 +1,8 @@
idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_bytes rx_tcp_packets rx_udp_bytes rx_udp_packets rx_other_bytes rx_other_packets tx_tcp_bytes tx_tcp_packets tx_udp_bytes tx_udp_packets tx_other_bytes tx_other_packets
2 test_nss_tun0 0x0 1001 0 2000 200 1000 100 0 0 0 0 0 0 0 0 0 0 0 0
3 test_nss_tun0 0x0 1002 0 1000 100 500 50 0 0 0 0 0 0 0 0 0 0 0 0
4 v4-test0 0x0 1004 0 3300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 v4-test0 0x0 1004 1 0 0 1650 150 0 0 0 0 0 0 0 0 0 0 0 0
6 test0 0x0 0 0 9300 300 0 0 0 0 0 0 0 0 0 0 0 0 0 0
7 test0 0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
8 test0 0x0 1029 0 0 0 4650 150 0 0 0 0 0 0 0 0 0 0 0 0

View File

@@ -2,5 +2,4 @@ idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packe
2 v4-wlan0 0x0 10060 0 42600 213 4100 41 42600 213 0 0 0 0 4100 41 0 0 0 0 2 v4-wlan0 0x0 10060 0 42600 213 4100 41 42600 213 0 0 0 0 4100 41 0 0 0 0
3 v4-wlan0 0x0 10060 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 v4-wlan0 0x0 10060 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 wlan0 0x0 0 0 46860 213 0 0 46860 213 0 0 0 0 0 0 0 0 0 0 4 wlan0 0x0 0 0 46860 213 0 0 46860 213 0 0 0 0 0 0 0 0 0 0
5 wlan0 0x0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 wlan0 0x0 1029 0 0 0 4920 41 0 0 0 0 0 0 4920 41 0 0 0 0
6 wlan0 0x0 1029 0 0 0 4920 41 0 0 0 0 0 0 4920 41 0 0 0 0