From ad5e2827ead7fa8ebafc291ceb6b4672e70c1775 Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Mon, 7 Aug 2017 15:47:35 +0900 Subject: [PATCH] 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 --- core/java/android/net/NetworkStats.java | 45 ++++++++++++------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index 77ce65b0815a5..be9e80973875f 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -672,36 +672,33 @@ public class NetworkStats implements Parcelable { 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);