Network stats with varint, omit parcel fields.
Persist NetworkStatsHistory using variable-length encoding; since most buckets have small numbers, we can encode them tighter. Initial test showed 44% space savings. Also persist packet and operation counters. Let NetworkStatsHistory consumers request which fields they actually need to reduce parcel overhead. Tests for verify varint and history field requests, also verify end- to-end by persisting history into byte[] and restoring. Expose bandwidth control enabled state. Extend random generation to create packet and operation counts. Moved operation counts to long. Fix bug that miscalculated bytes since last persist, which would cause partial stats loss when battery pulled. Bug: 4581977, 5023706, 5023635, 5096903 Change-Id: If61e89f681ffa11fe5711471fd9f7c238d3d37b0
This commit is contained in:
@@ -24,9 +24,9 @@ import android.net.NetworkTemplate;
|
|||||||
interface INetworkStatsService {
|
interface INetworkStatsService {
|
||||||
|
|
||||||
/** Return historical network layer stats for traffic that matches template. */
|
/** Return historical network layer stats for traffic that matches template. */
|
||||||
NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template);
|
NetworkStatsHistory getHistoryForNetwork(in NetworkTemplate template, int fields);
|
||||||
/** Return historical network layer 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);
|
NetworkStatsHistory getHistoryForUid(in NetworkTemplate template, int uid, int tag, int fields);
|
||||||
|
|
||||||
/** Return network layer 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);
|
NetworkStats getSummaryForNetwork(in NetworkTemplate template, long start, long end);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class NetworkStats implements Parcelable {
|
|||||||
private long[] rxPackets;
|
private long[] rxPackets;
|
||||||
private long[] txBytes;
|
private long[] txBytes;
|
||||||
private long[] txPackets;
|
private long[] txPackets;
|
||||||
private int[] operations;
|
private long[] operations;
|
||||||
|
|
||||||
public static class Entry {
|
public static class Entry {
|
||||||
public String iface;
|
public String iface;
|
||||||
@@ -68,13 +68,18 @@ public class NetworkStats implements Parcelable {
|
|||||||
public long rxPackets;
|
public long rxPackets;
|
||||||
public long txBytes;
|
public long txBytes;
|
||||||
public long txPackets;
|
public long txPackets;
|
||||||
public int operations;
|
public long operations;
|
||||||
|
|
||||||
public Entry() {
|
public Entry() {
|
||||||
|
this(IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) {
|
||||||
|
this(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entry(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes,
|
public Entry(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes,
|
||||||
long txPackets, int operations) {
|
long txPackets, long operations) {
|
||||||
this.iface = iface;
|
this.iface = iface;
|
||||||
this.uid = uid;
|
this.uid = uid;
|
||||||
this.tag = tag;
|
this.tag = tag;
|
||||||
@@ -96,7 +101,7 @@ public class NetworkStats implements Parcelable {
|
|||||||
this.rxPackets = new long[initialSize];
|
this.rxPackets = new long[initialSize];
|
||||||
this.txBytes = new long[initialSize];
|
this.txBytes = new long[initialSize];
|
||||||
this.txPackets = new long[initialSize];
|
this.txPackets = new long[initialSize];
|
||||||
this.operations = new int[initialSize];
|
this.operations = new long[initialSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkStats(Parcel parcel) {
|
public NetworkStats(Parcel parcel) {
|
||||||
@@ -109,7 +114,7 @@ public class NetworkStats implements Parcelable {
|
|||||||
rxPackets = parcel.createLongArray();
|
rxPackets = parcel.createLongArray();
|
||||||
txBytes = parcel.createLongArray();
|
txBytes = parcel.createLongArray();
|
||||||
txPackets = parcel.createLongArray();
|
txPackets = parcel.createLongArray();
|
||||||
operations = parcel.createIntArray();
|
operations = parcel.createLongArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@@ -123,16 +128,16 @@ public class NetworkStats implements Parcelable {
|
|||||||
dest.writeLongArray(rxPackets);
|
dest.writeLongArray(rxPackets);
|
||||||
dest.writeLongArray(txBytes);
|
dest.writeLongArray(txBytes);
|
||||||
dest.writeLongArray(txPackets);
|
dest.writeLongArray(txPackets);
|
||||||
dest.writeIntArray(operations);
|
dest.writeLongArray(operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
|
public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
|
||||||
long txBytes, long txPackets) {
|
long txBytes, long txPackets) {
|
||||||
return addValues(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, 0);
|
return addValues(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
|
public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
|
||||||
long txBytes, long txPackets, int operations) {
|
long txBytes, long txPackets, long operations) {
|
||||||
return addValues(
|
return addValues(
|
||||||
new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
|
new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
|
||||||
}
|
}
|
||||||
@@ -197,7 +202,7 @@ public class NetworkStats implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
|
public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
|
||||||
long txBytes, long txPackets, int operations) {
|
long txBytes, long txPackets, long operations) {
|
||||||
return combineValues(
|
return combineValues(
|
||||||
new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
|
new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets, operations));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ package android.net;
|
|||||||
import static android.net.NetworkStats.IFACE_ALL;
|
import static android.net.NetworkStats.IFACE_ALL;
|
||||||
import static android.net.NetworkStats.TAG_NONE;
|
import static android.net.NetworkStats.TAG_NONE;
|
||||||
import static android.net.NetworkStats.UID_ALL;
|
import static android.net.NetworkStats.UID_ALL;
|
||||||
import static android.net.NetworkStatsHistory.DataStreamUtils.readLongArray;
|
import static android.net.NetworkStatsHistory.DataStreamUtils.readFullLongArray;
|
||||||
import static android.net.NetworkStatsHistory.DataStreamUtils.writeLongArray;
|
import static android.net.NetworkStatsHistory.DataStreamUtils.readVarLongArray;
|
||||||
import static android.net.NetworkStatsHistory.ParcelUtils.readIntArray;
|
import static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLongArray;
|
||||||
|
import static android.net.NetworkStatsHistory.Entry.UNKNOWN;
|
||||||
import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
|
import static android.net.NetworkStatsHistory.ParcelUtils.readLongArray;
|
||||||
import static android.net.NetworkStatsHistory.ParcelUtils.writeIntArray;
|
|
||||||
import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
|
import static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray;
|
||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
@@ -51,42 +51,53 @@ import java.util.Random;
|
|||||||
*/
|
*/
|
||||||
public class NetworkStatsHistory implements Parcelable {
|
public class NetworkStatsHistory implements Parcelable {
|
||||||
private static final int VERSION_INIT = 1;
|
private static final int VERSION_INIT = 1;
|
||||||
|
private static final int VERSION_ADD_PACKETS = 2;
|
||||||
|
|
||||||
// TODO: teach about varint encoding to use less disk space
|
public static final int FIELD_RX_BYTES = 0x01;
|
||||||
// TODO: teach about omitting entire fields to reduce parcel pressure
|
public static final int FIELD_RX_PACKETS = 0x02;
|
||||||
// TODO: persist/restore packet and operation counts
|
public static final int FIELD_TX_BYTES = 0x04;
|
||||||
|
public static final int FIELD_TX_PACKETS = 0x08;
|
||||||
|
public static final int FIELD_OPERATIONS = 0x10;
|
||||||
|
|
||||||
private final long bucketDuration;
|
public static final int FIELD_ALL = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
private long bucketDuration;
|
||||||
private int bucketCount;
|
private int bucketCount;
|
||||||
private long[] bucketStart;
|
private long[] bucketStart;
|
||||||
private long[] rxBytes;
|
private long[] rxBytes;
|
||||||
private long[] rxPackets;
|
private long[] rxPackets;
|
||||||
private long[] txBytes;
|
private long[] txBytes;
|
||||||
private long[] txPackets;
|
private long[] txPackets;
|
||||||
private int[] operations;
|
private long[] operations;
|
||||||
|
|
||||||
public static class Entry {
|
public static class Entry {
|
||||||
|
public static final long UNKNOWN = -1;
|
||||||
|
|
||||||
public long bucketStart;
|
public long bucketStart;
|
||||||
public long bucketDuration;
|
public long bucketDuration;
|
||||||
public long rxBytes;
|
public long rxBytes;
|
||||||
public long rxPackets;
|
public long rxPackets;
|
||||||
public long txBytes;
|
public long txBytes;
|
||||||
public long txPackets;
|
public long txPackets;
|
||||||
public int operations;
|
public long operations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkStatsHistory(long bucketDuration) {
|
public NetworkStatsHistory(long bucketDuration) {
|
||||||
this(bucketDuration, 10);
|
this(bucketDuration, 10, FIELD_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkStatsHistory(long bucketDuration, int initialSize) {
|
public NetworkStatsHistory(long bucketDuration, int initialSize) {
|
||||||
|
this(bucketDuration, initialSize, FIELD_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkStatsHistory(long bucketDuration, int initialSize, int fields) {
|
||||||
this.bucketDuration = bucketDuration;
|
this.bucketDuration = bucketDuration;
|
||||||
bucketStart = new long[initialSize];
|
bucketStart = new long[initialSize];
|
||||||
rxBytes = new long[initialSize];
|
if ((fields & FIELD_RX_BYTES) != 0) rxBytes = new long[initialSize];
|
||||||
rxPackets = new long[initialSize];
|
if ((fields & FIELD_RX_PACKETS) != 0) rxPackets = new long[initialSize];
|
||||||
txBytes = new long[initialSize];
|
if ((fields & FIELD_TX_BYTES) != 0) txBytes = new long[initialSize];
|
||||||
txPackets = new long[initialSize];
|
if ((fields & FIELD_TX_PACKETS) != 0) txPackets = new long[initialSize];
|
||||||
operations = new int[initialSize];
|
if ((fields & FIELD_OPERATIONS) != 0) operations = new long[initialSize];
|
||||||
bucketCount = 0;
|
bucketCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +108,7 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
rxPackets = readLongArray(in);
|
rxPackets = readLongArray(in);
|
||||||
txBytes = readLongArray(in);
|
txBytes = readLongArray(in);
|
||||||
txPackets = readLongArray(in);
|
txPackets = readLongArray(in);
|
||||||
operations = readIntArray(in);
|
operations = readLongArray(in);
|
||||||
bucketCount = bucketStart.length;
|
bucketCount = bucketStart.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,21 +120,31 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
writeLongArray(out, rxPackets, bucketCount);
|
writeLongArray(out, rxPackets, bucketCount);
|
||||||
writeLongArray(out, txBytes, bucketCount);
|
writeLongArray(out, txBytes, bucketCount);
|
||||||
writeLongArray(out, txPackets, bucketCount);
|
writeLongArray(out, txPackets, bucketCount);
|
||||||
writeIntArray(out, operations, bucketCount);
|
writeLongArray(out, operations, bucketCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkStatsHistory(DataInputStream in) throws IOException {
|
public NetworkStatsHistory(DataInputStream in) throws IOException {
|
||||||
// TODO: read packet and operation counts
|
|
||||||
final int version = in.readInt();
|
final int version = in.readInt();
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case VERSION_INIT: {
|
case VERSION_INIT: {
|
||||||
bucketDuration = in.readLong();
|
bucketDuration = in.readLong();
|
||||||
bucketStart = readLongArray(in);
|
bucketStart = readFullLongArray(in);
|
||||||
rxBytes = readLongArray(in);
|
rxBytes = readFullLongArray(in);
|
||||||
rxPackets = new long[bucketStart.length];
|
rxPackets = new long[bucketStart.length];
|
||||||
txBytes = readLongArray(in);
|
txBytes = readFullLongArray(in);
|
||||||
txPackets = new long[bucketStart.length];
|
txPackets = new long[bucketStart.length];
|
||||||
operations = new int[bucketStart.length];
|
operations = new long[bucketStart.length];
|
||||||
|
bucketCount = bucketStart.length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VERSION_ADD_PACKETS: {
|
||||||
|
bucketDuration = in.readLong();
|
||||||
|
bucketStart = readVarLongArray(in);
|
||||||
|
rxBytes = readVarLongArray(in);
|
||||||
|
rxPackets = readVarLongArray(in);
|
||||||
|
txBytes = readVarLongArray(in);
|
||||||
|
txPackets = readVarLongArray(in);
|
||||||
|
operations = readVarLongArray(in);
|
||||||
bucketCount = bucketStart.length;
|
bucketCount = bucketStart.length;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -134,12 +155,14 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void writeToStream(DataOutputStream out) throws IOException {
|
public void writeToStream(DataOutputStream out) throws IOException {
|
||||||
// TODO: write packet and operation counts
|
out.writeInt(VERSION_ADD_PACKETS);
|
||||||
out.writeInt(VERSION_INIT);
|
|
||||||
out.writeLong(bucketDuration);
|
out.writeLong(bucketDuration);
|
||||||
writeLongArray(out, bucketStart, bucketCount);
|
writeVarLongArray(out, bucketStart, bucketCount);
|
||||||
writeLongArray(out, rxBytes, bucketCount);
|
writeVarLongArray(out, rxBytes, bucketCount);
|
||||||
writeLongArray(out, txBytes, bucketCount);
|
writeVarLongArray(out, rxPackets, bucketCount);
|
||||||
|
writeVarLongArray(out, txBytes, bucketCount);
|
||||||
|
writeVarLongArray(out, txPackets, bucketCount);
|
||||||
|
writeVarLongArray(out, operations, bucketCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@@ -178,11 +201,11 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
final Entry entry = recycle != null ? recycle : new Entry();
|
final Entry entry = recycle != null ? recycle : new Entry();
|
||||||
entry.bucketStart = bucketStart[i];
|
entry.bucketStart = bucketStart[i];
|
||||||
entry.bucketDuration = bucketDuration;
|
entry.bucketDuration = bucketDuration;
|
||||||
entry.rxBytes = rxBytes[i];
|
entry.rxBytes = getLong(rxBytes, i, UNKNOWN);
|
||||||
entry.rxPackets = rxPackets[i];
|
entry.rxPackets = getLong(rxPackets, i, UNKNOWN);
|
||||||
entry.txBytes = txBytes[i];
|
entry.txBytes = getLong(txBytes, i, UNKNOWN);
|
||||||
entry.txPackets = txPackets[i];
|
entry.txPackets = getLong(txPackets, i, UNKNOWN);
|
||||||
entry.operations = operations[i];
|
entry.operations = getLong(operations, i, UNKNOWN);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +216,7 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public void recordData(long start, long end, long rxBytes, long txBytes) {
|
public void recordData(long start, long end, long rxBytes, long txBytes) {
|
||||||
recordData(start, end,
|
recordData(start, end,
|
||||||
new NetworkStats.Entry(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0));
|
new NetworkStats.Entry(IFACE_ALL, UID_ALL, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0L));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -230,11 +253,11 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
final long fracTxPackets = entry.txPackets * overlap / duration;
|
final long fracTxPackets = entry.txPackets * overlap / duration;
|
||||||
final int fracOperations = (int) (entry.operations * overlap / duration);
|
final int fracOperations = (int) (entry.operations * overlap / duration);
|
||||||
|
|
||||||
rxBytes[i] += fracRxBytes; entry.rxBytes -= fracRxBytes;
|
addLong(rxBytes, i, fracRxBytes); entry.rxBytes -= fracRxBytes;
|
||||||
rxPackets[i] += fracRxPackets; entry.rxPackets -= fracRxPackets;
|
addLong(rxPackets, i, fracRxPackets); entry.rxPackets -= fracRxPackets;
|
||||||
txBytes[i] += fracTxBytes; entry.txBytes -= fracTxBytes;
|
addLong(txBytes, i, fracTxBytes); entry.txBytes -= fracTxBytes;
|
||||||
txPackets[i] += fracTxPackets; entry.txPackets -= fracTxPackets;
|
addLong(txPackets, i, fracTxPackets); entry.txPackets -= fracTxPackets;
|
||||||
operations[i] += fracOperations; entry.operations -= fracOperations;
|
addLong(operations, i, fracOperations); entry.operations -= fracOperations;
|
||||||
|
|
||||||
duration -= overlap;
|
duration -= overlap;
|
||||||
}
|
}
|
||||||
@@ -246,16 +269,16 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public void recordEntireHistory(NetworkStatsHistory input) {
|
public void recordEntireHistory(NetworkStatsHistory input) {
|
||||||
final NetworkStats.Entry entry = new NetworkStats.Entry(
|
final NetworkStats.Entry entry = new NetworkStats.Entry(
|
||||||
IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0);
|
IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
|
||||||
for (int i = 0; i < input.bucketCount; i++) {
|
for (int i = 0; i < input.bucketCount; i++) {
|
||||||
final long start = input.bucketStart[i];
|
final long start = input.bucketStart[i];
|
||||||
final long end = start + input.bucketDuration;
|
final long end = start + input.bucketDuration;
|
||||||
|
|
||||||
entry.rxBytes = input.rxBytes[i];
|
entry.rxBytes = getLong(input.rxBytes, i, 0L);
|
||||||
entry.rxPackets = input.rxPackets[i];
|
entry.rxPackets = getLong(input.rxPackets, i, 0L);
|
||||||
entry.txBytes = input.txBytes[i];
|
entry.txBytes = getLong(input.txBytes, i, 0L);
|
||||||
entry.txPackets = input.txPackets[i];
|
entry.txPackets = getLong(input.txPackets, i, 0L);
|
||||||
entry.operations = input.operations[i];
|
entry.operations = getLong(input.operations, i, 0L);
|
||||||
|
|
||||||
recordData(start, end, entry);
|
recordData(start, end, entry);
|
||||||
}
|
}
|
||||||
@@ -287,11 +310,11 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
if (bucketCount >= bucketStart.length) {
|
if (bucketCount >= bucketStart.length) {
|
||||||
final int newLength = Math.max(bucketStart.length, 10) * 3 / 2;
|
final int newLength = Math.max(bucketStart.length, 10) * 3 / 2;
|
||||||
bucketStart = Arrays.copyOf(bucketStart, newLength);
|
bucketStart = Arrays.copyOf(bucketStart, newLength);
|
||||||
rxBytes = Arrays.copyOf(rxBytes, newLength);
|
if (rxBytes != null) rxBytes = Arrays.copyOf(rxBytes, newLength);
|
||||||
rxPackets = Arrays.copyOf(rxPackets, newLength);
|
if (rxPackets != null) rxPackets = Arrays.copyOf(rxPackets, newLength);
|
||||||
txBytes = Arrays.copyOf(txBytes, newLength);
|
if (txBytes != null) txBytes = Arrays.copyOf(txBytes, newLength);
|
||||||
txPackets = Arrays.copyOf(txPackets, newLength);
|
if (txPackets != null) txPackets = Arrays.copyOf(txPackets, newLength);
|
||||||
operations = Arrays.copyOf(operations, newLength);
|
if (operations != null) operations = Arrays.copyOf(operations, newLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create gap when inserting bucket in middle
|
// create gap when inserting bucket in middle
|
||||||
@@ -300,19 +323,19 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
final int length = bucketCount - index;
|
final int length = bucketCount - index;
|
||||||
|
|
||||||
System.arraycopy(bucketStart, index, bucketStart, dstPos, length);
|
System.arraycopy(bucketStart, index, bucketStart, dstPos, length);
|
||||||
System.arraycopy(rxBytes, index, rxBytes, dstPos, length);
|
if (rxBytes != null) System.arraycopy(rxBytes, index, rxBytes, dstPos, length);
|
||||||
System.arraycopy(rxPackets, index, rxPackets, dstPos, length);
|
if (rxPackets != null) System.arraycopy(rxPackets, index, rxPackets, dstPos, length);
|
||||||
System.arraycopy(txBytes, index, txBytes, dstPos, length);
|
if (txBytes != null) System.arraycopy(txBytes, index, txBytes, dstPos, length);
|
||||||
System.arraycopy(txPackets, index, txPackets, dstPos, length);
|
if (txPackets != null) System.arraycopy(txPackets, index, txPackets, dstPos, length);
|
||||||
System.arraycopy(operations, index, operations, dstPos, length);
|
if (operations != null) System.arraycopy(operations, index, operations, dstPos, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bucketStart[index] = start;
|
bucketStart[index] = start;
|
||||||
rxBytes[index] = 0;
|
setLong(rxBytes, index, 0L);
|
||||||
rxPackets[index] = 0;
|
setLong(rxPackets, index, 0L);
|
||||||
txBytes[index] = 0;
|
setLong(txBytes, index, 0L);
|
||||||
txPackets[index] = 0;
|
setLong(txPackets, index, 0L);
|
||||||
operations[index] = 0;
|
setLong(operations, index, 0L);
|
||||||
bucketCount++;
|
bucketCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,11 +356,11 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
final int length = bucketStart.length;
|
final int length = bucketStart.length;
|
||||||
bucketStart = Arrays.copyOfRange(bucketStart, i, length);
|
bucketStart = Arrays.copyOfRange(bucketStart, i, length);
|
||||||
rxBytes = Arrays.copyOfRange(rxBytes, i, length);
|
if (rxBytes != null) rxBytes = Arrays.copyOfRange(rxBytes, i, length);
|
||||||
rxPackets = Arrays.copyOfRange(rxPackets, i, length);
|
if (rxPackets != null) rxPackets = Arrays.copyOfRange(rxPackets, i, length);
|
||||||
txBytes = Arrays.copyOfRange(txBytes, i, length);
|
if (txBytes != null) txBytes = Arrays.copyOfRange(txBytes, i, length);
|
||||||
txPackets = Arrays.copyOfRange(txPackets, i, length);
|
if (txPackets != null) txPackets = Arrays.copyOfRange(txPackets, i, length);
|
||||||
operations = Arrays.copyOfRange(operations, i, length);
|
if (operations != null) operations = Arrays.copyOfRange(operations, i, length);
|
||||||
bucketCount -= i;
|
bucketCount -= i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,11 +381,11 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
final Entry entry = recycle != null ? recycle : new Entry();
|
final Entry entry = recycle != null ? recycle : new Entry();
|
||||||
entry.bucketStart = start;
|
entry.bucketStart = start;
|
||||||
entry.bucketDuration = end - start;
|
entry.bucketDuration = end - start;
|
||||||
entry.rxBytes = 0;
|
entry.rxBytes = rxBytes != null ? 0 : UNKNOWN;
|
||||||
entry.rxPackets = 0;
|
entry.rxPackets = rxPackets != null ? 0 : UNKNOWN;
|
||||||
entry.txBytes = 0;
|
entry.txBytes = txBytes != null ? 0 : UNKNOWN;
|
||||||
entry.txPackets = 0;
|
entry.txPackets = txPackets != null ? 0 : UNKNOWN;
|
||||||
entry.operations = 0;
|
entry.operations = operations != null ? 0 : UNKNOWN;
|
||||||
|
|
||||||
for (int i = bucketCount - 1; i >= 0; i--) {
|
for (int i = bucketCount - 1; i >= 0; i--) {
|
||||||
final long curStart = bucketStart[i];
|
final long curStart = bucketStart[i];
|
||||||
@@ -380,11 +403,11 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
if (overlap <= 0) continue;
|
if (overlap <= 0) continue;
|
||||||
|
|
||||||
// integer math each time is faster than floating point
|
// integer math each time is faster than floating point
|
||||||
entry.rxBytes += rxBytes[i] * overlap / bucketDuration;
|
if (rxBytes != null) entry.rxBytes += rxBytes[i] * overlap / bucketDuration;
|
||||||
entry.rxPackets += rxPackets[i] * overlap / bucketDuration;
|
if (rxPackets != null) entry.rxPackets += rxPackets[i] * overlap / bucketDuration;
|
||||||
entry.txBytes += txBytes[i] * overlap / bucketDuration;
|
if (txBytes != null) entry.txBytes += txBytes[i] * overlap / bucketDuration;
|
||||||
entry.txPackets += txPackets[i] * overlap / bucketDuration;
|
if (txPackets != null) entry.txPackets += txPackets[i] * overlap / bucketDuration;
|
||||||
entry.operations += operations[i] * overlap / bucketDuration;
|
if (operations != null) entry.operations += operations[i] * overlap / bucketDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
@@ -394,19 +417,29 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
* @deprecated only for temporary testing
|
* @deprecated only for temporary testing
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void generateRandom(long start, long end, long rx, long tx) {
|
public void generateRandom(long start, long end, long rxBytes, long rxPackets, long txBytes,
|
||||||
|
long txPackets, long operations) {
|
||||||
ensureBuckets(start, end);
|
ensureBuckets(start, end);
|
||||||
|
|
||||||
final NetworkStats.Entry entry = new NetworkStats.Entry(
|
final NetworkStats.Entry entry = new NetworkStats.Entry(
|
||||||
IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0);
|
IFACE_ALL, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0L);
|
||||||
final Random r = new Random();
|
final Random r = new Random();
|
||||||
while (rx > 1024 && tx > 1024) {
|
while (rxBytes > 1024 && rxPackets > 128 && txBytes > 1024 && txPackets > 128
|
||||||
|
&& operations > 32) {
|
||||||
final long curStart = randomLong(r, start, end);
|
final long curStart = randomLong(r, start, end);
|
||||||
final long curEnd = randomLong(r, curStart, end);
|
final long curEnd = randomLong(r, curStart, end);
|
||||||
entry.rxBytes = randomLong(r, 0, rx);
|
|
||||||
entry.txBytes = randomLong(r, 0, tx);
|
entry.rxBytes = randomLong(r, 0, rxBytes);
|
||||||
rx -= entry.rxBytes;
|
entry.rxPackets = randomLong(r, 0, rxPackets);
|
||||||
tx -= entry.txBytes;
|
entry.txBytes = randomLong(r, 0, txBytes);
|
||||||
|
entry.txPackets = randomLong(r, 0, txPackets);
|
||||||
|
entry.operations = randomLong(r, 0, operations);
|
||||||
|
|
||||||
|
rxBytes -= entry.rxBytes;
|
||||||
|
rxPackets -= entry.rxPackets;
|
||||||
|
txBytes -= entry.txBytes;
|
||||||
|
txPackets -= entry.txPackets;
|
||||||
|
operations -= entry.operations;
|
||||||
|
|
||||||
recordData(curStart, curEnd, entry);
|
recordData(curStart, curEnd, entry);
|
||||||
}
|
}
|
||||||
@@ -429,11 +462,12 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
for (int i = start; i < bucketCount; i++) {
|
for (int i = start; i < bucketCount; i++) {
|
||||||
pw.print(prefix);
|
pw.print(prefix);
|
||||||
pw.print(" bucketStart="); pw.print(bucketStart[i]);
|
pw.print(" bucketStart="); pw.print(bucketStart[i]);
|
||||||
pw.print(" rxBytes="); pw.print(rxBytes[i]);
|
if (rxBytes != null) pw.print(" rxBytes="); pw.print(rxBytes[i]);
|
||||||
pw.print(" rxPackets="); pw.print(rxPackets[i]);
|
if (rxPackets != null) pw.print(" rxPackets="); pw.print(rxPackets[i]);
|
||||||
pw.print(" txBytes="); pw.print(txBytes[i]);
|
if (txBytes != null) pw.print(" txBytes="); pw.print(txBytes[i]);
|
||||||
pw.print(" txPackets="); pw.print(txPackets[i]);
|
if (txPackets != null) pw.print(" txPackets="); pw.print(txPackets[i]);
|
||||||
pw.print(" operations="); pw.println(operations[i]);
|
if (operations != null) pw.print(" operations="); pw.print(operations[i]);
|
||||||
|
pw.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,12 +488,25 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static long getLong(long[] array, int i, long value) {
|
||||||
|
return array != null ? array[i] : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setLong(long[] array, int i, long value) {
|
||||||
|
if (array != null) array[i] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addLong(long[] array, int i, long value) {
|
||||||
|
if (array != null) array[i] += value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods for interacting with {@link DataInputStream} and
|
* Utility methods for interacting with {@link DataInputStream} and
|
||||||
* {@link DataOutputStream}, mostly dealing with writing partial arrays.
|
* {@link DataOutputStream}, mostly dealing with writing partial arrays.
|
||||||
*/
|
*/
|
||||||
public static class DataStreamUtils {
|
public static class DataStreamUtils {
|
||||||
public static long[] readLongArray(DataInputStream in) throws IOException {
|
@Deprecated
|
||||||
|
public static long[] readFullLongArray(DataInputStream in) throws IOException {
|
||||||
final int size = in.readInt();
|
final int size = in.readInt();
|
||||||
final long[] values = new long[size];
|
final long[] values = new long[size];
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
@@ -468,14 +515,59 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeLongArray(DataOutputStream out, long[] values, int size)
|
/**
|
||||||
|
* Read variable-length {@link Long} using protobuf-style approach.
|
||||||
|
*/
|
||||||
|
public static long readVarLong(DataInputStream in) throws IOException {
|
||||||
|
int shift = 0;
|
||||||
|
long result = 0;
|
||||||
|
while (shift < 64) {
|
||||||
|
byte b = in.readByte();
|
||||||
|
result |= (long) (b & 0x7F) << shift;
|
||||||
|
if ((b & 0x80) == 0)
|
||||||
|
return result;
|
||||||
|
shift += 7;
|
||||||
|
}
|
||||||
|
throw new ProtocolException("malformed long");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write variable-length {@link Long} using protobuf-style approach.
|
||||||
|
*/
|
||||||
|
public static void writeVarLong(DataOutputStream out, long value) throws IOException {
|
||||||
|
while (true) {
|
||||||
|
if ((value & ~0x7FL) == 0) {
|
||||||
|
out.writeByte((int) value);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
out.writeByte(((int) value & 0x7F) | 0x80);
|
||||||
|
value >>>= 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long[] readVarLongArray(DataInputStream in) throws IOException {
|
||||||
|
final int size = in.readInt();
|
||||||
|
if (size == -1) return null;
|
||||||
|
final long[] values = new long[size];
|
||||||
|
for (int i = 0; i < values.length; i++) {
|
||||||
|
values[i] = readVarLong(in);
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeVarLongArray(DataOutputStream out, long[] values, int size)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
if (values == null) {
|
||||||
|
out.writeInt(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (size > values.length) {
|
if (size > values.length) {
|
||||||
throw new IllegalArgumentException("size larger than length");
|
throw new IllegalArgumentException("size larger than length");
|
||||||
}
|
}
|
||||||
out.writeInt(size);
|
out.writeInt(size);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
out.writeLong(values[i]);
|
writeVarLong(out, values[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -487,6 +579,7 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
public static class ParcelUtils {
|
public static class ParcelUtils {
|
||||||
public static long[] readLongArray(Parcel in) {
|
public static long[] readLongArray(Parcel in) {
|
||||||
final int size = in.readInt();
|
final int size = in.readInt();
|
||||||
|
if (size == -1) return null;
|
||||||
final long[] values = new long[size];
|
final long[] values = new long[size];
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
values[i] = in.readLong();
|
values[i] = in.readLong();
|
||||||
@@ -495,6 +588,10 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void writeLongArray(Parcel out, long[] values, int size) {
|
public static void writeLongArray(Parcel out, long[] values, int size) {
|
||||||
|
if (values == null) {
|
||||||
|
out.writeInt(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (size > values.length) {
|
if (size > values.length) {
|
||||||
throw new IllegalArgumentException("size larger than length");
|
throw new IllegalArgumentException("size larger than length");
|
||||||
}
|
}
|
||||||
@@ -503,25 +600,6 @@ public class NetworkStatsHistory implements Parcelable {
|
|||||||
out.writeLong(values[i]);
|
out.writeLong(values[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package com.android.server.net;
|
package com.android.server.net;
|
||||||
|
|
||||||
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
|
||||||
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
|
import static android.Manifest.permission.ACCESS_NETWORK_STATE;
|
||||||
import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING;
|
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
|
||||||
import static android.Manifest.permission.DUMP;
|
import static android.Manifest.permission.DUMP;
|
||||||
|
import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING;
|
||||||
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
|
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
|
||||||
import static android.content.Intent.ACTION_SHUTDOWN;
|
import static android.content.Intent.ACTION_SHUTDOWN;
|
||||||
import static android.content.Intent.ACTION_UID_REMOVED;
|
import static android.content.Intent.ACTION_UID_REMOVED;
|
||||||
@@ -68,7 +68,6 @@ import android.os.RemoteException;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.Log;
|
|
||||||
import android.util.LongSparseArray;
|
import android.util.LongSparseArray;
|
||||||
import android.util.NtpTrustedTime;
|
import android.util.NtpTrustedTime;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -282,13 +281,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template) {
|
public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
|
||||||
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
|
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
|
||||||
|
|
||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
// combine all interfaces that match template
|
// combine all interfaces that match template
|
||||||
final NetworkStatsHistory combined = new NetworkStatsHistory(
|
final NetworkStatsHistory combined = new NetworkStatsHistory(
|
||||||
mSettings.getNetworkBucketDuration(), estimateNetworkBuckets());
|
mSettings.getNetworkBucketDuration(), estimateNetworkBuckets(), fields);
|
||||||
for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
|
for (NetworkIdentitySet ident : mNetworkStats.keySet()) {
|
||||||
if (templateMatches(template, ident)) {
|
if (templateMatches(template, ident)) {
|
||||||
final NetworkStatsHistory history = mNetworkStats.get(ident);
|
final NetworkStatsHistory history = mNetworkStats.get(ident);
|
||||||
@@ -302,7 +301,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkStatsHistory getHistoryForUid(NetworkTemplate template, int uid, int tag) {
|
public NetworkStatsHistory getHistoryForUid(
|
||||||
|
NetworkTemplate template, int uid, int tag, int fields) {
|
||||||
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
|
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
|
||||||
|
|
||||||
synchronized (mStatsLock) {
|
synchronized (mStatsLock) {
|
||||||
@@ -311,7 +311,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
|
|
||||||
// combine all interfaces that match template
|
// combine all interfaces that match template
|
||||||
final NetworkStatsHistory combined = new NetworkStatsHistory(
|
final NetworkStatsHistory combined = new NetworkStatsHistory(
|
||||||
mSettings.getUidBucketDuration(), estimateUidBuckets());
|
mSettings.getUidBucketDuration(), estimateUidBuckets(), fields);
|
||||||
for (NetworkIdentitySet ident : mUidStats.keySet()) {
|
for (NetworkIdentitySet ident : mUidStats.keySet()) {
|
||||||
if (templateMatches(template, ident)) {
|
if (templateMatches(template, ident)) {
|
||||||
final NetworkStatsHistory history = mUidStats.get(ident).get(packed);
|
final NetworkStatsHistory history = mUidStats.get(ident).get(packed);
|
||||||
@@ -596,7 +596,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
|
|
||||||
// decide if enough has changed to trigger persist
|
// decide if enough has changed to trigger persist
|
||||||
final NetworkStats persistDelta = computeStatsDelta(
|
final NetworkStats persistDelta = computeStatsDelta(
|
||||||
mLastPersistNetworkSnapshot, networkSnapshot);
|
mLastPersistNetworkSnapshot, networkSnapshot, true);
|
||||||
final long persistThreshold = mSettings.getPersistThreshold();
|
final long persistThreshold = mSettings.getPersistThreshold();
|
||||||
|
|
||||||
NetworkStats.Entry entry = null;
|
NetworkStats.Entry entry = null;
|
||||||
@@ -626,7 +626,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
private void performNetworkPollLocked(NetworkStats networkSnapshot, long currentTime) {
|
private void performNetworkPollLocked(NetworkStats networkSnapshot, long currentTime) {
|
||||||
final HashSet<String> unknownIface = Sets.newHashSet();
|
final HashSet<String> unknownIface = Sets.newHashSet();
|
||||||
|
|
||||||
final NetworkStats delta = computeStatsDelta(mLastNetworkSnapshot, networkSnapshot);
|
final NetworkStats delta = computeStatsDelta(mLastNetworkSnapshot, networkSnapshot, false);
|
||||||
final long timeStart = currentTime - delta.getElapsedRealtime();
|
final long timeStart = currentTime - delta.getElapsedRealtime();
|
||||||
|
|
||||||
NetworkStats.Entry entry = null;
|
NetworkStats.Entry entry = null;
|
||||||
@@ -661,9 +661,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
private void performUidPollLocked(NetworkStats uidSnapshot, long currentTime) {
|
private void performUidPollLocked(NetworkStats uidSnapshot, long currentTime) {
|
||||||
ensureUidStatsLoadedLocked();
|
ensureUidStatsLoadedLocked();
|
||||||
|
|
||||||
final NetworkStats delta = computeStatsDelta(mLastUidSnapshot, uidSnapshot);
|
final NetworkStats delta = computeStatsDelta(mLastUidSnapshot, uidSnapshot, false);
|
||||||
final NetworkStats operationsDelta = computeStatsDelta(
|
final NetworkStats operationsDelta = computeStatsDelta(
|
||||||
mLastOperationsSnapshot, mOperations);
|
mLastOperationsSnapshot, mOperations, false);
|
||||||
final long timeStart = currentTime - delta.getElapsedRealtime();
|
final long timeStart = currentTime - delta.getElapsedRealtime();
|
||||||
|
|
||||||
NetworkStats.Entry entry = null;
|
NetworkStats.Entry entry = null;
|
||||||
@@ -932,6 +932,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
out.flush();
|
out.flush();
|
||||||
mNetworkFile.finishWrite(fos);
|
mNetworkFile.finishWrite(fos);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
Slog.w(TAG, "problem writing stats: ", e);
|
||||||
if (fos != null) {
|
if (fos != null) {
|
||||||
mNetworkFile.failWrite(fos);
|
mNetworkFile.failWrite(fos);
|
||||||
}
|
}
|
||||||
@@ -978,6 +979,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
out.flush();
|
out.flush();
|
||||||
mUidFile.finishWrite(fos);
|
mUidFile.finishWrite(fos);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
Slog.w(TAG, "problem writing stats: ", e);
|
||||||
if (fos != null) {
|
if (fos != null) {
|
||||||
mUidFile.failWrite(fos);
|
mUidFile.failWrite(fos);
|
||||||
}
|
}
|
||||||
@@ -1052,15 +1054,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
private void generateRandomLocked() {
|
private void generateRandomLocked() {
|
||||||
long networkEnd = System.currentTimeMillis();
|
final long NET_END = System.currentTimeMillis();
|
||||||
long networkStart = networkEnd - mSettings.getNetworkMaxHistory();
|
final long NET_START = NET_END - mSettings.getNetworkMaxHistory();
|
||||||
long networkRx = 3 * GB_IN_BYTES;
|
final long NET_RX_BYTES = 3 * GB_IN_BYTES;
|
||||||
long networkTx = 2 * GB_IN_BYTES;
|
final long NET_RX_PACKETS = NET_RX_BYTES / 1024;
|
||||||
|
final long NET_TX_BYTES = 2 * GB_IN_BYTES;
|
||||||
|
final long NET_TX_PACKETS = NET_TX_BYTES / 1024;
|
||||||
|
|
||||||
long uidEnd = System.currentTimeMillis();
|
final long UID_END = System.currentTimeMillis();
|
||||||
long uidStart = uidEnd - mSettings.getUidMaxHistory();
|
final long UID_START = UID_END - mSettings.getUidMaxHistory();
|
||||||
long uidRx = 500 * MB_IN_BYTES;
|
final long UID_RX_BYTES = 500 * MB_IN_BYTES;
|
||||||
long uidTx = 100 * MB_IN_BYTES;
|
final long UID_RX_PACKETS = UID_RX_BYTES / 1024;
|
||||||
|
final long UID_TX_BYTES = 100 * MB_IN_BYTES;
|
||||||
|
final long UID_TX_PACKETS = UID_TX_BYTES / 1024;
|
||||||
|
final long UID_OPERATIONS = UID_RX_BYTES / 2048;
|
||||||
|
|
||||||
final List<ApplicationInfo> installedApps = mContext
|
final List<ApplicationInfo> installedApps = mContext
|
||||||
.getPackageManager().getInstalledApplications(0);
|
.getPackageManager().getInstalledApplications(0);
|
||||||
@@ -1068,13 +1075,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
mNetworkStats.clear();
|
mNetworkStats.clear();
|
||||||
mUidStats.clear();
|
mUidStats.clear();
|
||||||
for (NetworkIdentitySet ident : mActiveIfaces.values()) {
|
for (NetworkIdentitySet ident : mActiveIfaces.values()) {
|
||||||
findOrCreateNetworkStatsLocked(ident).generateRandom(
|
findOrCreateNetworkStatsLocked(ident).generateRandom(NET_START, NET_END, NET_RX_BYTES,
|
||||||
networkStart, networkEnd, networkRx, networkTx);
|
NET_RX_PACKETS, NET_TX_BYTES, NET_TX_PACKETS, 0L);
|
||||||
|
|
||||||
for (ApplicationInfo info : installedApps) {
|
for (ApplicationInfo info : installedApps) {
|
||||||
final int uid = info.uid;
|
final int uid = info.uid;
|
||||||
findOrCreateUidStatsLocked(ident, uid, TAG_NONE).generateRandom(
|
findOrCreateUidStatsLocked(ident, uid, TAG_NONE).generateRandom(UID_START, UID_END,
|
||||||
uidStart, uidEnd, uidRx, uidTx);
|
UID_RX_BYTES, UID_RX_PACKETS, UID_TX_BYTES, UID_TX_PACKETS, UID_OPERATIONS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1083,9 +1090,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||||||
* Return the delta between two {@link NetworkStats} snapshots, where {@code
|
* Return the delta between two {@link NetworkStats} snapshots, where {@code
|
||||||
* before} can be {@code null}.
|
* before} can be {@code null}.
|
||||||
*/
|
*/
|
||||||
private static NetworkStats computeStatsDelta(NetworkStats before, NetworkStats current) {
|
private static NetworkStats computeStatsDelta(
|
||||||
|
NetworkStats before, NetworkStats current, boolean collectStale) {
|
||||||
if (before != null) {
|
if (before != null) {
|
||||||
return current.subtractClamped(before);
|
return current.subtractClamped(before);
|
||||||
|
} else if (collectStale) {
|
||||||
|
// caller is okay collecting stale stats for first call.
|
||||||
|
return current;
|
||||||
} else {
|
} else {
|
||||||
// this is first snapshot; to prevent from double-counting we only
|
// this is first snapshot; to prevent from double-counting we only
|
||||||
// observe traffic occuring between known snapshots.
|
// observe traffic occuring between known snapshots.
|
||||||
|
|||||||
Reference in New Issue
Block a user