Merge changes from topic 'framework-net-aosp'

* changes:
  DO NOT MERGE: frameworks-test: adding missing @SmallTest
  DO NOT MERGE: Netd events: record connect() success/errno
  DO NOT MERGE: Add missing dependency.
  DO NOT MERGE: Show notification for always-on app VPN
  DO NOT MERGE: Implement metered tracking for NetworkStats summary queries.
  DO NOT MERGE: NetworkMonitor: send one DNS probe per web probe
  DO NOT MERGE: NetworkMonitor metrics: add first validation information
  DO NOT MERGE: APF: also drop any ICMPv6 RSs
  DO NOT MERGE: ConnectivityServiceTest: fix testAvoidBadWifiSettings
  DO NOT MERGE: Fix ConnectivityServiceTest testRequestBenchmark
  DO NOT MERGE: Switch over to new "time.android.com" NTP pool.
  DO NOT MERGE: Define API for metering network stats buckets.
  DO NOT MERGE: Refactored NetworkStatsServiceTest to use Mockito instead of EasyMock.
  DO NOT MERGE: Use @Ignore to explicitly disable a @Test method.
  DO NOT MERGE: Fixed NetworkStatsServiceTest and converted it to JUnit4.
  DO NOT MERGE: VPN network stat accounting changes.
  DO NOT MERGE: ConnectivityThread: use lazy holder idiom
  DO NOT MERGE: ConnectivityManager: use ConnectivityThread looper
  DO NOT MERGE: ConnectivityManager: a simpler CallbackHandler
  DO NOT MERGE: Indicate the NsdServiceInfo attributes are only filled in for a resolved service.
  DO NOT MERGE: Add a null check for the OnStartTetheringCallback.
This commit is contained in:
Lorenzo Colitti
2016-12-09 09:11:21 +00:00
committed by Gerrit Code Review
9 changed files with 197 additions and 60 deletions

View File

