Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -11336,6 +11336,7 @@ package android.net { method public static long getUidUdpRxPackets(int); method public static long getUidUdpTxBytes(int); method public static long getUidUdpTxPackets(int); method public static void incrementOperationCount(int, int); method public static void setThreadStatsTag(int); method public static deprecated void setThreadStatsTag(java.lang.String); method public static void tagSocket(java.net.Socket) throws java.net.SocketException; core/java/android/net/INetworkStatsService.aidl +9 −4 Original line number Diff line number Diff line Loading @@ -23,16 +23,21 @@ import android.net.NetworkTemplate; /** {@hide} */ interface INetworkStatsService { /** Return historical stats for traffic that matches template. */ /** Return historical network layer stats for traffic that matches template. */ NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template); /** Return historical stats for specific UID traffic that matches template. */ /** Return historical network layer stats for specific UID traffic that matches template. */ NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int tag); /** Return usage summary for traffic that matches template. */ /** Return network layer usage summary for traffic that matches template. */ NetworkStats getSummaryForNetwork(in NetworkTemplate template, long start, long end); /** Return usage summary per UID for traffic that matches template. */ /** Return network layer usage summary per UID for traffic that matches template. */ NetworkStats getSummaryForAllUid(in NetworkTemplate template, long start, long end, boolean includeTags); /** Return data layer snapshot of UID network usage. */ NetworkStats getDataLayerSnapshotForUid(int uid); /** Increment data layer count of operations performed for UID and tag. */ void incrementOperationCount(int uid, int tag, int operationCount); /** Force update of statistics. */ void forceUpdate(); Loading core/java/android/net/NetworkStats.java +60 −25 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.os.Parcelable; import android.os.SystemClock; import android.util.SparseBooleanArray; import com.android.internal.util.Objects; import java.io.CharArrayWriter; import java.io.PrintWriter; import java.util.Arrays; Loading Loading @@ -56,6 +58,7 @@ public class NetworkStats implements Parcelable { private long[] rxPackets; private long[] txBytes; private long[] txPackets; private int[] operations; public static class Entry { public String iface; Loading @@ -65,12 +68,13 @@ public class NetworkStats implements Parcelable { public long rxPackets; public long txBytes; public long txPackets; public int operations; public Entry() { } public Entry(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { long txPackets, int operations) { this.iface = iface; this.uid = uid; this.tag = tag; Loading @@ -78,6 +82,7 @@ public class NetworkStats implements Parcelable { this.rxPackets = rxPackets; this.txBytes = txBytes; this.txPackets = txPackets; this.operations = operations; } } Loading @@ -91,6 +96,7 @@ public class NetworkStats implements Parcelable { this.rxPackets = new long[initialSize]; this.txBytes = new long[initialSize]; this.txPackets = new long[initialSize]; this.operations = new int[initialSize]; } public NetworkStats(Parcel parcel) { Loading @@ -103,11 +109,32 @@ public class NetworkStats implements Parcelable { rxPackets = parcel.createLongArray(); txBytes = parcel.createLongArray(); txPackets = parcel.createLongArray(); operations = parcel.createIntArray(); } /** {@inheritDoc} */ public void writeToParcel(Parcel dest, int flags) { dest.writeLong(elapsedRealtime); dest.writeInt(size); dest.writeStringArray(iface); dest.writeIntArray(uid); dest.writeIntArray(tag); dest.writeLongArray(rxBytes); dest.writeLongArray(rxPackets); dest.writeLongArray(txBytes); dest.writeLongArray(txPackets); dest.writeIntArray(operations); } public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { return addValues(new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets)); return addValues(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, 0); } public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) { return addValues( new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); } /** Loading @@ -124,6 +151,7 @@ public class NetworkStats implements Parcelable { rxPackets = Arrays.copyOf(rxPackets, newLength); txBytes = Arrays.copyOf(txBytes, newLength); txPackets = Arrays.copyOf(txPackets, newLength); operations = Arrays.copyOf(operations, newLength); } iface[size] = entry.iface; Loading @@ -133,6 +161,7 @@ public class NetworkStats implements Parcelable { rxPackets[size] = entry.rxPackets; txBytes[size] = entry.txBytes; txPackets[size] = entry.txPackets; operations[size] = entry.operations; size++; return this; Loading @@ -150,6 +179,7 @@ public class NetworkStats implements Parcelable { entry.rxPackets = rxPackets[i]; entry.txBytes = txBytes[i]; entry.txPackets = txPackets[i]; entry.operations = operations[i]; return entry; } Loading @@ -167,8 +197,9 @@ public class NetworkStats implements Parcelable { } public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { return combineValues(new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets)); long txBytes, long txPackets, int operations) { return combineValues( new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); } /** Loading @@ -186,6 +217,7 @@ public class NetworkStats implements Parcelable { rxPackets[i] += entry.rxPackets; txBytes[i] += entry.txBytes; txPackets[i] += entry.txPackets; operations[i] += entry.operations; } return this; } Loading @@ -195,13 +227,29 @@ public class NetworkStats implements Parcelable { */ public int findIndex(String iface, int uid, int tag) { for (int i = 0; i < size; i++) { if (equal(iface, this.iface[i]) && uid == this.uid[i] && tag == this.tag[i]) { if (Objects.equal(iface, this.iface[i]) && uid == this.uid[i] && tag == this.tag[i]) { return i; } } return -1; } /** * Splice in {@link #operations} from the given {@link NetworkStats} based * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface}, * since operation counts are at data layer. */ public void spliceOperationsFrom(NetworkStats stats) { for (int i = 0; i < size; i++) { final int j = stats.findIndex(IFACE_ALL, uid[i], tag[i]); if (j == -1) { operations[i] = 0; } else { operations[i] = stats.operations[j]; } } } /** * Return list of unique interfaces known by this data structure. */ Loading Loading @@ -289,15 +337,17 @@ public class NetworkStats implements Parcelable { entry.rxPackets = rxPackets[i]; entry.txBytes = txBytes[i]; entry.txPackets = txPackets[i]; entry.operations = operations[i]; } else { // existing row, subtract remote value entry.rxBytes = rxBytes[i] - value.rxBytes[j]; entry.rxPackets = rxPackets[i] - value.rxPackets[j]; entry.txBytes = txBytes[i] - value.txBytes[j]; entry.txPackets = txPackets[i] - value.txPackets[j]; entry.operations = operations[i] - value.operations[j]; if (enforceMonotonic && (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 || entry.txPackets < 0)) { || entry.txPackets < 0 || entry.operations < 0)) { throw new IllegalArgumentException("found non-monotonic values"); } if (clampNegative) { Loading @@ -305,6 +355,7 @@ public class NetworkStats implements Parcelable { entry.rxPackets = Math.max(0, entry.rxPackets); entry.txBytes = Math.max(0, entry.txBytes); entry.txPackets = Math.max(0, entry.txPackets); entry.operations = Math.max(0, entry.operations); } } Loading @@ -314,10 +365,6 @@ public class NetworkStats implements Parcelable { return result; } private static boolean equal(Object a, Object b) { return a == b || (a != null && a.equals(b)); } public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime); Loading @@ -325,11 +372,12 @@ public class NetworkStats implements Parcelable { pw.print(prefix); pw.print(" iface="); pw.print(iface[i]); pw.print(" uid="); pw.print(uid[i]); pw.print(" tag="); pw.print(tag[i]); pw.print(" tag=0x"); pw.print(Integer.toHexString(tag[i])); pw.print(" rxBytes="); pw.print(rxBytes[i]); pw.print(" rxPackets="); pw.print(rxPackets[i]); pw.print(" txBytes="); pw.print(txBytes[i]); pw.print(" txPackets="); pw.println(txPackets[i]); pw.print(" txPackets="); pw.print(txPackets[i]); pw.print(" operations="); pw.println(operations[i]); } } Loading @@ -345,19 +393,6 @@ public class NetworkStats implements Parcelable { return 0; } /** {@inheritDoc} */ public void writeToParcel(Parcel dest, int flags) { dest.writeLong(elapsedRealtime); dest.writeInt(size); dest.writeStringArray(iface); dest.writeIntArray(uid); dest.writeIntArray(tag); dest.writeLongArray(rxBytes); dest.writeLongArray(rxPackets); dest.writeLongArray(txBytes); dest.writeLongArray(txPackets); } public static final Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() { public NetworkStats createFromParcel(Parcel in) { return new NetworkStats(in); Loading core/java/android/net/NetworkStatsHistory.java +173 −54 Original line number Diff line number Diff line Loading @@ -16,6 +16,16 @@ package android.net; import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.DataStreamUtils.readLongArray; import static android.net.NetworkStatsHistory.DataStreamUtils.writeLongArray; import static android.net.NetworkStatsHistory.ParcelUtils.readIntArray; import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray; import static android.net.NetworkStatsHistory.ParcelUtils.writeIntArray; import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -43,19 +53,26 @@ public class NetworkStatsHistory implements Parcelable { private static final int VERSION_INIT = 1; // TODO: teach about varint encoding to use less disk space // TODO: extend to record rxPackets/txPackets // TODO: teach about omitting entire fields to reduce parcel pressure // TODO: persist/restore packet and operation counts private final long bucketDuration; private int bucketCount; private long[] bucketStart; private long[] rxBytes; private long[] rxPackets; private long[] txBytes; private long[] txPackets; private int[] operations; public static class Entry { public long bucketStart; public long bucketDuration; public long rxBytes; public long rxPackets; public long txBytes; public long txPackets; public int operations; } public NetworkStatsHistory(long bucketDuration) { Loading @@ -66,15 +83,21 @@ public class NetworkStatsHistory implements Parcelable { this.bucketDuration = bucketDuration; bucketStart = new long[initialSize]; rxBytes = new long[initialSize]; rxPackets = new long[initialSize]; txBytes = new long[initialSize]; txPackets = new long[initialSize]; operations = new int[initialSize]; bucketCount = 0; } public NetworkStatsHistory(Parcel in) { bucketDuration = in.readLong(); bucketStart = readLongArray(in); rxBytes = in.createLongArray(); txBytes = in.createLongArray(); rxBytes = readLongArray(in); rxPackets = readLongArray(in); txBytes = readLongArray(in); txPackets = readLongArray(in); operations = readIntArray(in); bucketCount = bucketStart.length; } Loading @@ -83,17 +106,24 @@ public class NetworkStatsHistory implements Parcelable { out.writeLong(bucketDuration); writeLongArray(out, bucketStart, bucketCount); writeLongArray(out, rxBytes, bucketCount); writeLongArray(out, rxPackets, bucketCount); writeLongArray(out, txBytes, bucketCount); writeLongArray(out, txPackets, bucketCount); writeIntArray(out, operations, bucketCount); } public NetworkStatsHistory(DataInputStream in) throws IOException { // TODO: read packet and operation counts final int version = in.readInt(); switch (version) { case VERSION_INIT: { bucketDuration = in.readLong(); bucketStart = readLongArray(in); rxBytes = readLongArray(in); rxPackets = new long[bucketStart.length]; txBytes = readLongArray(in); txPackets = new long[bucketStart.length]; operations = new int[bucketStart.length]; bucketCount = bucketStart.length; break; } Loading @@ -104,6 +134,7 @@ public class NetworkStatsHistory implements Parcelable { } public void writeToStream(DataOutputStream out) throws IOException { // TODO: write packet and operation counts out.writeInt(VERSION_INIT); out.writeLong(bucketDuration); writeLongArray(out, bucketStart, bucketCount); Loading Loading @@ -148,7 +179,10 @@ public class NetworkStatsHistory implements Parcelable { entry.bucketStart = bucketStart[i]; entry.bucketDuration = bucketDuration; entry.rxBytes = rxBytes[i]; entry.rxPackets = rxPackets[i]; entry.txBytes = txBytes[i]; entry.txPackets = txPackets[i]; entry.operations = operations[i]; return entry; } Loading @@ -156,17 +190,27 @@ public class NetworkStatsHistory implements Parcelable { * Record that data traffic occurred in the given time range. Will * distribute across internal buckets, creating new buckets as needed. */ public void recordData(long start, long end, long rx, long tx) { if (rx < 0 || tx < 0) { throw new IllegalArgumentException( "tried recording negative data: rx=" + rx + ", tx=" + tx); @Deprecated public void recordData(long start, long end, long rxBytes, long txBytes) { recordData(start, end, new NetworkStats.Entry(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0)); } /** * Record that data traffic occurred in the given time range. Will * distribute across internal buckets, creating new buckets as needed. */ public void recordData(long start, long end, NetworkStats.Entry entry) { if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 || entry.txPackets < 0 || entry.operations < 0) { throw new IllegalArgumentException("tried recording negative data"); } // create any buckets needed by this range ensureBuckets(start, end); // distribute data usage into buckets final long duration = end - start; long duration = end - start; for (int i = bucketCount - 1; i >= 0; i--) { final long curStart = bucketStart[i]; final long curEnd = curStart + bucketDuration; Loading @@ -177,10 +221,22 @@ public class NetworkStatsHistory implements Parcelable { if (curStart > end) continue; final long overlap = Math.min(curEnd, end) - Math.max(curStart, start); if (overlap > 0) { this.rxBytes[i] += rx * overlap / duration; this.txBytes[i] += tx * overlap / duration; } if (overlap <= 0) continue; // integer math each time is faster than floating point final long fracRxBytes = entry.rxBytes * overlap / duration; final long fracRxPackets = entry.rxPackets * overlap / duration; final long fracTxBytes = entry.txBytes * overlap / duration; final long fracTxPackets = entry.txPackets * overlap / duration; final int fracOperations = (int) (entry.operations * overlap / duration); rxBytes[i] += fracRxBytes; entry.rxBytes -= fracRxBytes; rxPackets[i] += fracRxPackets; entry.rxPackets -= fracRxPackets; txBytes[i] += fracTxBytes; entry.txBytes -= fracTxBytes; txPackets[i] += fracTxPackets; entry.txPackets -= fracTxPackets; operations[i] += fracOperations; entry.operations -= fracOperations; duration -= overlap; } } Loading @@ -189,10 +245,19 @@ public class NetworkStatsHistory implements Parcelable { * for combining together stats for external reporting. */ public void recordEntireHistory(NetworkStatsHistory input) { final NetworkStats.Entry entry = new NetworkStats.Entry( IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0); for (int i = 0; i < input.bucketCount; i++) { final long start = input.bucketStart[i]; final long end = start + input.bucketDuration; recordData(start, end, input.rxBytes[i], input.txBytes[i]); entry.rxBytes = input.rxBytes[i]; entry.rxPackets = input.rxPackets[i]; entry.txBytes = input.txBytes[i]; entry.txPackets = input.txPackets[i]; entry.operations = input.operations[i]; recordData(start, end, entry); } } Loading Loading @@ -223,7 +288,10 @@ public class NetworkStatsHistory implements Parcelable { final int newLength = Math.max(bucketStart.length, 10) * 3 / 2; bucketStart = Arrays.copyOf(bucketStart, newLength); rxBytes = Arrays.copyOf(rxBytes, newLength); rxPackets = Arrays.copyOf(rxPackets, newLength); txBytes = Arrays.copyOf(txBytes, newLength); txPackets = Arrays.copyOf(txPackets, newLength); operations = Arrays.copyOf(operations, newLength); } // create gap when inserting bucket in middle Loading @@ -233,12 +301,18 @@ public class NetworkStatsHistory implements Parcelable { System.arraycopy(bucketStart, index, bucketStart, dstPos, length); System.arraycopy(rxBytes, index, rxBytes, dstPos, length); System.arraycopy(rxPackets, index, rxPackets, dstPos, length); System.arraycopy(txBytes, index, txBytes, dstPos, length); System.arraycopy(txPackets, index, txPackets, dstPos, length); System.arraycopy(operations, index, operations, dstPos, length); } bucketStart[index] = start; rxBytes[index] = 0; rxPackets[index] = 0; txBytes[index] = 0; txPackets[index] = 0; operations[index] = 0; bucketCount++; } Loading @@ -260,7 +334,10 @@ public class NetworkStatsHistory implements Parcelable { final int length = bucketStart.length; bucketStart = Arrays.copyOfRange(bucketStart, i, length); rxBytes = Arrays.copyOfRange(rxBytes, i, length); rxPackets = Arrays.copyOfRange(rxPackets, i, length); txBytes = Arrays.copyOfRange(txBytes, i, length); txPackets = Arrays.copyOfRange(txPackets, i, length); operations = Arrays.copyOfRange(operations, i, length); bucketCount -= i; } } Loading @@ -282,7 +359,10 @@ public class NetworkStatsHistory implements Parcelable { entry.bucketStart = start; entry.bucketDuration = end - start; entry.rxBytes = 0; entry.rxPackets = 0; entry.txBytes = 0; entry.txPackets = 0; entry.operations = 0; for (int i = bucketCount - 1; i >= 0; i--) { final long curStart = bucketStart[i]; Loading @@ -295,14 +375,16 @@ public class NetworkStatsHistory implements Parcelable { // include full value for active buckets, otherwise only fractional final boolean activeBucket = curStart < now && curEnd > now; final long overlap = Math.min(curEnd, end) - Math.max(curStart, start); if (activeBucket || overlap == bucketDuration) { entry.rxBytes += rxBytes[i]; entry.txBytes += txBytes[i]; } else if (overlap > 0) { final long overlap = activeBucket ? bucketDuration : Math.min(curEnd, end) - Math.max(curStart, start); if (overlap <= 0) continue; // integer math each time is faster than floating point entry.rxBytes += rxBytes[i] * overlap / bucketDuration; entry.rxPackets += rxPackets[i] * overlap / bucketDuration; entry.txBytes += txBytes[i] * overlap / bucketDuration; } entry.txPackets += txPackets[i] * overlap / bucketDuration; entry.operations += operations[i] * overlap / bucketDuration; } return entry; Loading @@ -315,17 +397,19 @@ public class NetworkStatsHistory implements Parcelable { public void generateRandom(long start, long end, long rx, long tx) { ensureBuckets(start, end); final NetworkStats.Entry entry = new NetworkStats.Entry( IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0); final Random r = new Random(); while (rx > 1024 && tx > 1024) { final long curStart = randomLong(r, start, end); final long curEnd = randomLong(r, curStart, end); final long curRx = randomLong(r, 0, rx); final long curTx = randomLong(r, 0, tx); entry.rxBytes = randomLong(r, 0, rx); entry.txBytes = randomLong(r, 0, tx); recordData(curStart, curEnd, curRx, curTx); recordData(curStart, curEnd, entry); rx -= curRx; tx -= curTx; rx -= entry.rxBytes; tx -= entry.txBytes; } } Loading @@ -347,7 +431,10 @@ public class NetworkStatsHistory implements Parcelable { pw.print(prefix); pw.print(" bucketStart="); pw.print(bucketStart[i]); pw.print(" rxBytes="); pw.print(rxBytes[i]); pw.print(" txBytes="); pw.println(txBytes[i]); pw.print(" rxPackets="); pw.print(rxPackets[i]); pw.print(" txBytes="); pw.print(txBytes[i]); pw.print(" txPackets="); pw.print(txPackets[i]); pw.print(" operations="); pw.println(operations[i]); } } Loading @@ -368,7 +455,12 @@ public class NetworkStatsHistory implements Parcelable { } }; private static long[] readLongArray(DataInputStream in) throws IOException { /** * Utility methods for interacting with {@link DataInputStream} and * {@link DataOutputStream}, mostly dealing with writing partial arrays. */ public static class DataStreamUtils { public static long[] readLongArray(DataInputStream in) throws IOException { final int size = in.readInt(); final long[] values = new long[size]; for (int i = 0; i < values.length; i++) { Loading @@ -377,7 +469,8 @@ public class NetworkStatsHistory implements Parcelable { return values; } private static void writeLongArray(DataOutputStream out, long[] values, int size) throws IOException { public static void writeLongArray(DataOutputStream out, long[] values, int size) throws IOException { if (size > values.length) { throw new IllegalArgumentException("size larger than length"); } Loading @@ -386,8 +479,14 @@ public class NetworkStatsHistory implements Parcelable { out.writeLong(values[i]); } } } private static long[] readLongArray(Parcel in) { /** * Utility methods for interacting with {@link Parcel} structures, mostly * dealing with writing partial arrays. */ public static class ParcelUtils { public static long[] readLongArray(Parcel in) { final int size = in.readInt(); final long[] values = new long[size]; for (int i = 0; i < values.length; i++) { Loading @@ -396,7 +495,7 @@ public class NetworkStatsHistory implements Parcelable { return values; } private static void writeLongArray(Parcel out, long[] values, int size) { public static void writeLongArray(Parcel out, long[] values, int size) { if (size > values.length) { throw new IllegalArgumentException("size larger than length"); } Loading @@ -406,4 +505,24 @@ public class NetworkStatsHistory implements Parcelable { } } public static int[] readIntArray(Parcel in) { final int size = in.readInt(); final int[] values = new int[size]; for (int i = 0; i < values.length; i++) { values[i] = in.readInt(); } return values; } public static void writeIntArray(Parcel out, int[] values, int size) { if (size > values.length) { throw new IllegalArgumentException("size larger than length"); } out.writeInt(size); for (int i = 0; i < size; i++) { out.writeInt(values[i]); } } } } core/java/android/net/TrafficStats.java +29 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -11336,6 +11336,7 @@ package android.net { method public static long getUidUdpRxPackets(int); method public static long getUidUdpTxBytes(int); method public static long getUidUdpTxPackets(int); method public static void incrementOperationCount(int, int); method public static void setThreadStatsTag(int); method public static deprecated void setThreadStatsTag(java.lang.String); method public static void tagSocket(java.net.Socket) throws java.net.SocketException;
core/java/android/net/INetworkStatsService.aidl +9 −4 Original line number Diff line number Diff line Loading @@ -23,16 +23,21 @@ import android.net.NetworkTemplate; /** {@hide} */ interface INetworkStatsService { /** Return historical stats for traffic that matches template. */ /** Return historical network layer stats for traffic that matches template. */ NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template); /** Return historical stats for specific UID traffic that matches template. */ /** Return historical network layer stats for specific UID traffic that matches template. */ NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int tag); /** Return usage summary for traffic that matches template. */ /** Return network layer usage summary for traffic that matches template. */ NetworkStats getSummaryForNetwork(in NetworkTemplate template, long start, long end); /** Return usage summary per UID for traffic that matches template. */ /** Return network layer usage summary per UID for traffic that matches template. */ NetworkStats getSummaryForAllUid(in NetworkTemplate template, long start, long end, boolean includeTags); /** Return data layer snapshot of UID network usage. */ NetworkStats getDataLayerSnapshotForUid(int uid); /** Increment data layer count of operations performed for UID and tag. */ void incrementOperationCount(int uid, int tag, int operationCount); /** Force update of statistics. */ void forceUpdate(); Loading
core/java/android/net/NetworkStats.java +60 −25 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.os.Parcelable; import android.os.SystemClock; import android.util.SparseBooleanArray; import com.android.internal.util.Objects; import java.io.CharArrayWriter; import java.io.PrintWriter; import java.util.Arrays; Loading Loading @@ -56,6 +58,7 @@ public class NetworkStats implements Parcelable { private long[] rxPackets; private long[] txBytes; private long[] txPackets; private int[] operations; public static class Entry { public String iface; Loading @@ -65,12 +68,13 @@ public class NetworkStats implements Parcelable { public long rxPackets; public long txBytes; public long txPackets; public int operations; public Entry() { } public Entry(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { long txPackets, int operations) { this.iface = iface; this.uid = uid; this.tag = tag; Loading @@ -78,6 +82,7 @@ public class NetworkStats implements Parcelable { this.rxPackets = rxPackets; this.txBytes = txBytes; this.txPackets = txPackets; this.operations = operations; } } Loading @@ -91,6 +96,7 @@ public class NetworkStats implements Parcelable { this.rxPackets = new long[initialSize]; this.txBytes = new long[initialSize]; this.txPackets = new long[initialSize]; this.operations = new int[initialSize]; } public NetworkStats(Parcel parcel) { Loading @@ -103,11 +109,32 @@ public class NetworkStats implements Parcelable { rxPackets = parcel.createLongArray(); txBytes = parcel.createLongArray(); txPackets = parcel.createLongArray(); operations = parcel.createIntArray(); } /** {@inheritDoc} */ public void writeToParcel(Parcel dest, int flags) { dest.writeLong(elapsedRealtime); dest.writeInt(size); dest.writeStringArray(iface); dest.writeIntArray(uid); dest.writeIntArray(tag); dest.writeLongArray(rxBytes); dest.writeLongArray(rxPackets); dest.writeLongArray(txBytes); dest.writeLongArray(txPackets); dest.writeIntArray(operations); } public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { return addValues(new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets)); return addValues(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, 0); } public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) { return addValues( new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); } /** Loading @@ -124,6 +151,7 @@ public class NetworkStats implements Parcelable { rxPackets = Arrays.copyOf(rxPackets, newLength); txBytes = Arrays.copyOf(txBytes, newLength); txPackets = Arrays.copyOf(txPackets, newLength); operations = Arrays.copyOf(operations, newLength); } iface[size] = entry.iface; Loading @@ -133,6 +161,7 @@ public class NetworkStats implements Parcelable { rxPackets[size] = entry.rxPackets; txBytes[size] = entry.txBytes; txPackets[size] = entry.txPackets; operations[size] = entry.operations; size++; return this; Loading @@ -150,6 +179,7 @@ public class NetworkStats implements Parcelable { entry.rxPackets = rxPackets[i]; entry.txBytes = txBytes[i]; entry.txPackets = txPackets[i]; entry.operations = operations[i]; return entry; } Loading @@ -167,8 +197,9 @@ public class NetworkStats implements Parcelable { } public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes, long txPackets) { return combineValues(new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets)); long txBytes, long txPackets, int operations) { return combineValues( new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); } /** Loading @@ -186,6 +217,7 @@ public class NetworkStats implements Parcelable { rxPackets[i] += entry.rxPackets; txBytes[i] += entry.txBytes; txPackets[i] += entry.txPackets; operations[i] += entry.operations; } return this; } Loading @@ -195,13 +227,29 @@ public class NetworkStats implements Parcelable { */ public int findIndex(String iface, int uid, int tag) { for (int i = 0; i < size; i++) { if (equal(iface, this.iface[i]) && uid == this.uid[i] && tag == this.tag[i]) { if (Objects.equal(iface, this.iface[i]) && uid == this.uid[i] && tag == this.tag[i]) { return i; } } return -1; } /** * Splice in {@link #operations} from the given {@link NetworkStats} based * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface}, * since operation counts are at data layer. */ public void spliceOperationsFrom(NetworkStats stats) { for (int i = 0; i < size; i++) { final int j = stats.findIndex(IFACE_ALL, uid[i], tag[i]); if (j == -1) { operations[i] = 0; } else { operations[i] = stats.operations[j]; } } } /** * Return list of unique interfaces known by this data structure. */ Loading Loading @@ -289,15 +337,17 @@ public class NetworkStats implements Parcelable { entry.rxPackets = rxPackets[i]; entry.txBytes = txBytes[i]; entry.txPackets = txPackets[i]; entry.operations = operations[i]; } else { // existing row, subtract remote value entry.rxBytes = rxBytes[i] - value.rxBytes[j]; entry.rxPackets = rxPackets[i] - value.rxPackets[j]; entry.txBytes = txBytes[i] - value.txBytes[j]; entry.txPackets = txPackets[i] - value.txPackets[j]; entry.operations = operations[i] - value.operations[j]; if (enforceMonotonic && (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 || entry.txPackets < 0)) { || entry.txPackets < 0 || entry.operations < 0)) { throw new IllegalArgumentException("found non-monotonic values"); } if (clampNegative) { Loading @@ -305,6 +355,7 @@ public class NetworkStats implements Parcelable { entry.rxPackets = Math.max(0, entry.rxPackets); entry.txBytes = Math.max(0, entry.txBytes); entry.txPackets = Math.max(0, entry.txPackets); entry.operations = Math.max(0, entry.operations); } } Loading @@ -314,10 +365,6 @@ public class NetworkStats implements Parcelable { return result; } private static boolean equal(Object a, Object b) { return a == b || (a != null && a.equals(b)); } public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime); Loading @@ -325,11 +372,12 @@ public class NetworkStats implements Parcelable { pw.print(prefix); pw.print(" iface="); pw.print(iface[i]); pw.print(" uid="); pw.print(uid[i]); pw.print(" tag="); pw.print(tag[i]); pw.print(" tag=0x"); pw.print(Integer.toHexString(tag[i])); pw.print(" rxBytes="); pw.print(rxBytes[i]); pw.print(" rxPackets="); pw.print(rxPackets[i]); pw.print(" txBytes="); pw.print(txBytes[i]); pw.print(" txPackets="); pw.println(txPackets[i]); pw.print(" txPackets="); pw.print(txPackets[i]); pw.print(" operations="); pw.println(operations[i]); } } Loading @@ -345,19 +393,6 @@ public class NetworkStats implements Parcelable { return 0; } /** {@inheritDoc} */ public void writeToParcel(Parcel dest, int flags) { dest.writeLong(elapsedRealtime); dest.writeInt(size); dest.writeStringArray(iface); dest.writeIntArray(uid); dest.writeIntArray(tag); dest.writeLongArray(rxBytes); dest.writeLongArray(rxPackets); dest.writeLongArray(txBytes); dest.writeLongArray(txPackets); } public static final Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() { public NetworkStats createFromParcel(Parcel in) { return new NetworkStats(in); Loading
core/java/android/net/NetworkStatsHistory.java +173 −54 Original line number Diff line number Diff line Loading @@ -16,6 +16,16 @@ package android.net; import static android.net.NetworkStats.IFACE_ALL; import static android.net.NetworkStats.TAG_NONE; import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.DataStreamUtils.readLongArray; import static android.net.NetworkStatsHistory.DataStreamUtils.writeLongArray; import static android.net.NetworkStatsHistory.ParcelUtils.readIntArray; import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray; import static android.net.NetworkStatsHistory.ParcelUtils.writeIntArray; import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -43,19 +53,26 @@ public class NetworkStatsHistory implements Parcelable { private static final int VERSION_INIT = 1; // TODO: teach about varint encoding to use less disk space // TODO: extend to record rxPackets/txPackets // TODO: teach about omitting entire fields to reduce parcel pressure // TODO: persist/restore packet and operation counts private final long bucketDuration; private int bucketCount; private long[] bucketStart; private long[] rxBytes; private long[] rxPackets; private long[] txBytes; private long[] txPackets; private int[] operations; public static class Entry { public long bucketStart; public long bucketDuration; public long rxBytes; public long rxPackets; public long txBytes; public long txPackets; public int operations; } public NetworkStatsHistory(long bucketDuration) { Loading @@ -66,15 +83,21 @@ public class NetworkStatsHistory implements Parcelable { this.bucketDuration = bucketDuration; bucketStart = new long[initialSize]; rxBytes = new long[initialSize]; rxPackets = new long[initialSize]; txBytes = new long[initialSize]; txPackets = new long[initialSize]; operations = new int[initialSize]; bucketCount = 0; } public NetworkStatsHistory(Parcel in) { bucketDuration = in.readLong(); bucketStart = readLongArray(in); rxBytes = in.createLongArray(); txBytes = in.createLongArray(); rxBytes = readLongArray(in); rxPackets = readLongArray(in); txBytes = readLongArray(in); txPackets = readLongArray(in); operations = readIntArray(in); bucketCount = bucketStart.length; } Loading @@ -83,17 +106,24 @@ public class NetworkStatsHistory implements Parcelable { out.writeLong(bucketDuration); writeLongArray(out, bucketStart, bucketCount); writeLongArray(out, rxBytes, bucketCount); writeLongArray(out, rxPackets, bucketCount); writeLongArray(out, txBytes, bucketCount); writeLongArray(out, txPackets, bucketCount); writeIntArray(out, operations, bucketCount); } public NetworkStatsHistory(DataInputStream in) throws IOException { // TODO: read packet and operation counts final int version = in.readInt(); switch (version) { case VERSION_INIT: { bucketDuration = in.readLong(); bucketStart = readLongArray(in); rxBytes = readLongArray(in); rxPackets = new long[bucketStart.length]; txBytes = readLongArray(in); txPackets = new long[bucketStart.length]; operations = new int[bucketStart.length]; bucketCount = bucketStart.length; break; } Loading @@ -104,6 +134,7 @@ public class NetworkStatsHistory implements Parcelable { } public void writeToStream(DataOutputStream out) throws IOException { // TODO: write packet and operation counts out.writeInt(VERSION_INIT); out.writeLong(bucketDuration); writeLongArray(out, bucketStart, bucketCount); Loading Loading @@ -148,7 +179,10 @@ public class NetworkStatsHistory implements Parcelable { entry.bucketStart = bucketStart[i]; entry.bucketDuration = bucketDuration; entry.rxBytes = rxBytes[i]; entry.rxPackets = rxPackets[i]; entry.txBytes = txBytes[i]; entry.txPackets = txPackets[i]; entry.operations = operations[i]; return entry; } Loading @@ -156,17 +190,27 @@ public class NetworkStatsHistory implements Parcelable { * Record that data traffic occurred in the given time range. Will * distribute across internal buckets, creating new buckets as needed. */ public void recordData(long start, long end, long rx, long tx) { if (rx < 0 || tx < 0) { throw new IllegalArgumentException( "tried recording negative data: rx=" + rx + ", tx=" + tx); @Deprecated public void recordData(long start, long end, long rxBytes, long txBytes) { recordData(start, end, new NetworkStats.Entry(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0)); } /** * Record that data traffic occurred in the given time range. Will * distribute across internal buckets, creating new buckets as needed. */ public void recordData(long start, long end, NetworkStats.Entry entry) { if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 || entry.txPackets < 0 || entry.operations < 0) { throw new IllegalArgumentException("tried recording negative data"); } // create any buckets needed by this range ensureBuckets(start, end); // distribute data usage into buckets final long duration = end - start; long duration = end - start; for (int i = bucketCount - 1; i >= 0; i--) { final long curStart = bucketStart[i]; final long curEnd = curStart + bucketDuration; Loading @@ -177,10 +221,22 @@ public class NetworkStatsHistory implements Parcelable { if (curStart > end) continue; final long overlap = Math.min(curEnd, end) - Math.max(curStart, start); if (overlap > 0) { this.rxBytes[i] += rx * overlap / duration; this.txBytes[i] += tx * overlap / duration; } if (overlap <= 0) continue; // integer math each time is faster than floating point final long fracRxBytes = entry.rxBytes * overlap / duration; final long fracRxPackets = entry.rxPackets * overlap / duration; final long fracTxBytes = entry.txBytes * overlap / duration; final long fracTxPackets = entry.txPackets * overlap / duration; final int fracOperations = (int) (entry.operations * overlap / duration); rxBytes[i] += fracRxBytes; entry.rxBytes -= fracRxBytes; rxPackets[i] += fracRxPackets; entry.rxPackets -= fracRxPackets; txBytes[i] += fracTxBytes; entry.txBytes -= fracTxBytes; txPackets[i] += fracTxPackets; entry.txPackets -= fracTxPackets; operations[i] += fracOperations; entry.operations -= fracOperations; duration -= overlap; } } Loading @@ -189,10 +245,19 @@ public class NetworkStatsHistory implements Parcelable { * for combining together stats for external reporting. */ public void recordEntireHistory(NetworkStatsHistory input) { final NetworkStats.Entry entry = new NetworkStats.Entry( IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0); for (int i = 0; i < input.bucketCount; i++) { final long start = input.bucketStart[i]; final long end = start + input.bucketDuration; recordData(start, end, input.rxBytes[i], input.txBytes[i]); entry.rxBytes = input.rxBytes[i]; entry.rxPackets = input.rxPackets[i]; entry.txBytes = input.txBytes[i]; entry.txPackets = input.txPackets[i]; entry.operations = input.operations[i]; recordData(start, end, entry); } } Loading Loading @@ -223,7 +288,10 @@ public class NetworkStatsHistory implements Parcelable { final int newLength = Math.max(bucketStart.length, 10) * 3 / 2; bucketStart = Arrays.copyOf(bucketStart, newLength); rxBytes = Arrays.copyOf(rxBytes, newLength); rxPackets = Arrays.copyOf(rxPackets, newLength); txBytes = Arrays.copyOf(txBytes, newLength); txPackets = Arrays.copyOf(txPackets, newLength); operations = Arrays.copyOf(operations, newLength); } // create gap when inserting bucket in middle Loading @@ -233,12 +301,18 @@ public class NetworkStatsHistory implements Parcelable { System.arraycopy(bucketStart, index, bucketStart, dstPos, length); System.arraycopy(rxBytes, index, rxBytes, dstPos, length); System.arraycopy(rxPackets, index, rxPackets, dstPos, length); System.arraycopy(txBytes, index, txBytes, dstPos, length); System.arraycopy(txPackets, index, txPackets, dstPos, length); System.arraycopy(operations, index, operations, dstPos, length); } bucketStart[index] = start; rxBytes[index] = 0; rxPackets[index] = 0; txBytes[index] = 0; txPackets[index] = 0; operations[index] = 0; bucketCount++; } Loading @@ -260,7 +334,10 @@ public class NetworkStatsHistory implements Parcelable { final int length = bucketStart.length; bucketStart = Arrays.copyOfRange(bucketStart, i, length); rxBytes = Arrays.copyOfRange(rxBytes, i, length); rxPackets = Arrays.copyOfRange(rxPackets, i, length); txBytes = Arrays.copyOfRange(txBytes, i, length); txPackets = Arrays.copyOfRange(txPackets, i, length); operations = Arrays.copyOfRange(operations, i, length); bucketCount -= i; } } Loading @@ -282,7 +359,10 @@ public class NetworkStatsHistory implements Parcelable { entry.bucketStart = start; entry.bucketDuration = end - start; entry.rxBytes = 0; entry.rxPackets = 0; entry.txBytes = 0; entry.txPackets = 0; entry.operations = 0; for (int i = bucketCount - 1; i >= 0; i--) { final long curStart = bucketStart[i]; Loading @@ -295,14 +375,16 @@ public class NetworkStatsHistory implements Parcelable { // include full value for active buckets, otherwise only fractional final boolean activeBucket = curStart < now && curEnd > now; final long overlap = Math.min(curEnd, end) - Math.max(curStart, start); if (activeBucket || overlap == bucketDuration) { entry.rxBytes += rxBytes[i]; entry.txBytes += txBytes[i]; } else if (overlap > 0) { final long overlap = activeBucket ? bucketDuration : Math.min(curEnd, end) - Math.max(curStart, start); if (overlap <= 0) continue; // integer math each time is faster than floating point entry.rxBytes += rxBytes[i] * overlap / bucketDuration; entry.rxPackets += rxPackets[i] * overlap / bucketDuration; entry.txBytes += txBytes[i] * overlap / bucketDuration; } entry.txPackets += txPackets[i] * overlap / bucketDuration; entry.operations += operations[i] * overlap / bucketDuration; } return entry; Loading @@ -315,17 +397,19 @@ public class NetworkStatsHistory implements Parcelable { public void generateRandom(long start, long end, long rx, long tx) { ensureBuckets(start, end); final NetworkStats.Entry entry = new NetworkStats.Entry( IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0); final Random r = new Random(); while (rx > 1024 && tx > 1024) { final long curStart = randomLong(r, start, end); final long curEnd = randomLong(r, curStart, end); final long curRx = randomLong(r, 0, rx); final long curTx = randomLong(r, 0, tx); entry.rxBytes = randomLong(r, 0, rx); entry.txBytes = randomLong(r, 0, tx); recordData(curStart, curEnd, curRx, curTx); recordData(curStart, curEnd, entry); rx -= curRx; tx -= curTx; rx -= entry.rxBytes; tx -= entry.txBytes; } } Loading @@ -347,7 +431,10 @@ public class NetworkStatsHistory implements Parcelable { pw.print(prefix); pw.print(" bucketStart="); pw.print(bucketStart[i]); pw.print(" rxBytes="); pw.print(rxBytes[i]); pw.print(" txBytes="); pw.println(txBytes[i]); pw.print(" rxPackets="); pw.print(rxPackets[i]); pw.print(" txBytes="); pw.print(txBytes[i]); pw.print(" txPackets="); pw.print(txPackets[i]); pw.print(" operations="); pw.println(operations[i]); } } Loading @@ -368,7 +455,12 @@ public class NetworkStatsHistory implements Parcelable { } }; private static long[] readLongArray(DataInputStream in) throws IOException { /** * Utility methods for interacting with {@link DataInputStream} and * {@link DataOutputStream}, mostly dealing with writing partial arrays. */ public static class DataStreamUtils { public static long[] readLongArray(DataInputStream in) throws IOException { final int size = in.readInt(); final long[] values = new long[size]; for (int i = 0; i < values.length; i++) { Loading @@ -377,7 +469,8 @@ public class NetworkStatsHistory implements Parcelable { return values; } private static void writeLongArray(DataOutputStream out, long[] values, int size) throws IOException { public static void writeLongArray(DataOutputStream out, long[] values, int size) throws IOException { if (size > values.length) { throw new IllegalArgumentException("size larger than length"); } Loading @@ -386,8 +479,14 @@ public class NetworkStatsHistory implements Parcelable { out.writeLong(values[i]); } } } private static long[] readLongArray(Parcel in) { /** * Utility methods for interacting with {@link Parcel} structures, mostly * dealing with writing partial arrays. */ public static class ParcelUtils { public static long[] readLongArray(Parcel in) { final int size = in.readInt(); final long[] values = new long[size]; for (int i = 0; i < values.length; i++) { Loading @@ -396,7 +495,7 @@ public class NetworkStatsHistory implements Parcelable { return values; } private static void writeLongArray(Parcel out, long[] values, int size) { public static void writeLongArray(Parcel out, long[] values, int size) { if (size > values.length) { throw new IllegalArgumentException("size larger than length"); } Loading @@ -406,4 +505,24 @@ public class NetworkStatsHistory implements Parcelable { } } public static int[] readIntArray(Parcel in) { final int size = in.readInt(); final int[] values = new int[size]; for (int i = 0; i < values.length; i++) { values[i] = in.readInt(); } return values; } public static void writeIntArray(Parcel out, int[] values, int size) { if (size > values.length) { throw new IllegalArgumentException("size larger than length"); } out.writeInt(size); for (int i = 0; i < size; i++) { out.writeInt(values[i]); } } } }
core/java/android/net/TrafficStats.java +29 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes