Occasionally retest for captive portals once detected

Once a captive portal has been detected, retest for the presence of
the captive portal every 10 minutes.  Some WiFi routers present a
captive portal when the backhaul goes away; with this change if the
backhaul returns and the captive portal goes away, the device will
detect this after a period and remove the notification.

Bug: 21545788
Change-Id: Icabf0a3fff37bccc95f99eba52af13f7a2ddc2f3
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index fc50e2c..99a0567 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -178,6 +178,13 @@
      */
     private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = BASE + 11;
 
+    /**
+     * Retest network to see if captive portal is still in place.
+     * arg1 = UID responsible for requesting this reeval.  Will be billed for data.
+     *        0 indicates self-initiated, so nobody to blame.
+     */
+    private static final int CMD_CAPTIVE_PORTAL_RECHECK = BASE + 12;
+
     private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
     // Default to 30s linger time-out.  Modifyable only for testing.
     private static int DEFAULT_LINGER_DELAY_MS = 30000;
@@ -194,6 +201,8 @@
     private int mUidResponsibleForReeval = INVALID_UID;
     // Stop blaming UID that requested re-evaluation after this many attempts.
     private static final int BLAME_FOR_EVALUATION_ATTEMPTS = 5;
+    // Delay between reevaluations once a captive portal has been found.
+    private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10*60*1000;
 
     private final Context mContext;
     private final Handler mConnectivityServiceHandler;
@@ -287,6 +296,7 @@
                     quit();
                     return HANDLED;
                 case CMD_FORCE_REEVALUATION:
+                case CMD_CAPTIVE_PORTAL_RECHECK:
                     if (DBG) log("Forcing reevaluation");
                     mUidResponsibleForReeval = message.arg1;
                     transitionTo(mEvaluatingState);
@@ -517,6 +527,9 @@
                     mNetworkAgentInfo.network.netId,
                     mLaunchCaptivePortalAppBroadcastReceiver.getPendingIntent());
             mConnectivityServiceHandler.sendMessage(message);
+            // Retest for captive portal occasionally.
+            sendMessageDelayed(CMD_CAPTIVE_PORTAL_RECHECK, 0 /* no UID */,
+                    CAPTIVE_PORTAL_REEVALUATE_DELAY_MS);
         }
 
         @Override
@@ -524,6 +537,11 @@
             if (DBG) log(getName() + message.toString());
             return NOT_HANDLED;
         }
+
+        @Override
+        public void exit() {
+             removeMessages(CMD_CAPTIVE_PORTAL_RECHECK);
+        }
     }
 
     // Being in the LingeringState State indicates a Network's validated bit is true and it once