Hide NetworkStatsHistory internals.

Instead of exposing internal storage details, offer getValues()
accessor which populates values into a recycled structure.

Change-Id: I5228d7099a8f61b2018a435a813435a67dae49b4
This commit is contained in:
Jeff Sharkey
2011-07-12 13:57:00 -07:00
parent 21b9c72ad7
commit 188480b216
3 changed files with 164 additions and 123 deletions

View File

@@ -43,31 +43,19 @@ public class NetworkStats implements Parcelable {
/** {@link #tag} value for without tag. */ /** {@link #tag} value for without tag. */
public static final int TAG_NONE = 0; public static final int TAG_NONE = 0;
// TODO: move public fields to Entry accessors, then undeprecate
// TODO: refactor rx/tx to rxBytes/txBytes
/** /**
* {@link SystemClock#elapsedRealtime()} timestamp when this data was * {@link SystemClock#elapsedRealtime()} timestamp when this data was
* generated. * generated.
*/ */
@Deprecated private final long elapsedRealtime;
public final long elapsedRealtime; private int size;
@Deprecated private String[] iface;
public int size; private int[] uid;
@Deprecated private int[] tag;
public String[] iface; private long[] rxBytes;
@Deprecated private long[] rxPackets;
public int[] uid; private long[] txBytes;
@Deprecated private long[] txPackets;
public int[] tag;
@Deprecated
public long[] rx;
@Deprecated
public long[] rxPackets;
@Deprecated
public long[] tx;
@Deprecated
public long[] txPackets;
public static class Entry { public static class Entry {
public String iface; public String iface;
@@ -77,6 +65,20 @@ public class NetworkStats implements Parcelable {
public long rxPackets; public long rxPackets;
public long txBytes; public long txBytes;
public long txPackets; public long txPackets;
public Entry() {
}
public Entry(String iface, int uid, int tag, long rxBytes, long rxPackets, long txBytes,
long txPackets) {
this.iface = iface;
this.uid = uid;
this.tag = tag;
this.rxBytes = rxBytes;
this.rxPackets = rxPackets;
this.txBytes = txBytes;
this.txPackets = txPackets;
}
} }
public NetworkStats(long elapsedRealtime, int initialSize) { public NetworkStats(long elapsedRealtime, int initialSize) {
@@ -85,9 +87,9 @@ public class NetworkStats implements Parcelable {
this.iface = new String[initialSize]; this.iface = new String[initialSize];
this.uid = new int[initialSize]; this.uid = new int[initialSize];
this.tag = new int[initialSize]; this.tag = new int[initialSize];
this.rx = new long[initialSize]; this.rxBytes = new long[initialSize];
this.rxPackets = new long[initialSize]; this.rxPackets = new long[initialSize];
this.tx = new long[initialSize]; this.txBytes = new long[initialSize];
this.txPackets = new long[initialSize]; this.txPackets = new long[initialSize];
} }
@@ -97,23 +99,15 @@ public class NetworkStats implements Parcelable {
iface = parcel.createStringArray(); iface = parcel.createStringArray();
uid = parcel.createIntArray(); uid = parcel.createIntArray();
tag = parcel.createIntArray(); tag = parcel.createIntArray();
rx = parcel.createLongArray(); rxBytes = parcel.createLongArray();
rxPackets = parcel.createLongArray(); rxPackets = parcel.createLongArray();
tx = parcel.createLongArray(); txBytes = parcel.createLongArray();
txPackets = parcel.createLongArray(); txPackets = parcel.createLongArray();
} }
/** public NetworkStats addValues(String iface, int uid, int tag, long rxBytes, long rxPackets,
* Add new stats entry with given values. long txBytes, long txPackets) {
*/ return addValues(new Entry(iface, uid, tag, rxBytes, rxPackets, txBytes, txPackets));
public NetworkStats addEntry(String iface, int uid, int tag, long rx, long tx) {
final Entry entry = new Entry();
entry.iface = iface;
entry.uid = uid;
entry.tag = tag;
entry.rxBytes = rx;
entry.txBytes = tx;
return addValues(entry);
} }
/** /**
@@ -126,18 +120,18 @@ public class NetworkStats implements Parcelable {
iface = Arrays.copyOf(iface, newLength); iface = Arrays.copyOf(iface, newLength);
uid = Arrays.copyOf(uid, newLength); uid = Arrays.copyOf(uid, newLength);
tag = Arrays.copyOf(tag, newLength); tag = Arrays.copyOf(tag, newLength);
rx = Arrays.copyOf(rx, newLength); rxBytes = Arrays.copyOf(rxBytes, newLength);
rxPackets = Arrays.copyOf(rxPackets, newLength); rxPackets = Arrays.copyOf(rxPackets, newLength);
tx = Arrays.copyOf(tx, newLength); txBytes = Arrays.copyOf(txBytes, newLength);
txPackets = Arrays.copyOf(txPackets, newLength); txPackets = Arrays.copyOf(txPackets, newLength);
} }
iface[size] = entry.iface; iface[size] = entry.iface;
uid[size] = entry.uid; uid[size] = entry.uid;
tag[size] = entry.tag; tag[size] = entry.tag;
rx[size] = entry.rxBytes; rxBytes[size] = entry.rxBytes;
rxPackets[size] = entry.rxPackets; rxPackets[size] = entry.rxPackets;
tx[size] = entry.txBytes; txBytes[size] = entry.txBytes;
txPackets[size] = entry.txPackets; txPackets[size] = entry.txPackets;
size++; size++;
@@ -152,9 +146,9 @@ public class NetworkStats implements Parcelable {
entry.iface = iface[i]; entry.iface = iface[i];
entry.uid = uid[i]; entry.uid = uid[i];
entry.tag = tag[i]; entry.tag = tag[i];
entry.rxBytes = rx[i]; entry.rxBytes = rxBytes[i];
entry.rxPackets = rxPackets[i]; entry.rxPackets = rxPackets[i];
entry.txBytes = tx[i]; entry.txBytes = txBytes[i];
entry.txPackets = txPackets[i]; entry.txPackets = txPackets[i];
return entry; return entry;
} }
@@ -167,20 +161,31 @@ public class NetworkStats implements Parcelable {
return size; return size;
} }
// @VisibleForTesting
public int internalSize() {
return iface.length;
}
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));
}
/** /**
* Combine given values with an existing row, or create a new row if * Combine given values with an existing row, or create a new row if
* {@link #findIndex(String, int, int)} is unable to find match. Can also be * {@link #findIndex(String, int, int)} is unable to find match. Can also be
* used to subtract values from existing rows. * used to subtract values from existing rows.
*/ */
public NetworkStats combineEntry(String iface, int uid, int tag, long rx, long tx) { public NetworkStats combineValues(Entry entry) {
// TODO: extent to accept rxPackets/txPackets final int i = findIndex(entry.iface, entry.uid, entry.tag);
final int i = findIndex(iface, uid, tag);
if (i == -1) { if (i == -1) {
// only create new entry when positive contribution // only create new entry when positive contribution
addEntry(iface, uid, tag, rx, tx); addValues(entry);
} else { } else {
this.rx[i] += rx; rxBytes[i] += entry.rxBytes;
this.tx[i] += tx; rxPackets[i] += entry.rxPackets;
txBytes[i] += entry.txBytes;
txPackets[i] += entry.txPackets;
} }
return this; return this;
} }
@@ -280,15 +285,15 @@ public class NetworkStats implements Parcelable {
final int j = value.findIndex(entry.iface, entry.uid, entry.tag); final int j = value.findIndex(entry.iface, entry.uid, entry.tag);
if (j == -1) { if (j == -1) {
// newly appearing row, return entire value // newly appearing row, return entire value
entry.rxBytes = rx[i]; entry.rxBytes = rxBytes[i];
entry.rxPackets = rxPackets[i]; entry.rxPackets = rxPackets[i];
entry.txBytes = tx[i]; entry.txBytes = txBytes[i];
entry.txPackets = txPackets[i]; entry.txPackets = txPackets[i];
} else { } else {
// existing row, subtract remote value // existing row, subtract remote value
entry.rxBytes = rx[i] - value.rx[j]; entry.rxBytes = rxBytes[i] - value.rxBytes[j];
entry.rxPackets = rxPackets[i] - value.rxPackets[j]; entry.rxPackets = rxPackets[i] - value.rxPackets[j];
entry.txBytes = tx[i] - value.tx[j]; entry.txBytes = txBytes[i] - value.txBytes[j];
entry.txPackets = txPackets[i] - value.txPackets[j]; entry.txPackets = txPackets[i] - value.txPackets[j];
if (enforceMonotonic if (enforceMonotonic
&& (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 && (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0
@@ -321,9 +326,9 @@ public class NetworkStats implements Parcelable {
pw.print(" iface="); pw.print(iface[i]); pw.print(" iface="); pw.print(iface[i]);
pw.print(" uid="); pw.print(uid[i]); pw.print(" uid="); pw.print(uid[i]);
pw.print(" tag="); pw.print(tag[i]); pw.print(" tag="); pw.print(tag[i]);
pw.print(" rxBytes="); pw.print(rx[i]); pw.print(" rxBytes="); pw.print(rxBytes[i]);
pw.print(" rxPackets="); pw.print(rxPackets[i]); pw.print(" rxPackets="); pw.print(rxPackets[i]);
pw.print(" txBytes="); pw.print(tx[i]); pw.print(" txBytes="); pw.print(txBytes[i]);
pw.print(" txPackets="); pw.println(txPackets[i]); pw.print(" txPackets="); pw.println(txPackets[i]);
} }
} }
@@ -347,9 +352,9 @@ public class NetworkStats implements Parcelable {
dest.writeStringArray(iface); dest.writeStringArray(iface);
dest.writeIntArray(uid); dest.writeIntArray(uid);
dest.writeIntArray(tag); dest.writeIntArray(tag);
dest.writeLongArray(rx); dest.writeLongArray(rxBytes);
dest.writeLongArray(rxPackets); dest.writeLongArray(rxPackets);
dest.writeLongArray(tx); dest.writeLongArray(txBytes);
dest.writeLongArray(txPackets); dest.writeLongArray(txPackets);
} }

View File

@@ -43,13 +43,20 @@ public class NetworkStatsHistory implements Parcelable {
private static final int VERSION_INIT = 1; private static final int VERSION_INIT = 1;
// TODO: teach about varint encoding to use less disk space // TODO: teach about varint encoding to use less disk space
// TODO: extend to record rxPackets/txPackets
public final long bucketDuration; private final long bucketDuration;
private int bucketCount;
private long[] bucketStart;
private long[] rxBytes;
private long[] txBytes;
public int bucketCount; public static class Entry {
public long[] bucketStart; public long bucketStart;
public long[] rx; public long bucketDuration;
public long[] tx; public long rxBytes;
public long txBytes;
}
public NetworkStatsHistory(long bucketDuration) { public NetworkStatsHistory(long bucketDuration) {
this(bucketDuration, 10); this(bucketDuration, 10);
@@ -58,16 +65,16 @@ public class NetworkStatsHistory implements Parcelable {
public NetworkStatsHistory(long bucketDuration, int initialSize) { public NetworkStatsHistory(long bucketDuration, int initialSize) {
this.bucketDuration = bucketDuration; this.bucketDuration = bucketDuration;
bucketStart = new long[initialSize]; bucketStart = new long[initialSize];
rx = new long[initialSize]; rxBytes = new long[initialSize];
tx = new long[initialSize]; txBytes = new long[initialSize];
bucketCount = 0; bucketCount = 0;
} }
public NetworkStatsHistory(Parcel in) { public NetworkStatsHistory(Parcel in) {
bucketDuration = in.readLong(); bucketDuration = in.readLong();
bucketStart = readLongArray(in); bucketStart = readLongArray(in);
rx = in.createLongArray(); rxBytes = in.createLongArray();
tx = in.createLongArray(); txBytes = in.createLongArray();
bucketCount = bucketStart.length; bucketCount = bucketStart.length;
} }
@@ -75,8 +82,8 @@ public class NetworkStatsHistory implements Parcelable {
public void writeToParcel(Parcel out, int flags) { public void writeToParcel(Parcel out, int flags) {
out.writeLong(bucketDuration); out.writeLong(bucketDuration);
writeLongArray(out, bucketStart, bucketCount); writeLongArray(out, bucketStart, bucketCount);
writeLongArray(out, rx, bucketCount); writeLongArray(out, rxBytes, bucketCount);
writeLongArray(out, tx, bucketCount); writeLongArray(out, txBytes, bucketCount);
} }
public NetworkStatsHistory(DataInputStream in) throws IOException { public NetworkStatsHistory(DataInputStream in) throws IOException {
@@ -85,8 +92,8 @@ public class NetworkStatsHistory implements Parcelable {
case VERSION_INIT: { case VERSION_INIT: {
bucketDuration = in.readLong(); bucketDuration = in.readLong();
bucketStart = readLongArray(in); bucketStart = readLongArray(in);
rx = readLongArray(in); rxBytes = readLongArray(in);
tx = readLongArray(in); txBytes = readLongArray(in);
bucketCount = bucketStart.length; bucketCount = bucketStart.length;
break; break;
} }
@@ -100,8 +107,8 @@ public class NetworkStatsHistory implements Parcelable {
out.writeInt(VERSION_INIT); out.writeInt(VERSION_INIT);
out.writeLong(bucketDuration); out.writeLong(bucketDuration);
writeLongArray(out, bucketStart, bucketCount); writeLongArray(out, bucketStart, bucketCount);
writeLongArray(out, rx, bucketCount); writeLongArray(out, rxBytes, bucketCount);
writeLongArray(out, tx, bucketCount); writeLongArray(out, txBytes, bucketCount);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@@ -109,6 +116,26 @@ public class NetworkStatsHistory implements Parcelable {
return 0; return 0;
} }
public int size() {
return bucketCount;
}
public long getBucketDuration() {
return bucketDuration;
}
/**
* Return specific stats entry.
*/
public Entry getValues(int i, Entry recycle) {
final Entry entry = recycle != null ? recycle : new Entry();
entry.bucketStart = bucketStart[i];
entry.bucketDuration = bucketDuration;
entry.rxBytes = rxBytes[i];
entry.txBytes = txBytes[i];
return entry;
}
/** /**
* Record that data traffic occurred in the given time range. Will * Record that data traffic occurred in the given time range. Will
* distribute across internal buckets, creating new buckets as needed. * distribute across internal buckets, creating new buckets as needed.
@@ -135,8 +162,8 @@ public class NetworkStatsHistory implements Parcelable {
final long overlap = Math.min(curEnd, end) - Math.max(curStart, start); final long overlap = Math.min(curEnd, end) - Math.max(curStart, start);
if (overlap > 0) { if (overlap > 0) {
this.rx[i] += rx * overlap / duration; this.rxBytes[i] += rx * overlap / duration;
this.tx[i] += tx * overlap / duration; this.txBytes[i] += tx * overlap / duration;
} }
} }
} }
@@ -149,7 +176,7 @@ public class NetworkStatsHistory implements Parcelable {
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;
recordData(start, end, input.rx[i], input.tx[i]); recordData(start, end, input.rxBytes[i], input.txBytes[i]);
} }
} }
@@ -179,8 +206,8 @@ 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);
rx = Arrays.copyOf(rx, newLength); rxBytes = Arrays.copyOf(rxBytes, newLength);
tx = Arrays.copyOf(tx, newLength); txBytes = Arrays.copyOf(txBytes, newLength);
} }
// create gap when inserting bucket in middle // create gap when inserting bucket in middle
@@ -189,13 +216,13 @@ 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(rx, index, rx, dstPos, length); System.arraycopy(rxBytes, index, rxBytes, dstPos, length);
System.arraycopy(tx, index, tx, dstPos, length); System.arraycopy(txBytes, index, txBytes, dstPos, length);
} }
bucketStart[index] = start; bucketStart[index] = start;
rx[index] = 0; rxBytes[index] = 0;
tx[index] = 0; txBytes[index] = 0;
bucketCount++; bucketCount++;
} }
@@ -216,8 +243,8 @@ 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);
rx = Arrays.copyOfRange(rx, i, length); rxBytes = Arrays.copyOfRange(rxBytes, i, length);
tx = Arrays.copyOfRange(tx, i, length); txBytes = Arrays.copyOfRange(txBytes, i, length);
bucketCount -= i; bucketCount -= i;
} }
} }
@@ -241,8 +268,8 @@ public class NetworkStatsHistory implements Parcelable {
final long overlap = Math.min(curEnd, end) - Math.max(curStart, start); final long overlap = Math.min(curEnd, end) - Math.max(curStart, start);
if (overlap > 0) { if (overlap > 0) {
rx += this.rx[i] * overlap / bucketDuration; rx += this.rxBytes[i] * overlap / bucketDuration;
tx += this.tx[i] * overlap / bucketDuration; tx += this.txBytes[i] * overlap / bucketDuration;
} }
} }
@@ -292,8 +319,8 @@ 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(" rx="); pw.print(rx[i]); pw.print(" rxBytes="); pw.print(rxBytes[i]);
pw.print(" tx="); pw.println(tx[i]); pw.print(" txBytes="); pw.println(txBytes[i]);
} }
} }

View File

@@ -313,22 +313,26 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
synchronized (mStatsLock) { synchronized (mStatsLock) {
long rx = 0; final NetworkStats stats = new NetworkStats(end - start, 1);
long tx = 0; final NetworkStats.Entry entry = new NetworkStats.Entry();
long[] networkTotal = new long[2]; long[] total = new long[2];
// combine total from all interfaces that match template // combine total from all interfaces that match template
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);
networkTotal = history.getTotalData(start, end, networkTotal); total = history.getTotalData(start, end, total);
rx += networkTotal[0];
tx += networkTotal[1]; entry.iface = IFACE_ALL;
entry.uid = UID_ALL;
entry.tag = TAG_NONE;
entry.rxBytes = total[0];
entry.txBytes = total[1];
stats.combineValues(entry);
} }
} }
final NetworkStats stats = new NetworkStats(end - start, 1);
stats.addEntry(IFACE_ALL, UID_ALL, TAG_NONE, rx, tx);
return stats; return stats;
} }
} }
@@ -342,6 +346,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
ensureUidStatsLoadedLocked(); ensureUidStatsLoadedLocked();
final NetworkStats stats = new NetworkStats(end - start, 24); final NetworkStats stats = new NetworkStats(end - start, 24);
final NetworkStats.Entry entry = new NetworkStats.Entry();
long[] total = new long[2]; long[] total = new long[2];
for (NetworkIdentitySet ident : mUidStats.keySet()) { for (NetworkIdentitySet ident : mUidStats.keySet()) {
@@ -357,10 +362,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
if (tag == TAG_NONE || includeTags) { if (tag == TAG_NONE || includeTags) {
final NetworkStatsHistory history = uidStats.valueAt(i); final NetworkStatsHistory history = uidStats.valueAt(i);
total = history.getTotalData(start, end, total); total = history.getTotalData(start, end, total);
final long rx = total[0];
final long tx = total[1]; entry.iface = IFACE_ALL;
if (rx > 0 || tx > 0) { entry.uid = uid;
stats.combineEntry(IFACE_ALL, uid, tag, rx, tx); entry.tag = tag;
entry.rxBytes = total[0];
entry.txBytes = total[1];
if (entry.rxBytes > 0 || entry.txBytes > 0) {
stats.combineValues(entry);
} }
} }
} }
@@ -512,10 +522,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final NetworkStats persistDelta = computeStatsDelta( final NetworkStats persistDelta = computeStatsDelta(
mLastPersistNetworkSnapshot, networkSnapshot); mLastPersistNetworkSnapshot, networkSnapshot);
final long persistThreshold = mSettings.getPersistThreshold(); final long persistThreshold = mSettings.getPersistThreshold();
NetworkStats.Entry entry = null;
for (String iface : persistDelta.getUniqueIfaces()) { for (String iface : persistDelta.getUniqueIfaces()) {
final int index = persistDelta.findIndex(iface, UID_ALL, TAG_NONE); final int index = persistDelta.findIndex(iface, UID_ALL, TAG_NONE);
if (forcePersist || persistDelta.rx[index] > persistThreshold entry = persistDelta.getValues(index, entry);
|| persistDelta.tx[index] > persistThreshold) { if (forcePersist || entry.rxBytes > persistThreshold
|| entry.txBytes > persistThreshold) {
writeNetworkStatsLocked(); writeNetworkStatsLocked();
if (mUidStatsLoaded) { if (mUidStatsLoaded) {
writeUidStatsLocked(); writeUidStatsLocked();
@@ -538,20 +551,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final HashSet<String> unknownIface = Sets.newHashSet(); final HashSet<String> unknownIface = Sets.newHashSet();
final NetworkStats delta = computeStatsDelta(mLastNetworkSnapshot, networkSnapshot); final NetworkStats delta = computeStatsDelta(mLastNetworkSnapshot, networkSnapshot);
final long timeStart = currentTime - delta.elapsedRealtime; final long timeStart = currentTime - delta.getElapsedRealtime();
for (int i = 0; i < delta.size; i++) {
final String iface = delta.iface[i]; NetworkStats.Entry entry = null;
final NetworkIdentitySet ident = mActiveIfaces.get(iface); for (int i = 0; i < delta.size(); i++) {
entry = delta.getValues(i, entry);
final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
if (ident == null) { if (ident == null) {
unknownIface.add(iface); unknownIface.add(entry.iface);
continue; continue;
} }
final long rx = delta.rx[i];
final long tx = delta.tx[i];
final NetworkStatsHistory history = findOrCreateNetworkStatsLocked(ident); final NetworkStatsHistory history = findOrCreateNetworkStatsLocked(ident);
history.recordData(timeStart, currentTime, rx, tx); history.recordData(timeStart, currentTime, entry.rxBytes, entry.txBytes);
} }
// trim any history beyond max // trim any history beyond max
@@ -574,22 +586,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
ensureUidStatsLoadedLocked(); ensureUidStatsLoadedLocked();
final NetworkStats delta = computeStatsDelta(mLastUidSnapshot, uidSnapshot); final NetworkStats delta = computeStatsDelta(mLastUidSnapshot, uidSnapshot);
final long timeStart = currentTime - delta.elapsedRealtime; final long timeStart = currentTime - delta.getElapsedRealtime();
for (int i = 0; i < delta.size; i++) { NetworkStats.Entry entry = null;
final String iface = delta.iface[i]; for (int i = 0; i < delta.size(); i++) {
final NetworkIdentitySet ident = mActiveIfaces.get(iface); entry = delta.getValues(i, entry);
final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
if (ident == null) { if (ident == null) {
continue; continue;
} }
final int uid = delta.uid[i]; final NetworkStatsHistory history = findOrCreateUidStatsLocked(
final int tag = delta.tag[i]; ident, entry.uid, entry.tag);
final long rx = delta.rx[i]; history.recordData(timeStart, currentTime, entry.rxBytes, entry.txBytes);
final long tx = delta.tx[i];
final NetworkStatsHistory history = findOrCreateUidStatsLocked(ident, uid, tag);
history.recordData(timeStart, currentTime, rx, tx);
} }
// trim any history beyond max // trim any history beyond max
@@ -651,7 +660,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
NetworkStatsHistory updated = null; NetworkStatsHistory updated = null;
if (existing == null) { if (existing == null) {
updated = new NetworkStatsHistory(bucketDuration, 10); updated = new NetworkStatsHistory(bucketDuration, 10);
} else if (existing.bucketDuration != bucketDuration) { } else if (existing.getBucketDuration() != bucketDuration) {
updated = new NetworkStatsHistory( updated = new NetworkStatsHistory(
bucketDuration, estimateResizeBuckets(existing, bucketDuration)); bucketDuration, estimateResizeBuckets(existing, bucketDuration));
updated.recordEntireHistory(existing); updated.recordEntireHistory(existing);
@@ -683,7 +692,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
NetworkStatsHistory updated = null; NetworkStatsHistory updated = null;
if (existing == null) { if (existing == null) {
updated = new NetworkStatsHistory(bucketDuration, 10); updated = new NetworkStatsHistory(bucketDuration, 10);
} else if (existing.bucketDuration != bucketDuration) { } else if (existing.getBucketDuration() != bucketDuration) {
updated = new NetworkStatsHistory( updated = new NetworkStatsHistory(
bucketDuration, estimateResizeBuckets(existing, bucketDuration)); bucketDuration, estimateResizeBuckets(existing, bucketDuration));
updated.recordEntireHistory(existing); updated.recordEntireHistory(existing);
@@ -1003,7 +1012,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
private static int estimateResizeBuckets(NetworkStatsHistory existing, long newBucketDuration) { private static int estimateResizeBuckets(NetworkStatsHistory existing, long newBucketDuration) {
return (int) (existing.bucketCount * existing.bucketDuration / newBucketDuration); return (int) (existing.size() * existing.getBucketDuration() / newBucketDuration);
} }
// @VisibleForTesting // @VisibleForTesting