|
16 | 16 |
|
17 | 17 | package android.net; |
18 | 18 |
|
19 | | -import static com.android.internal.util.Preconditions.checkNotNull; |
20 | | - |
21 | 19 | import android.os.Parcel; |
22 | 20 | import android.os.Parcelable; |
23 | 21 | import android.os.SystemClock; |
|
40 | 38 | * @hide |
41 | 39 | */ |
42 | 40 | public class NetworkStats implements Parcelable { |
43 | | - private static final String TAG = "NetworkStats"; |
44 | | - |
45 | 41 | /** {@link #iface} value when interface details unavailable. */ |
46 | 42 | public static final String IFACE_ALL = null; |
47 | 43 | /** {@link #uid} value when UID details unavailable. */ |
@@ -463,62 +459,64 @@ private Entry getTotal(Entry recycle, HashSet<String> limitIface, int limitUid) |
463 | 459 | * between two snapshots in time. Assumes that statistics rows collect over |
464 | 460 | * time, and that none of them have disappeared. |
465 | 461 | */ |
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); |
468 | 464 | } |
469 | 465 |
|
470 | 466 | /** |
471 | | - * Subtract the given {@link NetworkStats}, effectively leaving the delta |
| 467 | + * Subtract the two given {@link NetworkStats} objects, returning the delta |
472 | 468 | * between two snapshots in time. Assumes that statistics rows collect over |
473 | 469 | * 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}. |
477 | 473 | */ |
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; |
481 | 477 | if (deltaRealtime < 0) { |
482 | | - throw new NonMonotonicException(this, value); |
| 478 | + if (observer != null) { |
| 479 | + observer.foundNonMonotonic(left, -1, right, -1); |
| 480 | + } |
| 481 | + deltaRealtime = 0; |
483 | 482 | } |
484 | 483 |
|
485 | 484 | // result will have our rows, and elapsed time between snapshots |
486 | 485 | 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]; |
493 | 492 |
|
494 | 493 | // 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); |
496 | 495 | if (j == -1) { |
497 | 496 | // 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]; |
503 | 502 | } else { |
504 | 503 | // 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]; |
510 | 509 |
|
511 | 510 | if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 |
512 | 511 | || 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); |
521 | 514 | } |
| 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); |
522 | 520 | } |
523 | 521 | } |
524 | 522 |
|
@@ -665,22 +663,8 @@ public NetworkStats[] newArray(int size) { |
665 | 663 | } |
666 | 664 | }; |
667 | 665 |
|
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); |
685 | 669 | } |
686 | 670 | } |
0 commit comments