NetworkStats: more robust subtraction for deltas
This patch ensures that subtract() between two NetworkStats object will
return a delta with no negative entries in all cases.
When the stats delta contains some negative values, there are clamped to
0. Some logging is added when this happens.
This is what's expected by NetworkStatsHistory#recordData().
Bug: 64365917
Test: runtest frameworks-net
Change-Id: I16e97e73f600225f80e0ce517e80c07c6f399196
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index 77ce65b..be9e809 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -672,36 +672,33 @@
entry.tag = left.tag[i];
entry.metered = left.metered[i];
entry.roaming = left.roaming[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];
// find remote row that matches, and subtract
final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag,
entry.metered, entry.roaming, i);
- if (j == -1) {
- // newly appearing row, return entire value
- 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 = 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 (j != -1) {
+ // Found matching row, subtract remote value.
+ entry.rxBytes -= right.rxBytes[j];
+ entry.rxPackets -= right.rxPackets[j];
+ entry.txBytes -= right.txBytes[j];
+ entry.txPackets -= right.txPackets[j];
+ entry.operations -= right.operations[j];
+ }
- if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0
- || entry.txPackets < 0 || entry.operations < 0) {
- if (observer != null) {
- observer.foundNonMonotonic(left, i, right, j, cookie);
- }
- 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);
+ if (entry.isNegative()) {
+ if (observer != null) {
+ observer.foundNonMonotonic(left, i, right, j, cookie);
}
+ 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);
}
result.addValues(entry);