Loading core/java/android/net/NetworkStats.java +75 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import java.io.CharArrayWriter; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Objects; /** Loading Loading @@ -97,6 +98,11 @@ public class NetworkStats implements Parcelable { /** Denotes a request for stats at the interface and UID level. */ public static final int STATS_PER_UID = 1; private static final String CLATD_INTERFACE_PREFIX = "v4-"; // Delta between IPv4 header (20b) and IPv6 header (40b). // Used for correct stats accounting on clatd interfaces. private static final int IPV4V6_HEADER_DELTA = 20; // TODO: move fields to "mVariable" notation /** Loading Loading @@ -758,6 +764,75 @@ public class NetworkStats implements Parcelable { return result; } /** * Calculate and apply adjustments to captured statistics for 464xlat traffic counted twice. * * <p>This mutates both base and stacked traffic stats, to account respectively for * double-counted traffic and IPv4/IPv6 header size difference. * * <p>For 464xlat traffic, xt_qtaguid sees every IPv4 packet twice, once as a native IPv4 * packet on the stacked interface, and once as translated to an IPv6 packet on the * base interface. For correct stats accounting on the base interface, every 464xlat * packet needs to be subtracted from the root UID on the base interface both for tx * and rx traffic (http://b/12249687, http:/b/33681750). * * <p>This method will behave fine if {@code stackedIfaces} is an non-synchronized but add-only * {@code ConcurrentHashMap} * @param baseTraffic Traffic on the base interfaces. Will be mutated. * @param stackedTraffic Stats with traffic stacked on top of our ifaces. Will also be mutated. * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both. */ public static void apply464xlatAdjustments(NetworkStats baseTraffic, NetworkStats stackedTraffic, Map<String, String> stackedIfaces) { // Total 464xlat traffic to subtract from uid 0 on all base interfaces. // stackedIfaces may grow afterwards, but NetworkStats will just be resized automatically. final NetworkStats adjustments = new NetworkStats(0, stackedIfaces.size()); // For recycling Entry entry = null; Entry adjust = new NetworkStats.Entry(IFACE_ALL, 0, 0, 0, 0, 0, 0, 0L, 0L, 0L, 0L, 0L); for (int i = 0; i < stackedTraffic.size; i++) { entry = stackedTraffic.getValues(i, entry); if (entry.iface == null || !entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) { continue; } final String baseIface = stackedIfaces.get(entry.iface); if (baseIface == null) { continue; } // Subtract any 464lat traffic seen for the root UID on the current base interface. adjust.iface = baseIface; adjust.rxBytes = -(entry.rxBytes + entry.rxPackets * IPV4V6_HEADER_DELTA); adjust.txBytes = -(entry.txBytes + entry.txPackets * IPV4V6_HEADER_DELTA); adjust.rxPackets = -entry.rxPackets; adjust.txPackets = -entry.txPackets; adjustments.combineValues(adjust); // For 464xlat traffic, xt_qtaguid only counts the bytes of the native IPv4 packet sent // on the stacked interface with prefix "v4-" and drops the IPv6 header size after // unwrapping. To account correctly for on-the-wire traffic, add the 20 additional bytes // difference for all packets (http://b/12249687, http:/b/33681750). entry.rxBytes += entry.rxPackets * IPV4V6_HEADER_DELTA; entry.txBytes += entry.txPackets * IPV4V6_HEADER_DELTA; stackedTraffic.setValues(i, entry); } baseTraffic.combineAllValues(adjustments); } /** * Calculate and apply adjustments to captured statistics for 464xlat traffic counted twice. * * <p>This mutates the object this method is called on. Equivalent to calling * {@link #apply464xlatAdjustments(NetworkStats, NetworkStats, Map)} with {@code this} as * base and stacked traffic. * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both. */ public void apply464xlatAdjustments(Map<String, String> stackedIfaces) { apply464xlatAdjustments(this, this, stackedIfaces); } /** * Return total statistics grouped by {@link #iface}; doesn't mutate the * original structure. Loading core/java/com/android/internal/net/NetworkStatsFactory.java +13 −47 Original line number Diff line number Diff line Loading @@ -56,11 +56,6 @@ public class NetworkStatsFactory { private static final boolean USE_NATIVE_PARSING = true; private static final boolean SANITY_CHECK_NATIVE = false; private static final String CLATD_INTERFACE_PREFIX = "v4-"; // Delta between IPv4 header (20b) and IPv6 header (40b). // Used for correct stats accounting on clatd interfaces. private static final int IPV4V6_HEADER_DELTA = 20; /** Path to {@code /proc/net/dev}. */ private final File mStatsIfaceDev; /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */ Loading Loading @@ -96,7 +91,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[] augmentWithStackedInterfacesLocked(@Nullable String[] requiredIfaces) { public static String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) { if (requiredIfaces == NetworkStats.INTERFACES_ALL) { return null; } Loading @@ -118,6 +113,15 @@ public class NetworkStatsFactory { return relatedIfaces.toArray(outArray); } /** * Applies 464xlat adjustments with ifaces noted with {@link #noteStackedIface(String, String)}. * @see NetworkStats#apply464xlatAdjustments(NetworkStats, NetworkStats, Map) */ public static void apply464xlatAdjustments(NetworkStats baseTraffic, NetworkStats stackedTraffic) { NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, sStackedIfaces); } @VisibleForTesting public static void clearStackedIfaces() { sStackedIfaces.clear(); Loading Loading @@ -289,48 +293,10 @@ public class NetworkStatsFactory { NetworkStats lastStats) throws IOException { final NetworkStats stats = readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, lastStats); // Total 464xlat traffic to subtract from uid 0 on all base interfaces. // sStackedIfaces may grow afterwards, but NetworkStats will just be resized automatically. final NetworkStats adjustments = new NetworkStats(0, sStackedIfaces.size()); NetworkStats.Entry entry = null; // For recycling // For 464xlat traffic, xt_qtaguid sees every IPv4 packet twice, once as a native IPv4 // packet on the stacked interface, and once as translated to an IPv6 packet on the // base interface. For correct stats accounting on the base interface, every 464xlat // packet needs to be subtracted from the root UID on the base interface both for tx // and rx traffic (http://b/12249687, http:/b/33681750). for (int i = 0; i < stats.size(); i++) { entry = stats.getValues(i, entry); if (entry.iface == null || !entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) { continue; } final String baseIface = sStackedIfaces.get(entry.iface); if (baseIface == null) { continue; } NetworkStats.Entry adjust = new NetworkStats.Entry(baseIface, 0, 0, 0, 0, 0, 0, 0L, 0L, 0L, 0L, 0L); // Subtract any 464lat traffic seen for the root UID on the current base interface. adjust.rxBytes -= (entry.rxBytes + entry.rxPackets * IPV4V6_HEADER_DELTA); adjust.txBytes -= (entry.txBytes + entry.txPackets * IPV4V6_HEADER_DELTA); adjust.rxPackets -= entry.rxPackets; adjust.txPackets -= entry.txPackets; adjustments.combineValues(adjust); // For 464xlat traffic, xt_qtaguid only counts the bytes of the native IPv4 packet sent // on the stacked interface with prefix "v4-" and drops the IPv6 header size after // unwrapping. To account correctly for on-the-wire traffic, add the 20 additional bytes // difference for all packets (http://b/12249687, http:/b/33681750). entry.rxBytes = entry.rxPackets * IPV4V6_HEADER_DELTA; entry.txBytes = entry.txPackets * IPV4V6_HEADER_DELTA; entry.rxPackets = 0; entry.txPackets = 0; stats.combineValues(entry); } stats.combineAllValues(adjustments); // No locking here: apply464xlatAdjustments behaves fine with an add-only ConcurrentHashMap. // TODO: remove this and only apply adjustments in NetworkStatsService. stats.apply464xlatAdjustments(sStackedIfaces); return stats; } Loading services/core/java/com/android/server/net/NetworkStatsService.java +4 −4 Original line number Diff line number Diff line Loading @@ -148,7 +148,6 @@ import java.time.ZoneOffset; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; /** * Collect and persist detailed network statistics, and provide this data to Loading Loading @@ -768,7 +767,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public NetworkStats getDetailedUidStats(String[] requiredIfaces) { try { final String[] ifacesToQuery = NetworkStatsFactory.augmentWithStackedInterfacesLocked(requiredIfaces); NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces); return getNetworkStatsUidDetail(ifacesToQuery); } catch (RemoteException e) { Log.wtf(TAG, "Error compiling UID stats", e); Loading Loading @@ -1526,12 +1525,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private NetworkStats getNetworkStatsUidDetail(String[] ifaces) throws RemoteException { // TODO: remove 464xlat adjustments from NetworkStatsFactory and apply all at once here. final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL, ifaces); // 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); uidSnapshot.combineAllValues(tetherSnapshot); final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService( Loading @@ -1541,13 +1542,12 @@ 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); uidSnapshot.combineAllValues(vtStats); } uidSnapshot.combineAllValues(mUidOperations); // TODO: apply tethering & VC 464xlat adjustments here return uidSnapshot; } Loading tests/net/java/android/net/NetworkStatsTest.java +84 −0 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.os.Process; import android.support.test.runner.AndroidJUnit4; import android.support.test.filters.SmallTest; import android.util.ArrayMap; import com.google.android.collect.Sets; Loading Loading @@ -773,6 +775,88 @@ public class NetworkStatsTest { assertEquals(entry2, stats.getValues(1, null)); } @Test public void testApply464xlatAdjustments() { final String v4Iface = "v4-wlan0"; final String baseIface = "wlan0"; final String otherIface = "other"; final int appUid = 10001; final int rootUid = Process.ROOT_UID; ArrayMap<String, String> stackedIface = new ArrayMap<>(); stackedIface.put(v4Iface, baseIface); NetworkStats.Entry otherEntry = new NetworkStats.Entry( otherIface, appUid, SET_DEFAULT, TAG_NONE, 2600 /* rxBytes */, 2 /* rxPackets */, 3800 /* txBytes */, 3 /* txPackets */, 0 /* operations */); NetworkStats stats = new NetworkStats(TEST_START, 3) .addValues(v4Iface, appUid, SET_DEFAULT, TAG_NONE, 30501490 /* rxBytes */, 22401 /* rxPackets */, 876235 /* txBytes */, 13805 /* txPackets */, 0 /* operations */) .addValues(baseIface, rootUid, SET_DEFAULT, TAG_NONE, 31113087, 22588, 1169942, 13902, 0) .addValues(otherEntry); stats.apply464xlatAdjustments(stackedIface); assertEquals(3, stats.size()); assertValues(stats, 0, v4Iface, appUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 30949510, 22401, 1152335, 13805, 0); assertValues(stats, 1, baseIface, 0, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 163577, 187, 17607, 97, 0); assertEquals(otherEntry, stats.getValues(2, null)); } @Test public void testApply464xlatAdjustments_noStackedIface() { NetworkStats.Entry firstEntry = new NetworkStats.Entry( "if1", 10002, SET_DEFAULT, TAG_NONE, 2600 /* rxBytes */, 2 /* rxPackets */, 3800 /* txBytes */, 3 /* txPackets */, 0 /* operations */); NetworkStats.Entry secondEntry = new NetworkStats.Entry( "if2", 10002, SET_DEFAULT, TAG_NONE, 5000 /* rxBytes */, 3 /* rxPackets */, 6000 /* txBytes */, 4 /* txPackets */, 0 /* operations */); NetworkStats stats = new NetworkStats(TEST_START, 2) .addValues(firstEntry) .addValues(secondEntry); // Empty map: no adjustment stats.apply464xlatAdjustments(new ArrayMap<>()); assertEquals(2, stats.size()); assertEquals(firstEntry, stats.getValues(0, null)); assertEquals(secondEntry, stats.getValues(1, null)); } private static void assertContains(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) { Loading Loading
core/java/android/net/NetworkStats.java +75 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import java.io.CharArrayWriter; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Objects; /** Loading Loading @@ -97,6 +98,11 @@ public class NetworkStats implements Parcelable { /** Denotes a request for stats at the interface and UID level. */ public static final int STATS_PER_UID = 1; private static final String CLATD_INTERFACE_PREFIX = "v4-"; // Delta between IPv4 header (20b) and IPv6 header (40b). // Used for correct stats accounting on clatd interfaces. private static final int IPV4V6_HEADER_DELTA = 20; // TODO: move fields to "mVariable" notation /** Loading Loading @@ -758,6 +764,75 @@ public class NetworkStats implements Parcelable { return result; } /** * Calculate and apply adjustments to captured statistics for 464xlat traffic counted twice. * * <p>This mutates both base and stacked traffic stats, to account respectively for * double-counted traffic and IPv4/IPv6 header size difference. * * <p>For 464xlat traffic, xt_qtaguid sees every IPv4 packet twice, once as a native IPv4 * packet on the stacked interface, and once as translated to an IPv6 packet on the * base interface. For correct stats accounting on the base interface, every 464xlat * packet needs to be subtracted from the root UID on the base interface both for tx * and rx traffic (http://b/12249687, http:/b/33681750). * * <p>This method will behave fine if {@code stackedIfaces} is an non-synchronized but add-only * {@code ConcurrentHashMap} * @param baseTraffic Traffic on the base interfaces. Will be mutated. * @param stackedTraffic Stats with traffic stacked on top of our ifaces. Will also be mutated. * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both. */ public static void apply464xlatAdjustments(NetworkStats baseTraffic, NetworkStats stackedTraffic, Map<String, String> stackedIfaces) { // Total 464xlat traffic to subtract from uid 0 on all base interfaces. // stackedIfaces may grow afterwards, but NetworkStats will just be resized automatically. final NetworkStats adjustments = new NetworkStats(0, stackedIfaces.size()); // For recycling Entry entry = null; Entry adjust = new NetworkStats.Entry(IFACE_ALL, 0, 0, 0, 0, 0, 0, 0L, 0L, 0L, 0L, 0L); for (int i = 0; i < stackedTraffic.size; i++) { entry = stackedTraffic.getValues(i, entry); if (entry.iface == null || !entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) { continue; } final String baseIface = stackedIfaces.get(entry.iface); if (baseIface == null) { continue; } // Subtract any 464lat traffic seen for the root UID on the current base interface. adjust.iface = baseIface; adjust.rxBytes = -(entry.rxBytes + entry.rxPackets * IPV4V6_HEADER_DELTA); adjust.txBytes = -(entry.txBytes + entry.txPackets * IPV4V6_HEADER_DELTA); adjust.rxPackets = -entry.rxPackets; adjust.txPackets = -entry.txPackets; adjustments.combineValues(adjust); // For 464xlat traffic, xt_qtaguid only counts the bytes of the native IPv4 packet sent // on the stacked interface with prefix "v4-" and drops the IPv6 header size after // unwrapping. To account correctly for on-the-wire traffic, add the 20 additional bytes // difference for all packets (http://b/12249687, http:/b/33681750). entry.rxBytes += entry.rxPackets * IPV4V6_HEADER_DELTA; entry.txBytes += entry.txPackets * IPV4V6_HEADER_DELTA; stackedTraffic.setValues(i, entry); } baseTraffic.combineAllValues(adjustments); } /** * Calculate and apply adjustments to captured statistics for 464xlat traffic counted twice. * * <p>This mutates the object this method is called on. Equivalent to calling * {@link #apply464xlatAdjustments(NetworkStats, NetworkStats, Map)} with {@code this} as * base and stacked traffic. * @param stackedIfaces Mapping ipv6if -> ipv4if interface where traffic is counted on both. */ public void apply464xlatAdjustments(Map<String, String> stackedIfaces) { apply464xlatAdjustments(this, this, stackedIfaces); } /** * Return total statistics grouped by {@link #iface}; doesn't mutate the * original structure. Loading
core/java/com/android/internal/net/NetworkStatsFactory.java +13 −47 Original line number Diff line number Diff line Loading @@ -56,11 +56,6 @@ public class NetworkStatsFactory { private static final boolean USE_NATIVE_PARSING = true; private static final boolean SANITY_CHECK_NATIVE = false; private static final String CLATD_INTERFACE_PREFIX = "v4-"; // Delta between IPv4 header (20b) and IPv6 header (40b). // Used for correct stats accounting on clatd interfaces. private static final int IPV4V6_HEADER_DELTA = 20; /** Path to {@code /proc/net/dev}. */ private final File mStatsIfaceDev; /** Path to {@code /proc/net/xt_qtaguid/iface_stat_all}. */ Loading Loading @@ -96,7 +91,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[] augmentWithStackedInterfacesLocked(@Nullable String[] requiredIfaces) { public static String[] augmentWithStackedInterfaces(@Nullable String[] requiredIfaces) { if (requiredIfaces == NetworkStats.INTERFACES_ALL) { return null; } Loading @@ -118,6 +113,15 @@ public class NetworkStatsFactory { return relatedIfaces.toArray(outArray); } /** * Applies 464xlat adjustments with ifaces noted with {@link #noteStackedIface(String, String)}. * @see NetworkStats#apply464xlatAdjustments(NetworkStats, NetworkStats, Map) */ public static void apply464xlatAdjustments(NetworkStats baseTraffic, NetworkStats stackedTraffic) { NetworkStats.apply464xlatAdjustments(baseTraffic, stackedTraffic, sStackedIfaces); } @VisibleForTesting public static void clearStackedIfaces() { sStackedIfaces.clear(); Loading Loading @@ -289,48 +293,10 @@ public class NetworkStatsFactory { NetworkStats lastStats) throws IOException { final NetworkStats stats = readNetworkStatsDetailInternal(limitUid, limitIfaces, limitTag, lastStats); // Total 464xlat traffic to subtract from uid 0 on all base interfaces. // sStackedIfaces may grow afterwards, but NetworkStats will just be resized automatically. final NetworkStats adjustments = new NetworkStats(0, sStackedIfaces.size()); NetworkStats.Entry entry = null; // For recycling // For 464xlat traffic, xt_qtaguid sees every IPv4 packet twice, once as a native IPv4 // packet on the stacked interface, and once as translated to an IPv6 packet on the // base interface. For correct stats accounting on the base interface, every 464xlat // packet needs to be subtracted from the root UID on the base interface both for tx // and rx traffic (http://b/12249687, http:/b/33681750). for (int i = 0; i < stats.size(); i++) { entry = stats.getValues(i, entry); if (entry.iface == null || !entry.iface.startsWith(CLATD_INTERFACE_PREFIX)) { continue; } final String baseIface = sStackedIfaces.get(entry.iface); if (baseIface == null) { continue; } NetworkStats.Entry adjust = new NetworkStats.Entry(baseIface, 0, 0, 0, 0, 0, 0, 0L, 0L, 0L, 0L, 0L); // Subtract any 464lat traffic seen for the root UID on the current base interface. adjust.rxBytes -= (entry.rxBytes + entry.rxPackets * IPV4V6_HEADER_DELTA); adjust.txBytes -= (entry.txBytes + entry.txPackets * IPV4V6_HEADER_DELTA); adjust.rxPackets -= entry.rxPackets; adjust.txPackets -= entry.txPackets; adjustments.combineValues(adjust); // For 464xlat traffic, xt_qtaguid only counts the bytes of the native IPv4 packet sent // on the stacked interface with prefix "v4-" and drops the IPv6 header size after // unwrapping. To account correctly for on-the-wire traffic, add the 20 additional bytes // difference for all packets (http://b/12249687, http:/b/33681750). entry.rxBytes = entry.rxPackets * IPV4V6_HEADER_DELTA; entry.txBytes = entry.txPackets * IPV4V6_HEADER_DELTA; entry.rxPackets = 0; entry.txPackets = 0; stats.combineValues(entry); } stats.combineAllValues(adjustments); // No locking here: apply464xlatAdjustments behaves fine with an add-only ConcurrentHashMap. // TODO: remove this and only apply adjustments in NetworkStatsService. stats.apply464xlatAdjustments(sStackedIfaces); return stats; } Loading
services/core/java/com/android/server/net/NetworkStatsService.java +4 −4 Original line number Diff line number Diff line Loading @@ -148,7 +148,6 @@ import java.time.ZoneOffset; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; /** * Collect and persist detailed network statistics, and provide this data to Loading Loading @@ -768,7 +767,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public NetworkStats getDetailedUidStats(String[] requiredIfaces) { try { final String[] ifacesToQuery = NetworkStatsFactory.augmentWithStackedInterfacesLocked(requiredIfaces); NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces); return getNetworkStatsUidDetail(ifacesToQuery); } catch (RemoteException e) { Log.wtf(TAG, "Error compiling UID stats", e); Loading Loading @@ -1526,12 +1525,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private NetworkStats getNetworkStatsUidDetail(String[] ifaces) throws RemoteException { // TODO: remove 464xlat adjustments from NetworkStatsFactory and apply all at once here. final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL, ifaces); // 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); uidSnapshot.combineAllValues(tetherSnapshot); final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService( Loading @@ -1541,13 +1542,12 @@ 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); uidSnapshot.combineAllValues(vtStats); } uidSnapshot.combineAllValues(mUidOperations); // TODO: apply tethering & VC 464xlat adjustments here return uidSnapshot; } Loading
tests/net/java/android/net/NetworkStatsTest.java +84 −0 Original line number Diff line number Diff line Loading @@ -39,8 +39,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import android.os.Process; import android.support.test.runner.AndroidJUnit4; import android.support.test.filters.SmallTest; import android.util.ArrayMap; import com.google.android.collect.Sets; Loading Loading @@ -773,6 +775,88 @@ public class NetworkStatsTest { assertEquals(entry2, stats.getValues(1, null)); } @Test public void testApply464xlatAdjustments() { final String v4Iface = "v4-wlan0"; final String baseIface = "wlan0"; final String otherIface = "other"; final int appUid = 10001; final int rootUid = Process.ROOT_UID; ArrayMap<String, String> stackedIface = new ArrayMap<>(); stackedIface.put(v4Iface, baseIface); NetworkStats.Entry otherEntry = new NetworkStats.Entry( otherIface, appUid, SET_DEFAULT, TAG_NONE, 2600 /* rxBytes */, 2 /* rxPackets */, 3800 /* txBytes */, 3 /* txPackets */, 0 /* operations */); NetworkStats stats = new NetworkStats(TEST_START, 3) .addValues(v4Iface, appUid, SET_DEFAULT, TAG_NONE, 30501490 /* rxBytes */, 22401 /* rxPackets */, 876235 /* txBytes */, 13805 /* txPackets */, 0 /* operations */) .addValues(baseIface, rootUid, SET_DEFAULT, TAG_NONE, 31113087, 22588, 1169942, 13902, 0) .addValues(otherEntry); stats.apply464xlatAdjustments(stackedIface); assertEquals(3, stats.size()); assertValues(stats, 0, v4Iface, appUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 30949510, 22401, 1152335, 13805, 0); assertValues(stats, 1, baseIface, 0, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 163577, 187, 17607, 97, 0); assertEquals(otherEntry, stats.getValues(2, null)); } @Test public void testApply464xlatAdjustments_noStackedIface() { NetworkStats.Entry firstEntry = new NetworkStats.Entry( "if1", 10002, SET_DEFAULT, TAG_NONE, 2600 /* rxBytes */, 2 /* rxPackets */, 3800 /* txBytes */, 3 /* txPackets */, 0 /* operations */); NetworkStats.Entry secondEntry = new NetworkStats.Entry( "if2", 10002, SET_DEFAULT, TAG_NONE, 5000 /* rxBytes */, 3 /* rxPackets */, 6000 /* txBytes */, 4 /* txPackets */, 0 /* operations */); NetworkStats stats = new NetworkStats(TEST_START, 2) .addValues(firstEntry) .addValues(secondEntry); // Empty map: no adjustment stats.apply464xlatAdjustments(new ArrayMap<>()); assertEquals(2, stats.size()); assertEquals(firstEntry, stats.getValues(0, null)); assertEquals(secondEntry, stats.getValues(1, null)); } private static void assertContains(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) { Loading