diff options
18 files changed, 729 insertions, 465 deletions
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index b65506c411e8..0e883cf8ac55 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 f2fcb8fad852..272545d0dc5d 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 4ba44cac296f..b4f15acff1c9 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 f138e49140fa..c2c5c183d337 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 16336e0e81b3..9c45dc64f469 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 4667e5fc978d..23af37e6188d 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 { * <li><i>*_tag</i> are 64bit values</li></ul> * */ - 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 73c92b08d876..5ee8fdd9b50f 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 69ad0f45229f..47ba88af4735 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); - - 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)); + .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, 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 2fd9b21a694f..06077dd97728 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 implements /** {@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 implements 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 implements 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 implements 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 cd649ce4c554..24b6ac3c3774 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 a07525502003..9c3d166c5481 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 deca7a91cfa4..c911687ab7a2 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<NetworkIdentitySet, NetworkStatsHistory> mNetworkStats = Maps.newHashMap(); /** Set of historical network layer stats for known UIDs. */ - private HashMap<NetworkIdentitySet, LongSparseArray<NetworkStatsHistory>> mUidStats = - Maps.newHashMap(); + private HashMap<UidStatsKey, NetworkStatsHistory> 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<NetworkStatsHistory> 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); - - // 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 = 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); - } + 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); + + 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; + + 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<NetworkStatsHistory> uidStats : mUidStats.values()) { - for (int i = 0; i < uidStats.size(); i++) { - final long packed = uidStats.keyAt(i); - final NetworkStatsHistory history = uidStats.valueAt(i); - - // detailed tags are trimmed sooner than summary in TAG_NONE - if (unpackTag(packed) == TAG_NONE) { - history.removeBucketsBefore(currentTime - maxUidHistory); - } else { - history.removeBucketsBefore(currentTime - maxTagHistory); - } + for (UidStatsKey key : mUidStats.keySet()) { + final NetworkStatsHistory history = mUidStats.get(key); + + // 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<UidStatsKey> knownKeys = Lists.newArrayList(); + knownKeys.addAll(mUidStats.keySet()); + // migrate all UID stats into special "removed" bucket - for (NetworkIdentitySet ident : mUidStats.keySet()) { - final LongSparseArray<NetworkStatsHistory> 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<NetworkStatsHistory> uidStats = mUidStats.get(ident); - if (uidStats == null) { - uidStats = new LongSparseArray<NetworkStatsHistory>(); - 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<NetworkStatsHistory> 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<NetworkIdentitySet, ArrayList<UidStatsKey>> keysByIdent = Maps.newHashMap(); + for (UidStatsKey key : mUidStats.keySet()) { + ArrayList<UidStatsKey> 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<NetworkStatsHistory> uidStats = mUidStats.get(ident); + out.writeInt(keysByIdent.size()); + for (NetworkIdentitySet ident : keysByIdent.keySet()) { + final ArrayList<UidStatsKey> 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(); + final ArrayList<UidStatsKey> keys = Lists.newArrayList(); + keys.addAll(mUidStats.keySet()); + Collections.sort(keys); + pw.println("Detailed UID stats:"); - for (NetworkIdentitySet ident : mUidStats.keySet()) { - pw.print(" ident="); pw.println(ident.toString()); - - final LongSparseArray<NetworkStatsHistory> 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); - } + 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<UidStatsKey> { + 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 000000000000..3678b101529c --- /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 fe8879321265..f14569c5c7f7 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) { @@ -126,6 +138,11 @@ public class BroadcastInterceptingContext extends ContextWrapper { } @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 f628977908bc..5f3569783e69 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("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(rxBytes, entry.rxBytes); - assertEquals(txBytes, entry.txBytes); + 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 09f8ff39c97e..845aa3f2bb01 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<Void> 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<Void> 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<Void> 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 8eb9cc305397..6138490781a0 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)); - - mService.incrementOperationCount(UID_RED, TAG_NONE, 20); - mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10); + 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.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)); - - mService.incrementOperationCount(UID_RED, TAG_NONE, 15); + 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, 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 c0870c76edd6..6a9778ee94ab 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(); } |