diff --git a/core/java/android/app/usage/NetworkStats.java b/core/java/android/app/usage/NetworkStats.java index 5f97c9e1d4..d2636467ca 100644 --- a/core/java/android/app/usage/NetworkStats.java +++ b/core/java/android/app/usage/NetworkStats.java @@ -208,6 +208,15 @@ public final class NetworkStats implements AutoCloseable { return uid; } + private static int convertRoaming(int roaming) { + switch (roaming) { + case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL; + case android.net.NetworkStats.ROAMING_DEFAULT : return ROAMING_DEFAULT; + case android.net.NetworkStats.ROAMING_ROAMING : return ROAMING_ROAMING; + } + return 0; + } + public Bucket() { } @@ -454,9 +463,9 @@ public final class NetworkStats implements AutoCloseable { private void fillBucketFromSummaryEntry(Bucket bucketOut) { bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid); bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set); - // TODO: Implement metering/roaming tracking. + // TODO: Implement metering tracking. bucketOut.mMetering = Bucket.METERING_ALL; - bucketOut.mRoaming = Bucket.ROAMING_ALL; + bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming); bucketOut.mBeginTimeStamp = mStartTimeStamp; bucketOut.mEndTimeStamp = mEndTimeStamp; bucketOut.mRxBytes = mRecycledSummaryEntry.rxBytes; diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 0fce7a90ea..e8373a175e 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -40,16 +40,17 @@ import android.util.Log; * {@link #querySummaryForUser}
* {@link #querySummary} * These queries aggregate network usage across the whole interval. Therefore there will be only one - * bucket for a particular key and state combination. In case of the user-wide and device-wide - * summaries a single bucket containing the totalised network usage is returned. + * bucket for a particular key and state and roaming combination. In case of the user-wide and + * device-wide summaries a single bucket containing the totalised network usage is returned. *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 * method cannot be used to measure data usage on a fine grained time scale. @@ -215,6 +217,7 @@ public class NetworkStatsManager { * calling user. Result is aggregated over state but not aggregated over time or uid. This means * buckets' start and end timestamps are going to be between 'startTime' and 'endTime' * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid will vary. + * roaming is going to be {@link NetworkStats.Bucket#ROAMING_ALL}. *
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
* method cannot be used to measure data usage on a fine grained time scale.
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 77d7e0cd76..8919d516d5 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -50,7 +50,7 @@ public class NetworkStats implements Parcelable {
public static final int UID_ALL = -1;
/** {@link #tag} value matching any tag. */
public static final int TAG_ALL = -1;
- /** {@link #set} value when all sets combined, not including debug sets. */
+ /** {@link #set} value for all sets combined, not including debug sets. */
public static final int SET_ALL = -1;
/** {@link #set} value where background data is accounted. */
public static final int SET_DEFAULT = 0;
@@ -66,6 +66,13 @@ public class NetworkStats implements Parcelable {
/** {@link #tag} value for total data across all tags. */
public static final int TAG_NONE = 0;
+ /** {@link #set} value for all roaming values. */
+ public static final int ROAMING_ALL = -1;
+ /** {@link #set} value where native, non-roaming data is accounted. */
+ public static final int ROAMING_DEFAULT = 0;
+ /** {@link #set} value where roaming data is accounted. */
+ public static final int ROAMING_ROAMING = 1;
+
// TODO: move fields to "mVariable" notation
/**
@@ -79,6 +86,7 @@ public class NetworkStats implements Parcelable {
private int[] uid;
private int[] set;
private int[] tag;
+ private int[] roaming;
private long[] rxBytes;
private long[] rxPackets;
private long[] txBytes;
@@ -90,6 +98,12 @@ public class NetworkStats implements Parcelable {
public int uid;
public int set;
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 roaming;
public long rxBytes;
public long rxPackets;
public long txBytes;
@@ -107,10 +121,17 @@ public class NetworkStats implements Parcelable {
public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets,
long txBytes, long txPackets, long operations) {
+ this(iface, uid, set, tag, ROAMING_DEFAULT, rxBytes, rxPackets, txBytes, txPackets,
+ operations);
+ }
+
+ public Entry(String iface, int uid, int set, int tag, int roaming, long rxBytes,
+ long rxPackets, long txBytes, long txPackets, long operations) {
this.iface = iface;
this.uid = uid;
this.set = set;
this.tag = tag;
+ this.roaming = roaming;
this.rxBytes = rxBytes;
this.rxPackets = rxPackets;
this.txBytes = txBytes;
@@ -142,6 +163,7 @@ public class NetworkStats implements Parcelable {
builder.append(" uid=").append(uid);
builder.append(" set=").append(setToString(set));
builder.append(" tag=").append(tagToString(tag));
+ builder.append(" roaming=").append(roamingToString(roaming));
builder.append(" rxBytes=").append(rxBytes);
builder.append(" rxPackets=").append(rxPackets);
builder.append(" txBytes=").append(txBytes);
@@ -154,8 +176,8 @@ public class NetworkStats implements Parcelable {
public boolean equals(Object o) {
if (o instanceof Entry) {
final Entry e = (Entry) o;
- return uid == e.uid && set == e.set && tag == e.tag && rxBytes == e.rxBytes
- && rxPackets == e.rxPackets && txBytes == e.txBytes
+ return uid == e.uid && set == e.set && tag == e.tag && roaming == e.roaming
+ && rxBytes == e.rxBytes && rxPackets == e.rxPackets && txBytes == e.txBytes
&& txPackets == e.txPackets && operations == e.operations
&& iface.equals(e.iface);
}
@@ -172,6 +194,7 @@ public class NetworkStats implements Parcelable {
this.uid = new int[initialSize];
this.set = new int[initialSize];
this.tag = new int[initialSize];
+ this.roaming = new int[initialSize];
this.rxBytes = new long[initialSize];
this.rxPackets = new long[initialSize];
this.txBytes = new long[initialSize];
@@ -184,6 +207,7 @@ public class NetworkStats implements Parcelable {
this.uid = EmptyArray.INT;
this.set = EmptyArray.INT;
this.tag = EmptyArray.INT;
+ this.roaming = EmptyArray.INT;
this.rxBytes = EmptyArray.LONG;
this.rxPackets = EmptyArray.LONG;
this.txBytes = EmptyArray.LONG;
@@ -200,6 +224,7 @@ public class NetworkStats implements Parcelable {
uid = parcel.createIntArray();
set = parcel.createIntArray();
tag = parcel.createIntArray();
+ roaming = parcel.createIntArray();
rxBytes = parcel.createLongArray();
rxPackets = parcel.createLongArray();
txBytes = parcel.createLongArray();
@@ -216,6 +241,7 @@ public class NetworkStats implements Parcelable {
dest.writeIntArray(uid);
dest.writeIntArray(set);
dest.writeIntArray(tag);
+ dest.writeIntArray(roaming);
dest.writeLongArray(rxBytes);
dest.writeLongArray(rxPackets);
dest.writeLongArray(txBytes);
@@ -248,6 +274,13 @@ public class NetworkStats implements Parcelable {
iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
}
+ @VisibleForTesting
+ public NetworkStats addValues(String iface, int uid, int set, int tag, int roaming,
+ long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
+ return addValues(new Entry(
+ iface, uid, set, tag, roaming, rxBytes, rxPackets, txBytes, txPackets, operations));
+ }
+
/**
* Add new stats entry, copying from given {@link Entry}. The {@link Entry}
* object can be recycled across multiple calls.
@@ -259,6 +292,7 @@ public class NetworkStats implements Parcelable {
uid = Arrays.copyOf(uid, newLength);
set = Arrays.copyOf(set, newLength);
tag = Arrays.copyOf(tag, newLength);
+ roaming = Arrays.copyOf(roaming, newLength);
rxBytes = Arrays.copyOf(rxBytes, newLength);
rxPackets = Arrays.copyOf(rxPackets, newLength);
txBytes = Arrays.copyOf(txBytes, newLength);
@@ -271,6 +305,7 @@ public class NetworkStats implements Parcelable {
uid[size] = entry.uid;
set[size] = entry.set;
tag[size] = entry.tag;
+ roaming[size] = entry.roaming;
rxBytes[size] = entry.rxBytes;
rxPackets[size] = entry.rxPackets;
txBytes[size] = entry.txBytes;
@@ -290,6 +325,7 @@ public class NetworkStats implements Parcelable {
entry.uid = uid[i];
entry.set = set[i];
entry.tag = tag[i];
+ entry.roaming = roaming[i];
entry.rxBytes = rxBytes[i];
entry.rxPackets = rxPackets[i];
entry.txBytes = txBytes[i];
@@ -327,22 +363,23 @@ public class NetworkStats implements Parcelable {
public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
long txBytes, long txPackets, long operations) {
return combineValues(
- iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes, txPackets, operations);
+ iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes,
+ txPackets, operations);
}
- public NetworkStats combineValues(String iface, int uid, int set, int tag, long rxBytes,
- long rxPackets, long txBytes, long txPackets, long operations) {
+ public NetworkStats combineValues(String iface, int uid, int set, int tag,
+ long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
return combineValues(new Entry(
iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
}
/**
* Combine given values with an existing row, or create a new row if
- * {@link #findIndex(String, int, int, int)} is unable to find match. Can
+ * {@link #findIndex(String, int, int, int, int)} is unable to find match. Can
* also be used to subtract values from existing rows.
*/
public NetworkStats combineValues(Entry entry) {
- final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag);
+ final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.roaming);
if (i == -1) {
// only create new entry when positive contribution
addValues(entry);
@@ -370,10 +407,10 @@ public class NetworkStats implements Parcelable {
/**
* Find first stats index that matches the requested parameters.
*/
- public int findIndex(String iface, int uid, int set, int tag) {
+ public int findIndex(String iface, int uid, int set, int tag, int roaming) {
for (int i = 0; i < size; i++) {
if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
- && Objects.equals(iface, this.iface[i])) {
+ && roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) {
return i;
}
}
@@ -385,7 +422,8 @@ public class NetworkStats implements Parcelable {
* search around the hinted index as an optimization.
*/
@VisibleForTesting
- public int findIndexHinted(String iface, int uid, int set, int tag, int hintIndex) {
+ public int findIndexHinted(String iface, int uid, int set, int tag, int roaming,
+ int hintIndex) {
for (int offset = 0; offset < size; offset++) {
final int halfOffset = offset / 2;
@@ -398,7 +436,7 @@ public class NetworkStats implements Parcelable {
}
if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i]
- && Objects.equals(iface, this.iface[i])) {
+ && roaming == this.roaming[i] && Objects.equals(iface, this.iface[i])) {
return i;
}
}
@@ -412,7 +450,7 @@ public class NetworkStats implements Parcelable {
*/
public void spliceOperationsFrom(NetworkStats stats) {
for (int i = 0; i < size; i++) {
- final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i]);
+ final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], roaming[i]);
if (j == -1) {
operations[i] = 0;
} else {
@@ -502,6 +540,7 @@ public class NetworkStats implements Parcelable {
entry.uid = limitUid;
entry.set = SET_ALL;
entry.tag = TAG_NONE;
+ entry.roaming = ROAMING_ALL;
entry.rxBytes = 0;
entry.rxPackets = 0;
entry.txBytes = 0;
@@ -596,9 +635,11 @@ public class NetworkStats implements Parcelable {
entry.uid = left.uid[i];
entry.set = left.set[i];
entry.tag = left.tag[i];
+ entry.roaming = left.roaming[i];
// find remote row that matches, and subtract
- final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i);
+ final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag,
+ entry.roaming, i);
if (j == -1) {
// newly appearing row, return entire value
entry.rxBytes = left.rxBytes[i];
@@ -644,6 +685,7 @@ public class NetworkStats implements Parcelable {
entry.uid = UID_ALL;
entry.set = SET_ALL;
entry.tag = TAG_NONE;
+ entry.roaming = ROAMING_ALL;
entry.operations = 0L;
for (int i = 0; i < size; i++) {
@@ -672,6 +714,7 @@ public class NetworkStats implements Parcelable {
entry.iface = IFACE_ALL;
entry.set = SET_ALL;
entry.tag = TAG_NONE;
+ entry.roaming = ROAMING_ALL;
for (int i = 0; i < size; i++) {
// skip specific tags, since already counted in TAG_NONE
@@ -717,6 +760,7 @@ public class NetworkStats implements Parcelable {
pw.print(" uid="); pw.print(uid[i]);
pw.print(" set="); pw.print(setToString(set[i]));
pw.print(" tag="); pw.print(tagToString(tag[i]));
+ pw.print(" roaming="); pw.print(roamingToString(roaming[i]));
pw.print(" rxBytes="); pw.print(rxBytes[i]);
pw.print(" rxPackets="); pw.print(rxPackets[i]);
pw.print(" txBytes="); pw.print(txBytes[i]);
@@ -783,6 +827,22 @@ public class NetworkStats implements Parcelable {
return "0x" + Integer.toHexString(tag);
}
+ /**
+ * Return text description of {@link #roaming} value.
+ */
+ public static String roamingToString(int roaming) {
+ switch (roaming) {
+ case ROAMING_ALL:
+ return "ALL";
+ case ROAMING_DEFAULT:
+ return "DEFAULT";
+ case ROAMING_ROAMING:
+ return "ROAMING";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
@Override
public String toString() {
final CharArrayWriter writer = new CharArrayWriter();
@@ -932,6 +992,7 @@ public class NetworkStats implements Parcelable {
tmpEntry.uid = uid[i];
tmpEntry.tag = tag[i];
tmpEntry.set = set[i];
+ tmpEntry.roaming = roaming[i];
combineValues(tmpEntry);
if (tag[i] == TAG_NONE) {
moved.add(tmpEntry);
@@ -950,16 +1011,24 @@ public class NetworkStats implements Parcelable {
moved.set = SET_DBG_VPN_OUT;
moved.tag = TAG_NONE;
moved.iface = underlyingIface;
+ moved.roaming = ROAMING_ALL;
combineValues(moved);
// Caveat: if the vpn software uses tag, the total tagged traffic may be greater than
// the TAG_NONE traffic.
- int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE);
+ //
+ // Relies on the fact that the underlying traffic only has state ROAMING_DEFAULT, 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
+ // underlying iface.
+ int idxVpnBackground = findIndex(underlyingIface, tunUid, SET_DEFAULT, TAG_NONE,
+ ROAMING_DEFAULT);
if (idxVpnBackground != -1) {
tunSubtract(idxVpnBackground, this, moved);
}
- int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE);
+ int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE,
+ ROAMING_DEFAULT);
if (idxVpnForeground != -1) {
tunSubtract(idxVpnForeground, this, moved);
}
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index 70134ab04a..9fa90acc02 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -43,6 +43,7 @@ static struct {
jfieldID uid;
jfieldID set;
jfieldID tag;
+ jfieldID roaming;
jfieldID rxBytes;
jfieldID rxPackets;
jfieldID txBytes;
@@ -238,6 +239,9 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
ScopedIntArrayRW tag(env, get_int_array(env, stats,
gNetworkStatsClassInfo.tag, size, grow));
if (tag.get() == NULL) return -1;
+ ScopedIntArrayRW roaming(env, get_int_array(env, stats,
+ gNetworkStatsClassInfo.roaming, size, grow));
+ if (roaming.get() == NULL) return -1;
ScopedLongArrayRW rxBytes(env, get_long_array(env, stats,
gNetworkStatsClassInfo.rxBytes, size, grow));
if (rxBytes.get() == NULL) return -1;
@@ -261,6 +265,7 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
uid[i] = lines[i].uid;
set[i] = lines[i].set;
tag[i] = lines[i].tag;
+ // Roaming is populated in Java-land by inspecting the iface properties.
rxBytes[i] = lines[i].rxBytes;
rxPackets[i] = lines[i].rxPackets;
txBytes[i] = lines[i].txBytes;
@@ -274,6 +279,7 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
+ env->SetObjectField(stats, gNetworkStatsClassInfo.roaming, roaming.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray());
@@ -305,6 +311,7 @@ int register_com_android_internal_net_NetworkStatsFactory(JNIEnv* env) {
gNetworkStatsClassInfo.uid = GetFieldIDOrDie(env, clazz, "uid", "[I");
gNetworkStatsClassInfo.set = GetFieldIDOrDie(env, clazz, "set", "[I");
gNetworkStatsClassInfo.tag = GetFieldIDOrDie(env, clazz, "tag", "[I");
+ gNetworkStatsClassInfo.roaming = GetFieldIDOrDie(env, clazz, "roaming", "[I");
gNetworkStatsClassInfo.rxBytes = GetFieldIDOrDie(env, clazz, "rxBytes", "[J");
gNetworkStatsClassInfo.rxPackets = GetFieldIDOrDie(env, clazz, "rxPackets", "[J");
gNetworkStatsClassInfo.txBytes = GetFieldIDOrDie(env, clazz, "txBytes", "[J");
diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java
index f230bb39be..68dc715b08 100644
--- a/services/core/java/com/android/server/net/NetworkIdentitySet.java
+++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java
@@ -61,7 +61,7 @@ public class NetworkIdentitySet extends HashSet