Over-limit within handful of MTU's, update assets.

Consider a network over-limit when it's measured usage is within a
handful of MTU's, since kernel completely drops packets that trigger
limit alert.

Update notification drawables.

Bug: 5433359, 5224629
Change-Id: I10b19cc34c34b47775904229829a25208cd85d25
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index aaad8a1..1b24f0c 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -40,6 +40,8 @@
     public long limitBytes;
     public long lastSnooze;
 
+    private static final long DEFAULT_MTU = 1500;
+
     public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes, long limitBytes,
             long lastSnooze) {
         this.template = checkNotNull(template, "missing NetworkTemplate");
@@ -71,6 +73,17 @@
         return 0;
     }
 
+    /**
+     * Test if given measurement is near enough to {@link #limitBytes} to be
+     * considered over-limit.
+     */
+    public boolean isOverLimit(long totalBytes) {
+        // over-estimate, since kernel will trigger limit once first packet
+        // trips over limit.
+        totalBytes += 2 * DEFAULT_MTU;
+        return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes;
+    }
+
     /** {@inheritDoc} */
     public int compareTo(NetworkPolicy another) {
         if (another == null || another.limitBytes == LIMIT_DISABLED) {
diff --git a/core/res/res/drawable-hdpi/stat_notify_disabled.png b/core/res/res/drawable-hdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..5b5a7dc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_notify_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_disabled.png b/core/res/res/drawable-mdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..9661d31
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_notify_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_disabled.png b/core/res/res/drawable-xhdpi/stat_notify_disabled.png
new file mode 100644
index 0000000..0a003af
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/stat_notify_disabled.png
Binary files differ
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 0da5cc6..e610782 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -85,7 +85,6 @@
 import android.net.NetworkPolicy;
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkState;
-import android.net.NetworkStats;
 import android.net.NetworkTemplate;
 import android.os.Binder;
 import android.os.Environment;
@@ -489,7 +488,7 @@
             final long end = currentTime;
             final long totalBytes = getTotalBytes(policy.template, start, end);
 
-            if (policy.limitBytes != LIMIT_DISABLED && totalBytes >= policy.limitBytes) {
+            if (policy.isOverLimit(totalBytes)) {
                 if (policy.lastSnooze >= start) {
                     enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes);
                 } else {
@@ -574,7 +573,7 @@
                 final CharSequence title = res.getText(R.string.data_usage_warning_title);
                 final CharSequence body = res.getString(R.string.data_usage_warning_body);
 
-                builder.setSmallIcon(R.drawable.ic_menu_info_details);
+                builder.setSmallIcon(R.drawable.stat_notify_error);
                 builder.setTicker(title);
                 builder.setContentTitle(title);
                 builder.setContentText(body);
@@ -606,7 +605,7 @@
                         break;
                 }
 
-                builder.setSmallIcon(com.android.internal.R.drawable.ic_menu_block);
+                builder.setSmallIcon(R.drawable.stat_notify_disabled);
                 builder.setTicker(title);
                 builder.setContentTitle(title);
                 builder.setContentText(body);
@@ -640,7 +639,7 @@
                         break;
                 }
 
-                builder.setSmallIcon(R.drawable.ic_menu_info_details);
+                builder.setSmallIcon(R.drawable.stat_notify_error);
                 builder.setTicker(title);
                 builder.setContentTitle(title);
                 builder.setContentText(body);
@@ -677,7 +676,7 @@
 
         builder.setOnlyAlertOnce(true);
         builder.setOngoing(true);
-        builder.setSmallIcon(R.drawable.ic_menu_info_details);
+        builder.setSmallIcon(R.drawable.stat_notify_error);
         builder.setTicker(title);
         builder.setContentTitle(title);
         builder.setContentText(body);
@@ -750,8 +749,7 @@
             final long totalBytes = getTotalBytes(policy.template, start, end);
 
             // disable data connection when over limit and not snoozed
-            final boolean overLimit = policy.limitBytes != LIMIT_DISABLED
-                    && totalBytes > policy.limitBytes && policy.lastSnooze < start;
+            final boolean overLimit = policy.isOverLimit(totalBytes) && policy.lastSnooze < start;
             final boolean enabled = !overLimit;
 
             setNetworkTemplateEnabled(policy.template, enabled);
@@ -1535,10 +1533,7 @@
 
     private long getTotalBytes(NetworkTemplate template, long start, long end) {
         try {
-            final NetworkStats stats = mNetworkStats.getSummaryForNetwork(
-                    template, start, end);
-            final NetworkStats.Entry entry = stats.getValues(0, null);
-            return entry.rxBytes + entry.txBytes;
+            return mNetworkStats.getSummaryForNetwork(template, start, end).getTotalBytes();
         } catch (RemoteException e) {
             // ignored; service lives in system_server
             return 0;