Add a lastValidated bit and use it when reporting capabilities.

When we switched the way the status bar determines if a
connection is validated from using INET_CONDITION_ACTION
broadcasts to calling getDefaultNetworkCapabilitiesForUser(),
the statusbar stopped displaying ! when a network stopped having
working Internet connectivity. This is because the validated bit
is never set to false once a network is validated.

Fix this, hopefully temporarily, by introducing a new validated
bit that does go back to being false when a network no longer
has working connectivity, and use that bit in
getDefaultNetworkCapabilitiesForUser().

Bug: 18777225
Change-Id: I991c068be50252391d0e64c647fcf2e053dc82f9
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 3387c0f..b1f14a9 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1048,7 +1048,7 @@
             synchronized (nai) {
                 if (nai.created) {
                     NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
-                    if (nai.everValidated) {
+                    if (nai.lastValidated) {
                         nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
                     } else {
                         nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
@@ -1954,6 +1954,7 @@
                     NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
                     if (isLiveNetworkAgent(nai, "EVENT_NETWORK_VALIDATED")) {
                         boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID);
+                        nai.lastValidated = valid;
                         if (valid) {
                             if (DBG) log("Validated " + nai.name());
                             if (!nai.everValidated) {
@@ -1964,7 +1965,7 @@
                                 sendUpdatedScoreToFactories(nai);
                             }
                         }
-                        updateInetCondition(nai, valid);
+                        updateInetCondition(nai);
                         // Let the NetworkAgent know the state of its network
                         nai.asyncChannel.sendMessage(
                                 android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS,
@@ -4200,14 +4201,14 @@
         }
     }
 
-    private void updateInetCondition(NetworkAgentInfo nai, boolean valid) {
+    private void updateInetCondition(NetworkAgentInfo nai) {
         // Don't bother updating until we've graduated to validated at least once.
         if (!nai.everValidated) return;
         // For now only update icons for default connection.
         // TODO: Update WiFi and cellular icons separately. b/17237507
         if (!isDefaultNetwork(nai)) return;
 
-        int newInetCondition = valid ? 100 : 0;
+        int newInetCondition = nai.lastValidated ? 100 : 0;
         // Don't repeat publish.
         if (newInetCondition == mDefaultInetConditionPublished) return;
 
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 94a8c0f..f3e0bbc 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -55,6 +55,13 @@
     // fail.
     public boolean everValidated;
 
+    // The result of the last validation attempt on this network (true if validated, false if not).
+    // This bit exists only because we never unvalidate a network once it's been validated, and that
+    // is because the network scoring and revalidation code does not (may not?) deal properly with
+    // networks becoming unvalidated.
+    // TODO: Fix the network scoring code, remove this, and rename everValidated to validated.
+    public boolean lastValidated;
+
     // This represents the last score received from the NetworkAgent.
     private int currentScore;
     // Penalty applied to scores of Networks that have not been validated.
@@ -90,6 +97,7 @@
         networkMisc = misc;
         created = false;
         everValidated = false;
+        lastValidated = false;
     }
 
     public void addRequest(NetworkRequest networkRequest) {
@@ -142,8 +150,9 @@
         return "NetworkAgentInfo{ ni{" + networkInfo + "}  network{" +
                 network + "}  lp{" +
                 linkProperties + "}  nc{" +
-                networkCapabilities + "}  Score{" + getCurrentScore() + "} " +
-                "everValidated{" + everValidated + "} created{" + created + "} " +
+                networkCapabilities + "}  Score{" + getCurrentScore() + "}  " +
+                "everValidated{" + everValidated + "}  lastValidated{" + lastValidated + "}  " +
+                "created{" + created + "}  " +
                 "explicitlySelected{" + networkMisc.explicitlySelected + "} }";
     }