[NS A44 2/2] Apply requests after all networks rematching is computed

This patch finally separates completely computing the rematch
from all the side effects. A collateral effect of this is to
compute correctly the background network state in
rematchNetworkAndRequests, which compensates the breakage
from the previous patch.

Bug: 113554781
Test: ConnectivityServiceTest
Change-Id: I998c729c385940168fcd6ba3f2e01911f1844ce1
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 197b0f1..b9c718c 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -6601,11 +6601,9 @@
         return change;
     }
 
-    private ArrayMap<NetworkRequestInfo, NetworkAgentInfo> computeRequestReassignmentForNetwork(
-            @NonNull final NetworkReassignment changes,
+    private void computeRequestReassignmentForNetwork(@NonNull final NetworkReassignment changes,
             @NonNull final NetworkAgentInfo newNetwork) {
         final int score = newNetwork.getCurrentScore();
-        final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests = new ArrayMap<>();
         for (NetworkRequestInfo nri : mNetworkRequests.values()) {
             // Process requests in the first pass and listens in the second pass. This allows us to
             // change a network's capabilities depending on which requests it has. This is only
@@ -6631,18 +6629,14 @@
                             + ", newScore = " + score);
                 }
                 if (currentNetwork == null || currentNetwork.getCurrentScore() < score) {
-                    reassignedRequests.put(nri, newNetwork);
                     changes.addRequestReassignment(new NetworkReassignment.RequestReassignment(
                             nri, currentNetwork, newNetwork));
                 }
             } else if (newNetwork == currentNetwork) {
-                reassignedRequests.put(nri, null);
                 changes.addRequestReassignment(new NetworkReassignment.RequestReassignment(
                         nri, currentNetwork, null));
             }
         }
-
-        return reassignedRequests;
     }
 
     // Handles a network appearing or improving its score.
@@ -6661,7 +6655,7 @@
     // @param newNetwork is the network to be matched against NetworkRequests.
     // @param now the time the rematch starts, as returned by SystemClock.elapsedRealtime();
     private void rematchNetworkAndRequests(@NonNull final NetworkReassignment changes,
-            @NonNull final NetworkAgentInfo newNetwork, final long now) {
+            @NonNull final NetworkAgentInfo newNetwork) {
         ensureRunningOnConnectivityServiceThread();
         if (!newNetwork.everConnected) return;
 
@@ -6670,18 +6664,7 @@
 
         if (VDBG || DDBG) log("rematching " + newNetwork.name());
 
-        final ArrayMap<NetworkRequestInfo, NetworkAgentInfo> reassignedRequests =
-                computeRequestReassignmentForNetwork(changes, newNetwork);
-
-        // Find and migrate to this Network any NetworkRequests for
-        // which this network is now the best.
-        for (final Map.Entry<NetworkRequestInfo, NetworkAgentInfo> entry :
-                reassignedRequests.entrySet()) {
-            final NetworkRequestInfo nri = entry.getKey();
-            final NetworkAgentInfo previousSatisfier = nri.mSatisfier;
-            final NetworkAgentInfo newSatisfier = entry.getValue();
-            updateSatisfiersForRematchRequest(nri, previousSatisfier, newSatisfier, now);
-        }
+        computeRequestReassignmentForNetwork(changes, newNetwork);
     }
 
     private void updateSatisfiersForRematchRequest(@NonNull final NetworkRequestInfo nri,
@@ -6734,7 +6717,20 @@
         Arrays.sort(nais);
         final NetworkReassignment changes = computeInitialReassignment();
         for (final NetworkAgentInfo nai : nais) {
-            rematchNetworkAndRequests(changes, nai, now);
+            rematchNetworkAndRequests(changes, nai);
+        }
+
+        // Now that the entire rematch is computed, update the lists of satisfied requests in
+        // the network agents. This is necessary because some code later depends on this state
+        // to be correct, most prominently computing the linger status.
+        for (final NetworkReassignment.RequestReassignment event :
+                changes.getRequestReassignments()) {
+            // The rematch is seeded with an entry for each request, and requests that don't
+            // change satisfiers have the same network as old and new.
+            // TODO : remove these entries when they are not needed any more.
+            if (event.mOldNetwork == event.mNewNetwork) continue;
+            updateSatisfiersForRematchRequest(event.mRequest, event.mOldNetwork,
+                    event.mNewNetwork, now);
         }
 
         final NetworkRequestInfo defaultRequestInfo = mNetworkRequests.get(mDefaultRequest);