Merge "Last-ditch clamping of negative NetworkStats." into pi-dev
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index f0dd262..edf9bc1 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -1100,6 +1100,8 @@
     public interface NonMonotonicObserver<C> {
         public void foundNonMonotonic(
                 NetworkStats left, int leftIndex, NetworkStats right, int rightIndex, C cookie);
+        public void foundNonMonotonic(
+                NetworkStats stats, int statsIndex, C cookie);
     }
 
     /**
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index 4bee55e..a16dcf3 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -241,6 +241,20 @@
         NetworkStats.Entry entry = null;
         for (int i = 0; i < delta.size(); i++) {
             entry = delta.getValues(i, entry);
+
+            // As a last-ditch sanity check, report any negative values and
+            // clamp them so recording below doesn't croak.
+            if (entry.isNegative()) {
+                if (mObserver != null) {
+                    mObserver.foundNonMonotonic(delta, i, mCookie);
+                }
+                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);
+            }
+
             final NetworkIdentitySet ident = ifaceIdent.get(entry.iface);
             if (ident == null) {
                 unknownIfaces.add(entry.iface);
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 492c6d6..addc479 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -1716,7 +1716,7 @@
         @Override
         public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
                 int rightIndex, String cookie) {
-            Log.w(TAG, "found non-monotonic values; saving to dropbox");
+            Log.w(TAG, "Found non-monotonic values; saving to dropbox");
 
             // record error for debugging
             final StringBuilder builder = new StringBuilder();
@@ -1725,9 +1725,21 @@
             builder.append("left=").append(left).append('\n');
             builder.append("right=").append(right).append('\n');
 
-            final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
-                    Context.DROPBOX_SERVICE);
-            dropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
+            mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
+                    builder.toString());
+        }
+
+        @Override
+        public void foundNonMonotonic(
+                NetworkStats stats, int statsIndex, String cookie) {
+            Log.w(TAG, "Found non-monotonic values; saving to dropbox");
+
+            final StringBuilder builder = new StringBuilder();
+            builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
+            builder.append("stats=").append(stats).append('\n');
+
+            mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
+                    builder.toString());
         }
     }