Skip to content

Commit 5a7bcf3

Browse files
committed
Move non-monotonic reporting to interface.
Report non-monotonic NetworkStats through an observer interface instead of throwing, since those events are still recoverable. Change-Id: Ic0749f4634b0ac05dbe90e95ca490957ec8b2f23
1 parent b8f90a0 commit 5a7bcf3

File tree

3 files changed

+73
-88
lines changed

3 files changed

+73
-88
lines changed

core/java/android/net/NetworkStats.java

Lines changed: 40 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
package android.net;
1818

19-
import static com.android.internal.util.Preconditions.checkNotNull;
20-
2119
import android.os.Parcel;
2220
import android.os.Parcelable;
2321
import android.os.SystemClock;
@@ -40,8 +38,6 @@
4038
* @hide
4139
*/
4240
public class NetworkStats implements Parcelable {
43-
private static final String TAG = "NetworkStats";
44-
4541
/** {@link #iface} value when interface details unavailable. */
4642
public static final String IFACE_ALL = null;
4743
/** {@link #uid} value when UID details unavailable. */
@@ -463,62 +459,64 @@ private Entry getTotal(Entry recycle, HashSet<String> limitIface, int limitUid)
463459
* between two snapshots in time. Assumes that statistics rows collect over
464460
* time, and that none of them have disappeared.
465461
*/
466-
public NetworkStats subtract(NetworkStats value) throws NonMonotonicException {
467-
return subtract(value, false);
462+
public NetworkStats subtract(NetworkStats right) {
463+
return subtract(this, right, null);
468464
}
469465

470466
/**
471-
* Subtract the given {@link NetworkStats}, effectively leaving the delta
467+
* Subtract the two given {@link NetworkStats} objects, returning the delta
472468
* between two snapshots in time. Assumes that statistics rows collect over
473469
* 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}.
470+
* <p>
471+
* If counters have rolled backwards, they are clamped to {@code 0} and
472+
* reported to the given {@link NonMonotonicObserver}.
477473
*/
478-
public NetworkStats subtract(NetworkStats value, boolean clampNonMonotonic)
479-
throws NonMonotonicException {
480-
final long deltaRealtime = this.elapsedRealtime - value.elapsedRealtime;
474+
public static NetworkStats subtract(
475+
NetworkStats left, NetworkStats right, NonMonotonicObserver observer) {
476+
long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime;
481477
if (deltaRealtime < 0) {
482-
throw new NonMonotonicException(this, value);
478+
if (observer != null) {
479+
observer.foundNonMonotonic(left, -1, right, -1);
480+
}
481+
deltaRealtime = 0;
483482
}
484483

485484
// result will have our rows, and elapsed time between snapshots
486485
final Entry entry = new Entry();
487-
final NetworkStats result = new NetworkStats(deltaRealtime, size);
488-
for (int i = 0; i < size; i++) {
489-
entry.iface = iface[i];
490-
entry.uid = uid[i];
491-
entry.set = set[i];
492-
entry.tag = tag[i];
486+
final NetworkStats result = new NetworkStats(deltaRealtime, left.size);
487+
for (int i = 0; i < left.size; i++) {
488+
entry.iface = left.iface[i];
489+
entry.uid = left.uid[i];
490+
entry.set = left.set[i];
491+
entry.tag = left.tag[i];
493492

494493
// find remote row that matches, and subtract
495-
final int j = value.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i);
494+
final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i);
496495
if (j == -1) {
497496
// newly appearing row, return entire value
498-
entry.rxBytes = rxBytes[i];
499-
entry.rxPackets = rxPackets[i];
500-
entry.txBytes = txBytes[i];
501-
entry.txPackets = txPackets[i];
502-
entry.operations = operations[i];
497+
entry.rxBytes = left.rxBytes[i];
498+
entry.rxPackets = left.rxPackets[i];
499+
entry.txBytes = left.txBytes[i];
500+
entry.txPackets = left.txPackets[i];
501+
entry.operations = left.operations[i];
503502
} else {
504503
// existing row, subtract remote value
505-
entry.rxBytes = rxBytes[i] - value.rxBytes[j];
506-
entry.rxPackets = rxPackets[i] - value.rxPackets[j];
507-
entry.txBytes = txBytes[i] - value.txBytes[j];
508-
entry.txPackets = txPackets[i] - value.txPackets[j];
509-
entry.operations = operations[i] - value.operations[j];
504+
entry.rxBytes = left.rxBytes[i] - right.rxBytes[j];
505+
entry.rxPackets = left.rxPackets[i] - right.rxPackets[j];
506+
entry.txBytes = left.txBytes[i] - right.txBytes[j];
507+
entry.txPackets = left.txPackets[i] - right.txPackets[j];
508+
entry.operations = left.operations[i] - right.operations[j];
510509

511510
if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0
512511
|| entry.txPackets < 0 || entry.operations < 0) {
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);
512+
if (observer != null) {
513+
observer.foundNonMonotonic(left, i, right, j);
521514
}
515+
entry.rxBytes = Math.max(entry.rxBytes, 0);
516+
entry.rxPackets = Math.max(entry.rxPackets, 0);
517+
entry.txBytes = Math.max(entry.txBytes, 0);
518+
entry.txPackets = Math.max(entry.txPackets, 0);
519+
entry.operations = Math.max(entry.operations, 0);
522520
}
523521
}
524522

@@ -665,22 +663,8 @@ public NetworkStats[] newArray(int size) {
665663
}
666664
};
667665

668-
public static class NonMonotonicException extends Exception {
669-
public final NetworkStats left;
670-
public final NetworkStats right;
671-
public final int leftIndex;
672-
public final int rightIndex;
673-
674-
public NonMonotonicException(NetworkStats left, NetworkStats right) {
675-
this(left, -1, right, -1);
676-
}
677-
678-
public NonMonotonicException(
679-
NetworkStats left, int leftIndex, NetworkStats right, int rightIndex) {
680-
this.left = checkNotNull(left, "missing left");
681-
this.right = checkNotNull(right, "missing right");
682-
this.leftIndex = leftIndex;
683-
this.rightIndex = rightIndex;
684-
}
666+
public interface NonMonotonicObserver {
667+
public void foundNonMonotonic(
668+
NetworkStats left, int leftIndex, NetworkStats right, int rightIndex);
685669
}
686670
}

core/java/android/net/TrafficStats.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import android.app.backup.BackupManager;
2121
import android.content.Context;
2222
import android.media.MediaPlayer;
23-
import android.net.NetworkStats.NonMonotonicException;
2423
import android.os.RemoteException;
2524
import android.os.ServiceManager;
2625

@@ -193,15 +192,12 @@ public static NetworkStats stopDataProfiling(Context context) {
193192
throw new IllegalStateException("not profiling data");
194193
}
195194

196-
try {
197-
// subtract starting values and return delta
198-
final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
199-
final NetworkStats profilingDelta = profilingStop.subtract(sActiveProfilingStart);
200-
sActiveProfilingStart = null;
201-
return profilingDelta;
202-
} catch (NonMonotonicException e) {
203-
throw new RuntimeException(e);
204-
}
195+
// subtract starting values and return delta
196+
final NetworkStats profilingStop = getDataLayerSnapshotForUid(context);
197+
final NetworkStats profilingDelta = NetworkStats.subtract(
198+
profilingStop, sActiveProfilingStart, null);
199+
sActiveProfilingStart = null;
200+
return profilingDelta;
205201
}
206202
}
207203

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

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
import android.net.NetworkInfo;
7272
import android.net.NetworkState;
7373
import android.net.NetworkStats;
74-
import android.net.NetworkStats.NonMonotonicException;
74+
import android.net.NetworkStats.NonMonotonicObserver;
7575
import android.net.NetworkStatsHistory;
7676
import android.net.NetworkTemplate;
7777
import android.os.Binder;
@@ -1551,34 +1551,39 @@ private void generateRandomLocked(String[] args) {
15511551
}
15521552
}
15531553

