am b2a1ae10: Merge "Send updated NetworkAgent score to NetworkFactories when validated." into lmp-dev

* commit 'b2a1ae1042e6b40c1c8122ba77a96e06084068c0':
  Send updated NetworkAgent score to NetworkFactories when validated.
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2ef3bea..39e5540 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1792,6 +1792,10 @@
         return false;
     }
 
+    private boolean isRequest(NetworkRequest request) {
+        return mNetworkRequests.get(request).isRequest;
+    }
+
     // must be stateless - things change under us.
     private class NetworkStateTrackerHandler extends Handler {
         public NetworkStateTrackerHandler(Looper looper) {
@@ -1908,8 +1912,13 @@
                         if (valid) {
                             if (DBG) log("Validated " + nai.name());
                             final boolean previouslyValidated = nai.validated;
+                            final int previousScore = nai.getCurrentScore();
                             nai.validated = true;
                             rematchNetworkAndRequests(nai, !previouslyValidated);
+                            // If score has changed, rebroadcast to NetworkFactories. b/17726566
+                            if (nai.getCurrentScore() != previousScore) {
+                                sendUpdatedScoreToFactories(nai);
+                            }
                         }
                         updateInetCondition(nai, valid);
                         // Let the NetworkAgent know the state of its network
@@ -2203,7 +2212,7 @@
                         boolean keep = nai.isVPN();
                         for (int i = 0; i < nai.networkRequests.size() && !keep; i++) {
                             NetworkRequest r = nai.networkRequests.valueAt(i);
-                            if (mNetworkRequests.get(r).isRequest) keep = true;
+                            if (isRequest(r)) keep = true;
                         }
                         if (!keep) {
                             if (DBG) log("no live requests for " + nai.name() + "; disconnecting");
@@ -2487,6 +2496,10 @@
         if (nai == null) return;
         if (DBG) log("reportBadNetwork(" + nai.name() + ") by " + uid);
         synchronized (nai) {
+            // Validating an uncreated network could result in a call to rematchNetworkAndRequests()
+            // which isn't meant to work on uncreated networks.
+            if (!nai.created) return;
+
             if (isNetworkBlocked(nai, uid)) return;
 
             nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid);
@@ -3692,6 +3705,15 @@
         }
     }
 
+    private void sendUpdatedScoreToFactories(NetworkAgentInfo nai) {
+        for (int i = 0; i < nai.networkRequests.size(); i++) {
+            NetworkRequest nr = nai.networkRequests.valueAt(i);
+            // Don't send listening requests to factories. b/17393458
+            if (!isRequest(nr)) continue;
+            sendUpdatedScoreToFactories(nr, nai.getCurrentScore());
+        }
+    }
+
     private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
         if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
         for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
@@ -3746,22 +3768,24 @@
         }
     }
 
+    private void teardownUnneededNetwork(NetworkAgentInfo nai) {
+        for (int i = 0; i < nai.networkRequests.size(); i++) {
+            NetworkRequest nr = nai.networkRequests.valueAt(i);
+            // Ignore listening requests.
+            if (!isRequest(nr)) continue;
+            loge("Dead network still had at least " + nr);
+            break;
+        }
+        nai.asyncChannel.disconnect();
+    }
+
     private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
         if (oldNetwork == null) {
             loge("Unknown NetworkAgentInfo in handleLingerComplete");
             return;
         }
-        if (DBG) {
-            log("handleLingerComplete for " + oldNetwork.name());
-            for (int i = 0; i < oldNetwork.networkRequests.size(); i++) {
-                NetworkRequest nr = oldNetwork.networkRequests.valueAt(i);
-                // Ignore listening requests.
-                if (mNetworkRequests.get(nr).isRequest == false) continue;
-                loge("Dead network still had at least " + nr);
-                break;
-            }
-        }
-        oldNetwork.asyncChannel.disconnect();
+        if (DBG) log("handleLingerComplete for " + oldNetwork.name());
+        teardownUnneededNetwork(oldNetwork);
     }
 
     private void makeDefault(NetworkAgentInfo newNetwork) {
@@ -3898,7 +3922,7 @@
             for (int i = 0; i < nai.networkRequests.size() && teardown; i++) {
                 NetworkRequest nr = nai.networkRequests.valueAt(i);
                 try {
-                if (mNetworkRequests.get(nr).isRequest) {
+                if (isRequest(nr)) {
                     teardown = false;
                 }
                 } catch (Exception e) {
@@ -3961,14 +3985,8 @@
             // the lingering process so communication on that network is given time to wrap up.
             // TODO: Could teardown unvalidated networks when their NetworkCapabilities
             // satisfy no NetworkRequests.
-            if (DBG && newNetwork.networkRequests.size() != 0) {
-                loge("tearing down network with live requests:");
-                for (int i=0; i < newNetwork.networkRequests.size(); i++) {
-                    loge("  " + newNetwork.networkRequests.valueAt(i));
-                }
-            }
             if (DBG) log("Validated network turns out to be unwanted.  Tear it down.");
-            newNetwork.asyncChannel.disconnect();
+            teardownUnneededNetwork(newNetwork);
         }
     }
 
@@ -4097,12 +4115,7 @@
 
         if (nai.created) rematchAllNetworksAndRequests(nai, oldScore);
 
-        for (int i = 0; i < nai.networkRequests.size(); i++) {
-            NetworkRequest nr = nai.networkRequests.valueAt(i);
-            // Don't send listening requests to factories. b/17393458
-            if (mNetworkRequests.get(nr).isRequest == false) continue;
-            sendUpdatedScoreToFactories(nr, score);
-        }
+        sendUpdatedScoreToFactories(nai);
     }
 
     // notify only this one new request of the current state