Read "qtaguid" network stats, refactor templates.
Teach NMS to read qtaguid stats from kernel, but fall back to older
stats when kernel doesn't support. Add "tags" to NetworkStats entries
to support qtaguid. To work around double-reporting bug, subtract
tagged stats from TAG_NONE entry.
Flesh out stronger NetworkTemplate. All NetworkStatsService requests
now require a template, and moved matching logic into template.
Record UID stats keyed on complete NetworkIdentitySet definition,
similar to how interface stats are stored. Since previous UID stats
didn't have iface breakdown, discard during file format upgrade.
Change-Id: I0447b5e7d205d73d28e71c889c568e536e91b8e4
diff --git a/core/tests/coretests/src/android/net/NetworkStatsTest.java b/core/tests/coretests/src/android/net/NetworkStatsTest.java
index 5250a7c..3cb64c7 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsTest.java
@@ -16,6 +16,8 @@
package android.net;
+import static android.net.NetworkStats.TAG_NONE;
+
import android.test.suitebuilder.annotation.SmallTest;
import junit.framework.TestCase;
@@ -29,14 +31,14 @@
public void testFindIndex() throws Exception {
final NetworkStats stats = new NetworkStats(TEST_START, 3)
- .addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024)
- .addEntry(TEST_IFACE, 102, 1024, 1024);
+ .addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
+ .addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L)
+ .addEntry(TEST_IFACE, 102, TAG_NONE, 1024L, 1024L);
- assertEquals(2, stats.findIndex(TEST_IFACE, 102));
- assertEquals(2, stats.findIndex(TEST_IFACE, 102));
- assertEquals(0, stats.findIndex(TEST_IFACE, 100));
- assertEquals(-1, stats.findIndex(TEST_IFACE, 6));
+ 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));
}
public void testAddEntryGrow() throws Exception {
@@ -45,15 +47,15 @@
assertEquals(0, stats.size);
assertEquals(2, stats.iface.length);
- stats.addEntry(TEST_IFACE, TEST_UID, 1L, 2L);
- stats.addEntry(TEST_IFACE, TEST_UID, 2L, 2L);
+ stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 1L, 2L);
+ stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 2L, 2L);
assertEquals(2, stats.size);
assertEquals(2, stats.iface.length);
- stats.addEntry(TEST_IFACE, TEST_UID, 3L, 4L);
- stats.addEntry(TEST_IFACE, TEST_UID, 4L, 4L);
- stats.addEntry(TEST_IFACE, TEST_UID, 5L, 5L);
+ stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 3L, 4L);
+ stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 4L, 4L);
+ stats.addEntry(TEST_IFACE, TEST_UID, TAG_NONE, 5L, 5L);
assertEquals(5, stats.size);
assertTrue(stats.iface.length >= 5);
@@ -65,14 +67,31 @@
assertEquals(5L, stats.rx[4]);
}
+ public void testCombineExisting() throws Exception {
+ final NetworkStats stats = new NetworkStats(TEST_START, 10);
+
+ stats.addEntry(TEST_IFACE, 1001, TAG_NONE, 512L, 256L);
+ stats.addEntry(TEST_IFACE, 1001, 0xff, 128L, 128L);
+ stats.combineEntry(TEST_IFACE, 1001, TAG_NONE, -128L, -128L);
+
+ assertStatsEntry(stats, 0, TEST_IFACE, 1001, TAG_NONE, 384L, 128L);
+ assertStatsEntry(stats, 1, TEST_IFACE, 1001, 0xff, 128L, 128L);
+
+ // now try combining that should create row
+ stats.combineEntry(TEST_IFACE, 5005, TAG_NONE, 128L, 128L);
+ assertStatsEntry(stats, 2, TEST_IFACE, 5005, TAG_NONE, 128L, 128L);
+ stats.combineEntry(TEST_IFACE, 5005, TAG_NONE, 128L, 128L);
+ assertStatsEntry(stats, 2, TEST_IFACE, 5005, TAG_NONE, 256L, 256L);
+ }
+
public void testSubtractIdenticalData() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024);
+ .addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
+ .addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L);
final NetworkStats after = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024);
+ .addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
+ .addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L);
final NetworkStats result = after.subtract(before);
@@ -85,12 +104,12 @@
public void testSubtractIdenticalRows() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024);
+ .addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
+ .addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L);
final NetworkStats after = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, 1025, 2)
- .addEntry(TEST_IFACE, 101, 3, 1028);
+ .addEntry(TEST_IFACE, 100, TAG_NONE, 1025L, 2L)
+ .addEntry(TEST_IFACE, 101, TAG_NONE, 3L, 1028L);
final NetworkStats result = after.subtract(before);
@@ -103,13 +122,13 @@
public void testSubtractNewRows() throws Exception {
final NetworkStats before = new NetworkStats(TEST_START, 2)
- .addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024);
+ .addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
+ .addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L);
final NetworkStats after = new NetworkStats(TEST_START, 3)
- .addEntry(TEST_IFACE, 100, 1024, 0)
- .addEntry(TEST_IFACE, 101, 0, 1024)
- .addEntry(TEST_IFACE, 102, 1024, 1024);
+ .addEntry(TEST_IFACE, 100, TAG_NONE, 1024L, 0L)
+ .addEntry(TEST_IFACE, 101, TAG_NONE, 0L, 1024L)
+ .addEntry(TEST_IFACE, 102, TAG_NONE, 1024L, 1024L);
final NetworkStats result = after.subtract(before);
@@ -122,4 +141,13 @@
assertEquals(1024, result.tx[2]);
}
+ private static void assertStatsEntry(
+ NetworkStats stats, int i, String iface, int uid, int tag, long rx, long tx) {
+ assertEquals(iface, stats.iface[i]);
+ assertEquals(uid, stats.uid[i]);
+ assertEquals(tag, stats.tag[i]);
+ assertEquals(rx, stats.rx[i]);
+ assertEquals(tx, stats.tx[i]);
+ }
+
}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index 2457ff3..1d2634c 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -18,9 +18,9 @@
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.NetworkStats.IFACE_ALL;
+import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
-import static android.net.TrafficStats.TEMPLATE_WIFI;
+import static android.net.NetworkTemplate.MATCH_WIFI;
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;
@@ -44,6 +44,7 @@
import android.net.NetworkState;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
+import android.net.NetworkTemplate;
import android.os.INetworkManagementService;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -66,6 +67,8 @@
private static final String TEST_IFACE = "test0";
private static final long TEST_START = 1194220800000L;
+ private static NetworkTemplate sTemplateWifi = new NetworkTemplate(MATCH_WIFI, null);
+
private static final int TEST_UID_1 = 1001;
private static final int TEST_UID_2 = 1002;
@@ -138,7 +141,7 @@
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
// verify service has empty history for wifi
- assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L);
verifyAndReset();
// modify some number on wifi, and trigger poll event
@@ -146,14 +149,14 @@
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
- .addEntry(TEST_IFACE, UID_ALL, 1024L, 2048L));
+ .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 2048L));
expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
+ assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
verifyAndReset();
// and bump forward again, with counters going higher. this is
@@ -162,14 +165,14 @@
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
- .addEntry(TEST_IFACE, UID_ALL, 4096L, 8192L));
+ .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 4096L, 8192L));
expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(TEMPLATE_WIFI, 4096L, 8192L);
+ assertNetworkTotal(sTemplateWifi, 4096L, 8192L);
verifyAndReset();
}
@@ -189,7 +192,7 @@
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
// verify service has empty history for wifi
- assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L);
verifyAndReset();
// modify some number on wifi, and trigger poll event
@@ -197,19 +200,18 @@
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
- .addEntry(TEST_IFACE, UID_ALL, 1024L, 2048L));
- // TODO: switch these stats to specific iface
+ .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 2048L));
expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2)
- .addEntry(IFACE_ALL, TEST_UID_1, 512L, 256L)
- .addEntry(IFACE_ALL, TEST_UID_2, 128L, 128L));
+ .addEntry(TEST_IFACE, TEST_UID_1, TAG_NONE, 512L, 256L)
+ .addEntry(TEST_IFACE, TEST_UID_2, TAG_NONE, 128L, 128L));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
- assertUidTotal(TEST_UID_1, TEMPLATE_WIFI, 512L, 256L);
- assertUidTotal(TEST_UID_2, TEMPLATE_WIFI, 128L, 128L);
+ assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
+ assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L);
+ assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L);
verifyAndReset();
// graceful shutdown system, which should trigger persist of stats, and
@@ -220,7 +222,7 @@
// we persisted them to file.
expectDefaultSettings();
replay();
- assertNetworkTotal(TEMPLATE_WIFI, 0L, 0L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L);
verifyAndReset();
assertStatsFilesExist(true);
@@ -233,9 +235,9 @@
mService.systemReady();
// after systemReady(), we should have historical stats loaded again
- assertNetworkTotal(TEMPLATE_WIFI, 1024L, 2048L);
- assertUidTotal(TEST_UID_1, TEMPLATE_WIFI, 512L, 256L);
- assertUidTotal(TEST_UID_2, TEMPLATE_WIFI, 128L, 128L);
+ assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
+ assertUidTotal(sTemplateWifi, TEST_UID_1, 512L, 256L);
+ assertUidTotal(sTemplateWifi, TEST_UID_2, 128L, 128L);
verifyAndReset();
}
@@ -263,14 +265,14 @@
expectTime(TEST_START + elapsedRealtime);
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
- .addEntry(TEST_IFACE, UID_ALL, 512L, 512L));
+ .addEntry(TEST_IFACE, UID_ALL, TAG_NONE, 512L, 512L));
expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- history = mService.getHistoryForNetwork(TEMPLATE_WIFI);
+ history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
assertEquals(512L, total[0]);
assertEquals(512L, total[1]);
@@ -289,7 +291,7 @@
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify identical stats, but spread across 4 buckets now
- history = mService.getHistoryForNetwork(TEMPLATE_WIFI);
+ history = mService.getHistoryForNetwork(new NetworkTemplate(MATCH_WIFI, null));
total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
assertEquals(512L, total[0]);
assertEquals(512L, total[1]);
@@ -299,15 +301,15 @@
}
- private void assertNetworkTotal(int template, long rx, long tx) {
+ private void assertNetworkTotal(NetworkTemplate template, long rx, long tx) {
final NetworkStatsHistory history = mService.getHistoryForNetwork(template);
final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
assertEquals(rx, total[0]);
assertEquals(tx, total[1]);
}
- private void assertUidTotal(int uid, int template, long rx, long tx) {
- final NetworkStatsHistory history = mService.getHistoryForUid(uid, template);
+ private void assertUidTotal(NetworkTemplate template, int uid, long rx, long tx) {
+ final NetworkStatsHistory history = mService.getHistoryForUid(template, uid);
final long[] total = history.getTotalData(Long.MIN_VALUE, Long.MAX_VALUE, null);
assertEquals(rx, total[0]);
assertEquals(tx, total[1]);