DO NOT MERGE: Implement metered tracking for NetworkStats summary queries.

Dependent on ag/1550196 where API is defined.

Bug: 31015360
Bug: 26545374
Test: runtest --path
frameworks/base/core/tests/coretests/src/android/net/NetworkStatsTest.java,
other test classes.

(cherry picked from commit 2514787897)

Change-Id: I46da93ba4afa968facf98f7c3d844fd0c469095a
This commit is contained in:
Stephen Chen
2016-10-21 12:44:26 -07:00
committed by Lorenzo Colitti
parent 2a43b208cc
commit 963e8ddf6d
11 changed files with 561 additions and 350 deletions

View File

@@ -256,6 +256,15 @@ public final class NetworkStats implements AutoCloseable {
return tag; return tag;
} }
private static @Metered int convertMetered(int metered) {
switch (metered) {
case android.net.NetworkStats.METERED_ALL : return METERED_ALL;
case android.net.NetworkStats.METERED_NO: return METERED_NO;
case android.net.NetworkStats.METERED_YES: return METERED_YES;
}
return 0;
}
private static @Roaming int convertRoaming(int roaming) { private static @Roaming int convertRoaming(int roaming) {
switch (roaming) { switch (roaming) {
case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL; case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL;
@@ -530,8 +539,7 @@ public final class NetworkStats implements AutoCloseable {
bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid); bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid);
bucketOut.mTag = Bucket.convertTag(mRecycledSummaryEntry.tag); bucketOut.mTag = Bucket.convertTag(mRecycledSummaryEntry.tag);
bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set); bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set);
// TODO: Implement metered tracking. bucketOut.mMetered = Bucket.convertMetered(mRecycledSummaryEntry.metered);
bucketOut.mMetered = Bucket.METERED_ALL;
bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming); bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming);
bucketOut.mBeginTimeStamp = mStartTimeStamp; bucketOut.mBeginTimeStamp = mStartTimeStamp;
bucketOut.mEndTimeStamp = mEndTimeStamp; bucketOut.mEndTimeStamp = mEndTimeStamp;

View File

