diff options
author | Chalard Jean <jchalard@google.com> | 2019-12-02 09:40:44 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-12-02 09:40:44 +0000 |
commit | 82001cf9939451a66827873ef811af8ac49634fd (patch) | |
tree | 68b6d69d327a84bc46e907a24150a5b0e9dbce97 | |
parent | 5cf5b30990cd33dc59a4e99559e8fc2ee2dcc11c (diff) | |
parent | a3984a18dd8b199981e92b6c180abb20c1981783 (diff) | |
download | base-82001cf9939451a66827873ef811af8ac49634fd.tar.gz |
Merge changes I720a1feb,I9539b8cc,Ib79b777b
* changes:
[NS A17] Update linger state after rematching.
[NS A16] Cleanup
[NS A15] Move legacy default broadcasts out of the loop
-rw-r--r-- | services/core/java/com/android/server/ConnectivityService.java | 102 | ||||
-rw-r--r-- | services/core/java/com/android/server/connectivity/NetworkAgentInfo.java | 2 |
2 files changed, 62 insertions, 42 deletions
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 36f44e48b877..a3a61720ac3d 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -6467,29 +6467,6 @@ public class ConnectivityService extends IConnectivityManager.Stub // do this after the default net is switched, but // before LegacyTypeTracker sends legacy broadcasts for (NetworkRequestInfo nri : addedRequests) notifyNetworkAvailable(newNetwork, nri); - - // Linger any networks that are no longer needed. This should be done after sending the - // available callback for newNetwork. - for (NetworkAgentInfo nai : removedRequests) { - updateLingerState(nai, now); - } - // Possibly unlinger newNetwork. Unlingering a network does not send any callbacks so it - // does not need to be done in any particular order. - updateLingerState(newNetwork, now); - - if (isNewDefault) { - // Maintain the illusion: since the legacy API only - // understands one network at a time, we must pretend - // that the current default network disconnected before - // the new one connected. - if (oldDefaultNetwork != null) { - mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), - oldDefaultNetwork, true); - } - mDefaultInetConditionPublished = newNetwork.lastValidated ? 100 : 0; - mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork); - notifyLockdownVpn(newNetwork); - } } /** @@ -6503,34 +6480,31 @@ public class ConnectivityService extends IConnectivityManager.Stub // requests. Once the code has switched to a request-major iteration style, this can // be optimized to only do the processing needed. final long now = SystemClock.elapsedRealtime(); + final NetworkAgentInfo oldDefaultNetwork = getDefaultNetwork(); + final NetworkAgentInfo[] nais = mNetworkAgentInfos.values().toArray( new NetworkAgentInfo[mNetworkAgentInfos.size()]); // Rematch higher scoring networks first to prevent requests first matching a lower // scoring network and then a higher scoring network, which could produce multiple - // callbacks and inadvertently unlinger networks. + // callbacks. Arrays.sort(nais); - for (NetworkAgentInfo nai : nais) { + for (final NetworkAgentInfo nai : nais) { rematchNetworkAndRequests(nai, now); } - // Now that all the callbacks have been sent, send the legacy network broadcasts - // as needed. This is necessary so that legacy requests correctly bind dns - // requests to this network. The legacy users are listening for this broadcast - // and will generally do a dns request so they can ensureRouteToHost and if - // they do that before the callbacks happen they'll use the default network. - // - // TODO: Is there still a race here? The legacy broadcast will be sent after sending - // callbacks, but if apps can receive the broadcast before the callback, they still might - // have an inconsistent view of networking. - // - // This *does* introduce a race where if the user uses the new api - // (notification callbacks) and then uses the old api (getNetworkInfo(type)) - // they may get old info. Reverse this after the old startUsing api is removed. - // This is on top of the multiple intent sequencing referenced in the todo above. - for (NetworkAgentInfo nai : nais) { - addNetworkToLegacyTypeTracker(nai); + final NetworkAgentInfo newDefaultNetwork = getDefaultNetwork(); + + for (final NetworkAgentInfo nai : nais) { + // Rematching may have altered the linger state of some networks, so update all linger + // timers. updateLingerState reads the state from the network agent and does nothing + // if the state has not changed : the source of truth is controlled with + // NetworkAgentInfo#lingerRequest and NetworkAgentInfo#unlingerRequest, which have been + // called while rematching the individual networks above. + updateLingerState(nai, now); } + updateLegacyTypeTrackerAndVpnLockdownForRematch(oldDefaultNetwork, newDefaultNetwork, nais); + // Tear down all unneeded networks. for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { if (unneeded(nai, UnneededFor.TEARDOWN)) { @@ -6551,6 +6525,52 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + private void updateLegacyTypeTrackerAndVpnLockdownForRematch( + @Nullable final NetworkAgentInfo oldDefaultNetwork, + @Nullable final NetworkAgentInfo newDefaultNetwork, + @NonNull final NetworkAgentInfo[] nais) { + if (oldDefaultNetwork != newDefaultNetwork) { + // Maintain the illusion : since the legacy API only understands one network at a time, + // if the default network changed, apps should see a disconnected broadcast for the + // old default network before they see a connected broadcast for the new one. + if (oldDefaultNetwork != null) { + mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(), + oldDefaultNetwork, true); + } + if (newDefaultNetwork != null) { + // The new default network can be newly null if and only if the old default + // network doesn't satisfy the default request any more because it lost a + // capability. + mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0; + mLegacyTypeTracker.add(newDefaultNetwork.networkInfo.getType(), newDefaultNetwork); + // If the legacy VPN is connected, notifyLockdownVpn may end up sending a broadcast + // to reflect the NetworkInfo of this new network. This broadcast has to be sent + // after the disconnect broadcasts above, but before the broadcasts sent by the + // legacy type tracker below. + // TODO : refactor this, it's too complex + notifyLockdownVpn(newDefaultNetwork); + } + } + + // Now that all the callbacks have been sent, send the legacy network broadcasts + // as needed. This is necessary so that legacy requests correctly bind dns + // requests to this network. The legacy users are listening for this broadcast + // and will generally do a dns request so they can ensureRouteToHost and if + // they do that before the callbacks happen they'll use the default network. + // + // TODO: Is there still a race here? The legacy broadcast will be sent after sending + // callbacks, but if apps can receive the broadcast before the callback, they still might + // have an inconsistent view of networking. + // + // This *does* introduce a race where if the user uses the new api + // (notification callbacks) and then uses the old api (getNetworkInfo(type)) + // they may get old info. Reverse this after the old startUsing api is removed. + // This is on top of the multiple intent sequencing referenced in the todo above. + for (NetworkAgentInfo nai : nais) { + addNetworkToLegacyTypeTracker(nai); + } + } + private void addNetworkToLegacyTypeTracker(@NonNull final NetworkAgentInfo nai) { for (int i = 0; i < nai.numNetworkRequests(); i++) { NetworkRequest nr = nai.requestAt(i); diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 24a5b7fa1489..bb7f86233a40 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -580,7 +580,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { // semantics of WakeupMessage guarantee that if cancel is called then the alarm will // never call its callback (handleLingerComplete), even if it has already fired. // WakeupMessage makes no such guarantees about rescheduling a message, so if mLingerMessage - // has already been dispatched, rescheduling to some time in the future it won't stop it + // has already been dispatched, rescheduling to some time in the future won't stop it // from calling its callback immediately. if (mLingerMessage != null) { mLingerMessage.cancel(); |