1554+
private StatsObserver mStatsObserver = new StatsObserver();
1555+
1556+
private class StatsObserver implements NonMonotonicObserver {
1557+
private String mCurrentType;
1558+
1559+
public void setCurrentType(String type) {
1560+
mCurrentType = type;
1561+
}
1562+
1563+
/** {@inheritDoc} */
1564+
public void foundNonMonotonic(
1565+
NetworkStats left, int leftIndex, NetworkStats right, int rightIndex) {
1566+
Log.w(TAG, "found non-monotonic values; saving to dropbox");
1567+
1568+
// record error for debugging
1569+
final StringBuilder builder = new StringBuilder();
1570+
builder.append("found non-monotonic " + mCurrentType + " values at left[" + leftIndex
1571+
+ "] - right[" + rightIndex + "]\n");
1572+
builder.append("left=").append(left).append('\n');
1573+
builder.append("right=").append(right).append('\n');
1574+
mDropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
1575+
}
1576+
}
1577+
15541578
/**
15551579
* Return the delta between two {@link NetworkStats} snapshots, where {@code
15561580
* before} can be {@code null}.
15571581
*/
15581582
private NetworkStats computeStatsDelta(
15591583
NetworkStats before, NetworkStats current, boolean collectStale, String type) {
15601584
if (before != null) {
1561-
try {
1562-
return current.subtract(before, false);
1563-
} catch (NonMonotonicException e) {
1564-
Log.w(TAG, "found non-monotonic values; saving to dropbox");
1565-
1566-
// record error for debugging
1567-
final StringBuilder builder = new StringBuilder();
1568-
builder.append("found non-monotonic " + type + " values at left[" + e.leftIndex
1569-
+ "] - right[" + e.rightIndex + "]\n");
1570-
builder.append("left=").append(e.left).append('\n');
1571-
builder.append("right=").append(e.right).append('\n');
1572-
mDropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
1573-
1574-
try {
1575-
// return clamped delta to help recover
1576-
return current.subtract(before, true);
1577-
} catch (NonMonotonicException e1) {
1578-
Log.wtf(TAG, "found non-monotonic values; returning empty delta", e1);
1579-
return new NetworkStats(0L, 10);
1580-
}
1581-
}
1585+
mStatsObserver.setCurrentType(type);
1586+
return NetworkStats.subtract(current, before, mStatsObserver);
15821587
} else if (collectStale) {
15831588
// caller is okay collecting stale stats for first call.
15841589
return current;

0 commit comments

Comments
 (0)