From b5d55e302d2253e4bfb233ea705caf258cdc4cb9 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 10 Aug 2011 17:53:27 -0700 Subject: [PATCH] Foreground/background network stats using sets. Teach NetworkStats about "counter sets" coming from kernel, and use them to track usage in foreground/background. Add AID_NET_BW_ACCT to system_server so it can control counter sets. Move to composite key of NetworkIdentitySet, UID, set, and tag when recording historical usage. Persisting still clusters by identity, since that is heaviest object. Request async stats poll during systemReady() to bootstrap later delta calculations. Reset kernel counters when UID removed. Update various tests. Bug: 5105592, 5146067 Change-Id: Idabec9e3ffcaf212879821515602ecde0a03de8c --- .../android/net/INetworkStatsService.aidl | 4 +- core/java/android/net/NetworkStats.java | 94 +++- .../java/android/net/NetworkStatsHistory.java | 9 +- core/java/android/net/TrafficStats.java | 4 - .../com/android/internal/os/ZygoteInit.java | 2 +- .../server/NetworkManagementSocketTagger.java | 25 +- .../android/bandwidthtest/BandwidthTest.java | 3 +- .../src/android/net/NetworkStatsTest.java | 98 ++-- .../server/NetworkManagementService.java | 9 +- .../com/android/server/ThrottleService.java | 4 +- .../net/NetworkPolicyManagerService.java | 7 + .../server/net/NetworkStatsService.java | 342 +++++++------ .../res/raw/xt_qtaguid_typical_with_set | 13 + .../server/BroadcastInterceptingContext.java | 17 + .../server/NetworkManagementServiceTest.java | 62 ++- .../NetworkPolicyManagerServiceTest.java | 30 +- .../server/NetworkStatsServiceTest.java | 454 ++++++++++-------- .../android/server/ThrottleServiceTest.java | 5 +- 18 files changed, 723 insertions(+), 459 deletions(-) create mode 100644 services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index b65506c411e80..0e883cf8ac55a 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -26,7 +26,7 @@ interface INetworkStatsService { /** Return historical network layer stats for traffic that matches template. */ NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template, int fields); /** Return historical network layer stats for specific UID traffic that matches template. */ - NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int tag, int fields); + NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int set, int tag, int fields); /** Return network layer usage summary for traffic that matches template. */ NetworkStats getSummaryForNetwork(in NetworkTemplate template, long start, long end); @@ -38,6 +38,8 @@ interface INetworkStatsService { /** Increment data layer count of operations performed for UID and tag. */ void incrementOperationCount(int uid, int tag, int operationCount); + /** Mark given UID as being in foreground for stats purposes. */ + void setUidForeground(int uid, boolean uidForeground); /** Force update of statistics. */ void forceUpdate(); diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index f2fcb8fad852b..272545d0dc5dd 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -42,7 +42,13 @@ public class NetworkStats implements Parcelable { public static final String IFACE_ALL = null; /** {@link #uid} value when UID details unavailable. */ public static final int UID_ALL = -1; - /** {@link #tag} value for without tag. */ + /** {@link #set} value when all sets combined. */ + public static final int SET_ALL = -1; + /** {@link #set} value where background data is accounted. */ + public static final int SET_DEFAULT = 0; + /** {@link #set} value where foreground data is accounted. */ + public static final int SET_FOREGROUND = 1; + /** {@link #tag} value for total data across all tags. */ public static final int TAG_NONE = 0; /** @@ -53,6 +59,7 @@ public class NetworkStats implements Parcelable { private int size; private String[] iface; private int[] uid; + private int[] set; private int[] tag; private long[] rxBytes; private long[] rxPackets; @@ -63,6 +70,7 @@ public class NetworkStats implements Parcelable { public static class Entry { public String iface; public int uid; + public int set; public int tag; public long rxBytes; public long rxPackets; @@ -71,17 +79,19 @@ public class NetworkStats implements Parcelable { public long operations; public Entry() { - this(IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L); + this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); } public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { - this(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, operations); + this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, + operations); } - public Entry(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, - long txPackets, long operations) { + public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, + long txBytes, long txPackets, long operations) { this.iface = iface; this.uid = uid; + this.set = set; this.tag = tag; this.rxBytes = rxBytes; this.rxPackets = rxPackets; @@ -96,6 +106,7 @@ public class NetworkStats implements Parcelable { this.size = 0; this.iface = new String[initialSize]; this.uid = new int[initialSize]; + this.set = new int[initialSize]; this.tag = new int[initialSize]; this.rxBytes = new long[initialSize]; this.rxPackets = new long[initialSize]; @@ -109,6 +120,7 @@ public class NetworkStats implements Parcelable { size = parcel.readInt(); iface = parcel.createStringArray(); uid = parcel.createIntArray(); + set = parcel.createIntArray(); tag = parcel.createIntArray(); rxBytes = parcel.createLongArray(); rxPackets = parcel.createLongArray(); @@ -123,6 +135,7 @@ public class NetworkStats implements Parcelable { dest.writeInt(size); dest.writeStringArray(iface); dest.writeIntArray(uid); + dest.writeIntArray(set); dest.writeIntArray(tag); dest.writeLongArray(rxBytes); dest.writeLongArray(rxPackets); @@ -131,15 +144,18 @@ public class NetworkStats implements Parcelable { dest.writeLongArray(operations); } - public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets, - long txBytes, long txPackets) { - return addValues(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, 0L); + // @VisibleForTesting + public NetworkStats addIfaceValues( + String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { + return addValues( + iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L); } - public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets, - long txBytes, long txPackets, long operations) { - return addValues( - new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); + // @VisibleForTesting + public NetworkStats addValues(String iface, int uid, int set, int tag, long rxBytes, + long rxPackets, long txBytes, long txPackets, long operations) { + return addValues(new Entry( + iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); } /** @@ -151,6 +167,7 @@ public class NetworkStats implements Parcelable { final int newLength = Math.max(iface.length, 10) * 3 / 2; iface = Arrays.copyOf(iface, newLength); uid = Arrays.copyOf(uid, newLength); + set = Arrays.copyOf(set, newLength); tag = Arrays.copyOf(tag, newLength); rxBytes = Arrays.copyOf(rxBytes, newLength); rxPackets = Arrays.copyOf(rxPackets, newLength); @@ -161,6 +178,7 @@ public class NetworkStats implements Parcelable { iface[size] = entry.iface; uid[size] = entry.uid; + set[size] = entry.set; tag[size] = entry.tag; rxBytes[size] = entry.rxBytes; rxPackets[size] = entry.rxPackets; @@ -179,6 +197,7 @@ public class NetworkStats implements Parcelable { final Entry entry = recycle != null ? recycle : new Entry(); entry.iface = iface[i]; entry.uid = uid[i]; + entry.set = set[i]; entry.tag = tag[i]; entry.rxBytes = rxBytes[i]; entry.rxPackets = rxPackets[i]; @@ -201,19 +220,26 @@ public class NetworkStats implements Parcelable { return iface.length; } + @Deprecated public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { return combineValues( - new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); + iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes, txPackets, operations); + } + + public NetworkStats combineValues(String iface, int uid, int set, int tag, long rxBytes, + long rxPackets, long txBytes, long txPackets, long operations) { + return combineValues(new Entry( + iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); } /** * Combine given values with an existing row, or create a new row if - * {@link #findIndex(String, int, int)} is unable to find match. Can also be - * used to subtract values from existing rows. + * {@link #findIndex(String, int, int, int)} is unable to find match. Can + * also be used to subtract values from existing rows. */ public NetworkStats combineValues(Entry entry) { - final int i = findIndex(entry.iface, entry.uid, entry.tag); + final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag); if (i == -1) { // only create new entry when positive contribution addValues(entry); @@ -230,9 +256,10 @@ public class NetworkStats implements Parcelable { /** * Find first stats index that matches the requested parameters. */ - public int findIndex(String iface, int uid, int tag) { + public int findIndex(String iface, int uid, int set, int tag) { for (int i = 0; i < size; i++) { - if (Objects.equal(iface, this.iface[i]) && uid == this.uid[i] && tag == this.tag[i]) { + if (Objects.equal(iface, this.iface[i]) && uid == this.uid[i] && set == this.set[i] + && tag == this.tag[i]) { return i; } } @@ -246,7 +273,7 @@ public class NetworkStats implements Parcelable { */ public void spliceOperationsFrom(NetworkStats stats) { for (int i = 0; i < size; i++) { - final int j = stats.findIndex(IFACE_ALL, uid[i], tag[i]); + final int j = stats.findIndex(IFACE_ALL, uid[i], set[i], tag[i]); if (j == -1) { operations[i] = 0; } else { @@ -332,10 +359,11 @@ public class NetworkStats implements Parcelable { for (int i = 0; i < size; i++) { entry.iface = iface[i]; entry.uid = uid[i]; + entry.set = set[i]; entry.tag = tag[i]; // find remote row that matches, and subtract - final int j = value.findIndex(entry.iface, entry.uid, entry.tag); + final int j = value.findIndex(entry.iface, entry.uid, entry.set, entry.tag); if (j == -1) { // newly appearing row, return entire value entry.rxBytes = rxBytes[i]; @@ -377,7 +405,8 @@ public class NetworkStats implements Parcelable { pw.print(prefix); pw.print(" iface="); pw.print(iface[i]); pw.print(" uid="); pw.print(uid[i]); - pw.print(" tag=0x"); pw.print(Integer.toHexString(tag[i])); + pw.print(" set="); pw.print(setToString(set[i])); + pw.print(" tag="); pw.print(tagToString(tag[i])); pw.print(" rxBytes="); pw.print(rxBytes[i]); pw.print(" rxPackets="); pw.print(rxPackets[i]); pw.print(" txBytes="); pw.print(txBytes[i]); @@ -386,6 +415,29 @@ public class NetworkStats implements Parcelable { } } + /** + * Return text description of {@link #set} value. + */ + public static String setToString(int set) { + switch (set) { + case SET_ALL: + return "ALL"; + case SET_DEFAULT: + return "DEFAULT"; + case SET_FOREGROUND: + return "FOREGROUND"; + default: + return "UNKNOWN"; + } + } + + /** + * Return text description of {@link #tag} value. + */ + public static String tagToString(int tag) { + return "0x" + Integer.toHexString(tag); + } + @Override public String toString() { final CharArrayWriter writer = new CharArrayWriter(); diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index 4ba44cac296f2..b4f15acff1c9d 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -17,6 +17,7 @@ package android.net; import static android.net.NetworkStats.IFACE_ALL; +import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.DataStreamUtils.readFullLongArray; @@ -215,8 +216,8 @@ public class NetworkStatsHistory implements Parcelable { */ @Deprecated public void recordData(long start, long end, long rxBytes, long txBytes) { - recordData(start, end, - new NetworkStats.Entry(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0L)); + recordData(start, end, new NetworkStats.Entry( + IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0L)); } /** @@ -269,7 +270,7 @@ public class NetworkStatsHistory implements Parcelable { */ public void recordEntireHistory(NetworkStatsHistory input) { final NetworkStats.Entry entry = new NetworkStats.Entry( - IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L); + IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); for (int i = 0; i < input.bucketCount; i++) { final long start = input.bucketStart[i]; final long end = start + input.bucketDuration; @@ -422,7 +423,7 @@ public class NetworkStatsHistory implements Parcelable { ensureBuckets(start, end); final NetworkStats.Entry entry = new NetworkStats.Entry( - IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L); + IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); final Random r = new Random(); while (rxBytes > 1024 || rxPackets > 128 || txBytes > 1024 || txPackets > 128 || operations > 32) { diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index f138e49140fa0..c2c5c183d337e 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -205,10 +205,6 @@ public class TrafficStats { * @param operationCount Number of operations to increment count by. */ public static void incrementOperationCount(int tag, int operationCount) { - if (operationCount < 0) { - throw new IllegalArgumentException("operation count can only be incremented"); - } - final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); final int uid = android.os.Process.myUid(); diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 16336e0e81b38..9c45dc64f4697 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -474,7 +474,7 @@ public class ZygoteInit { String args[] = { "--setuid=1000", "--setgid=1000", - "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006", + "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007", "--capabilities=130104352,130104352", "--runtime-init", "--nice-name=system_server", diff --git a/core/java/com/android/server/NetworkManagementSocketTagger.java b/core/java/com/android/server/NetworkManagementSocketTagger.java index 4667e5fc978d0..23af37e6188d4 100644 --- a/core/java/com/android/server/NetworkManagementSocketTagger.java +++ b/core/java/com/android/server/NetworkManagementSocketTagger.java @@ -16,8 +16,11 @@ package com.android.server; +import android.net.NetworkStats; import android.os.SystemProperties; import android.util.Log; +import android.util.Slog; + import dalvik.system.SocketTagger; import libcore.io.IoUtils; @@ -122,6 +125,26 @@ public final class NetworkManagementSocketTagger extends SocketTagger { public int statsUid = -1; } + public static void setKernelCounterSet(int uid, int counterSet) { + final StringBuilder command = new StringBuilder(); + command.append("s ").append(counterSet).append(" ").append(uid); + try { + internalModuleCtrl(command.toString()); + } catch (IOException e) { + Slog.w(TAG, "problem changing counter set for uid " + uid + " : " + e); + } + } + + public static void resetKernelUidStats(int uid) { + final StringBuilder command = new StringBuilder(); + command.append("d 0 ").append(uid); + try { + internalModuleCtrl(command.toString()); + } catch (IOException e) { + Slog.w(TAG, "problem clearing counters for uid " + uid + " : " + e); + } + } + /** * Sends commands to the kernel netfilter module. * @@ -141,7 +164,7 @@ public final class NetworkManagementSocketTagger extends SocketTagger { *
  • *_tag are 64bit values
  • * */ - private void internalModuleCtrl(String cmd) throws IOException { + private static void internalModuleCtrl(String cmd) throws IOException { if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return; // TODO: migrate to native library for tagging commands diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java index 73c92b08d8769..5ee8fdd9b50ff 100644 --- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java +++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java @@ -164,7 +164,8 @@ public class BandwidthTest extends InstrumentationTestCase { File snd_stat = new File (root_filepath + "tcp_snd"); int tx = BandwidthTestUtil.parseIntValueFromFile(snd_stat); NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); - stats.addValues(NetworkStats.IFACE_ALL, uid, NetworkStats.TAG_NONE, rx, 0, tx, 0); + stats.addValues(NetworkStats.IFACE_ALL, uid, NetworkStats.SET_DEFAULT, + NetworkStats.TAG_NONE, rx, 0, tx, 0, 0); return stats; } diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java index 69ad0f45229fc..47ba88af47359 100644 --- a/core/tests/coretests/src/android/net/NetworkStatsTest.java +++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java @@ -16,6 +16,7 @@ package android.net; +import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.TAG_NONE; import android.test.suitebuilder.annotation.SmallTest; @@ -31,14 +32,14 @@ public class NetworkStatsTest extends TestCase { public void testFindIndex() throws Exception { final NetworkStats stats = new NetworkStats(TEST_START, 3) - .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 10) - .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 11) - .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L, 12); + .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 10) + .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 11) + .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 12); - assertEquals(2, stats.findIndex(TEST_IFACE, 102, TAG_NONE)); - assertEquals(2, stats.findIndex(TEST_IFACE, 102, TAG_NONE)); - assertEquals(0, stats.findIndex(TEST_IFACE, 100, TAG_NONE)); - assertEquals(-1, stats.findIndex(TEST_IFACE, 6, TAG_NONE)); + assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE)); + assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE)); + assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE)); + assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE)); } public void testAddEntryGrow() throws Exception { @@ -47,98 +48,99 @@ public class NetworkStatsTest extends TestCase { assertEquals(0, stats.size()); assertEquals(2, stats.internalSize()); - stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L, 3); - stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L, 4); + stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 1L, 1L, 2L, 2L, 3); + stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 2L, 2L, 2L, 2L, 4); assertEquals(2, stats.size()); assertEquals(2, stats.internalSize()); - stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L, 7); - stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L, 8); - stats.addValues(TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L, 10); + stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 3L, 30L, 4L, 40L, 7); + stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 4L, 40L, 4L, 40L, 8); + stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 5L, 50L, 5L, 50L, 10); assertEquals(5, stats.size()); assertTrue(stats.internalSize() >= 5); - assertValues(stats, 0, TEST_IFACE, TEST_UID, TAG_NONE, 1L, 1L, 2L, 2L, 3); - assertValues(stats, 1, TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L, 2L, 2L, 4); - assertValues(stats, 2, TEST_IFACE, TEST_UID, TAG_NONE, 3L, 30L, 4L, 40L, 7); - assertValues(stats, 3, TEST_IFACE, TEST_UID, TAG_NONE, 4L, 40L, 4L, 40L, 8); - assertValues(stats, 4, TEST_IFACE, TEST_UID, TAG_NONE, 5L, 50L, 5L, 50L, 10); + assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 1L, 1L, 2L, 2L, 3); + assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 2L, 2L, 2L, 2L, 4); + assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 3L, 30L, 4L, 40L, 7); + assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 4L, 40L, 4L, 40L, 8); + assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, 5L, 50L, 5L, 50L, 10); } public void testCombineExisting() throws Exception { final NetworkStats stats = new NetworkStats(TEST_START, 10); - stats.addValues(TEST_IFACE, 1001, TAG_NONE, 512L, 4L, 256L, 2L, 10); - stats.addValues(TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L, 2); - stats.combineValues(TEST_IFACE, 1001, TAG_NONE, -128L, -1L, -128L, -1L, -1); + stats.addValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 10); + stats.addValues(TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2); + stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L, -128L, -1L, -1); - assertValues(stats, 0, TEST_IFACE, 1001, TAG_NONE, 384L, 3L, 128L, 1L, 9); - assertValues(stats, 1, TEST_IFACE, 1001, 0xff, 128L, 1L, 128L, 1L, 2); + assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, 384L, 3L, 128L, 1L, 9); + assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, 128L, 1L, 128L, 1L, 2); // now try combining that should create row - stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L, 3); - assertValues(stats, 2, TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L, 3); - stats.combineValues(TEST_IFACE, 5005, TAG_NONE, 128L, 1L, 128L, 1L, 3); - assertValues(stats, 2, TEST_IFACE, 5005, TAG_NONE, 256L, 2L, 256L, 2L, 6); + stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3); + assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3); + stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3); + assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 256L, 2L, 256L, 2L, 6); } public void testSubtractIdenticalData() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats after = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats result = after.subtract(before); // identical data should result in zero delta - assertValues(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L, 0); - assertValues(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L, 0); + assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0); + assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0); } public void testSubtractIdenticalRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats after = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, TAG_NONE, 1025L, 9L, 2L, 1L, 15) - .addValues(TEST_IFACE, 101, TAG_NONE, 3L, 1L, 1028L, 9L, 20); + .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1025L, 9L, 2L, 1L, 15) + .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 1028L, 9L, 20); final NetworkStats result = after.subtract(before); // expect delta between measurements - assertValues(result, 0, TEST_IFACE, 100, TAG_NONE, 1L, 1L, 2L, 1L, 4); - assertValues(result, 1, TEST_IFACE, 101, TAG_NONE, 3L, 1L, 4L, 1L, 8); + assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1L, 1L, 2L, 1L, 4); + assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 3L, 1L, 4L, 1L, 8); } public void testSubtractNewRows() throws Exception { final NetworkStats before = new NetworkStats(TEST_START, 2) - .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12); + .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12); final NetworkStats after = new NetworkStats(TEST_START, 3) - .addValues(TEST_IFACE, 100, TAG_NONE, 1024L, 8L, 0L, 0L, 11) - .addValues(TEST_IFACE, 101, TAG_NONE, 0L, 0L, 1024L, 8L, 12) - .addValues(TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L, 20); + .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 1024L, 8L, 0L, 0L, 11) + .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 1024L, 8L, 12) + .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20); final NetworkStats result = after.subtract(before); // its okay to have new rows - assertValues(result, 0, TEST_IFACE, 100, TAG_NONE, 0L, 0L, 0L, 0L, 0); - assertValues(result, 1, TEST_IFACE, 101, TAG_NONE, 0L, 0L, 0L, 0L, 0); - assertValues(result, 2, TEST_IFACE, 102, TAG_NONE, 1024L, 8L, 1024L, 8L, 20); + assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0); + assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0); + assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 20); } - private static void assertValues(NetworkStats stats, int index, String iface, int uid, int tag, - long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) { + private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set, + int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) { final NetworkStats.Entry entry = stats.getValues(index, null); assertEquals(iface, entry.iface); assertEquals(uid, entry.uid); + assertEquals(set, entry.set); assertEquals(tag, entry.tag); assertEquals(rxBytes, entry.rxBytes); assertEquals(rxPackets, entry.rxPackets); diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 782e7d7acdd55..a854db00b83d9 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -18,6 +18,7 @@ package com.android.server; import static android.Manifest.permission.MANAGE_NETWORK_POLICY; import static android.net.NetworkStats.IFACE_ALL; +import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.provider.Settings.Secure.NETSTATS_ENABLED; @@ -88,8 +89,9 @@ class NetworkManagementService extends INetworkManagementService.Stub { /** {@link #mStatsXtUid} headers. */ private static final String KEY_IFACE = "iface"; - private static final String KEY_TAG_HEX = "acct_tag_hex"; private static final String KEY_UID = "uid_tag_int"; + private static final String KEY_COUNTER_SET = "cnt_set"; + private static final String KEY_TAG_HEX = "acct_tag_hex"; private static final String KEY_RX_BYTES = "rx_bytes"; private static final String KEY_RX_PACKETS = "rx_packets"; private static final String KEY_TX_BYTES = "tx_bytes"; @@ -1041,6 +1043,7 @@ class NetworkManagementService extends INetworkManagementService.Stub { try { entry.iface = values.get(0); entry.uid = UID_ALL; + entry.set = SET_DEFAULT; entry.tag = TAG_NONE; entry.rxBytes = Long.parseLong(values.get(1)); entry.rxPackets = Long.parseLong(values.get(2)); @@ -1071,6 +1074,7 @@ class NetworkManagementService extends INetworkManagementService.Stub { entry.iface = iface; entry.uid = UID_ALL; + entry.set = SET_DEFAULT; entry.tag = TAG_NONE; entry.rxBytes = readSingleLongFromFile(new File(ifacePath, "rx_bytes")); entry.rxPackets = readSingleLongFromFile(new File(ifacePath, "rx_packets")); @@ -1319,8 +1323,9 @@ class NetworkManagementService extends INetworkManagementService.Stub { try { entry.iface = parsed.get(KEY_IFACE); - entry.tag = kernelToTag(parsed.get(KEY_TAG_HEX)); entry.uid = getParsedInt(parsed, KEY_UID); + entry.set = getParsedInt(parsed, KEY_COUNTER_SET); + entry.tag = kernelToTag(parsed.get(KEY_TAG_HEX)); entry.rxBytes = getParsedLong(parsed, KEY_RX_BYTES); entry.rxPackets = getParsedLong(parsed, KEY_RX_PACKETS); entry.txBytes = getParsedLong(parsed, KEY_TX_BYTES); diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java index cd649ce4c5548..24b6ac3c37747 100644 --- a/services/java/com/android/server/ThrottleService.java +++ b/services/java/com/android/server/ThrottleService.java @@ -512,8 +512,8 @@ public class ThrottleService extends IThrottleManager.Stub { long incWrite = 0; try { final NetworkStats stats = mNMService.getNetworkStatsSummary(); - final int index = stats.findIndex( - mIface, NetworkStats.UID_ALL, NetworkStats.TAG_NONE); + final int index = stats.findIndex(mIface, NetworkStats.UID_ALL, + NetworkStats.SET_DEFAULT, NetworkStats.TAG_NONE); if (index != -1) { final NetworkStats.Entry entry = stats.getValues(index, null); diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index a075255020035..9c3d166c5481f 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -1313,6 +1313,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // dispatch changed rule to existing listeners mHandler.obtainMessage(MSG_RULES_CHANGED, uid, uidRules).sendToTarget(); + + try { + // adjust stats accounting based on foreground status + mNetworkStats.setUidForeground(uid, uidForeground); + } catch (RemoteException e) { + Slog.w(TAG, "problem dispatching foreground change"); + } } private Handler.Callback mHandlerCallback = new Handler.Callback() { diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index deca7a91cfa49..c911687ab7a25 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -26,6 +26,9 @@ import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.EXTRA_UID; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.NetworkStats.IFACE_ALL; +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 android.net.NetworkStats.UID_ALL; import static android.net.TrafficStats.UID_REMOVED; @@ -40,6 +43,8 @@ import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static com.android.internal.util.Preconditions.checkNotNull; +import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats; +import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet; import android.app.AlarmManager; import android.app.IAlarmManager; @@ -63,17 +68,20 @@ import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.os.INetworkManagementService; +import android.os.Message; import android.os.PowerManager; import android.os.RemoteException; import android.os.SystemClock; import android.provider.Settings; import android.telephony.TelephonyManager; -import android.util.LongSparseArray; import android.util.NtpTrustedTime; import android.util.Slog; +import android.util.SparseIntArray; import android.util.TrustedTime; import com.android.internal.os.AtomicFile; +import com.android.internal.util.Objects; +import com.google.android.collect.Lists; import com.google.android.collect.Maps; import com.google.android.collect.Sets; @@ -88,6 +96,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.net.ProtocolException; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -109,6 +119,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static final int VERSION_UID_INIT = 1; private static final int VERSION_UID_WITH_IDENT = 2; private static final int VERSION_UID_WITH_TAG = 3; + private static final int VERSION_UID_WITH_SET = 4; + + private static final int MSG_FORCE_UPDATE = 0x1; private final Context mContext; private final INetworkManagementService mNetworkManager; @@ -156,8 +169,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { /** Set of historical network layer stats for known networks. */ private HashMap mNetworkStats = Maps.newHashMap(); /** Set of historical network layer stats for known UIDs. */ - private HashMap> mUidStats = - Maps.newHashMap(); + private HashMap mUidStats = Maps.newHashMap(); /** Flag if {@link #mUidStats} have been loaded from disk. */ private boolean mUidStatsLoaded = false; @@ -167,6 +179,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private NetworkStats mLastUidSnapshot; + /** Current counter sets for each UID. */ + private SparseIntArray mActiveUidCounterSet = new SparseIntArray(); + /** Data layer operation counters for splicing into other structures. */ private NetworkStats mOperations = new NetworkStats(0L, 10); private NetworkStats mLastOperationsSnapshot; @@ -177,11 +192,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final AtomicFile mNetworkFile; private final AtomicFile mUidFile; - // TODO: collect detailed uid stats, storing tag-granularity data until next - // dropbox, and uid summary for a specific bucket count. - - // TODO: periodically compile statistics and send to dropbox. - public NetworkStatsService( Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) { this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context), @@ -207,7 +217,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mHandlerThread = new HandlerThread(TAG); mHandlerThread.start(); - mHandler = new Handler(mHandlerThread.getLooper()); + mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback); mNetworkFile = new AtomicFile(new File(systemDir, "netstats.bin")); mUidFile = new AtomicFile(new File(systemDir, "netstats_uid.bin")); @@ -246,6 +256,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (RemoteException e) { Slog.w(TAG, "unable to register poll alarm"); } + + // kick off background poll to bootstrap deltas + mHandler.obtainMessage(MSG_FORCE_UPDATE).sendToTarget(); } private void shutdownLocked() { @@ -302,24 +315,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public NetworkStatsHistory getHistoryForUid( - NetworkTemplate template, int uid, int tag, int fields) { + NetworkTemplate template, int uid, int set, int tag, int fields) { mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); synchronized (mStatsLock) { ensureUidStatsLoadedLocked(); - final long packed = packUidAndTag(uid, tag); // combine all interfaces that match template final NetworkStatsHistory combined = new NetworkStatsHistory( mSettings.getUidBucketDuration(), estimateUidBuckets(), fields); - for (NetworkIdentitySet ident : mUidStats.keySet()) { - if (templateMatches(template, ident)) { - final NetworkStatsHistory history = mUidStats.get(ident).get(packed); - if (history != null) { - combined.recordEntireHistory(history); - } + for (UidStatsKey key : mUidStats.keySet()) { + final boolean setMatches = set == SET_ALL || key.set == set; + if (templateMatches(template, key.ident) && key.uid == uid && setMatches + && key.tag == tag) { + final NetworkStatsHistory history = mUidStats.get(key); + combined.recordEntireHistory(history); } } + return combined; } } @@ -371,33 +384,27 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final NetworkStats.Entry entry = new NetworkStats.Entry(); NetworkStatsHistory.Entry historyEntry = null; - for (NetworkIdentitySet ident : mUidStats.keySet()) { - if (templateMatches(template, ident)) { - final LongSparseArray uidStats = mUidStats.get(ident); - for (int i = 0; i < uidStats.size(); i++) { - final long packed = uidStats.keyAt(i); - final int uid = unpackUid(packed); - final int tag = unpackTag(packed); + for (UidStatsKey key : mUidStats.keySet()) { + if (templateMatches(template, key.ident)) { + // always include summary under TAG_NONE, and include + // other tags when requested. + if (key.tag == TAG_NONE || includeTags) { + final NetworkStatsHistory history = mUidStats.get(key); + historyEntry = history.getValues(start, end, now, historyEntry); - // always include summary under TAG_NONE, and include - // other tags when requested. - if (tag == TAG_NONE || includeTags) { - final NetworkStatsHistory history = uidStats.valueAt(i); - historyEntry = history.getValues(start, end, now, historyEntry); + entry.iface = IFACE_ALL; + entry.uid = key.uid; + entry.set = key.set; + entry.tag = key.tag; + entry.rxBytes = historyEntry.rxBytes; + entry.rxPackets = historyEntry.rxPackets; + entry.txBytes = historyEntry.txBytes; + entry.txPackets = historyEntry.txPackets; + entry.operations = historyEntry.operations; - entry.iface = IFACE_ALL; - entry.uid = uid; - entry.tag = tag; - entry.rxBytes = historyEntry.rxBytes; - entry.rxPackets = historyEntry.rxPackets; - entry.txBytes = historyEntry.txBytes; - entry.txPackets = historyEntry.txPackets; - entry.operations = historyEntry.operations; - - if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0 - || entry.txPackets > 0 || entry.operations > 0) { - stats.combineValues(entry); - } + if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0 + || entry.txPackets > 0 || entry.operations > 0) { + stats.combineValues(entry); } } } @@ -437,8 +444,31 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG); } + if (operationCount < 0) { + throw new IllegalArgumentException("operation count can only be incremented"); + } + if (tag == TAG_NONE) { + throw new IllegalArgumentException("operation count must have specific tag"); + } + synchronized (mStatsLock) { - mOperations.combineValues(IFACE_ALL, uid, tag, 0L, 0L, 0L, 0L, operationCount); + final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT); + mOperations.combineValues(IFACE_ALL, uid, set, tag, 0L, 0L, 0L, 0L, operationCount); + mOperations.combineValues(IFACE_ALL, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount); + } + } + + @Override + public void setUidForeground(int uid, boolean uidForeground) { + mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG); + + synchronized (mStatsLock) { + final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT; + final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT); + if (oldSet != set) { + mActiveUidCounterSet.put(uid, set); + setKernelCounterSet(uid, set); + } } } @@ -601,7 +631,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { NetworkStats.Entry entry = null; for (String iface : persistDelta.getUniqueIfaces()) { - final int index = persistDelta.findIndex(iface, UID_ALL, TAG_NONE); + final int index = persistDelta.findIndex(iface, UID_ALL, SET_DEFAULT, TAG_NONE); entry = persistDelta.getValues(index, entry); if (forcePersist || entry.rxBytes > persistThreshold || entry.txBytes > persistThreshold) { @@ -676,31 +706,28 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } // splice in operation counts since last poll - final int j = operationsDelta.findIndex(IFACE_ALL, entry.uid, entry.tag); + final int j = operationsDelta.findIndex(IFACE_ALL, entry.uid, entry.set, entry.tag); if (j != -1) { operationsEntry = operationsDelta.getValues(j, operationsEntry); entry.operations = operationsEntry.operations; } final NetworkStatsHistory history = findOrCreateUidStatsLocked( - ident, entry.uid, entry.tag); + ident, entry.uid, entry.set, entry.tag); history.recordData(timeStart, currentTime, entry); } // trim any history beyond max final long maxUidHistory = mSettings.getUidMaxHistory(); final long maxTagHistory = mSettings.getTagMaxHistory(); - for (LongSparseArray uidStats : mUidStats.values()) { - for (int i = 0; i < uidStats.size(); i++) { - final long packed = uidStats.keyAt(i); - final NetworkStatsHistory history = uidStats.valueAt(i); + for (UidStatsKey key : mUidStats.keySet()) { + final NetworkStatsHistory history = mUidStats.get(key); - // detailed tags are trimmed sooner than summary in TAG_NONE - if (unpackTag(packed) == TAG_NONE) { - history.removeBucketsBefore(currentTime - maxUidHistory); - } else { - history.removeBucketsBefore(currentTime - maxTagHistory); - } + // detailed tags are trimmed sooner than summary in TAG_NONE + if (key.tag == TAG_NONE) { + history.removeBucketsBefore(currentTime - maxUidHistory); + } else { + history.removeBucketsBefore(currentTime - maxTagHistory); } } @@ -715,26 +742,25 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private void removeUidLocked(int uid) { ensureUidStatsLoadedLocked(); + final ArrayList knownKeys = Lists.newArrayList(); + knownKeys.addAll(mUidStats.keySet()); + // migrate all UID stats into special "removed" bucket - for (NetworkIdentitySet ident : mUidStats.keySet()) { - final LongSparseArray uidStats = mUidStats.get(ident); - for (int i = 0; i < uidStats.size(); i++) { - final long packed = uidStats.keyAt(i); - if (unpackUid(packed) == uid) { - // only migrate combined TAG_NONE history - if (unpackTag(packed) == TAG_NONE) { - final NetworkStatsHistory uidHistory = uidStats.valueAt(i); - final NetworkStatsHistory removedHistory = findOrCreateUidStatsLocked( - ident, UID_REMOVED, TAG_NONE); - removedHistory.recordEntireHistory(uidHistory); - } - uidStats.remove(packed); + for (UidStatsKey key : knownKeys) { + if (key.uid == uid) { + // only migrate combined TAG_NONE history + if (key.tag == TAG_NONE) { + final NetworkStatsHistory uidHistory = mUidStats.get(key); + final NetworkStatsHistory removedHistory = findOrCreateUidStatsLocked( + key.ident, UID_REMOVED, SET_DEFAULT, TAG_NONE); + removedHistory.recordEntireHistory(uidHistory); } + mUidStats.remove(key); } } - // TODO: push kernel event to wipe stats for UID, otherwise we risk - // picking them up again during next poll. + // clear kernel stats associated with UID + resetKernelUidStats(uid); // since this was radical rewrite, push to disk writeUidStatsLocked(); @@ -763,17 +789,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } private NetworkStatsHistory findOrCreateUidStatsLocked( - NetworkIdentitySet ident, int uid, int tag) { + NetworkIdentitySet ident, int uid, int set, int tag) { ensureUidStatsLoadedLocked(); - LongSparseArray uidStats = mUidStats.get(ident); - if (uidStats == null) { - uidStats = new LongSparseArray(); - mUidStats.put(ident, uidStats); - } - - final long packed = packUidAndTag(uid, tag); - final NetworkStatsHistory existing = uidStats.get(packed); + final UidStatsKey key = new UidStatsKey(ident, uid, set, tag); + final NetworkStatsHistory existing = mUidStats.get(key); // update when no existing, or when bucket duration changed final long bucketDuration = mSettings.getUidBucketDuration(); @@ -787,7 +807,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } if (updated != null) { - uidStats.put(packed, updated); + mUidStats.put(key, updated); return updated; } else { return existing; @@ -874,25 +894,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // for a short time. break; } - case VERSION_UID_WITH_TAG: { - // uid := size *(NetworkIdentitySet size *(UID tag NetworkStatsHistory)) - final int ifaceSize = in.readInt(); - for (int i = 0; i < ifaceSize; i++) { + case VERSION_UID_WITH_TAG: + case VERSION_UID_WITH_SET: { + // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory)) + final int identSize = in.readInt(); + for (int i = 0; i < identSize; i++) { final NetworkIdentitySet ident = new NetworkIdentitySet(in); - final int childSize = in.readInt(); - final LongSparseArray uidStats = new LongSparseArray< - NetworkStatsHistory>(childSize); - for (int j = 0; j < childSize; j++) { + final int size = in.readInt(); + for (int j = 0; j < size; j++) { final int uid = in.readInt(); + final int set = (version >= VERSION_UID_WITH_SET) ? in.readInt() + : SET_DEFAULT; final int tag = in.readInt(); - final long packed = packUidAndTag(uid, tag); + final UidStatsKey key = new UidStatsKey(ident, uid, set, tag); final NetworkStatsHistory history = new NetworkStatsHistory(in); - uidStats.put(packed, history); + mUidStats.put(key, history); } - - mUidStats.put(ident, uidStats); } break; } @@ -949,29 +968,36 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // TODO: consider duplicating stats and releasing lock while writing + // build UidStatsKey lists grouped by ident + final HashMap> keysByIdent = Maps.newHashMap(); + for (UidStatsKey key : mUidStats.keySet()) { + ArrayList keys = keysByIdent.get(key.ident); + if (keys == null) { + keys = Lists.newArrayList(); + keysByIdent.put(key.ident, keys); + } + keys.add(key); + } + FileOutputStream fos = null; try { fos = mUidFile.startWrite(); final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos)); out.writeInt(FILE_MAGIC); - out.writeInt(VERSION_UID_WITH_TAG); + out.writeInt(VERSION_UID_WITH_SET); - final int size = mUidStats.size(); - out.writeInt(size); - for (NetworkIdentitySet ident : mUidStats.keySet()) { - final LongSparseArray uidStats = mUidStats.get(ident); + out.writeInt(keysByIdent.size()); + for (NetworkIdentitySet ident : keysByIdent.keySet()) { + final ArrayList keys = keysByIdent.get(ident); ident.writeToStream(out); - final int childSize = uidStats.size(); - out.writeInt(childSize); - for (int i = 0; i < childSize; i++) { - final long packed = uidStats.keyAt(i); - final int uid = unpackUid(packed); - final int tag = unpackTag(packed); - final NetworkStatsHistory history = uidStats.valueAt(i); - out.writeInt(uid); - out.writeInt(tag); + out.writeInt(keys.size()); + for (UidStatsKey key : keys) { + final NetworkStatsHistory history = mUidStats.get(key); + out.writeInt(key.uid); + out.writeInt(key.set); + out.writeInt(key.tag); history.writeToStream(out); } } @@ -1030,20 +1056,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // from disk if not already in memory. ensureUidStatsLoadedLocked(); - pw.println("Detailed UID stats:"); - for (NetworkIdentitySet ident : mUidStats.keySet()) { - pw.print(" ident="); pw.println(ident.toString()); + final ArrayList keys = Lists.newArrayList(); + keys.addAll(mUidStats.keySet()); + Collections.sort(keys); - final LongSparseArray uidStats = mUidStats.get(ident); - for (int i = 0; i < uidStats.size(); i++) { - final long packed = uidStats.keyAt(i); - final int uid = unpackUid(packed); - final int tag = unpackTag(packed); - final NetworkStatsHistory history = uidStats.valueAt(i); - pw.print(" UID="); pw.print(uid); - pw.print(" tag=0x"); pw.println(Integer.toHexString(tag)); - history.dump(" ", pw, fullHistory); - } + pw.println("Detailed UID stats:"); + for (UidStatsKey key : keys) { + pw.print(" ident="); pw.print(key.ident.toString()); + pw.print(" uid="); pw.print(key.uid); + pw.print(" set="); pw.print(NetworkStats.setToString(key.set)); + pw.print(" tag="); pw.println(NetworkStats.tagToString(key.tag)); + + final NetworkStatsHistory history = mUidStats.get(key); + history.dump(" ", pw, fullHistory); } } } @@ -1080,8 +1105,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { for (ApplicationInfo info : installedApps) { final int uid = info.uid; - findOrCreateUidStatsLocked(ident, uid, TAG_NONE).generateRandom(UID_START, UID_END, - UID_RX_BYTES, UID_RX_PACKETS, UID_TX_BYTES, UID_TX_PACKETS, UID_OPERATIONS); + findOrCreateUidStatsLocked(ident, uid, SET_DEFAULT, TAG_NONE).generateRandom( + UID_START, UID_END, UID_RX_BYTES, UID_RX_PACKETS, UID_TX_BYTES, + UID_TX_PACKETS, UID_OPERATIONS); + findOrCreateUidStatsLocked(ident, uid, SET_FOREGROUND, TAG_NONE).generateRandom( + UID_START, UID_END, UID_RX_BYTES, UID_RX_PACKETS, UID_TX_BYTES, + UID_TX_PACKETS, UID_OPERATIONS); } } } @@ -1116,23 +1145,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return (int) (existing.size() * existing.getBucketDuration() / newBucketDuration); } - // @VisibleForTesting - public static long packUidAndTag(int uid, int tag) { - final long uidLong = uid; - final long tagLong = tag; - return (uidLong << 32) | (tagLong & 0xFFFFFFFFL); - } - - // @VisibleForTesting - public static int unpackUid(long packed) { - return (int) (packed >> 32); - } - - // @VisibleForTesting - public static int unpackTag(long packed) { - return (int) (packed & 0xFFFFFFFFL); - } - /** * Test if given {@link NetworkTemplate} matches any {@link NetworkIdentity} * in the given {@link NetworkIdentitySet}. @@ -1146,6 +1158,58 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return false; } + private Handler.Callback mHandlerCallback = new Handler.Callback() { + /** {@inheritDoc} */ + public boolean handleMessage(Message msg) { + switch (msg.what) { + case MSG_FORCE_UPDATE: { + forceUpdate(); + return true; + } + default: { + return false; + } + } + } + }; + + /** + * Key uniquely identifying a {@link NetworkStatsHistory} for a UID. + */ + private static class UidStatsKey implements Comparable { + public final NetworkIdentitySet ident; + public final int uid; + public final int set; + public final int tag; + + public UidStatsKey(NetworkIdentitySet ident, int uid, int set, int tag) { + this.ident = ident; + this.uid = uid; + this.set = set; + this.tag = tag; + } + + @Override + public int hashCode() { + return Objects.hashCode(ident, uid, set, tag); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof UidStatsKey) { + final UidStatsKey key = (UidStatsKey) obj; + return Objects.equal(ident, key.ident) && uid == key.uid && set == key.set + && tag == key.tag; + } + return false; + } + + /** {@inheritDoc} */ + public int compareTo(UidStatsKey another) { + return Integer.compare(uid, another.uid); + } + } + /** * Default external settings that read from {@link Settings.Secure}. */ diff --git a/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set b/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set new file mode 100644 index 0000000000000..3678b101529cc --- /dev/null +++ b/services/tests/servicestests/res/raw/xt_qtaguid_typical_with_set @@ -0,0 +1,13 @@ +idx iface acct_tag_hex uid_tag_int cnt_set rx_bytes rx_packets tx_bytes tx_packets rx_tcp_packets rx_tcp_bytes rx_udp_packets rx_udp_bytes rx_other_packets rx_other_bytes tx_tcp_packets tx_tcp_bytes tx_udp_packets tx_udp_bytes tx_other_packets tx_other_bytes +1 rmnet0 0x0 0 0 14855 82 2804 47 2000 45 12799 35 56 2 676 13 2128 34 0 0 +1 rmnet0 0x0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +2 rmnet0 0x0 1000 0 278102 253 10487 182 277342 243 760 10 0 0 9727 172 760 10 0 0 +2 rmnet0 0x0 1000 1 26033 30 1401 26 25881 28 152 2 0 0 1249 24 152 2 0 0 +3 rmnet0 0x0 10012 0 40524 272 134138 293 40524 272 0 0 0 0 134138 293 0 0 0 0 +3 rmnet0 0x0 10012 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +4 rmnet0 0x0 10034 0 15791 59 9905 69 15791 59 0 0 0 0 9905 69 0 0 0 0 +4 rmnet0 0x0 10034 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +5 rmnet0 0x0 10055 0 3602 29 7739 59 3602 29 0 0 0 0 7739 59 0 0 0 0 +5 rmnet0 0x0 10055 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +6 rmnet0 0x7fff000300000000 1000 0 483 4 1931 6 483 4 0 0 0 0 1931 6 0 0 0 0 +6 rmnet0 0x7fff000300000000 1000 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java index fe88793212650..f14569c5c7f76 100644 --- a/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java +++ b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java @@ -28,7 +28,10 @@ import com.google.common.util.concurrent.AbstractFuture; import java.util.Iterator; import java.util.List; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; /** * {@link ContextWrapper} that can attach listeners for upcoming @@ -62,6 +65,15 @@ public class BroadcastInterceptingContext extends ContextWrapper { return false; } } + + @Override + public Intent get() throws InterruptedException, ExecutionException { + try { + return get(5, TimeUnit.SECONDS); + } catch (TimeoutException e) { + throw new RuntimeException(e); + } + } } public BroadcastInterceptingContext(Context base) { @@ -125,6 +137,11 @@ public class BroadcastInterceptingContext extends ContextWrapper { sendBroadcast(intent); } + @Override + public void sendBroadcast(Intent intent, String receiverPermission) { + sendBroadcast(intent); + } + @Override public void removeStickyBroadcast(Intent intent) { // ignored diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java index f628977908bc3..5f3569783e69a 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java @@ -16,6 +16,8 @@ package com.android.server; +import static android.net.NetworkStats.SET_DEFAULT; +import static android.net.NetworkStats.SET_FOREGROUND; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static com.android.server.NetworkManagementSocketTagger.kernelToTag; @@ -27,7 +29,6 @@ import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; import com.android.frameworks.servicestests.R; -import com.google.common.io.Files; import java.io.File; import java.io.FileOutputStream; @@ -74,11 +75,11 @@ public class NetworkManagementServiceTest extends AndroidTestCase { final NetworkStats stats = mService.getNetworkStatsDetail(); assertEquals(31, stats.size()); - assertStatsEntry(stats, "wlan0", 0, 0, 14615L, 4270L); - assertStatsEntry(stats, "wlan0", 10004, 0, 333821L, 53558L); - assertStatsEntry(stats, "wlan0", 10004, 1947740890, 18725L, 1066L); - assertStatsEntry(stats, "rmnet0", 10037, 0, 31184994L, 684122L); - assertStatsEntry(stats, "rmnet0", 10037, 1947740890, 28507378L, 437004L); + assertStatsEntry(stats, "wlan0", 0, SET_DEFAULT, 0, 14615L, 4270L); + assertStatsEntry(stats, "wlan0", 10004, SET_DEFAULT, 0, 333821L, 53558L); + assertStatsEntry(stats, "wlan0", 10004, SET_DEFAULT, 1947740890, 18725L, 1066L); + assertStatsEntry(stats, "rmnet0", 10037, SET_DEFAULT, 0, 31184994L, 684122L); + assertStatsEntry(stats, "rmnet0", 10037, SET_DEFAULT, 1947740890, 28507378L, 437004L); } public void testNetworkStatsDetailExtended() throws Exception { @@ -86,8 +87,8 @@ public class NetworkManagementServiceTest extends AndroidTestCase { final NetworkStats stats = mService.getNetworkStatsDetail(); assertEquals(2, stats.size()); - assertStatsEntry(stats, "test0", 1000, 0, 1024L, 2048L); - assertStatsEntry(stats, "test0", 1000, 0xF00D, 512L, 512L); + assertStatsEntry(stats, "test0", 1000, SET_DEFAULT, 0, 1024L, 2048L); + assertStatsEntry(stats, "test0", 1000, SET_DEFAULT, 0xF00D, 512L, 512L); } public void testNetworkStatsSummary() throws Exception { @@ -95,12 +96,12 @@ public class NetworkManagementServiceTest extends AndroidTestCase { final NetworkStats stats = mService.getNetworkStatsSummary(); assertEquals(6, stats.size()); - assertStatsEntry(stats, "lo", UID_ALL, TAG_NONE, 8308L, 8308L); - assertStatsEntry(stats, "rmnet0", UID_ALL, TAG_NONE, 1507570L, 489339L); - assertStatsEntry(stats, "ifb0", UID_ALL, TAG_NONE, 52454L, 0L); - assertStatsEntry(stats, "ifb1", UID_ALL, TAG_NONE, 52454L, 0L); - assertStatsEntry(stats, "sit0", UID_ALL, TAG_NONE, 0L, 0L); - assertStatsEntry(stats, "ip6tnl0", UID_ALL, TAG_NONE, 0L, 0L); + assertStatsEntry(stats, "lo", UID_ALL, SET_DEFAULT, TAG_NONE, 8308L, 8308L); + assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 1507570L, 489339L); + assertStatsEntry(stats, "ifb0", UID_ALL, SET_DEFAULT, TAG_NONE, 52454L, 0L); + assertStatsEntry(stats, "ifb1", UID_ALL, SET_DEFAULT, TAG_NONE, 52454L, 0L); + assertStatsEntry(stats, "sit0", UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L); + assertStatsEntry(stats, "ip6tnl0", UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L); } public void testNetworkStatsSummaryDown() throws Exception { @@ -112,8 +113,8 @@ public class NetworkManagementServiceTest extends AndroidTestCase { final NetworkStats stats = mService.getNetworkStatsSummary(); assertEquals(7, stats.size()); - assertStatsEntry(stats, "rmnet0", UID_ALL, TAG_NONE, 1507570L, 489339L); - assertStatsEntry(stats, "wlan0", UID_ALL, TAG_NONE, 1024L, 2048L); + assertStatsEntry(stats, "rmnet0", UID_ALL, SET_DEFAULT, TAG_NONE, 1507570L, 489339L); + assertStatsEntry(stats, "wlan0", UID_ALL, SET_DEFAULT, TAG_NONE, 1024L, 2048L); } public void testKernelTags() throws Exception { @@ -130,6 +131,15 @@ public class NetworkManagementServiceTest extends AndroidTestCase { assertEquals(2147483136, kernelToTag("0x7FFFFE0000000000")); } + public void testNetworkStatsWithSet() throws Exception { + stageFile(R.raw.xt_qtaguid_typical_with_set, new File(mTestProc, "net/xt_qtaguid/stats")); + + final NetworkStats stats = mService.getNetworkStatsDetail(); + assertEquals(12, stats.size()); + assertStatsEntry(stats, "rmnet0", 1000, SET_DEFAULT, 0, 278102L, 253L, 10487L, 182L); + assertStatsEntry(stats, "rmnet0", 1000, SET_FOREGROUND, 0, 26033L, 30L, 1401L, 26L); + } + /** * Copy a {@link Resources#openRawResource(int)} into {@link File} for * testing purposes. @@ -159,12 +169,22 @@ public class NetworkManagementServiceTest extends AndroidTestCase { } } - private static void assertStatsEntry( - NetworkStats stats, String iface, int uid, int tag, long rxBytes, long txBytes) { - final int i = stats.findIndex(iface, uid, tag); + private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set, + int tag, long rxBytes, long txBytes) { + final int i = stats.findIndex(iface, uid, set, tag); final NetworkStats.Entry entry = stats.getValues(i, null); - assertEquals(rxBytes, entry.rxBytes); - assertEquals(txBytes, entry.txBytes); + assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); + assertEquals("unexpected txBytes", txBytes, entry.txBytes); + } + + private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set, + int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { + final int i = stats.findIndex(iface, uid, set, tag); + final NetworkStats.Entry entry = 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); } } diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java index 09f8ff39c97e1..845aa3f2bb01f 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java @@ -29,8 +29,6 @@ import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; import static android.net.NetworkPolicyManager.computeLastCycleBoundary; import static android.net.NetworkPolicyManager.computeNextCycleBoundary; -import static android.net.NetworkStats.TAG_NONE; -import static android.net.NetworkStats.UID_ALL; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT; @@ -282,6 +280,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { Future future; expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, true); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); @@ -290,6 +289,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // push strict policy for foreground uid, verify ALLOW rule expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, true); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); @@ -299,6 +299,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // now turn screen off and verify REJECT rule expect(mPowerManager.isScreenOn()).andReturn(false).atLeastOnce(); expectSetUidNetworkRules(UID_A, true); + expectSetUidForeground(UID_A, false); future = expectRulesChanged(UID_A, RULE_REJECT_METERED); replay(); mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF)); @@ -308,6 +309,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // and turn screen back on, verify ALLOW rule restored expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce(); expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, true); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON)); @@ -319,6 +321,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { Future future; expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, true); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); @@ -327,6 +330,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // POLICY_NONE should RULE_ALLOW in foreground expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, true); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mService.setUidPolicy(UID_A, POLICY_NONE); @@ -335,6 +339,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // POLICY_NONE should RULE_ALLOW in background expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, false); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); @@ -347,6 +352,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // POLICY_REJECT should RULE_ALLOW in background expectSetUidNetworkRules(UID_A, true); + expectSetUidForeground(UID_A, false); future = expectRulesChanged(UID_A, RULE_REJECT_METERED); replay(); mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); @@ -355,6 +361,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // POLICY_REJECT should RULE_ALLOW in foreground expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, true); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, true); @@ -363,6 +370,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // POLICY_REJECT should RULE_REJECT in background expectSetUidNetworkRules(UID_A, true); + expectSetUidForeground(UID_A, false); future = expectRulesChanged(UID_A, RULE_REJECT_METERED); replay(); mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); @@ -375,6 +383,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // POLICY_NONE should have RULE_ALLOW in background expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, false); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mProcessObserver.onForegroundActivitiesChanged(PID_1, UID_A, false); @@ -384,6 +393,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // adding POLICY_REJECT should cause RULE_REJECT expectSetUidNetworkRules(UID_A, true); + expectSetUidForeground(UID_A, false); future = expectRulesChanged(UID_A, RULE_REJECT_METERED); replay(); mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); @@ -392,6 +402,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // removing POLICY_REJECT should return us to RULE_ALLOW expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, false); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); mService.setUidPolicy(UID_A, POLICY_NONE); @@ -503,7 +514,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // pretend that 512 bytes total have happened stats = new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 256L, 2L, 256L, 2L, 11); + .addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L); expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, TIME_MAR_10)) .andReturn(stats).atLeastOnce(); @@ -527,6 +538,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // POLICY_REJECT should RULE_REJECT in background expectSetUidNetworkRules(UID_A, true); + expectSetUidForeground(UID_A, false); future = expectRulesChanged(UID_A, RULE_REJECT_METERED); replay(); mService.setUidPolicy(UID_A, POLICY_REJECT_METERED_BACKGROUND); @@ -535,6 +547,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { // uninstall should clear RULE_REJECT expectSetUidNetworkRules(UID_A, false); + expectSetUidForeground(UID_A, false); future = expectRulesChanged(UID_A, RULE_ALLOW_ALL); replay(); final Intent intent = new Intent(ACTION_UID_REMOVED); @@ -579,7 +592,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { elapsedRealtime += MINUTE_IN_MILLIS; currentTime = TIME_MAR_10 + elapsedRealtime; stats = new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0); + .addIfaceValues(TEST_IFACE, 0L, 0L, 0L, 0L); state = new NetworkState[] { buildWifi() }; { @@ -606,7 +619,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { elapsedRealtime += MINUTE_IN_MILLIS; currentTime = TIME_MAR_10 + elapsedRealtime; stats = new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1536L, 15L, 0L, 0L, 11); + .addIfaceValues(TEST_IFACE, 1536L, 15L, 0L, 0L); { expectTime(currentTime); @@ -627,7 +640,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { elapsedRealtime += MINUTE_IN_MILLIS; currentTime = TIME_MAR_10 + elapsedRealtime; stats = new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 5120L, 512L, 0L, 0L, 22); + .addIfaceValues(TEST_IFACE, 5120L, 512L, 0L, 0L); { expectTime(currentTime); @@ -738,6 +751,11 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { expectLastCall().atLeastOnce(); } + private void expectSetUidForeground(int uid, boolean uidForeground) throws Exception { + mStatsService.setUidForeground(uid, uidForeground); + expectLastCall().atLeastOnce(); + } + private Future expectRulesChanged(int uid, int policy) throws Exception { final FutureAnswer future = new FutureAnswer(); mPolicyListener.onUidRulesChanged(eq(uid), eq(policy)); diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java index 8eb9cc305397d..6138490781a0f 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java @@ -23,6 +23,9 @@ import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIMAX; import static android.net.NetworkStats.IFACE_ALL; +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 android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL; @@ -34,9 +37,6 @@ import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static android.text.format.DateUtils.WEEK_IN_MILLIS; import static com.android.server.net.NetworkStatsService.ACTION_NETWORK_STATS_POLL; -import static com.android.server.net.NetworkStatsService.packUidAndTag; -import static com.android.server.net.NetworkStatsService.unpackTag; -import static com.android.server.net.NetworkStatsService.unpackUid; import static org.easymock.EasyMock.anyLong; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.eq; @@ -68,6 +68,9 @@ import com.android.server.net.NetworkStatsService.NetworkStatsSettings; import org.easymock.EasyMock; import java.io.File; +import java.util.concurrent.Future; + +import libcore.io.IoUtils; /** * Tests for {@link NetworkStatsService}. @@ -90,6 +93,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase { private static final int UID_BLUE = 1002; private static final int UID_GREEN = 1003; + private long mElapsedRealtime; + private BroadcastInterceptingContext mServiceContext; private File mStatsDir; @@ -107,6 +112,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase { mServiceContext = new BroadcastInterceptingContext(getContext()); mStatsDir = getContext().getFilesDir(); + if (mStatsDir.exists()) { + IoUtils.deleteContents(mStatsDir); + } mNetManager = createMock(INetworkManagementService.class); mAlarmManager = createMock(IAlarmManager.class); @@ -118,11 +126,17 @@ public class NetworkStatsServiceTest extends AndroidTestCase { mServiceContext, mNetManager, mAlarmManager, mTime, mStatsDir, mSettings); mService.bindConnectivityManager(mConnManager); + mElapsedRealtime = 0L; + + expectCurrentTime(); expectDefaultSettings(); - expectSystemReady(); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + final Future firstPoll = expectSystemReady(); replay(); mService.systemReady(); + firstPoll.get(); verifyAndReset(); } @@ -148,14 +162,12 @@ public class NetworkStatsServiceTest extends AndroidTestCase { } public void testNetworkStatsWifi() throws Exception { - long elapsedRealtime = 0; - // pretend that wifi network comes online; service should ask about full // network state, and poll any existing interfaces before updating. - expectTime(TEST_START + elapsedRealtime); + expectCurrentTime(); expectDefaultSettings(); expectNetworkState(buildWifiState()); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); @@ -164,16 +176,13 @@ public class NetworkStatsServiceTest extends AndroidTestCase { assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); verifyAndReset(); - // bootstrap with full polling event to prime stats - performBootstrapPoll(TEST_START, elapsedRealtime); - // modify some number on wifi, and trigger poll event - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 1L, 2048L, 2L)); - expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) + .addIfaceValues(TEST_IFACE, 1024L, 1L, 2048L, 2L)); + expectNetworkStatsUidDetail(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); @@ -184,12 +193,12 @@ public class NetworkStatsServiceTest extends AndroidTestCase { // and bump forward again, with counters going higher. this is // important, since polling should correctly subtract last snapshot. - elapsedRealtime += DAY_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(DAY_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4096L, 4L, 8192L, 8L)); - expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) + .addIfaceValues(TEST_IFACE, 4096L, 4L, 8192L, 8L)); + expectNetworkStatsUidDetail(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); @@ -201,15 +210,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase { } public void testStatsRebootPersist() throws Exception { - long elapsedRealtime = 0; assertStatsFilesExist(false); // pretend that wifi network comes online; service should ask about full // network state, and poll any existing interfaces before updating. - expectTime(TEST_START + elapsedRealtime); + expectCurrentTime(); expectDefaultSettings(); expectNetworkState(buildWifiState()); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); @@ -218,29 +226,33 @@ public class NetworkStatsServiceTest extends AndroidTestCase { assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); verifyAndReset(); - // bootstrap with full polling event to prime stats - performBootstrapPoll(TEST_START, elapsedRealtime); - // modify some number on wifi, and trigger poll event - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 8L, 2048L, 16L)); - expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 2) - .addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L) - .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 128L, 1L)); + expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) + .addIfaceValues(TEST_IFACE, 1024L, 8L, 2048L, 16L)); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 256L, 2L, 128L, 1L, 0L) + .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L)); - mService.incrementOperationCount(UID_RED, TAG_NONE, 20); - mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10); + mService.setUidForeground(UID_RED, false); + mService.incrementOperationCount(UID_RED, 0xFAAD, 4); + mService.setUidForeground(UID_RED, true); + mService.incrementOperationCount(UID_RED, 0xFAAD, 6); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); // verify service recorded history assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0); - assertUidTotal(sTemplateWifi, UID_RED, 512L, 4L, 256L, 2L, 20); - assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 10); + assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10); + assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4); + assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6); + assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0); verifyAndReset(); // graceful shutdown system, which should trigger persist of stats, and @@ -257,47 +269,49 @@ public class NetworkStatsServiceTest extends AndroidTestCase { assertStatsFilesExist(true); // boot through serviceReady() again + expectCurrentTime(); expectDefaultSettings(); - expectSystemReady(); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); + final Future firstPoll = expectSystemReady(); replay(); mService.systemReady(); + firstPoll.get(); // after systemReady(), we should have historical stats loaded again assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0); - assertUidTotal(sTemplateWifi, UID_RED, 512L, 4L, 256L, 2L, 20); - assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 10); + assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10); + assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, 512L, 4L, 256L, 2L, 4); + assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, 512L, 4L, 256L, 2L, 6); + assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0); verifyAndReset(); } public void testStatsBucketResize() throws Exception { - long elapsedRealtime = 0; NetworkStatsHistory history = null; assertStatsFilesExist(false); // pretend that wifi network comes online; service should ask about full // network state, and poll any existing interfaces before updating. - expectTime(TEST_START + elapsedRealtime); + expectCurrentTime(); expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); expectNetworkState(buildWifiState()); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); verifyAndReset(); - // bootstrap with full polling event to prime stats - performBootstrapPoll(TEST_START, elapsedRealtime); - // modify some number on wifi, and trigger poll event - elapsedRealtime += 2 * HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(2 * HOUR_IN_MILLIS); + expectCurrentTime(); expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS); - expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 512L, 4L, 512L, 4L)); - expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) + .addIfaceValues(TEST_IFACE, 512L, 4L, 512L, 4L)); + expectNetworkStatsUidDetail(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); @@ -311,10 +325,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase { // now change bucket duration setting and trigger another poll with // exact same values, which should resize existing buckets. - expectTime(TEST_START + elapsedRealtime); + expectCurrentTime(); expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); - expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); @@ -329,35 +343,28 @@ public class NetworkStatsServiceTest extends AndroidTestCase { } public void testUidStatsAcrossNetworks() throws Exception { - long elapsedRealtime = 0; - // pretend first mobile network comes online - expectTime(TEST_START + elapsedRealtime); + expectCurrentTime(); expectDefaultSettings(); expectNetworkState(buildMobile3gState(IMSI_1)); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); verifyAndReset(); - // bootstrap with full polling event to prime stats - performBootstrapPoll(TEST_START, elapsedRealtime); - // create some traffic on first network - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 2048L, 16L, 512L, 4L)); - expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 3) - .addValues(TEST_IFACE, UID_RED, TAG_NONE, 1536L, 12L, 512L, 4L) - .addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L) - .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 512L, 4L, 0L, 0L)); + expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) + .addIfaceValues(TEST_IFACE, 2048L, 16L, 512L, 4L)); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L) + .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L)); - mService.incrementOperationCount(UID_RED, TAG_NONE, 15); mService.incrementOperationCount(UID_RED, 0xF00D, 10); - mService.incrementOperationCount(UID_BLUE, TAG_NONE, 5); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); @@ -365,18 +372,18 @@ public class NetworkStatsServiceTest extends AndroidTestCase { // verify service recorded history assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0); assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0); - assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 15); - assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 5); + assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10); + assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0); verifyAndReset(); // now switch networks; this also tests that we're okay with interfaces // disappearing, to verify we don't count backwards. - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); expectNetworkState(buildMobile3gState(IMSI_2)); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); - expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); @@ -384,23 +391,24 @@ public class NetworkStatsServiceTest extends AndroidTestCase { verifyAndReset(); // create traffic on second network - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 128L, 1L, 1024L, 8L)); - expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 1024L, 8L)); + expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) + .addIfaceValues(TEST_IFACE, 128L, 1L, 1024L, 8L)); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 1024L, 8L, 0L) + .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xFAAD, 128L, 1L, 1024L, 8L, 0L)); - mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10); + mService.incrementOperationCount(UID_BLUE, 0xFAAD, 10); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); // verify original history still intact assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0); - assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 15); - assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 5); + assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 10); + assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 0); // and verify new history also recorded under different template, which // verifies that we didn't cross the streams. @@ -412,35 +420,29 @@ public class NetworkStatsServiceTest extends AndroidTestCase { } public void testUidRemovedIsMoved() throws Exception { - long elapsedRealtime = 0; - // pretend that network comes online - expectTime(TEST_START + elapsedRealtime); + expectCurrentTime(); expectDefaultSettings(); expectNetworkState(buildWifiState()); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); verifyAndReset(); - // bootstrap with full polling event to prime stats - performBootstrapPoll(TEST_START, elapsedRealtime); - // create some traffic - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4128L, 258L, 544L, 34L)); - expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_RED, TAG_NONE, 16L, 1L, 16L, 1L) - .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 4096L, 258L, 512L, 32L) - .addValues(TEST_IFACE, UID_GREEN, TAG_NONE, 16L, 1L, 16L, 1L)); + expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1) + .addIfaceValues(TEST_IFACE, 4128L, 258L, 544L, 34L)); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L) + .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 4096L, 258L, 512L, 32L, 0L) + .addValues(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)); - mService.incrementOperationCount(UID_RED, TAG_NONE, 10); - mService.incrementOperationCount(UID_BLUE, TAG_NONE, 15); - mService.incrementOperationCount(UID_GREEN, TAG_NONE, 5); + mService.incrementOperationCount(UID_RED, 0xFAAD, 10); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); @@ -448,8 +450,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase { // verify service recorded history assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0); assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10); - assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 15); - assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 5); + assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0); + assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0); verifyAndReset(); // now pretend two UIDs are uninstalled, which should migrate stats to @@ -467,54 +469,48 @@ public class NetworkStatsServiceTest extends AndroidTestCase { assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0); assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0); assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0); - assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 5); - assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 25); + assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0); + assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 10); verifyAndReset(); } public void testUid3g4gCombinedByTemplate() throws Exception { - long elapsedRealtime = 0; - // pretend that network comes online - expectTime(TEST_START + elapsedRealtime); + expectCurrentTime(); expectDefaultSettings(); expectNetworkState(buildMobile3gState(IMSI_1)); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); verifyAndReset(); - // bootstrap with full polling event to prime stats - performBootstrapPoll(TEST_START, elapsedRealtime); - // create some traffic - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); - expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_RED, TAG_NONE, 1024L, 8L, 1024L, 8L) - .addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L)); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1024L, 8L, 1024L, 8L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)); - mService.incrementOperationCount(UID_RED, TAG_NONE, 10); mService.incrementOperationCount(UID_RED, 0xF00D, 5); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); // verify service recorded history - assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 10); + assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 5); verifyAndReset(); // now switch over to 4g network - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); expectNetworkState(buildMobile4gState()); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); - expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); @@ -522,92 +518,64 @@ public class NetworkStatsServiceTest extends AndroidTestCase { verifyAndReset(); // create traffic on second network - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); - expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L)); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 512L, 4L, 256L, 2L, 0L)); - mService.incrementOperationCount(UID_RED, TAG_NONE, 5); + mService.incrementOperationCount(UID_RED, 0xFAAD, 5); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); // verify that ALL_MOBILE template combines both - assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 15); + assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 10); verifyAndReset(); } - - public void testPackedUidAndTag() throws Exception { - assertEquals(0x0000000000000000L, packUidAndTag(0, 0x0)); - assertEquals(0x000003E900000000L, packUidAndTag(1001, 0x0)); - assertEquals(0x000003E90000F00DL, packUidAndTag(1001, 0xF00D)); - - long packed; - packed = packUidAndTag(Integer.MAX_VALUE, Integer.MIN_VALUE); - assertEquals(Integer.MAX_VALUE, unpackUid(packed)); - assertEquals(Integer.MIN_VALUE, unpackTag(packed)); - - packed = packUidAndTag(Integer.MIN_VALUE, Integer.MAX_VALUE); - assertEquals(Integer.MIN_VALUE, unpackUid(packed)); - assertEquals(Integer.MAX_VALUE, unpackTag(packed)); - - packed = packUidAndTag(10005, 0xFFFFFFFF); - assertEquals(10005, unpackUid(packed)); - assertEquals(0xFFFFFFFF, unpackTag(packed)); - - } public void testSummaryForAllUid() throws Exception { - long elapsedRealtime = 0; - // pretend that network comes online - expectTime(TEST_START + elapsedRealtime); + expectCurrentTime(); expectDefaultSettings(); expectNetworkState(buildWifiState()); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); + expectNetworkStatsSummary(buildEmptyStats()); replay(); mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); verifyAndReset(); - // bootstrap with full polling event to prime stats - performBootstrapPoll(TEST_START, elapsedRealtime); - // create some traffic for two apps - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); - expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L) - .addValues(TEST_IFACE, UID_RED, 0xF00D, 10L, 1L, 10L, 1L) - .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L)); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L) + .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L)); - mService.incrementOperationCount(UID_RED, TAG_NONE, 5); mService.incrementOperationCount(UID_RED, 0xF00D, 1); - mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); // verify service recorded history - assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 5); - assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 10); + assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 1); + assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 0); verifyAndReset(); // now create more traffic in next hour, but only for one app - elapsedRealtime += HOUR_IN_MILLIS; - expectTime(TEST_START + elapsedRealtime); + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); - expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1) - .addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L)); - - mService.incrementOperationCount(UID_BLUE, TAG_NONE, 15); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addValues(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0L)); replay(); mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); @@ -616,16 +584,77 @@ public class NetworkStatsServiceTest extends AndroidTestCase { NetworkStats stats = mService.getSummaryForAllUid( sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); assertEquals(3, stats.size()); - assertValues(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L, 5); - assertValues(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L, 1); - assertValues(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L, 15); + assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 1); + assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 1); + assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 2048L, 16L, 1024L, 8L, 0); // now verify that recent history only contains one uid - final long currentTime = TEST_START + elapsedRealtime; + final long currentTime = currentTimeMillis(); stats = mService.getSummaryForAllUid( sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true); assertEquals(1, stats.size()); - assertValues(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L, 5); + assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0); + + verifyAndReset(); + } + + public void testForegroundBackground() throws Exception { + // pretend that network comes online + expectCurrentTime(); + expectDefaultSettings(); + expectNetworkState(buildWifiState()); + expectNetworkStatsSummary(buildEmptyStats()); + + replay(); + mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION)); + verifyAndReset(); + + // create some initial traffic + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); + expectDefaultSettings(); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)); + + mService.incrementOperationCount(UID_RED, 0xF00D, 1); + + replay(); + mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); + + // verify service recorded history + assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1); + verifyAndReset(); + + // now switch to foreground + incrementCurrentTime(HOUR_IN_MILLIS); + expectCurrentTime(); + expectDefaultSettings(); + expectNetworkStatsSummary(buildEmptyStats()); + expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L) + .addValues(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L)); + + mService.setUidForeground(UID_RED, true); + mService.incrementOperationCount(UID_RED, 0xFAAD, 1); + + replay(); + mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); + + // test that we combined correctly + assertUidTotal(sTemplateWifi, UID_RED, 160L, 4L, 160L, 4L, 2); + + // verify entire history present + final NetworkStats stats = mService.getSummaryForAllUid( + sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); + assertEquals(4, stats.size()); + assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 1); + assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 1); + assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 1); + assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 1); verifyAndReset(); } @@ -639,19 +668,27 @@ public class NetworkStatsServiceTest extends AndroidTestCase { private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) { + assertUidTotal(template, uid, SET_ALL, rxBytes, rxPackets, txBytes, txPackets, operations); + } + + private void assertUidTotal(NetworkTemplate template, int uid, int set, long rxBytes, + long rxPackets, long txBytes, long txPackets, int operations) { final NetworkStatsHistory history = mService.getHistoryForUid( - template, uid, TAG_NONE, FIELD_ALL); + template, uid, set, TAG_NONE, FIELD_ALL); assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes, txPackets, operations); } - private void expectSystemReady() throws Exception { + private Future expectSystemReady() throws Exception { mAlarmManager.remove(isA(PendingIntent.class)); expectLastCall().anyTimes(); mAlarmManager.setInexactRepeating( eq(AlarmManager.ELAPSED_REALTIME), anyLong(), anyLong(), isA(PendingIntent.class)); expectLastCall().atLeastOnce(); + + return mServiceContext.nextBroadcastIntent( + NetworkStatsService.ACTION_NETWORK_STATS_UPDATED); } private void expectNetworkState(NetworkState... state) throws Exception { @@ -682,25 +719,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase { expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes(); } - private void expectTime(long currentTime) throws Exception { + private void expectCurrentTime() throws Exception { expect(mTime.forceRefresh()).andReturn(false).anyTimes(); expect(mTime.hasCache()).andReturn(true).anyTimes(); - expect(mTime.currentTimeMillis()).andReturn(currentTime).anyTimes(); + expect(mTime.currentTimeMillis()).andReturn(currentTimeMillis()).anyTimes(); expect(mTime.getCacheAge()).andReturn(0L).anyTimes(); expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes(); } - private void performBootstrapPoll(long testStart, long elapsedRealtime) throws Exception { - expectTime(testStart + elapsedRealtime); - expectDefaultSettings(); - expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime)); - expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime)); - - replay(); - mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL)); - verifyAndReset(); - } - private void assertStatsFilesExist(boolean exist) { final File networkFile = new File(mStatsDir, "netstats.bin"); final File uidFile = new File(mStatsDir, "netstats_uid.bin"); @@ -713,12 +739,10 @@ public class NetworkStatsServiceTest extends AndroidTestCase { } } - private static void assertValues(NetworkStats stats, int i, String iface, int uid, int tag, - long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) { + private static void assertValues(NetworkStats stats, String iface, int uid, int set, + int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) { + final int i = stats.findIndex(iface, uid, set, tag); final NetworkStats.Entry entry = stats.getValues(i, null); - assertEquals("unexpected iface", iface, entry.iface); - assertEquals("unexpected uid", uid, entry.uid); - assertEquals("unexpected tag", tag, entry.tag); assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets); assertEquals("unexpected txBytes", txBytes, entry.txBytes); @@ -761,8 +785,24 @@ public class NetworkStatsServiceTest extends AndroidTestCase { return new NetworkState(info, prop, null); } - private static NetworkStats buildEmptyStats(long elapsedRealtime) { - return new NetworkStats(elapsedRealtime, 0); + private NetworkStats buildEmptyStats() { + return new NetworkStats(getElapsedRealtime(), 0); + } + + private long getElapsedRealtime() { + return mElapsedRealtime; + } + + private long startTimeMillis() { + return TEST_START; + } + + private long currentTimeMillis() { + return startTimeMillis() + mElapsedRealtime; + } + + private void incrementCurrentTime(long duration) { + mElapsedRealtime += duration; } private void replay() { diff --git a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java index c0870c76edd61..6a9778ee94abd 100644 --- a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java @@ -16,6 +16,9 @@ package com.android.server; +import static android.net.NetworkStats.SET_DEFAULT; +import static android.net.NetworkStats.TAG_NONE; +import static android.net.NetworkStats.UID_ALL; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; @@ -289,7 +292,7 @@ public class ThrottleServiceTest extends AndroidTestCase { public void expectGetInterfaceCounter(long rx, long tx) throws Exception { // TODO: provide elapsedRealtime mock to match TimeAuthority final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); - stats.addValues(TEST_IFACE, NetworkStats.UID_ALL, NetworkStats.TAG_NONE, rx, 0L, tx, 0L, 0); + stats.addValues(TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, rx, 0L, tx, 0L, 0); expect(mMockNMService.getNetworkStatsSummary()).andReturn(stats).atLeastOnce(); }