@@ -51,16 +51,17 @@ import android.util.Log;
* {@link #querySummaryForUser} <p /> * {@link #querySummaryForUser} <p />
* {@link #querySummary} <p /> * {@link #querySummary} <p />
* These queries aggregate network usage across the whole interval. Therefore there will be only one * These queries aggregate network usage across the whole interval. Therefore there will be only one
* bucket for a particular key and state and roaming combination. In case of the user-wide and * bucket for a particular key, state, metered and roaming combination. In case of the user-wide
* device-wide summaries a single bucket containing the totalised network usage is returned. * and device-wide summaries a single bucket containing the totalised network usage is returned.
* <h3> * <h3>
* History queries * History queries
* </h3> * </h3>
* {@link #queryDetailsForUid} <p /> * {@link #queryDetailsForUid} <p />
* {@link #queryDetails} <p /> * {@link #queryDetails} <p />
* These queries do not aggregate over time but do aggregate over state and roaming. Therefore there * These queries do not aggregate over time but do aggregate over state, metered and roaming.
* can be multiple buckets for a particular key but all Bucket's state is going to be * Therefore there can be multiple buckets for a particular key but all Bucket's state is going to
* {@link NetworkStats.Bucket#STATE_ALL} and all Bucket's roaming is going to be * be {@link NetworkStats.Bucket#STATE_ALL}, all Bucket's metered is going to be
* {@link NetworkStats.Bucket#METERED_ALL}, and all Bucket's roaming is going to be
* {@link NetworkStats.Bucket#ROAMING_ALL}. * {@link NetworkStats.Bucket#ROAMING_ALL}.
* <p /> * <p />
* <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the * <b>NOTE:</b> Calling {@link #querySummaryForDevice} or accessing stats for apps other than the
@@ -103,10 +104,11 @@ public class NetworkStatsManager {
/** /**
* Query network usage statistics summaries. Result is summarised data usage for the whole * Query network usage statistics summaries. Result is summarised data usage for the whole
* device. Result is a single Bucket aggregated over time, state, uid, tag and roaming. This * device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and
* means the bucket's start and end timestamp are going to be the same as the 'startTime' and * roaming. This means the bucket's start and end timestamp are going to be the same as the
* 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid * 'startTime' and 'endTime' parameters. State is going to be
* {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE} * {@link NetworkStats.Bucket#STATE_ALL}, uid {@link NetworkStats.Bucket#UID_ALL},
* tag {@link NetworkStats.Bucket#TAG_NONE}, metered {@link NetworkStats.Bucket#METERED_ALL},
* and roaming {@link NetworkStats.Bucket#ROAMING_ALL}. * and roaming {@link NetworkStats.Bucket#ROAMING_ALL}.
* *
* @param networkType As defined in {@link ConnectivityManager}, e.g. * @param networkType As defined in {@link ConnectivityManager}, e.g.
@@ -142,8 +144,10 @@ public class NetworkStatsManager {
* Query network usage statistics summaries. Result is summarised data usage for all uids * Query network usage statistics summaries. Result is summarised data usage for all uids
* belonging to calling user. Result is a single Bucket aggregated over time, state and uid. * belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
* This means the bucket's start and end timestamp are going to be the same as the 'startTime' * This means the bucket's start and end timestamp are going to be the same as the 'startTime'
* and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid * and 'endTime' parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL},
* {@link NetworkStats.Bucket#UID_ALL}. * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE},
* metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming
* {@link NetworkStats.Bucket#ROAMING_ALL}.
* *
* @param networkType As defined in {@link ConnectivityManager}, e.g. * @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -177,9 +181,10 @@ public class NetworkStatsManager {
/** /**
* Query network usage statistics summaries. Result filtered to include only uids belonging to * Query network usage statistics summaries. Result filtered to include only uids belonging to
* calling user. Result is aggregated over time, hence all buckets will have the same start and * calling user. Result is aggregated over time, hence all buckets will have the same start and
* end timestamps. Not aggregated over state or uid. This means buckets' start and end * end timestamps. State is going to be {@link NetworkStats.Bucket#STATE_ALL},
* timestamps are going to be the same as the 'startTime' and 'endTime' parameters. * uid {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE},
* State and uid are going to vary, and tag is going to be the same. * metered {@link NetworkStats.Bucket#METERED_ALL}, and roaming
* {@link NetworkStats.Bucket#ROAMING_ALL}.
* *
* @param networkType As defined in {@link ConnectivityManager}, e.g. * @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI} * {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -262,10 +267,12 @@ public class NetworkStatsManager {
/** /**
* Query network usage statistics details. Result filtered to include only uids belonging to * Query network usage statistics details. Result filtered to include only uids belonging to
* calling user. Result is aggregated over state but not aggregated over time or uid. This means * calling user. Result is aggregated over state but not aggregated over time, uid, tag,
* buckets' start and end timestamps are going to be between 'startTime' and 'endTime' * metered, nor roaming. This means buckets' start and end timestamps are going to be between
* parameters. State is going to be {@link NetworkStats.Bucket#STATE_ALL}, uid will vary, * 'startTime' and 'endTime' parameters. State is going to be
* tag {@link NetworkStats.Bucket#TAG_NONE} and roaming is going to be * {@link NetworkStats.Bucket#STATE_ALL}, uid will vary,
* tag {@link NetworkStats.Bucket#TAG_NONE}, metered is going to be
* {@link NetworkStats.Bucket#METERED_ALL}, and roaming is going to be
* {@link NetworkStats.Bucket#ROAMING_ALL}. * {@link NetworkStats.Bucket#ROAMING_ALL}.
* <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't * <p>Only includes buckets that atomically occur in the inclusive time range. Doesn't
* interpolate across partial buckets. Since bucket length is in the order of hours, this * interpolate across partial buckets. Since bucket length is in the order of hours, this

View File

@@ -171,7 +171,8 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
String subscriberId = null; String subscriberId = null;
String networkId = null; String networkId = null;
boolean roaming = false; boolean roaming = false;
boolean metered = false; boolean metered = !state.networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
if (isNetworkTypeMobile(type)) { if (isNetworkTypeMobile(type)) {
if (state.subscriberId == null) { if (state.subscriberId == null) {
@@ -185,9 +186,6 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
subscriberId = state.subscriberId; subscriberId = state.subscriberId;
roaming = state.networkInfo.isRoaming(); roaming = state.networkInfo.isRoaming();
metered = !state.networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
} else if (type == TYPE_WIFI) { } else if (type == TYPE_WIFI) {
if (state.networkId != null) { if (state.networkId != null) {
networkId = state.networkId; networkId = state.networkId;

View File

@@ -68,11 +68,18 @@ public class NetworkStats implements Parcelable {
// TODO: Rename TAG_NONE to TAG_ALL. // TODO: Rename TAG_NONE to TAG_ALL.
public static final int TAG_NONE = 0; public static final int TAG_NONE = 0;
/** {@link #set} value for all roaming values. */ /** {@link #metered} value to account for all metered states. */
public static final int METERED_ALL = -1;
/** {@link #metered} value where native, unmetered data is accounted. */
public static final int METERED_NO = 0;
/** {@link #metered} value where metered data is accounted. */
public static final int METERED_YES = 1;
/** {@link #roaming} value to account for all roaming states. */
public static final int ROAMING_ALL = -1; public static final int ROAMING_ALL = -1;
/** {@link #set} value where native, non-roaming data is accounted. */ /** {@link #roaming} value where native, non-roaming data is accounted. */
public static final int ROAMING_NO = 0; public static final int ROAMING_NO = 0;
/** {@link #set} value where roaming data is accounted. */ /** {@link #roaming} value where roaming data is accounted. */
public static final int ROAMING_YES = 1; public static final int ROAMING_YES = 1;
// TODO: move fields to "mVariable" notation // TODO: move fields to "mVariable" notation
@@ -88,6 +95,7 @@ public class NetworkStats implements Parcelable {
private int[] uid; private int[] uid;
private int[] set; private int[] set;
private int[] tag; private int[] tag;
private int[] metered;
private int[] roaming; private int[] roaming;
private long[] rxBytes; private long[] rxBytes;
private long[] rxPackets; private long[] rxPackets;
@@ -100,6 +108,12 @@ public class NetworkStats implements Parcelable {
public int uid; public int uid;
public int set; public int set;
public int tag; public int tag;
/**
* Note that this is only populated w/ the default value when read from /proc or written
* to disk. We merge in the correct value when reporting this value to clients of
* getSummary().
*/
public int metered;
/** /**
* Note that this is only populated w/ the default value when read from /proc or written * Note that this is only populated w/ the default value when read from /proc or written
* to disk. We merge in the correct value when reporting this value to clients of * to disk. We merge in the correct value when reporting this value to clients of
@@ -123,16 +137,17 @@ public class NetworkStats implements Parcelable {
public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets,
long txBytes, long txPackets, long operations) { long txBytes, long txPackets, long operations) {
this(iface, uid, set, tag, ROAMING_NO, rxBytes, rxPackets, txBytes, txPackets, this(iface, uid, set, tag, METERED_NO, ROAMING_NO, rxBytes, rxPackets, txBytes,
operations); txPackets, operations);
} }
public Entry(String iface, int uid, int set, int tag, int roaming, long rxBytes, public Entry(String iface, int uid, int set, int tag, int metered, int roaming,
long rxPackets, long txBytes, long txPackets, long operations) { long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
this.iface = iface; this.iface = iface;
this.uid = uid; this.uid = uid;
this.set = set; this.set = set;
this.tag = tag; this.tag = tag;
this.metered = metered;
this.roaming = roaming; this.roaming = roaming;
this.rxBytes = rxBytes; this.rxBytes = rxBytes;
this.rxPackets = rxPackets; this.rxPackets = rxPackets;
@@ -165,6 +180,7 @@ public class NetworkStats implements Parcelable {
builder.append(" uid=").append(uid); builder.append(" uid=").append(uid);
builder.append(" set=").append(setToString(set)); builder.append(" set=").append(setToString(set));
builder.append(" tag=").append(tagToString(tag)); builder.append(" tag=").append(tagToString(tag));
builder.append(" metered=").append(meteredToString(metered));
builder.append(" roaming=").append(roamingToString(roaming)); builder.append(" roaming=").append(roamingToString(roaming));
builder.append(" rxBytes=").append(rxBytes); builder.append(" rxBytes=").append(rxBytes);
builder.append(" rxPackets=").append(rxPackets); builder.append(" rxPackets=").append(rxPackets);
@@ -178,13 +194,18 @@ public class NetworkStats implements Parcelable {
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof Entry) { if (o instanceof Entry) {
final Entry e = (Entry) o; final Entry e = (Entry) o;
return uid == e.uid && set == e.set && tag == e.tag && roaming == e.roaming return uid == e.uid && set == e.set && tag == e.tag && metered == e.metered
&& rxBytes == e.rxBytes && rxPackets == e.rxPackets && txBytes == e.txBytes && roaming == e.roaming && rxBytes == e.rxBytes && rxPackets == e.rxPackets
&& txPackets == e.txPackets && operations == e.operations && txBytes == e.txBytes && txPackets == e.txPackets
&& iface.equals(e.iface); && operations == e.operations && iface.equals(e.iface);
} }
return false; return false;
} }
@Override
public int hashCode() {
return Objects.hash(uid, set, tag, metered, roaming, iface);
}
} }
public NetworkStats(long elapsedRealtime, int initialSize) { public NetworkStats(long elapsedRealtime, int initialSize) {
@@ -196,6 +217,7 @@ public class NetworkStats implements Parcelable {
this.uid = new int[initialSize]; this.uid = new int[initialSize];
this.set = new int[initialSize]; this.set = new int[initialSize];
this.tag = new int[initialSize]; this.tag = new int[initialSize];
this.metered = new int[initialSize];
this.roaming = new int[initialSize]; this.roaming = new int[initialSize];
this.rxBytes = new long[initialSize]; this.rxBytes = new long[initialSize];
this.rxPackets = new long[initialSize]; this.rxPackets = new long[initialSize];
@@ -209,6 +231,7 @@ public class NetworkStats implements Parcelable {
this.uid = EmptyArray.INT; this.uid = EmptyArray.INT;
this.set = EmptyArray.INT; this.set = EmptyArray.INT;
this.tag = EmptyArray.INT; this.tag = EmptyArray.INT;
this.metered = EmptyArray.INT;
this.roaming = EmptyArray.INT; this.roaming = EmptyArray.INT;
this.rxBytes = EmptyArray.LONG; this.rxBytes = EmptyArray.LONG;
this.rxPackets = EmptyArray.LONG; this.rxPackets = EmptyArray.LONG;
@@ -226,6 +249,7 @@ public class NetworkStats implements Parcelable {
uid = parcel.createIntArray(); uid = parcel.createIntArray();
set = parcel.createIntArray(); set = parcel.createIntArray();
tag = parcel.createIntArray(); tag = parcel.createIntArray();
metered = parcel.createIntArray();
roaming = parcel.createIntArray(); roaming = parcel.createIntArray();
rxBytes = parcel.createLongArray(); rxBytes = parcel.createLongArray();
rxPackets = parcel.createLongArray(); rxPackets = parcel.createLongArray();
@@ -243,6 +267,7 @@ public class NetworkStats implements Parcelable {
dest.writeIntArray(uid); dest.writeIntArray(uid);
dest.writeIntArray(set); dest.writeIntArray(set);
dest.writeIntArray(tag); dest.writeIntArray(tag);
dest.writeIntArray(metered);
dest.writeIntArray(roaming); dest.writeIntArray(roaming);
dest.writeLongArray(rxBytes); dest.writeLongArray(rxBytes);
dest.writeLongArray(rxPackets); dest.writeLongArray(rxPackets);
@@ -277,10 +302,11 @@ public class NetworkStats implements Parcelable {
} }
@VisibleForTesting @VisibleForTesting
public NetworkStats addValues(String iface, int uid, int set, int tag, int roaming, public NetworkStats addValues(String iface, int uid, int set, int tag, int metered, int roaming,
long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
return addValues(new Entry( return addValues(new Entry(
iface, uid, set, tag, roaming, rxBytes, rxPackets, txBytes, txPackets, operations)); iface, uid, set, tag, metered, roaming, rxBytes, rxPackets, txBytes, txPackets,
operations));
} }
/** /**
@@ -294,6 +320,7 @@ public class NetworkStats implements Parcelable {
uid = Arrays.copyOf(uid, newLength); uid = Arrays.copyOf(uid, newLength);
set = Arrays.copyOf(set, newLength); set = Arrays.copyOf(set, newLength);
tag = Arrays.copyOf(tag, newLength); tag = Arrays.copyOf(tag, newLength);
metered = Arrays.copyOf(metered, newLength);
roaming = Arrays.copyOf(roaming, newLength); roaming = Arrays.copyOf(roaming, newLength);
rxBytes = Arrays.copyOf(rxBytes, newLength); rxBytes = Arrays.copyOf(rxBytes, newLength);
rxPackets = Arrays.copyOf(rxPackets, newLength); rxPackets = Arrays.copyOf(rxPackets, newLength);
@@ -307,6 +334,7 @@ public class NetworkStats implements Parcelable {
uid[size] = entry.uid; uid[size] = entry.uid;
set[size] = entry.set; set[size] = entry.set;
tag[size] = entry.tag; tag[size] = entry.tag;
metered[size] = entry.metered;
roaming[size] = entry.roaming; roaming[size] = entry.roaming;
rxBytes[size] = entry.rxBytes; rxBytes[size] = entry.rxBytes;
rxPackets[size] = entry.rxPackets; rxPackets[size] = entry.rxPackets;
@@ -327,6 +355,7 @@ public class NetworkStats implements Parcelable {
entry.uid = uid[i]; entry.uid = uid[i];
entry.set = set[i]; entry.set = set[i];
entry.tag = tag[i]; entry.tag = tag[i];
entry.metered = metered[i];
entry.roaming = roaming[i]; entry.roaming = roaming[i];
entry.rxBytes = rxBytes[i]; entry.rxBytes = rxBytes[i];
entry.rxPackets = rxPackets[i]; entry.rxPackets = rxPackets[i];
@@ -381,7 +410,8 @@ public class NetworkStats implements Parcelable {
* also be used to subtract values from existing rows. * also be used to subtract values from existing rows.
*/ */
public NetworkStats combineValues(Entry entry) { public NetworkStats combineValues(Entry entry) {
final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.roaming); final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.metered,
entry.roaming);
if (i == -1) { if (i == -1) {
// only create new entry when positive contribution // only create new entry when positive contribution
addValues(entry); addValues(entry);
@@ -409,10 +439,11 @@ public class NetworkStats implements Parcelable {
/** /**
* Find first stats index that matches the requested parameters. * Find first stats index that matches the requested parameters.
*/ */
public int findIndex(String iface, int uid, int set, int tag, int roaming) { public int findIndex(String iface, int uid, int set, int tag, int metered, int roaming) {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
&& roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) { && metered == this.metered[i] && roaming == this.roaming[i]
&& Objects.equals(iface, this.iface[i])) {
return i; return i;
} }
} }
@@ -424,7 +455,7 @@ public class NetworkStats implements Parcelable {
* search around the hinted index as an optimization. * search around the hinted index as an optimization.
*/ */
@VisibleForTesting @VisibleForTesting
public int findIndexHinted(String iface, int uid, int set, int tag, int roaming, public int findIndexHinted(String iface, int uid, int set, int tag, int metered, int roaming,
int hintIndex) { int hintIndex) {
for (int offset = 0; offset < size; offset++) { for (int offset = 0; offset < size; offset++) {
final int halfOffset = offset / 2; final int halfOffset = offset / 2;
@@ -438,7 +469,8 @@ public class NetworkStats implements Parcelable {
} }
if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
&& roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) { && metered == this.metered[i] && roaming == this.roaming[i]
&& Objects.equals(iface, this.iface[i])) {
return i; return i;
} }
} }
@@ -452,7 +484,7 @@ public class NetworkStats implements Parcelable {
*/ */
public void spliceOperationsFrom(NetworkStats stats) { public void spliceOperationsFrom(NetworkStats stats) {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], roaming[i]); final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], metered[i], roaming[i]);
if (j == -1) { if (j == -1) {
operations[i] = 0; operations[i] = 0;
} else { } else {
@@ -542,6 +574,7 @@ public class NetworkStats implements Parcelable {
entry.uid = limitUid; entry.uid = limitUid;
entry.set = SET_ALL; entry.set = SET_ALL;
entry.tag = TAG_NONE; entry.tag = TAG_NONE;
entry.metered = METERED_ALL;
entry.roaming = ROAMING_ALL; entry.roaming = ROAMING_ALL;
entry.rxBytes = 0; entry.rxBytes = 0;
entry.rxPackets = 0; entry.rxPackets = 0;
@@ -637,11 +670,12 @@ public class NetworkStats implements Parcelable {
entry.uid = left.uid[i]; entry.uid = left.uid[i];
entry.set = left.set[i]; entry.set = left.set[i];
entry.tag = left.tag[i]; entry.tag = left.tag[i];
entry.metered = left.metered[i];
entry.roaming = left.roaming[i]; entry.roaming = left.roaming[i];
// find remote row that matches, and subtract // find remote row that matches, and subtract
final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag,
entry.roaming, i); entry.metered, entry.roaming, i);
if (j == -1) { if (j == -1) {
// newly appearing row, return entire value // newly appearing row, return entire value
entry.rxBytes = left.rxBytes[i]; entry.rxBytes = left.rxBytes[i];
@@ -687,6 +721,7 @@ public class NetworkStats implements Parcelable {
entry.uid = UID_ALL; entry.uid = UID_ALL;
entry.set = SET_ALL; entry.set = SET_ALL;
entry.tag = TAG_NONE; entry.tag = TAG_NONE;
entry.metered = METERED_ALL;
entry.roaming = ROAMING_ALL; entry.roaming = ROAMING_ALL;
entry.operations = 0L; entry.operations = 0L;
@@ -716,6 +751,7 @@ public class NetworkStats implements Parcelable {
entry.iface = IFACE_ALL; entry.iface = IFACE_ALL;
entry.set = SET_ALL; entry.set = SET_ALL;
entry.tag = TAG_NONE; entry.tag = TAG_NONE;
entry.metered = METERED_ALL;
entry.roaming = ROAMING_ALL; entry.roaming = ROAMING_ALL;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@@ -762,6 +798,7 @@ public class NetworkStats implements Parcelable {
pw.print(" uid="); pw.print(uid[i]); pw.print(" uid="); pw.print(uid[i]);
pw.print(" set="); pw.print(setToString(set[i])); pw.print(" set="); pw.print(setToString(set[i]));
pw.print(" tag="); pw.print(tagToString(tag[i])); pw.print(" tag="); pw.print(tagToString(tag[i]));
pw.print(" metered="); pw.print(meteredToString(metered[i]));
pw.print(" roaming="); pw.print(roamingToString(roaming[i])); pw.print(" roaming="); pw.print(roamingToString(roaming[i]));
pw.print(" rxBytes="); pw.print(rxBytes[i]); pw.print(" rxBytes="); pw.print(rxBytes[i]);
pw.print(" rxPackets="); pw.print(rxPackets[i]); pw.print(" rxPackets="); pw.print(rxPackets[i]);
@@ -829,6 +866,22 @@ public class NetworkStats implements Parcelable {
return "0x" + Integer.toHexString(tag); return "0x" + Integer.toHexString(tag);
} }
/**
* Return text description of {@link #metered} value.
*/
public static String meteredToString(int metered) {
switch (metered) {
case METERED_ALL:
return "ALL";
case METERED_NO:
return "NO";
case METERED_YES:
return "YES";
default:
return "UNKNOWN";
}
}
/** /**
* Return text description of {@link #roaming} value. * Return text description of {@link #roaming} value.
*/ */
@@ -998,6 +1051,7 @@ public class NetworkStats implements Parcelable {
tmpEntry.uid = uid[i]; tmpEntry.uid = uid[i];
tmpEntry.tag = tag[i]; tmpEntry.tag = tag[i];
tmpEntry.set = set[i]; tmpEntry.set = set[i];
tmpEntry.metered = metered[i];
tmpEntry.roaming = roaming[i]; tmpEntry.roaming = roaming[i];
combineValues(tmpEntry); combineValues(tmpEntry);
if (tag[i] == TAG_NONE) { if (tag[i] == TAG_NONE) {
@@ -1017,24 +1071,25 @@ public class NetworkStats implements Parcelable {
moved.set = SET_DBG_VPN_OUT; moved.set = SET_DBG_VPN_OUT;
moved.tag = TAG_NONE; moved.tag = TAG_NONE;
moved.iface = underlyingIface; moved.iface = underlyingIface;
moved.metered = METERED_ALL;
moved.roaming = ROAMING_ALL; moved.roaming = ROAMING_ALL;
combineValues(moved); combineValues(moved);
// Caveat: if the vpn software uses tag, the total tagged traffic may be greater than // Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
// the TAG_NONE traffic. // the TAG_NONE traffic.
// //
// Relies on the fact that the underlying traffic only has state ROAMING_NO, which // Relies on the fact that the underlying traffic only has state ROAMING_NO and METERED_NO,
// should be the case as it comes directly from the /proc file. We only blend in the // which should be the case as it comes directly from the /proc file. We only blend in the
// roaming data after applying these adjustments, by checking the NetworkIdentity of the // roaming data after applying these adjustments, by checking the NetworkIdentity of the
// underlying iface. // underlying iface.
int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE,
ROAMING_NO); METERED_NO, ROAMING_NO);
if (idxVpnBackground != -1) { if (idxVpnBackground != -1) {
tunSubtract(idxVpnBackground, this, moved); tunSubtract(idxVpnBackground, this, moved);
} }
int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE,
ROAMING_NO); METERED_NO, ROAMING_NO);
if (idxVpnForeground != -1) { if (idxVpnForeground != -1) {
tunSubtract(idxVpnForeground, this, moved); tunSubtract(idxVpnForeground, this, moved);
} }

View File

@@ -43,6 +43,7 @@ static struct {
jfieldID uid; jfieldID uid;
jfieldID set; jfieldID set;
jfieldID tag; jfieldID tag;
jfieldID metered;
jfieldID roaming; jfieldID roaming;
jfieldID rxBytes; jfieldID rxBytes;
jfieldID rxPackets; jfieldID rxPackets;
@@ -239,6 +240,9 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
ScopedIntArrayRW tag(env, get_int_array(env, stats, ScopedIntArrayRW tag(env, get_int_array(env, stats,
gNetworkStatsClassInfo.tag, size, grow)); gNetworkStatsClassInfo.tag, size, grow));
if (tag.get() == NULL) return -1; if (tag.get() == NULL) return -1;
ScopedIntArrayRW metered(env, get_int_array(env, stats,
gNetworkStatsClassInfo.metered, size, grow));
if (metered.get() == NULL) return -1;
ScopedIntArrayRW roaming(env, get_int_array(env, stats, ScopedIntArrayRW roaming(env, get_int_array(env, stats,
gNetworkStatsClassInfo.roaming, size, grow)); gNetworkStatsClassInfo.roaming, size, grow));
if (roaming.get() == NULL) return -1; if (roaming.get() == NULL) return -1;
@@ -265,7 +269,7 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
uid[i] = lines[i].uid; uid[i] = lines[i].uid;
set[i] = lines[i].set; set[i] = lines[i].set;
tag[i] = lines[i].tag; tag[i] = lines[i].tag;
// Roaming is populated in Java-land by inspecting the iface properties. // Metered and Roaming are populated in Java-land by inspecting the iface properties.
rxBytes[i] = lines[i].rxBytes; rxBytes[i] = lines[i].rxBytes;
rxPackets[i] = lines[i].rxPackets; rxPackets[i] = lines[i].rxPackets;
txBytes[i] = lines[i].txBytes; txBytes[i] = lines[i].txBytes;
@@ -279,6 +283,7 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.metered, metered.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.roaming, roaming.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.roaming, roaming.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
@@ -311,6 +316,7 @@ int register_com_android_internal_net_NetworkStatsFactory(JNIEnv* env) {
gNetworkStatsClassInfo.uid = GetFieldIDOrDie(env, clazz, "uid", "[I"); gNetworkStatsClassInfo.uid = GetFieldIDOrDie(env, clazz, "uid", "[I");
gNetworkStatsClassInfo.set = GetFieldIDOrDie(env, clazz, "set", "[I"); gNetworkStatsClassInfo.set = GetFieldIDOrDie(env, clazz, "set", "[I");
gNetworkStatsClassInfo.tag = GetFieldIDOrDie(env, clazz, "tag", "[I"); gNetworkStatsClassInfo.tag = GetFieldIDOrDie(env, clazz, "tag", "[I");
gNetworkStatsClassInfo.metered = GetFieldIDOrDie(env, clazz, "metered", "[I");
gNetworkStatsClassInfo.roaming = GetFieldIDOrDie(env, clazz, "roaming", "[I"); gNetworkStatsClassInfo.roaming = GetFieldIDOrDie(env, clazz, "roaming", "[I");
gNetworkStatsClassInfo.rxBytes = GetFieldIDOrDie(env, clazz, "rxBytes", "[J"); gNetworkStatsClassInfo.rxBytes = GetFieldIDOrDie(env, clazz, "rxBytes", "[J");
gNetworkStatsClassInfo.rxPackets = GetFieldIDOrDie(env, clazz, "rxPackets", "[J"); gNetworkStatsClassInfo.rxPackets = GetFieldIDOrDie(env, clazz, "rxPackets", "[J");

View File

@@ -16,6 +16,9 @@
package android.net; package android.net;
import static android.net.NetworkStats.METERED_ALL;
import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkStats.ROAMING_ALL; import static android.net.NetworkStats.ROAMING_ALL;
import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_NO;
import static android.net.NetworkStats.ROAMING_YES; import static android.net.NetworkStats.ROAMING_YES;
@@ -45,103 +48,124 @@ public class NetworkStatsTest extends TestCase {
private static final long TEST_START = 1194220800000L; private static final long TEST_START = 1194220800000L;
public void testFindIndex() throws Exception { public void testFindIndex() throws Exception {
final NetworkStats stats = new NetworkStats(TEST_START, 4) final NetworkStats stats = new NetworkStats(TEST_START, 5)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, 0L, .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
0L, 10) 8L, 0L, 0L, 10)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 1024L, .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
8L, 11) 1024L, 8L, 11)
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 0L, 0L,
1024L, 8L, 12) 1024L, 8L, 11)
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES, 1024L, 8L, .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
1024L, 8L, 12); 8L, 1024L, 8L, 12)
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 1024L,
8L, 1024L, 8L, 12);
assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES)); assertEquals(4, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_YES,
assertEquals(2, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO)); ROAMING_YES));
assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO)); assertEquals(3, stats.findIndex(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO,
assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO)); ROAMING_NO));
assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, ROAMING_NO)); assertEquals(2, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES,
ROAMING_NO));
assertEquals(1, stats.findIndex(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO,
ROAMING_NO));
assertEquals(0, stats.findIndex(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO,
ROAMING_NO));
assertEquals(-1, stats.findIndex(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, METERED_NO,
ROAMING_NO));
} }
public void testFindIndexHinted() { public void testFindIndexHinted() {
final NetworkStats stats = new NetworkStats(TEST_START, 3) final NetworkStats stats = new NetworkStats(TEST_START, 3)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, 0L, .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
0L, 10) 8L, 0L, 0L, 10)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 1024L, .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
8L, 11) 1024L, 8L, 11)
.addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, .addValues(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
1024L, 8L, 12) 8L, 1024L, 8L, 12)
.addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 1024L, 8L, .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
0L, 0L, 10) 1024L, 8L, 0L, 0L, 10)
.addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 0L, 0L, 1024L, .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 0L, 0L,
8L, 11) 1024L, 8L, 11)
.addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, .addValues(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, 0L, 0L,
1024L, 8L, 12) 1024L, 8L, 11)
.addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, ROAMING_YES, 1024L, 8L, .addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1024L,
1024L, 8L, 12); 8L, 1024L, 8L, 12)
.addValues(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 1024L,
8L, 1024L, 8L, 12);
// verify that we correctly find across regardless of hinting // verify that we correctly find across regardless of hinting
for (int hint = 0; hint < stats.size(); hint++) { for (int hint = 0; hint < stats.size(); hint++) {
assertEquals(0, stats.findIndexHinted(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, assertEquals(0, stats.findIndexHinted(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE,
ROAMING_NO, hint)); METERED_NO, ROAMING_NO, hint));
assertEquals(1, stats.findIndexHinted(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, assertEquals(1, stats.findIndexHinted(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE,
ROAMING_NO, hint)); METERED_NO, ROAMING_NO, hint));
assertEquals(2, stats.findIndexHinted(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, assertEquals(2, stats.findIndexHinted(TEST_IFACE, 102, SET_DEFAULT, TAG_NONE,
ROAMING_NO, hint)); METERED_NO, ROAMING_NO, hint));
assertEquals(3, stats.findIndexHinted(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, assertEquals(3, stats.findIndexHinted(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE,
ROAMING_NO, hint)); METERED_NO, ROAMING_NO, hint));
assertEquals(4, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D, assertEquals(4, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D,
ROAMING_NO, hint)); METERED_NO, ROAMING_NO, hint));
assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, assertEquals(5, stats.findIndexHinted(TEST_IFACE2, 101, SET_DEFAULT, 0xF00D,
ROAMING_NO, hint)); METERED_YES, ROAMING_NO, hint));
assertEquals(6, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE, assertEquals(6, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
ROAMING_YES, hint)); METERED_NO, ROAMING_NO, hint));
assertEquals(7, stats.findIndexHinted(TEST_IFACE2, 102, SET_DEFAULT, TAG_NONE,
METERED_YES, ROAMING_YES, hint));
assertEquals(-1, stats.findIndexHinted(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE, assertEquals(-1, stats.findIndexHinted(TEST_IFACE, 6, SET_DEFAULT, TAG_NONE,
ROAMING_NO, hint)); METERED_NO, ROAMING_NO, hint));
} }
} }
public void testAddEntryGrow() throws Exception { public void testAddEntryGrow() throws Exception {
final NetworkStats stats = new NetworkStats(TEST_START, 3); final NetworkStats stats = new NetworkStats(TEST_START, 4);
assertEquals(0, stats.size()); assertEquals(0, stats.size());
assertEquals(3, stats.internalSize()); assertEquals(4, stats.internalSize());
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L, 2L, stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1L, 1L,
2L, 3);
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2L, 2L, 2L,
2L, 4);
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 3L, 3L, 2L,
2L, 5);
assertEquals(3, stats.size());
assertEquals(3, stats.internalSize());
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 4L, 40L, 4L,
40L, 7);
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 5L, 50L, 4L,
40L, 8);
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 6L, 60L, 5L,
50L, 10);
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 7L, 70L, 5L,
50L, 11);
assertEquals(7, stats.size());
assertTrue(stats.internalSize() >= 7);
assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L,
2L, 2L, 3); 2L, 2L, 3);
assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2L, 2L, stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 2L, 2L,
2L, 2L, 4); 2L, 2L, 4);
assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 3L, 3L, stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 3L,
2L, 2L, 5); 3L, 2L, 2L, 5);
assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 4L, stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 3L,
3L, 2L, 2L, 5);
assertEquals(4, stats.size());
assertEquals(4, stats.internalSize());
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 4L,
40L, 4L, 40L, 7); 40L, 4L, 40L, 7);
assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 5L, stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 5L,
50L, 4L, 40L, 8); 50L, 4L, 40L, 8);
assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_NO, 6L, stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 6L,
60L, 5L, 50L, 10); 60L, 5L, 50L, 10);
assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, ROAMING_YES, 7L, stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 7L,
70L, 5L, 50L, 11); 70L, 5L, 50L, 11);
stats.addValues(TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_YES, 7L,
70L, 5L, 50L, 11);
assertEquals(9, stats.size());
assertTrue(stats.internalSize() >= 9);
assertValues(stats, 0, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1L, 1L, 2L, 2L, 3);
assertValues(stats, 1, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
2L, 2L, 2L, 2L, 4);
assertValues(stats, 2, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
3L, 3L, 2L, 2L, 5);
assertValues(stats, 3, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES,
ROAMING_YES, 3L, 3L, 2L, 2L, 5);
assertValues(stats, 4, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
4L, 40L, 4L, 40L, 7);
assertValues(stats, 5, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
5L, 50L, 4L, 40L, 8);
assertValues(stats, 6, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
6L, 60L, 5L, 50L, 10);
assertValues(stats, 7, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES,
7L, 70L, 5L, 50L, 11);
assertValues(stats, 8, TEST_IFACE, TEST_UID, SET_DEFAULT, TAG_NONE, METERED_YES,
ROAMING_YES, 7L, 70L, 5L, 50L, 11);
} }
public void testCombineExisting() throws Exception { public void testCombineExisting() throws Exception {
@@ -152,20 +176,18 @@ public class NetworkStatsTest extends TestCase {
stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L, stats.combineValues(TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, -128L, -1L,
-128L, -1L, -1); -128L, -1L, -1);
assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, ROAMING_NO, 384L, 3L, assertValues(stats, 0, TEST_IFACE, 1001, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
128L, 1L, 9); 384L, 3L, 128L, 1L, 9);
assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, ROAMING_NO, 128L, 1L, 128L, assertValues(stats, 1, TEST_IFACE, 1001, SET_DEFAULT, 0xff, METERED_NO, ROAMING_NO, 128L,
1L, 2); 1L, 128L, 1L, 2);
// now try combining that should create row // now try combining that should create row
stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
128L, 1L, 3); assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 1L, 128L, 1L, 128L, 1L, 3);
128L, 1L, 3); stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 3);
stats.combineValues(TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, 128L, 1L, assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
128L, 1L, 3); 256L, 2L, 256L, 2L, 6);
assertValues(stats, 2, TEST_IFACE, 5005, SET_DEFAULT, TAG_NONE, ROAMING_NO, 256L, 2L,
256L, 2L, 6);
} }
public void testSubtractIdenticalData() throws Exception { public void testSubtractIdenticalData() throws Exception {
@@ -180,10 +202,10 @@ public class NetworkStatsTest extends TestCase {
final NetworkStats result = after.subtract(before); final NetworkStats result = after.subtract(before);
// identical data should result in zero delta // identical data should result in zero delta
assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L, assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
0L, 0); 0L, 0L, 0L, 0);
assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L, assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
0L, 0); 0L, 0L, 0L, 0);
} }
public void testSubtractIdenticalRows() throws Exception { public void testSubtractIdenticalRows() throws Exception {
@@ -198,10 +220,10 @@ public class NetworkStatsTest extends TestCase {
final NetworkStats result = after.subtract(before); final NetworkStats result = after.subtract(before);
// expect delta between measurements // expect delta between measurements
assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, 1L, 2L, assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1L,
1L, 4); 1L, 2L, 1L, 4);
assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 3L, 1L, 4L, assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 3L,
1L, 8); 1L, 4L, 1L, 8);
} }
public void testSubtractNewRows() throws Exception { public void testSubtractNewRows() throws Exception {
@@ -217,12 +239,12 @@ public class NetworkStatsTest extends TestCase {
final NetworkStats result = after.subtract(before); final NetworkStats result = after.subtract(before);
// its okay to have new rows // its okay to have new rows
assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L, assertValues(result, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
0L, 0); 0L, 0L, 0L, 0);
assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 0L, 0L, 0L, assertValues(result, 1, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
0L, 0); 0L, 0L, 0L, 0);
assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, assertValues(result, 2, TEST_IFACE, 102, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1024L, 8L, 20); 1024L, 8L, 1024L, 8L, 20);
} }
public void testSubtractMissingRows() throws Exception { public void testSubtractMissingRows() throws Exception {
@@ -237,8 +259,8 @@ public class NetworkStatsTest extends TestCase {
// should silently drop omitted rows // should silently drop omitted rows
assertEquals(1, result.size()); assertEquals(1, result.size());
assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1L, assertValues(result, 0, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO,
2L, 3L, 4L, 0); ROAMING_NO, 1L, 2L, 3L, 4L, 0);
assertEquals(4L, result.getTotalBytes()); assertEquals(4L, result.getTotalBytes());
} }
@@ -263,13 +285,22 @@ public class NetworkStatsTest extends TestCase {
.addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L); .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, 8L, 0L, 0L, 0L, 0L);
assertEquals(64L, uidTag.getTotalBytes()); assertEquals(64L, uidTag.getTotalBytes());
final NetworkStats uidMetered = new NetworkStats(TEST_START, 3)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 32L, 0L,
0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
0L, 0L, 0L);
assertEquals(96L, uidMetered.getTotalBytes());
final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3) final NetworkStats uidRoaming = new NetworkStats(TEST_START, 3)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L, .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 32L, 0L,
0L) 0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L, .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
0L) 0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_YES, 32L, 0L, 0L, 0L, .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 32L, 0L,
0L); 0L, 0L, 0L);
assertEquals(96L, uidRoaming.getTotalBytes()); assertEquals(96L, uidRoaming.getTotalBytes());
} }
@@ -283,95 +314,95 @@ public class NetworkStatsTest extends TestCase {
public void testGroupedByIfaceAll() throws Exception { public void testGroupedByIfaceAll() throws Exception {
final NetworkStats uidStats = new NetworkStats(TEST_START, 3) final NetworkStats uidStats = new NetworkStats(TEST_START, 3)
.addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, ROAMING_NO, 128L, 8L, 0L, 2L, .addValues(IFACE_ALL, 100, SET_ALL, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L, 0L,
20L)
.addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 128L, 8L, 0L,
2L, 20L) 2L, 20L)
.addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, ROAMING_YES, 128L, 8L, 0L, 2L, .addValues(IFACE_ALL, 101, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_NO, 128L,
20L); 8L, 0L, 2L, 20L)
.addValues(IFACE_ALL, 101, SET_ALL, TAG_NONE, METERED_NO, ROAMING_YES, 128L, 8L, 0L,
2L, 20L);
final NetworkStats grouped = uidStats.groupedByIface(); final NetworkStats grouped = uidStats.groupedByIface();
assertEquals(3, uidStats.size()); assertEquals(3, uidStats.size());
assertEquals(1, grouped.size()); assertEquals(1, grouped.size());
assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 384L, 24L, 0L, assertValues(grouped, 0, IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
6L, 0L); 384L, 24L, 0L, 6L, 0L);
} }
public void testGroupedByIface() throws Exception { public void testGroupedByIface() throws Exception {
final NetworkStats uidStats = new NetworkStats(TEST_START, 7) final NetworkStats uidStats = new NetworkStats(TEST_START, 7)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L, .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
2L, 20L) 0L, 2L, 20L)
.addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 512L, 32L, 0L, .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
0L, 0L) 32L, 0L, 0L, 0L)
.addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 4L, 0L, 0L, .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L, 4L,
0L)
.addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 512L, 32L,
0L, 0L, 0L) 0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L, .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
0L, 0L) 32L, 0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L, 0L, .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
0L) 0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 8L, 0L, .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, 128L, 8L,
0L, 0L); 0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 128L,
8L, 0L, 0L, 0L);
final NetworkStats grouped = uidStats.groupedByIface(); final NetworkStats grouped = uidStats.groupedByIface();
assertEquals(7, uidStats.size()); assertEquals(7, uidStats.size());
assertEquals(2, grouped.size()); assertEquals(2, grouped.size());
assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 384L, 24L, 0L, assertValues(grouped, 0, TEST_IFACE, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
2L, 0L); 384L, 24L, 0L, 2L, 0L);
assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, ROAMING_ALL, 1024L, 64L, assertValues(grouped, 1, TEST_IFACE2, UID_ALL, SET_ALL, TAG_NONE, METERED_ALL, ROAMING_ALL,
0L, 0L, 0L); 1024L, 64L, 0L, 0L, 0L);
} }
public void testAddAllValues() { public void testAddAllValues() {
final NetworkStats first = new NetworkStats(TEST_START, 5) final NetworkStats first = new NetworkStats(TEST_START, 5)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L, .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
0L) 0L, 0L, 0L)
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 32L,
0L, 0L) 0L, 0L, 0L, 0L)
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 32L, 0L, 0L, .addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, 32L,
0L, 0L); 0L, 0L, 0L, 0L);
final NetworkStats second = new NetworkStats(TEST_START, 2) final NetworkStats second = new NetworkStats(TEST_START, 2)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L, 0L, 0L, .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 32L, 0L,
0L)
.addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L, 0L,
0L, 0L, 0L) 0L, 0L, 0L)
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 32L, 0L, 0L, .addValues(TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 32L,
0L, 0L); 0L, 0L, 0L, 0L)
.addValues(TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES, 32L,
0L, 0L, 0L, 0L);
first.combineAllValues(second); first.combineAllValues(second);
assertEquals(4, first.size()); assertEquals(4, first.size());
assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 64L, 0L, 0L, assertValues(first, 0, TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 64L,
0L, 0L);
assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 0L,
0L, 0L, 0L);
assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, ROAMING_YES, 64L, 0L,
0L, 0L, 0L);
assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, 32L,
0L, 0L, 0L, 0L); 0L, 0L, 0L, 0L);
assertValues(first, 1, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
32L, 0L, 0L, 0L, 0L);
assertValues(first, 2, TEST_IFACE, 100, SET_FOREGROUND, TAG_NONE, METERED_YES, ROAMING_YES,
64L, 0L, 0L, 0L, 0L);
assertValues(first, 3, TEST_IFACE2, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
32L, 0L, 0L, 0L, 0L);
} }
public void testGetTotal() { public void testGetTotal() {
final NetworkStats stats = new NetworkStats(TEST_START, 7) final NetworkStats stats = new NetworkStats(TEST_START, 7)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L, .addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L, 8L,
2L, 20L) 0L, 2L, 20L)
.addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 512L, 32L, 0L, .addValues(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
0L, 0L) 32L, 0L, 0L, 0L)
.addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 4L, 0L, 0L, .addValues(TEST_IFACE2, 100, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L, 4L,
0L)
.addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 512L, 32L,
0L, 0L, 0L) 0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, 0L, .addValues(TEST_IFACE2, 100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 512L,
0L, 0L) 32L, 0L, 0L, 0L)
.addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L, 0L, .addValues(TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO, 128L,
0L) 8L, 0L, 0L, 0L)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 8L, 0L, .addValues(TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 128L, 8L,
0L, 0L); 0L, 0L, 0L)
.addValues(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_YES, 128L,
8L, 0L, 0L, 0L);
assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L); assertValues(stats.getTotal(null), 1408L, 88L, 0L, 2L, 20L);
assertValues(stats.getTotal(null, 100), 1280L, 80L, 0L, 2L, 20L); assertValues(stats.getTotal(null, 100), 1280L, 80L, 0L, 2L, 20L);
@@ -396,10 +427,10 @@ public class NetworkStatsTest extends TestCase {
final NetworkStats after = before.withoutUids(new int[] { 100 }); final NetworkStats after = before.withoutUids(new int[] { 100 });
assertEquals(6, before.size()); assertEquals(6, before.size());
assertEquals(2, after.size()); assertEquals(2, after.size());
assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 8L, assertValues(after, 0, TEST_IFACE, 101, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
0L, 0L, 0L); 128L, 8L, 0L, 0L, 0L);
assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, ROAMING_NO, 128L, 8L, 0L, assertValues(after, 1, TEST_IFACE, 101, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 128L,
0L, 0L); 8L, 0L, 0L, 0L);
} }
public void testClone() throws Exception { public void testClone() throws Exception {
@@ -434,77 +465,90 @@ public class NetworkStatsTest extends TestCase {
final String underlyingIface = "wlan0"; final String underlyingIface = "wlan0";
final int testTag1 = 8888; final int testTag1 = 8888;
NetworkStats delta = new NetworkStats(TEST_START, 17) NetworkStats delta = new NetworkStats(TEST_START, 17)
.addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, 39605L, 46L, 12259L, 55L, 0L) .addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 39605L, 46L,
.addValues(tunIface, 10100, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L) 12259L, 55L, 0L)
.addValues(tunIface, 10120, SET_DEFAULT, TAG_NONE, 72667L, 197L, 43909L, 241L, 0L) .addValues(tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
.addValues(tunIface, 10120, SET_FOREGROUND, TAG_NONE, 9297L, 17L, 4128L, 21L, 0L) 0L, 0L, 0L)
.addValues(tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 72667L, 197L,
43909L, 241L, 0L)
.addValues(tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 9297L,
17L, 4128L, 21L, 0L)
// VPN package also uses some traffic through unprotected network. // VPN package also uses some traffic through unprotected network.
.addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, 4983L, 10L, 1801L, 12L, 0L) .addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 4983L, 10L,
.addValues(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L) 1801L, 12L, 0L)
.addValues(tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 0L, 0L,
0L, 0L, 0L)
// Tag entries // Tag entries
.addValues(tunIface, 10120, SET_DEFAULT, testTag1, 21691L, 41L, 13820L, 51L, 0L) .addValues(tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO, 21691L, 41L,
.addValues(tunIface, 10120, SET_FOREGROUND, testTag1, 1281L, 2L, 665L, 2L, 0L) 13820L, 51L, 0L)
.addValues(tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO, 1281L, 2L,
665L, 2L, 0L)
// Irrelevant entries // Irrelevant entries
.addValues(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, 1685L, 5L, 2070L, 6L, 0L) .addValues(TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1685L, 5L,
2070L, 6L, 0L)
// Underlying Iface entries // Underlying Iface entries
.addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, 5178L, 8L, 2139L, 11L, 0L) .addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 5178L,
.addValues(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L) 8L, 2139L, 11L, 0L)
.addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, 149873L, 287L, .addValues(underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, 0L,
59217L /* smaller than sum(tun0) */, 299L /* smaller than sum(tun0) */, 0L) 0L, 0L, 0L, 0L)
.addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, 0L, 0L, 0L, 0L, 0L); .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
149873L, 287L, 59217L /* smaller than sum(tun0) */,
299L /* smaller than sum(tun0) */, 0L)
.addValues(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
0L, 0L, 0L, 0L, 0L);
assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface)); assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface));
assertEquals(20, delta.size()); assertEquals(20, delta.size());
// tunIface and TEST_IFACE entries are not changed. // tunIface and TEST_IFACE entries are not changed.
assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
39605L, 46L, 12259L, 55L, 0L); 39605L, 46L, 12259L, 55L, 0L);
assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 0L, 0L, assertValues(delta, 1, tunIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
0L, 0L, 0L); 0L, 0L, 0L, 0L, 0L);
assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 2, tunIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
72667L, 197L, 43909L, 241L, 0L); 72667L, 197L, 43909L, 241L, 0L);
assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_NO, assertValues(delta, 3, tunIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
9297L, 17L, 4128L, 21L, 0L); 9297L, 17L, 4128L, 21L, 0L);
assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 4, tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
4983L, 10L, 1801L, 12L, 0L); 4983L, 10L, 1801L, 12L, 0L);
assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 0L, 0L, assertValues(delta, 5, tunIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
0L, 0L, 0L); 0L, 0L, 0L, 0L, 0L);
assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, ROAMING_NO, assertValues(delta, 6, tunIface, 10120, SET_DEFAULT, testTag1, METERED_NO, ROAMING_NO,
21691L, 41L, 13820L, 51L, 0L); 21691L, 41L, 13820L, 51L, 0L);
assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, ROAMING_NO, 1281L, assertValues(delta, 7, tunIface, 10120, SET_FOREGROUND, testTag1, METERED_NO, ROAMING_NO,
2L, 665L, 2L, 0L); 1281L, 2L, 665L, 2L, 0L);
assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1685L, 5L, assertValues(delta, 8, TEST_IFACE, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
2070L, 6L, 0L); 1685L, 5L, 2070L, 6L, 0L);
// Existing underlying Iface entries are updated // Existing underlying Iface entries are updated
assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 9, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO,
44783L, 54L, 14178L, 62L, 0L); ROAMING_NO, 44783L, 54L, 14178L, 62L, 0L);
assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, ROAMING_NO, assertValues(delta, 10, underlyingIface, 10100, SET_FOREGROUND, TAG_NONE, METERED_NO,
0L, 0L, 0L, 0L, 0L); ROAMING_NO, 0L, 0L, 0L, 0L, 0L);
// VPN underlying Iface entries are updated // VPN underlying Iface entries are updated
assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 11, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO,
28304L, 27L, 1L, 2L, 0L); ROAMING_NO, 28304L, 27L, 1L, 2L, 0L);
assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, ROAMING_NO, assertValues(delta, 12, underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO,
0L, 0L, 0L, 0L, 0L); ROAMING_NO, 0L, 0L, 0L, 0L, 0L);
// New entries are added for new application's underlying Iface traffic // New entries are added for new application's underlying Iface traffic
assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertContains(delta, underlyingIface, 10120, SET_DEFAULT, TAG_NONE, METERED_NO,
72667L, 197L, 43123L, 227L, 0L); ROAMING_NO, 72667L, 197L, 43123L, 227L, 0L);
assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, ROAMING_NO, assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, TAG_NONE, METERED_NO,
9297L, 17L, 4054, 19L, 0L); ROAMING_NO, 9297L, 17L, 4054, 19L, 0L);
assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, ROAMING_NO, assertContains(delta, underlyingIface, 10120, SET_DEFAULT, testTag1, METERED_NO,
21691L, 41L, 13572L, 48L, 0L); ROAMING_NO, 21691L, 41L, 13572L, 48L, 0L);
assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, ROAMING_NO, assertContains(delta, underlyingIface, 10120, SET_FOREGROUND, testTag1, METERED_NO,
1281L, 2L, 653L, 1L, 0L); ROAMING_NO, 1281L, 2L, 653L, 1L, 0L);
// New entries are added for debug purpose // New entries are added for debug purpose
assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO, assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
39605L, 46L, 12039, 51, 0); ROAMING_NO, 39605L, 46L, 12039, 51, 0);
assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO, assertContains(delta, underlyingIface, 10120, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
81964, 214, 47177, 246, 0); ROAMING_NO, 81964, 214, 47177, 246, 0);
assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, ROAMING_ALL, assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, METERED_ALL,
121569, 260, 59216, 297, 0); ROAMING_ALL, 121569, 260, 59216, 297, 0);
} }
@@ -518,72 +562,78 @@ public class NetworkStatsTest extends TestCase {
final String underlyingIface = "wlan0"; final String underlyingIface = "wlan0";
NetworkStats delta = new NetworkStats(TEST_START, 9) NetworkStats delta = new NetworkStats(TEST_START, 9)
// 2 different apps sent/receive data via tun0. // 2 different apps sent/receive data via tun0.
.addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, 50000L, 25L, 100000L, 50L, 0L) .addValues(tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 50000L, 25L,
.addValues(tunIface, 20100, SET_DEFAULT, TAG_NONE, 500L, 2L, 200L, 5L, 0L) 100000L, 50L, 0L)
.addValues(tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 500L, 2L,
200L, 5L, 0L)
// VPN package resends data through the tunnel (with exaggerated overhead) // VPN package resends data through the tunnel (with exaggerated overhead)
.addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, 240000, 100L, 120000L, 60L, 0L) .addValues(tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 240000,
100L, 120000L, 60L, 0L)
// 1 app already has some traffic on the underlying interface, the other doesn't yet // 1 app already has some traffic on the underlying interface, the other doesn't yet
.addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, 1000L, 10L, 2000L, 20L, 0L) .addValues(underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 1000L,
10L, 2000L, 20L, 0L)
// Traffic through the underlying interface via the vpn app. // Traffic through the underlying interface via the vpn app.
// This test should redistribute this data correctly. // This test should redistribute this data correctly.
.addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, .addValues(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
75500L, 37L, 130000L, 70L, 0L); 75500L, 37L, 130000L, 70L, 0L);
assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface)); assertTrue(delta.migrateTun(tunUid, tunIface, underlyingIface));
assertEquals(9, delta.size()); assertEquals(9, delta.size());
// tunIface entries should not be changed. // tunIface entries should not be changed.
assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 0, tunIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
50000L, 25L, 100000L, 50L, 0L); 50000L, 25L, 100000L, 50L, 0L);
assertValues(delta, 1, tunIface, 20100, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 1, tunIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
500L, 2L, 200L, 5L, 0L); 500L, 2L, 200L, 5L, 0L);
assertValues(delta, 2, tunIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 2, tunIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
240000L, 100L, 120000L, 60L, 0L); 240000L, 100L, 120000L, 60L, 0L);
// Existing underlying Iface entries are updated // Existing underlying Iface entries are updated
assertValues(delta, 3, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 3, underlyingIface, 10100, SET_DEFAULT, TAG_NONE, METERED_NO,
51000L, 35L, 102000L, 70L, 0L); ROAMING_NO, 51000L, 35L, 102000L, 70L, 0L);
// VPN underlying Iface entries are updated // VPN underlying Iface entries are updated
assertValues(delta, 4, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertValues(delta, 4, underlyingIface, tunUid, SET_DEFAULT, TAG_NONE, METERED_NO,
25000L, 10L, 29800L, 15L, 0L); ROAMING_NO, 25000L, 10L, 29800L, 15L, 0L);
// New entries are added for new application's underlying Iface traffic // New entries are added for new application's underlying Iface traffic
assertContains(delta, underlyingIface, 20100, SET_DEFAULT, TAG_NONE, ROAMING_NO, assertContains(delta, underlyingIface, 20100, SET_DEFAULT, TAG_NONE, METERED_NO,
500L, 2L, 200L, 5L, 0L); ROAMING_NO, 500L, 2L, 200L, 5L, 0L);
// New entries are added for debug purpose // New entries are added for debug purpose
assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO, assertContains(delta, underlyingIface, 10100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
50000L, 25L, 100000L, 50L, 0L); ROAMING_NO, 50000L, 25L, 100000L, 50L, 0L);
assertContains(delta, underlyingIface, 20100, SET_DBG_VPN_IN, TAG_NONE, ROAMING_NO, assertContains(delta, underlyingIface, 20100, SET_DBG_VPN_IN, TAG_NONE, METERED_NO,
500, 2L, 200L, 5L, 0L); ROAMING_NO, 500, 2L, 200L, 5L, 0L);
assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, ROAMING_ALL, assertContains(delta, underlyingIface, tunUid, SET_DBG_VPN_OUT, TAG_NONE, METERED_ALL,
50500L, 27L, 100200L, 55, 0); ROAMING_ALL, 50500L, 27L, 100200L, 55, 0);
} }
private static void assertContains(NetworkStats stats, String iface, int uid, int set, private static void assertContains(NetworkStats stats, String iface, int uid, int set,
int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets, int tag, int metered, int roaming, long rxBytes, long rxPackets, long txBytes,
long operations) { long txPackets, long operations) {
int index = stats.findIndex(iface, uid, set, tag, roaming); int index = stats.findIndex(iface, uid, set, tag, metered, roaming);
assertTrue(index != -1); assertTrue(index != -1);
assertValues(stats, index, iface, uid, set, tag, roaming, assertValues(stats, index, iface, uid, set, tag, metered, roaming,
rxBytes, rxPackets, txBytes, txPackets, operations); rxBytes, rxPackets, txBytes, txPackets, operations);
} }
private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set, private static void assertValues(NetworkStats stats, int index, String iface, int uid, int set,
int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets, int tag, int metered, int roaming, long rxBytes, long rxPackets, long txBytes,
long operations) { long txPackets, long operations) {
final NetworkStats.Entry entry = stats.getValues(index, null); final NetworkStats.Entry entry = stats.getValues(index, null);
assertValues(entry, iface, uid, set, tag, roaming); assertValues(entry, iface, uid, set, tag, metered, roaming);
assertValues(entry, rxBytes, rxPackets, txBytes, txPackets, operations); assertValues(entry, rxBytes, rxPackets, txBytes, txPackets, operations);
} }
private static void assertValues( private static void assertValues(
NetworkStats.Entry entry, String iface, int uid, int set, int tag, int roaming) { NetworkStats.Entry entry, String iface, int uid, int set, int tag, int metered,
int roaming) {
assertEquals(iface, entry.iface); assertEquals(iface, entry.iface);
assertEquals(uid, entry.uid); assertEquals(uid, entry.uid);
assertEquals(set, entry.set); assertEquals(set, entry.set);
assertEquals(tag, entry.tag); assertEquals(tag, entry.tag);
assertEquals(metered, entry.metered);
assertEquals(roaming, entry.roaming); assertEquals(roaming, entry.roaming);
} }

