Skip to content

Commit 51c00a5

Browse files
jsharkeyAndroid (Google) Code Review
authored andcommitted
Merge "Clamp non-monotonic stats instead of dropping." into ics-mr1
2 parents 992e77a + d4ef8c8 commit 51c00a5

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

core/java/android/net/NetworkStats.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,19 @@ private Entry getTotal(Entry recycle, HashSet<String> limitIface, int limitUid)
464464
* time, and that none of them have disappeared.
465465
*/
466466
public NetworkStats subtract(NetworkStats value) throws NonMonotonicException {
467+
return subtract(value, false);
468+
}
469+
470+
/**
471+
* Subtract the given {@link NetworkStats}, effectively leaving the delta
472+
* between two snapshots in time. Assumes that statistics rows collect over
473+
* time, and that none of them have disappeared.
474+
*
475+
* @param clampNonMonotonic When non-monotonic stats are found, just clamp
476+
* to 0 instead of throwing {@link NonMonotonicException}.
477+
*/
478+
public NetworkStats subtract(NetworkStats value, boolean clampNonMonotonic)
479+
throws NonMonotonicException {
467480
final long deltaRealtime = this.elapsedRealtime - value.elapsedRealtime;
468481
if (deltaRealtime < 0) {
469482
throw new NonMonotonicException(this, value);
@@ -497,7 +510,15 @@ public NetworkStats subtract(NetworkStats value) throws NonMonotonicException {
497510

498511
if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0
499512
|| entry.txPackets < 0 || entry.operations < 0) {
500-
throw new NonMonotonicException(this, i, value, j);
513+
if (clampNonMonotonic) {
514+
entry.rxBytes = Math.max(entry.rxBytes, 0);
515+
entry.rxPackets = Math.max(entry.rxPackets, 0);
516+
entry.txBytes = Math.max(entry.txBytes, 0);
517+
entry.txPackets = Math.max(entry.txPackets, 0);
518+
entry.operations = Math.max(entry.operations, 0);
519+
} else {
520+
throw new NonMonotonicException(this, i, value, j);
521+
}
501522
}
502523
}
503524

services/java/com/android/server/net/NetworkStatsService.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -806,9 +806,7 @@ private void performPollLocked(int flags) {
806806
final NetworkStats networkDevSnapshot;
807807
try {
808808
// collect any tethering stats
809-
final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs();
810-
final NetworkStats tetherSnapshot = mNetworkManager.getNetworkStatsTethering(
811-
tetheredIfacePairs);
809+
final NetworkStats tetherSnapshot = getNetworkStatsTethering();
812810

813811
// record uid stats, folding in tethering stats
814812
uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
@@ -1505,7 +1503,7 @@ private NetworkStats computeStatsDelta(
15051503
NetworkStats before, NetworkStats current, boolean collectStale, String type) {
15061504
if (before != null) {
15071505
try {
1508-
return current.subtract(before);
1506+
return current.subtract(before, false);
15091507
} catch (NonMonotonicException e) {
15101508
Log.w(TAG, "found non-monotonic values; saving to dropbox");
15111509

@@ -1517,8 +1515,13 @@ private NetworkStats computeStatsDelta(
15171515
builder.append("right=").append(e.right).append('\n');
15181516
mDropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
15191517

1520-
// return empty delta to avoid recording broken stats
1521-
return new NetworkStats(0L, 10);
1518+
try {
1519+
// return clamped delta to help recover
1520+
return current.subtract(before, true);
1521+
} catch (NonMonotonicException e1) {
1522+
Log.wtf(TAG, "found non-monotonic values; returning empty delta", e1);
1523+
return new NetworkStats(0L, 10);
1524+
}
15221525
}
15231526
} else if (collectStale) {
15241527
// caller is okay collecting stale stats for first call.
@@ -1530,6 +1533,20 @@ private NetworkStats computeStatsDelta(
15301533
}
15311534
}
15321535

1536+
/**
1537+
* Return snapshot of current tethering statistics. Will return empty
1538+
* {@link NetworkStats} if any problems are encountered.
1539+
*/
1540+
private NetworkStats getNetworkStatsTethering() throws RemoteException {
1541+
try {
1542+
final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs();
1543+
return mNetworkManager.getNetworkStatsTethering(tetheredIfacePairs);
1544+
} catch (IllegalStateException e) {
1545+
Log.wtf(TAG, "problem reading network stats", e);
1546+
return new NetworkStats(0L, 10);
1547+
}
1548+
}
1549+
15331550
private static NetworkStats computeNetworkXtSnapshotFromUid(NetworkStats uidSnapshot) {
15341551
return uidSnapshot.groupedByIface();
15351552
}

0 commit comments

Comments
 (0)