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
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index f6e627c..e8f60b4 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -16,8 +16,6 @@
package android.net;
-import static com.android.internal.util.Preconditions.checkNotNull;
-
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -40,8 +38,6 @@
* @hide
*/
public class NetworkStats implements Parcelable {
- private static final String TAG = "NetworkStats";
-
/** {@link #iface} value when interface details unavailable. */
public static final String IFACE_ALL = null;
/** {@link #uid} value when UID details unavailable. */
@@ -463,62 +459,64 @@
* between two snapshots in time. Assumes that statistics rows collect over
* time, and that none of them have disappeared.
*/
- public NetworkStats subtract(NetworkStats value) throws NonMonotonicException {
- return subtract(value, false);
+ public NetworkStats subtract(NetworkStats right) {
+ return subtract(this, right, null);
}
/**
- * Subtract the given {@link NetworkStats}, effectively leaving the delta
+ * Subtract the two given {@link NetworkStats} objects, returning the delta
* between two snapshots in time. Assumes that statistics rows collect over
* time, and that none of them have disappeared.
- *
- * @param clampNonMonotonic When non-monotonic stats are found, just clamp
- * to 0 instead of throwing {@link NonMonotonicException}.
+ * <p>
+ * If counters have rolled backwards, they are clamped to {@code 0} and
+ * reported to the given {@link NonMonotonicObserver}.
*/
- public NetworkStats subtract(NetworkStats value, boolean clampNonMonotonic)
- throws NonMonotonicException {
- final long deltaRealtime = this.elapsedRealtime - value.elapsedRealtime;
+ public static NetworkStats subtract(
+ NetworkStats left, NetworkStats right, NonMonotonicObserver observer) {
+ long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime;
if (deltaRealtime < 0) {
- throw new NonMonotonicException(this, value);
+ if (observer != null) {
+ observer.foundNonMonotonic(left, -1, right, -1);
+ }
+ deltaRealtime = 0;
}
// result will have our rows, and elapsed time between snapshots
final Entry entry = new Entry();
- final NetworkStats result = new NetworkStats(deltaRealtime, size);
- for (int i = 0; i < size; i++) {
- entry.iface = iface[i];
- entry.uid = uid[i];
- entry.set = set[i];
- entry.tag = tag[i];
+ final NetworkStats result = new NetworkStats(deltaRealtime, left.size);
+ for (int i = 0; i < left.size; i++) {
+ entry.iface = left.iface[i];
+ entry.uid = left.uid[i];
+ entry.set = left.set[i];
+ entry.tag = left.tag[i];
// find remote row that matches, and subtract
- final int j = value.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i);
+ final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i);
if (j == -1) {
// newly appearing row, return entire value
- entry.rxBytes = rxBytes[i];
- entry.rxPackets = rxPackets[i];
- entry.txBytes = txBytes[i];
- entry.txPackets = txPackets[i];
- entry.operations = operations[i];
+ entry.rxBytes = left.rxBytes[i];
+ entry.rxPackets = left.rxPackets[i];
+ entry.txBytes = left.txBytes[i];
+ entry.txPackets = left.txPackets[i];
+ entry.operations = left.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];
+ entry.rxBytes = left.rxBytes[i] - right.rxBytes[j];
+ entry.rxPackets = left.rxPackets[i] - right.rxPackets[j];
+ entry.txBytes = left.txBytes[i] - right.txBytes[j];
+ entry.txPackets = left.txPackets[i] - right.txPackets[j];
+ entry.operations = left.operations[i] - right.operations[j];
if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0
|| entry.txPackets < 0 || entry.operations < 0) {
- if (clampNonMonotonic) {
- entry.rxBytes = Math.max(entry.rxBytes, 0);
- entry.rxPackets = Math.max(entry.rxPackets, 0);
- entry.txBytes = Math.max(entry.txBytes, 0);
- entry.txPackets = Math.max(entry.txPackets, 0);
- entry.operations = Math.max(entry.operations, 0);
- } else {
- throw new NonMonotonicException(this, i, value, j);
+ if (observer != null) {
+ observer.foundNonMonotonic(left, i, right, j);
}
+ entry.rxBytes = Math.max(entry.rxBytes, 0);
+ entry.rxPackets = Math.max(entry.rxPackets, 0);
+ entry.txBytes = Math.max(entry.txBytes, 0);
+ entry.txPackets = Math.max(entry.txPackets, 0);
+ entry.operations = Math.max(entry.operations, 0);
}
}
@@ -665,22 +663,8 @@
}
};
- public static class NonMonotonicException extends Exception {
- public final NetworkStats left;
- public final NetworkStats right;
- public final int leftIndex;
- public final int rightIndex;
-
- public NonMonotonicException(NetworkStats left, NetworkStats right) {
- this(left, -1, right, -1);
- }
-
- public NonMonotonicException(
- NetworkStats left, int leftIndex, NetworkStats right, int rightIndex) {
- this.left = checkNotNull(left, "missing left");
- this.right = checkNotNull(right, "missing right");
- this.leftIndex = leftIndex;
- this.rightIndex = rightIndex;
- }
+ public interface NonMonotonicObserver {
+ public void foundNonMonotonic(
+ NetworkStats left, int leftIndex, NetworkStats right, int rightIndex);
}
}