View File

@@ -16,6 +16,7 @@
package com.android.internal.net; package com.android.internal.net;
import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_NO;
import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_DEFAULT;
@@ -101,12 +102,14 @@ public class NetworkStatsFactoryTest extends AndroidTestCase {
final NetworkStats stats = mFactory.readNetworkStatsDetail(); final NetworkStats stats = mFactory.readNetworkStatsDetail();
assertEquals(70, stats.size()); assertEquals(70, stats.size());
assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L, 676L); assertStatsEntry(stats, "rmnet1", 10021, SET_DEFAULT, 0x30100000, 219110L, 578L, 227423L,
676L);
assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L); assertStatsEntry(stats, "rmnet1", 10021, SET_FOREGROUND, 0x30100000, 742L, 3L, 1265L, 3L);
} }
public void testNetworkStatsSingle() throws Exception { public void testNetworkStatsSingle() throws Exception {
stageFile(R.raw.xt_qtaguid_iface_typical, new File(mTestProc, "net/xt_qtaguid/iface_stat_all")); stageFile(R.raw.xt_qtaguid_iface_typical,
new File(mTestProc, "net/xt_qtaguid/iface_stat_all"));
final NetworkStats stats = mFactory.readNetworkStatsSummaryDev(); final NetworkStats stats = mFactory.readNetworkStatsSummaryDev();
assertEquals(6, stats.size()); assertEquals(6, stats.size());
@@ -122,7 +125,8 @@ public class NetworkStatsFactoryTest extends AndroidTestCase {
final NetworkStats stats = mFactory.readNetworkStatsSummaryXt(); final NetworkStats stats = mFactory.readNetworkStatsSummaryXt();
assertEquals(3, stats.size()); assertEquals(3, stats.size());
assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 6824L, 16L, 5692L, 10L); assertStatsEntry(stats, "rmnet0", UID_ALL, SET_ALL, TAG_NONE, 6824L, 16L, 5692L, 10L);
assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L, 2468L); assertStatsEntry(stats, "rmnet1", UID_ALL, SET_ALL, TAG_NONE, 11153922L, 8051L, 190226L,
2468L);
assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L); assertStatsEntry(stats, "rmnet2", UID_ALL, SET_ALL, TAG_NONE, 4968L, 35L, 3081L, 39L);
} }
@@ -157,7 +161,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase {
private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set, private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
int tag, long rxBytes, long txBytes) { int tag, long rxBytes, long txBytes) {
final int i = stats.findIndex(iface, uid, set, tag, ROAMING_NO); final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
final NetworkStats.Entry entry = stats.getValues(i, null); final NetworkStats.Entry entry = stats.getValues(i, null);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected txBytes", txBytes, entry.txBytes); assertEquals("unexpected txBytes", txBytes, entry.txBytes);
@@ -165,7 +169,7 @@ public class NetworkStatsFactoryTest extends AndroidTestCase {
private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set, private static void assertStatsEntry(NetworkStats stats, String iface, int uid, int set,
int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) {
final int i = stats.findIndex(iface, uid, set, tag, ROAMING_NO); final int i = stats.findIndex(iface, uid, set, tag, METERED_NO, ROAMING_NO);
final NetworkStats.Entry entry = stats.getValues(i, null); final NetworkStats.Entry entry = stats.getValues(i, null);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes); assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets); assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);