@@ -163,6 +163,29 @@ public final class NetworkStats implements AutoCloseable {
*/
public static final int UID_TETHERING = TrafficStats.UID_TETHERING;
/** @hide */
@IntDef({METERED_ALL, METERED_NO, METERED_YES})
@Retention(RetentionPolicy.SOURCE)
public @interface Metered {}
/**
* Combined usage across all metered states. Covers metered and unmetered usage.
*/
public static final int METERED_ALL = -1;
/**
* Usage that occurs on an unmetered network.
*/
public static final int METERED_NO = 0x1;
/**
* Usage that occurs on a metered network.
*
* <p>A network is classified as metered when the user is sensitive to heavy data usage on
* that connection.
*/
public static final int METERED_YES = 0x2;
/** @hide */
@IntDef({ROAMING_ALL, ROAMING_NO, ROAMING_YES})
@Retention(RetentionPolicy.SOURCE)
@@ -200,6 +223,7 @@ public final class NetworkStats implements AutoCloseable {
private int mUid;
private int mTag;
private int mState;
private int mMetered;
private int mRoaming;
private long mBeginTimeStamp;
private long mEndTimeStamp;
@@ -232,6 +256,15 @@ public final class NetworkStats implements AutoCloseable {
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) {
switch (roaming) {
case android.net.NetworkStats.ROAMING_ALL : return ROAMING_ALL;
@@ -278,6 +311,21 @@ public final class NetworkStats implements AutoCloseable {
return mState;
}
/**
* Metered state. One of the following values:<p/>
* <ul>
* <li>{@link #METERED_ALL}</li>
* <li>{@link #METERED_NO}</li>
* <li>{@link #METERED_YES}</li>
* </ul>
* <p>A network is classified as metered when the user is sensitive to heavy data usage on
* that connection. Apps may warn before using these networks for large downloads. The
* metered state can be set by the user within data usage network restrictions.
*/
public @Metered int getMetered() {
return mMetered;
}
/**
* Roaming state. One of the following values:<p/>
* <ul>
@@ -491,6 +539,7 @@ public final class NetworkStats implements AutoCloseable {
bucketOut.mUid = Bucket.convertUid(mRecycledSummaryEntry.uid);
bucketOut.mTag = Bucket.convertTag(mRecycledSummaryEntry.tag);
bucketOut.mState = Bucket.convertState(mRecycledSummaryEntry.set);
bucketOut.mMetered = Bucket.convertMetered(mRecycledSummaryEntry.metered);
bucketOut.mRoaming = Bucket.convertRoaming(mRecycledSummaryEntry.roaming);
bucketOut.mBeginTimeStamp = mStartTimeStamp;
bucketOut.mEndTimeStamp = mEndTimeStamp;
@@ -539,6 +588,7 @@ public final class NetworkStats implements AutoCloseable {
bucketOut.mUid = Bucket.convertUid(getUid());
bucketOut.mTag = Bucket.convertTag(mTag);
bucketOut.mState = Bucket.STATE_ALL;
bucketOut.mMetered = Bucket.METERED_ALL;
bucketOut.mRoaming = Bucket.ROAMING_ALL;
bucketOut.mBeginTimeStamp = mRecycledHistoryEntry.bucketStart;
bucketOut.mEndTimeStamp = mRecycledHistoryEntry.bucketStart +

View File

@@ -51,16 +51,17 @@ import android.util.Log;
* {@link #querySummaryForUser} <p />
* {@link #querySummary} <p />
* 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
* device-wide summaries a single bucket containing the totalised network usage is returned.
* bucket for a particular key, state, metered and roaming combination. In case of the user-wide
* and device-wide summaries a single bucket containing the totalised network usage is returned.
* <h3>
* History queries
* </h3>
* {@link #queryDetailsForUid} <p />
* {@link #queryDetails} <p />
* These queries do not aggregate over time but do aggregate over state and roaming. Therefore there
* can be multiple buckets for a particular key but all Bucket's state is going to be
* {@link NetworkStats.Bucket#STATE_ALL} and all Bucket's roaming is going to be
* These queries do not aggregate over time but do aggregate over state, metered and roaming.
* Therefore there can be multiple buckets for a particular key but all Bucket's state is going to
* 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}.
* <p />
* <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
* device. Result is a single Bucket aggregated over time, state, uid, tag and roaming. 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}, uid
* {@link NetworkStats.Bucket#UID_ALL}, tag {@link NetworkStats.Bucket#TAG_NONE}
* device. Result is a single Bucket aggregated over time, state, uid, tag, metered, and
* roaming. 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}, 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.
@@ -142,8 +144,10 @@ public class NetworkStatsManager {
* 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.
* 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
* {@link NetworkStats.Bucket#UID_ALL}.
* and 'endTime' parameters. State is going to be {@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}.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@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
* 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
* timestamps are going to be the same as the 'startTime' and 'endTime' parameters.
* State and uid are going to vary, and tag is going to be the same.
* end timestamps. State is going to be {@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}.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@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
* 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}, uid will vary,
* tag {@link NetworkStats.Bucket#TAG_NONE} and roaming is going to be
* calling user. Result is aggregated over state but not aggregated over time, uid, tag,
* metered, nor roaming. 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}, 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}.
* <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

View File

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

View File

@@ -68,11 +68,18 @@ public class NetworkStats implements Parcelable {
// TODO: Rename TAG_NONE to TAG_ALL.
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;
/** {@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;
/** {@link #set} value where roaming data is accounted. */
/** {@link #roaming} value where roaming data is accounted. */
public static final int ROAMING_YES = 1;
// TODO: move fields to "mVariable" notation
@@ -88,6 +95,7 @@ public class NetworkStats implements Parcelable {
private int[] uid;
private int[] set;
private int[] tag;
private int[] metered;
private int[] roaming;
private long[] rxBytes;
private long[] rxPackets;
@@ -100,6 +108,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 metered;
/**
* 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
@@ -123,16 +137,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_NO, rxBytes, rxPackets, txBytes, txPackets,
operations);
this(iface, uid, set, tag, METERED_NO, ROAMING_NO, 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) {
public Entry(String iface, int uid, int set, int tag, int metered, 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.metered = metered;
this.roaming = roaming;
this.rxBytes = rxBytes;
this.rxPackets = rxPackets;
@@ -165,6 +180,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(" metered=").append(meteredToString(metered));
builder.append(" roaming=").append(roamingToString(roaming));
builder.append(" rxBytes=").append(rxBytes);
builder.append(" rxPackets=").append(rxPackets);
@@ -178,13 +194,18 @@ 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 && roaming == e.roaming
&& rxBytes == e.rxBytes && rxPackets == e.rxPackets && txBytes == e.txBytes
&& txPackets == e.txPackets && operations == e.operations
&& iface.equals(e.iface);
return uid == e.uid && set == e.set && tag == e.tag && metered == e.metered
&& roaming == e.roaming && rxBytes == e.rxBytes && rxPackets == e.rxPackets
&& txBytes == e.txBytes && txPackets == e.txPackets
&& operations == e.operations && iface.equals(e.iface);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(uid, set, tag, metered, roaming, iface);
}
}
public NetworkStats(long elapsedRealtime, int initialSize) {
@@ -196,6 +217,7 @@ public class NetworkStats implements Parcelable {
this.uid = new int[initialSize];
this.set = new int[initialSize];
this.tag = new int[initialSize];
this.metered = new int[initialSize];
this.roaming = new int[initialSize];
this.rxBytes = new long[initialSize];
this.rxPackets = new long[initialSize];
@@ -209,6 +231,7 @@ public class NetworkStats implements Parcelable {
this.uid = EmptyArray.INT;
this.set = EmptyArray.INT;
this.tag = EmptyArray.INT;
this.metered = EmptyArray.INT;
this.roaming = EmptyArray.INT;
this.rxBytes = EmptyArray.LONG;
this.rxPackets = EmptyArray.LONG;
@@ -226,6 +249,7 @@ public class NetworkStats implements Parcelable {
uid = parcel.createIntArray();
set = parcel.createIntArray();
tag = parcel.createIntArray();
metered = parcel.createIntArray();
roaming = parcel.createIntArray();
rxBytes = parcel.createLongArray();
rxPackets = parcel.createLongArray();
@@ -243,6 +267,7 @@ public class NetworkStats implements Parcelable {
dest.writeIntArray(uid);
dest.writeIntArray(set);
dest.writeIntArray(tag);
dest.writeIntArray(metered);
dest.writeIntArray(roaming);
dest.writeLongArray(rxBytes);
dest.writeLongArray(rxPackets);
@@ -277,10 +302,11 @@ public class NetworkStats implements Parcelable {
}
@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) {
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);
set = Arrays.copyOf(set, newLength);
tag = Arrays.copyOf(tag, newLength);
metered = Arrays.copyOf(metered, newLength);
roaming = Arrays.copyOf(roaming, newLength);
rxBytes = Arrays.copyOf(rxBytes, newLength);
rxPackets = Arrays.copyOf(rxPackets, newLength);
@@ -307,6 +334,7 @@ public class NetworkStats implements Parcelable {
uid[size] = entry.uid;
set[size] = entry.set;
tag[size] = entry.tag;
metered[size] = entry.metered;
roaming[size] = entry.roaming;
rxBytes[size] = entry.rxBytes;
rxPackets[size] = entry.rxPackets;
@@ -327,6 +355,7 @@ public class NetworkStats implements Parcelable {
entry.uid = uid[i];
entry.set = set[i];
entry.tag = tag[i];
entry.metered = metered[i];
entry.roaming = roaming[i];
entry.rxBytes = rxBytes[i];
entry.rxPackets = rxPackets[i];
@@ -381,7 +410,8 @@ public class NetworkStats implements Parcelable {
* 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, entry.roaming);
final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag, entry.metered,
entry.roaming);
if (i == -1) {
// only create new entry when positive contribution
addValues(entry);
@@ -409,10 +439,11 @@ 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, int roaming) {
public int findIndex(String iface, int uid, int set, int tag, int metered, int roaming) {
for (int i = 0; i < size; 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;
}
}
@@ -424,7 +455,7 @@ 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 roaming,
public int findIndexHinted(String iface, int uid, int set, int tag, int metered, int roaming,
int hintIndex) {
for (int offset = 0; offset < size; offset++) {
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]
&& 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;
}
}
@@ -452,7 +484,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], roaming[i]);
final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i], metered[i], roaming[i]);
if (j == -1) {
operations[i] = 0;
} else {
@@ -542,6 +574,7 @@ public class NetworkStats implements Parcelable {
entry.uid = limitUid;
entry.set = SET_ALL;
entry.tag = TAG_NONE;
entry.metered = METERED_ALL;
entry.roaming = ROAMING_ALL;
entry.rxBytes = 0;
entry.rxPackets = 0;
@@ -637,11 +670,12 @@ public class NetworkStats implements Parcelable {
entry.uid = left.uid[i];
entry.set = left.set[i];
entry.tag = left.tag[i];
entry.metered = left.metered[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,
entry.roaming, i);
entry.metered, entry.roaming, i);
if (j == -1) {
// newly appearing row, return entire value
entry.rxBytes = left.rxBytes[i];
@@ -687,6 +721,7 @@ public class NetworkStats implements Parcelable {
entry.uid = UID_ALL;
entry.set = SET_ALL;
entry.tag = TAG_NONE;
entry.metered = METERED_ALL;
entry.roaming = ROAMING_ALL;
entry.operations = 0L;
@@ -716,6 +751,7 @@ public class NetworkStats implements Parcelable {
entry.iface = IFACE_ALL;
entry.set = SET_ALL;
entry.tag = TAG_NONE;
entry.metered = METERED_ALL;
entry.roaming = ROAMING_ALL;
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(" set="); pw.print(setToString(set[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(" rxBytes="); pw.print(rxBytes[i]);
pw.print(" rxPackets="); pw.print(rxPackets[i]);
@@ -829,6 +866,22 @@ public class NetworkStats implements Parcelable {
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.
*/
@@ -904,7 +957,8 @@ public class NetworkStats implements Parcelable {
if (pool.isEmpty()) {
return true;
}
Entry moved = addTrafficToApplications(tunIface, underlyingIface, tunIfaceTotal, pool);
Entry moved =
addTrafficToApplications(tunUid, tunIface, underlyingIface, tunIfaceTotal, pool);
deductTrafficFromVpnApp(tunUid, underlyingIface, moved);
if (!moved.isEmpty()) {
@@ -919,9 +973,9 @@ public class NetworkStats implements Parcelable {
* Initializes the data used by the migrateTun() method.
*
* This is the first pass iteration which does the following work:
* (1) Adds up all the traffic through tun0.
* (2) Adds up all the traffic through the tunUid's underlyingIface
* (1) Adds up all the traffic through the tunUid's underlyingIface
* (both foreground and background).
* (2) Adds up all the traffic through tun0 excluding traffic from the vpn app itself.
*/
private void tunAdjustmentInit(int tunUid, String tunIface, String underlyingIface,
Entry tunIfaceTotal, Entry underlyingIfaceTotal) {
@@ -941,8 +995,9 @@ public class NetworkStats implements Parcelable {
underlyingIfaceTotal.add(recycle);
}
if (recycle.tag == TAG_NONE && Objects.equals(tunIface, recycle.iface)) {
// Add up all tunIface traffic.
if (recycle.uid != tunUid && recycle.tag == TAG_NONE
&& Objects.equals(tunIface, recycle.iface)) {
// Add up all tunIface traffic excluding traffic from the vpn app itself.
tunIfaceTotal.add(recycle);
}
}
@@ -958,13 +1013,15 @@ public class NetworkStats implements Parcelable {
return pool;
}
private Entry addTrafficToApplications(String tunIface, String underlyingIface,
private Entry addTrafficToApplications(int tunUid, String tunIface, String underlyingIface,
Entry tunIfaceTotal, Entry pool) {
Entry moved = new Entry();
Entry tmpEntry = new Entry();
tmpEntry.iface = underlyingIface;
for (int i = 0; i < size; i++) {
if (Objects.equals(iface[i], tunIface)) {
// the vpn app is excluded from the redistribution but all moved traffic will be
// deducted from the vpn app (see deductTrafficFromVpnApp below).
if (Objects.equals(iface[i], tunIface) && uid[i] != tunUid) {
if (tunIfaceTotal.rxBytes > 0) {
tmpEntry.rxBytes = pool.rxBytes * rxBytes[i] / tunIfaceTotal.rxBytes;
} else {
@@ -994,6 +1051,7 @@ public class NetworkStats implements Parcelable {
tmpEntry.uid = uid[i];
tmpEntry.tag = tag[i];
tmpEntry.set = set[i];
tmpEntry.metered = metered[i];
tmpEntry.roaming = roaming[i];
combineValues(tmpEntry);
if (tag[i] == TAG_NONE) {
@@ -1013,24 +1071,25 @@ public class NetworkStats implements Parcelable {
moved.set = SET_DBG_VPN_OUT;
moved.tag = TAG_NONE;
moved.iface = underlyingIface;
moved.metered = METERED_ALL;
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.
//
// Relies on the fact that the underlying traffic only has state ROAMING_NO, which
// should be the case as it comes directly from the /proc file. We only blend in the
// Relies on the fact that the underlying traffic only has state ROAMING_NO and METERED_NO,
// 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_NO);
METERED_NO, ROAMING_NO);
if (idxVpnBackground != -1) {
tunSubtract(idxVpnBackground, this, moved);
}
int idxVpnForeground = findIndex(underlyingIface, tunUid, SET_FOREGROUND, TAG_NONE,
ROAMING_NO);
METERED_NO, ROAMING_NO);
if (idxVpnForeground != -1) {
tunSubtract(idxVpnForeground, this, moved);
}

View File

@@ -103,11 +103,11 @@ import com.android.internal.util.Protocol;
* to {@link DiscoveryListener#onServiceFound} and a service lost is notified on
* {@link DiscoveryListener#onServiceLost}.
*
* <p> Once the peer application discovers the "Example" http srevice, and needs to receive data
* from the "Example" application, it can initiate a resolve with {@link #resolveService} to
* resolve the host and port details for the purpose of establishing a connection. A successful
* resolve is notified on {@link ResolveListener#onServiceResolved} and a failure is notified
* on {@link ResolveListener#onResolveFailed}.
* <p> Once the peer application discovers the "Example" http service, and either needs to read the
* attributes of the service or wants to receive data from the "Example" application, it can
* initiate a resolve with {@link #resolveService} to resolve the attributes, host, and port
* details. A successful resolve is notified on {@link ResolveListener#onServiceResolved} and a
* failure is notified on {@link ResolveListener#onResolveFailed}.
*
* Applications can reserve for a service type at
* http://www.iana.org/form/ports-service. Existing services can be found at

View File

@@ -250,7 +250,8 @@ public final class NsdServiceInfo implements Parcelable {
}
/**
* Retrive attributes as a map of String keys to byte[] values.
* Retrieve attributes as a map of String keys to byte[] values. The attributes map is only
* valid for a resolved service.
*
* <p> The returned map is unmodifiable; changes must be made through {@link #setAttribute} and
* {@link #removeAttribute}.

View File

@@ -43,6 +43,7 @@ static struct {
jfieldID uid;
jfieldID set;
jfieldID tag;
jfieldID metered;
jfieldID roaming;
jfieldID rxBytes;
jfieldID rxPackets;
@@ -239,6 +240,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 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,
gNetworkStatsClassInfo.roaming, size, grow));
if (roaming.get() == NULL) return -1;
@@ -265,7 +269,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.
// Metered and Roaming are populated in Java-land by inspecting the iface properties.
rxBytes[i] = lines[i].rxBytes;
rxPackets[i] = lines[i].rxPackets;
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.set, set.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.rxBytes, rxBytes.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.set = GetFieldIDOrDie(env, clazz, "set", "[I");
gNetworkStatsClassInfo.tag = GetFieldIDOrDie(env, clazz, "tag", "[I");
gNetworkStatsClassInfo.metered = GetFieldIDOrDie(env, clazz, "metered", "[I");
gNetworkStatsClassInfo.roaming = GetFieldIDOrDie(env, clazz, "roaming", "[I");
gNetworkStatsClassInfo.rxBytes = GetFieldIDOrDie(env, clazz, "rxBytes", "[J");
gNetworkStatsClassInfo.rxPackets = GetFieldIDOrDie(env, clazz, "rxPackets", "[J");

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. */
public boolean isAnyMemberRoaming() {
if (isEmpty()) {

View File

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