View File

@@ -91,6 +91,19 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
} }
} }
/** @return whether any {@link NetworkIdentity} in this set is considered metered. */
public boolean isAnyMemberMetered() {
if (isEmpty()) {
return false;
}
for (NetworkIdentity ident : this) {
if (ident.getMetered()) {
return true;
}
}
return false;
}
/** @return whether any {@link NetworkIdentity} in this set is considered roaming. */ /** @return whether any {@link NetworkIdentity} in this set is considered roaming. */
public boolean isAnyMemberRoaming() { public boolean isAnyMemberRoaming() {
if (isEmpty()) { if (isEmpty()) {

View File

@@ -17,6 +17,8 @@
package com.android.server.net; package com.android.server.net;
import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_NO;
import static android.net.NetworkStats.ROAMING_YES; import static android.net.NetworkStats.ROAMING_YES;
import static android.net.NetworkStats.SET_ALL; import static android.net.NetworkStats.SET_ALL;
@@ -242,6 +244,7 @@ public class NetworkStatsCollection implements FileRotator.Reader {
entry.uid = key.uid; entry.uid = key.uid;
entry.set = key.set; entry.set = key.set;
entry.tag = key.tag; entry.tag = key.tag;
entry.metered = key.ident.isAnyMemberMetered() ? METERED_YES : METERED_NO;
entry.roaming = key.ident.isAnyMemberRoaming() ? ROAMING_YES : ROAMING_NO; entry.roaming = key.ident.isAnyMemberRoaming() ? ROAMING_YES : ROAMING_NO;
entry.rxBytes = historyEntry.rxBytes; entry.rxBytes = historyEntry.rxBytes;
entry.rxPackets = historyEntry.rxPackets; entry.rxPackets = historyEntry.rxPackets;

View File

@@ -25,6 +25,7 @@ import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static android.net.NetworkStats.SET_DEFAULT; import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_NO;
import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.NetworkTemplate.buildTemplateMobileAll;
@@ -336,7 +337,7 @@ public class NetworkStatsObserversTest extends TestCase {
// Baseline // Baseline
NetworkStats xtSnapshot = null; NetworkStats xtSnapshot = null;
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -344,7 +345,7 @@ public class NetworkStatsObserversTest extends TestCase {
// Delta // Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -374,7 +375,7 @@ public class NetworkStatsObserversTest extends TestCase {
// Baseline // Baseline
NetworkStats xtSnapshot = null; NetworkStats xtSnapshot = null;
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -382,7 +383,7 @@ public class NetworkStatsObserversTest extends TestCase {
// Delta // Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -412,7 +413,7 @@ public class NetworkStatsObserversTest extends TestCase {
// Baseline // Baseline
NetworkStats xtSnapshot = null; NetworkStats xtSnapshot = null;
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -420,7 +421,7 @@ public class NetworkStatsObserversTest extends TestCase {
// Delta // Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
@@ -450,16 +451,17 @@ public class NetworkStatsObserversTest extends TestCase {
// Baseline // Baseline
NetworkStats xtSnapshot = null; NetworkStats xtSnapshot = null;
NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */) NetworkStats uidSnapshot = new NetworkStats(TEST_START, 2 /* initialSize */)
.addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO, .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
BASE_BYTES, 2L, BASE_BYTES, 2L, 0L); ROAMING_NO, BASE_BYTES, 2L, BASE_BYTES, 2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
VPN_INFO, TEST_START); VPN_INFO, TEST_START);
// Delta // Delta
uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */) uidSnapshot = new NetworkStats(TEST_START + 2 * MINUTE_IN_MILLIS, 2 /* initialSize */)
.addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, ROAMING_NO, .addValues(TEST_IFACE, UID_ANOTHER_USER, SET_DEFAULT, TAG_NONE, METERED_NO,
BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES, 2L, 0L); ROAMING_NO, BASE_BYTES + THRESHOLD_BYTES, 2L, BASE_BYTES + THRESHOLD_BYTES,
2L, 0L);
mStatsObservers.updateStats( mStatsObservers.updateStats(
xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces, xtSnapshot, uidSnapshot, mActiveIfaces, mActiveUidIfaces,
VPN_INFO, TEST_START); VPN_INFO, TEST_START);

View File

@@ -22,6 +22,9 @@ import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.TYPE_WIMAX; import static android.net.ConnectivityManager.TYPE_WIMAX;
import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.METERED_ALL;
import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkStats.ROAMING_ALL; import static android.net.NetworkStats.ROAMING_ALL;
import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_NO;
import static android.net.NetworkStats.ROAMING_YES; import static android.net.NetworkStats.ROAMING_YES;
@@ -305,9 +308,10 @@ public class NetworkStatsServiceTest {
// verify service recorded history // verify service recorded history
assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0); assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10); assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_NO, 512L, 4L, 256L, 2L, 4); assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, METERED_NO, ROAMING_NO, 512L, 4L, 256L,
assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L, 2L, 4);
6); assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, METERED_NO, ROAMING_NO, 512L, 4L,
256L, 2L, 6);
assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0); assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
@@ -329,9 +333,10 @@ public class NetworkStatsServiceTest {
// after systemReady(), we should have historical stats loaded again // after systemReady(), we should have historical stats loaded again
assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0); assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10); assertUidTotal(sTemplateWifi, UID_RED, 1024L, 8L, 512L, 4L, 10);
assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, ROAMING_NO, 512L, 4L, 256L, 2L, 4); assertUidTotal(sTemplateWifi, UID_RED, SET_DEFAULT, METERED_NO, ROAMING_NO, 512L, 4L, 256L,
assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, ROAMING_NO, 512L, 4L, 256L, 2L, 2L, 4);
6); assertUidTotal(sTemplateWifi, UID_RED, SET_FOREGROUND, METERED_NO, ROAMING_NO, 512L, 4L,
256L, 2L, 6);
assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0); assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 0);
} }
@@ -638,20 +643,20 @@ public class NetworkStatsServiceTest {
NetworkStats stats = mSession.getSummaryForAllUid( NetworkStats stats = mSession.getSummaryForAllUid(
sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
assertEquals(3, stats.size()); assertEquals(3, stats.size());
assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 50L, 5L, assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 50L,
50L, 5L, 1); 5L, 50L, 5L, 1);
assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 10L, 1L, 10L, assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 10L,
1L, 1); 1L, 10L, 1L, 1);
assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_NO, 2048L, 16L, assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
1024L, 8L, 0); 2048L, 16L, 1024L, 8L, 0);
// now verify that recent history only contains one uid // now verify that recent history only contains one uid
final long currentTime = currentTimeMillis(); final long currentTime = currentTimeMillis();
stats = mSession.getSummaryForAllUid( stats = mSession.getSummaryForAllUid(
sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true); sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
assertEquals(1, stats.size()); assertEquals(1, stats.size());
assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, ROAMING_NO, 1024L, 8L, assertValues(stats, IFACE_ALL, UID_BLUE, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
512L, 4L, 0); 1024L, 8L, 512L, 4L, 0);
} }
@Test @Test
@@ -705,14 +710,56 @@ public class NetworkStatsServiceTest {
final NetworkStats stats = mSession.getSummaryForAllUid( final NetworkStats stats = mSession.getSummaryForAllUid(
sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true); sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
assertEquals(4, stats.size()); assertEquals(4, stats.size());
assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 2L, assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L,
128L, 2L, 1); 2L, 128L, 2L, 1);
assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L, assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L,
1L, 1); 1L, 64L, 1L, 1);
assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, ROAMING_NO, 32L, 2L, assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO,
32L, 2L, 1); 32L, 2L, 32L, 2L, 1);
assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, ROAMING_NO, 1L, 1L, 1L, assertValues(stats, IFACE_ALL, UID_RED, SET_FOREGROUND, 0xFAAD, METERED_NO, ROAMING_NO, 1L,
1L, 1); 1L, 1L, 1L, 1);
}
@Test
public void testMetered() throws Exception {
// pretend that network comes online
expectCurrentTime();
expectDefaultSettings();
expectNetworkState(buildWifiState(true /* isMetered */));
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
expectBandwidthControlCheck();
mService.forceUpdateIfaces();
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
expectCurrentTime();
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats());
// Note that all traffic from NetworkManagementService is tagged as METERED_NO and
// ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it
// on top by inspecting the iface properties.
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, 128L,
2L, 128L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO, 64L,
1L, 64L, 1L, 0L));
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
forcePollAndWaitForIdle();
// verify service recorded history
assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1);
// verify entire history present
final NetworkStats stats = mSession.getSummaryForAllUid(
sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
assertEquals(2, stats.size());
assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
128L, 2L, 128L, 2L, 1);
assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, 64L,
1L, 64L, 1L, 1);
} }
@Test @Test
@@ -733,14 +780,14 @@ public class NetworkStatsServiceTest {
expectCurrentTime(); expectCurrentTime();
expectDefaultSettings(); expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats()); expectNetworkStatsSummary(buildEmptyStats());
// Note that all traffic from NetworkManagementService is tagged as ROAMING_NO, because // Note that all traffic from NetworkManagementService is tagged as METERED_NO and
// roaming isn't tracked at that layer. We layer it on top by inspecting the iface // ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it
// properties. // on top by inspecting the iface properties.
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1) expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_NO, 128L, 2L, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
128L, 2L, 0L) 128L, 2L, 128L, 2L, 0L)
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_NO, 64L, 1L, 64L, .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO, 64L,
1L, 0L)); 1L, 64L, 1L, 0L));
forcePollAndWaitForIdle(); forcePollAndWaitForIdle();
// verify service recorded history // verify service recorded history
@@ -750,10 +797,10 @@ public class NetworkStatsServiceTest {
final NetworkStats stats = mSession.getSummaryForAllUid( final NetworkStats stats = mSession.getSummaryForAllUid(
sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true); sTemplateImsi1, Long.MIN_VALUE, Long.MAX_VALUE, true);
assertEquals(2, stats.size()); assertEquals(2, stats.size());
assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, ROAMING_YES, 128L, 2L, assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_YES,
128L, 2L, 0); 128L, 2L, 128L, 2L, 0);
assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, ROAMING_YES, 64L, 1L, 64L, assertValues(stats, IFACE_ALL, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_YES, 64L,
1L, 0); 1L, 64L, 1L, 0);
} }
@Test @Test
@@ -780,7 +827,8 @@ public class NetworkStatsServiceTest {
.addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L); .addValues(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L);
final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" }; final String[] tetherIfacePairs = new String[] { TEST_IFACE, "wlan0" };
final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1) final NetworkStats tetherStats = new NetworkStats(getElapsedRealtime(), 1)
.addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L, 0L); .addValues(TEST_IFACE, UID_TETHERING, SET_DEFAULT, TAG_NONE, 1920L, 14L, 384L, 2L,
0L);
expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats); expectNetworkStatsUidDetail(uidStats, tetherIfacePairs, tetherStats);
forcePollAndWaitForIdle(); forcePollAndWaitForIdle();
@@ -923,18 +971,18 @@ public class NetworkStatsServiceTest {
// verify summary API // verify summary API
final NetworkStats stats = mSession.getSummaryForNetwork(template, start, end); final NetworkStats stats = mSession.getSummaryForNetwork(template, start, end);
assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, ROAMING_NO, rxBytes, assertValues(stats, IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
rxPackets, txBytes, txPackets, operations); rxBytes, rxPackets, txBytes, txPackets, operations);
} }
private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets, private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
long txBytes, long txPackets, int operations) throws Exception { long txBytes, long txPackets, int operations) throws Exception {
assertUidTotal(template, uid, SET_ALL, ROAMING_ALL, rxBytes, rxPackets, txBytes, txPackets, assertUidTotal(template, uid, SET_ALL, METERED_ALL, ROAMING_ALL, rxBytes, rxPackets,
operations); txBytes, txPackets, operations);
} }
private void assertUidTotal(NetworkTemplate template, int uid, int set, int roaming, private void assertUidTotal(NetworkTemplate template, int uid, int set, int metered,
long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations)
throws Exception { throws Exception {
// verify history API // verify history API
final NetworkStatsHistory history = mSession.getHistoryForUid( final NetworkStatsHistory history = mSession.getHistoryForUid(
@@ -945,8 +993,8 @@ public class NetworkStatsServiceTest {
// verify summary API // verify summary API
final NetworkStats stats = mSession.getSummaryForAllUid( final NetworkStats stats = mSession.getSummaryForAllUid(
template, Long.MIN_VALUE, Long.MAX_VALUE, false); template, Long.MIN_VALUE, Long.MAX_VALUE, false);
assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, roaming, rxBytes, rxPackets, txBytes, assertValues(stats, IFACE_ALL, uid, set, TAG_NONE, metered, roaming, rxBytes, rxPackets,
txPackets, operations); txBytes, txPackets, operations);
} }
private void expectSystemReady() throws Exception { private void expectSystemReady() throws Exception {
@@ -1034,8 +1082,8 @@ public class NetworkStatsServiceTest {
} }
private static void assertValues(NetworkStats stats, String iface, int uid, int set, private static void assertValues(NetworkStats stats, String iface, int uid, int set,
int tag, int roaming, long rxBytes, long rxPackets, long txBytes, long txPackets, int tag, int metered, int roaming, long rxBytes, long rxPackets, long txBytes,
int operations) { long txPackets, int operations) {
final NetworkStats.Entry entry = new NetworkStats.Entry(); final NetworkStats.Entry entry = new NetworkStats.Entry();
List<Integer> sets = new ArrayList<>(); List<Integer> sets = new ArrayList<>();
if (set == SET_DEFAULT || set == SET_ALL) { if (set == SET_DEFAULT || set == SET_ALL) {
@@ -1053,11 +1101,21 @@ public class NetworkStatsServiceTest {
roamings.add(ROAMING_YES); roamings.add(ROAMING_YES);
} }
List<Integer> meterings = new ArrayList<>();
if (metered == METERED_NO || metered == METERED_ALL) {
meterings.add(METERED_NO);
}
if (metered == METERED_YES || metered == METERED_ALL) {
meterings.add(METERED_YES);
}
for (int s : sets) { for (int s : sets) {
for (int r : roamings) { for (int r : roamings) {
final int i = stats.findIndex(iface, uid, s, tag, r); for (int m : meterings) {
if (i != -1) { final int i = stats.findIndex(iface, uid, s, tag, m, r);
entry.add(stats.getValues(i, null)); if (i != -1) {
entry.add(stats.getValues(i, null));
}
} }
} }
} }
@@ -1080,11 +1138,18 @@ public class NetworkStatsServiceTest {
} }
private static NetworkState buildWifiState() { private static NetworkState buildWifiState() {
return buildWifiState(false);
}
private static NetworkState buildWifiState(boolean isMetered) {
final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null); final NetworkInfo info = new NetworkInfo(TYPE_WIFI, 0, null, null);
info.setDetailedState(DetailedState.CONNECTED, null, null); info.setDetailedState(DetailedState.CONNECTED, null, null);
final LinkProperties prop = new LinkProperties(); final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE); prop.setInterfaceName(TEST_IFACE);
final NetworkCapabilities capabilities = new NetworkCapabilities(); final NetworkCapabilities capabilities = new NetworkCapabilities();
if (!isMetered) {
capabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
}
return new NetworkState(info, prop, capabilities, null, null, TEST_SSID); return new NetworkState(info, prop, capabilities, null, null, TEST_SSID);
} }