Merge "Make NetworkCapabilities authoritative for roaming state"
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 3be49d5..ee4379a 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -467,6 +467,19 @@
}
/**
+ * Returns true iff. the capabilities requested in this NetworkRequest are satisfied by the
+ * provided {@link NetworkCapabilities}.
+ *
+ * @param nc Capabilities that should satisfy this NetworkRequest. null capabilities do not
+ * satisfy any request.
+ * @hide
+ */
+ @SystemApi
+ public boolean satisfiedBy(@Nullable NetworkCapabilities nc) {
+ return networkCapabilities.satisfiedByNetworkCapabilities(nc);
+ }
+
+ /**
* @see Builder#addTransportType(int)
*/
public boolean hasTransport(@Transport int transportType) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 7a998a5..a3795593 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -89,7 +89,6 @@
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
import android.net.NetworkConfig;
-import android.net.NetworkFactory;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkMisc;
@@ -2836,26 +2835,11 @@
return true;
}
- // TODO: delete when direct use of registerNetworkFactory is no longer supported.
- private boolean maybeHandleNetworkFactoryMessage(Message msg) {
- switch (msg.what) {
- default:
- return false;
- case NetworkFactory.EVENT_UNFULFILLABLE_REQUEST: {
- handleReleaseNetworkRequest((NetworkRequest) msg.obj, msg.sendingUid,
- /* callOnUnavailable */ true);
- break;
- }
- }
- return true;
- }
-
@Override
public void handleMessage(Message msg) {
if (!maybeHandleAsyncChannelMessage(msg)
&& !maybeHandleNetworkMonitorMessage(msg)
- && !maybeHandleNetworkAgentInfoMessage(msg)
- && !maybeHandleNetworkFactoryMessage(msg)) {
+ && !maybeHandleNetworkAgentInfoMessage(msg)) {
maybeHandleNetworkAgentMessage(msg);
}
}
@@ -5808,6 +5792,19 @@
return INetd.PERMISSION_NONE;
}
+ private void updateNetworkPermissions(@NonNull final NetworkAgentInfo nai,
+ @NonNull final NetworkCapabilities newNc) {
+ final int oldPermission = getNetworkPermission(nai.networkCapabilities);
+ final int newPermission = getNetworkPermission(newNc);
+ if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
+ try {
+ mNMS.setNetworkPermission(nai.network.netId, newPermission);
+ } catch (RemoteException e) {
+ loge("Exception in setNetworkPermission: " + e);
+ }
+ }
+ }
+
/**
* Augments the NetworkCapabilities passed in by a NetworkAgent with capabilities that are
* maintained here that the NetworkAgent is not aware of (e.g., validated, captive portal,
@@ -5880,21 +5877,11 @@
* @param nai the network having its capabilities updated.
* @param nc the new network capabilities.
*/
- private void updateCapabilities(int oldScore, NetworkAgentInfo nai, NetworkCapabilities nc) {
+ private void updateCapabilities(final int oldScore, @NonNull final NetworkAgentInfo nai,
+ @NonNull final NetworkCapabilities nc) {
NetworkCapabilities newNc = mixInCapabilities(nai, nc);
-
if (Objects.equals(nai.networkCapabilities, newNc)) return;
-
- final int oldPermission = getNetworkPermission(nai.networkCapabilities);
- final int newPermission = getNetworkPermission(newNc);
- if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
- try {
- mNMS.setNetworkPermission(nai.network.netId, newPermission);
- } catch (RemoteException e) {
- loge("Exception in setNetworkPermission: " + e);
- }
- }
-
+ updateNetworkPermissions(nai, newNc);
final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
updateUids(nai, prevNc, newNc);
@@ -6275,6 +6262,30 @@
}
}
+ // An accumulator class to gather the list of changes that result from a rematch.
+ // TODO : enrich to represent an entire set of changes to apply.
+ private static class NetworkReassignment {
+ static class NetworkBgStatePair {
+ @NonNull final NetworkAgentInfo mNetwork;
+ final boolean mOldBackground;
+ NetworkBgStatePair(@NonNull final NetworkAgentInfo network,
+ final boolean oldBackground) {
+ mNetwork = network;
+ mOldBackground = oldBackground;
+ }
+ }
+
+ @NonNull private final Set<NetworkBgStatePair> mRematchedNetworks = new ArraySet<>();
+
+ @NonNull Iterable<NetworkBgStatePair> getRematchedNetworks() {
+ return mRematchedNetworks;
+ }
+
+ void addRematchedNetwork(@NonNull final NetworkBgStatePair network) {
+ mRematchedNetworks.add(network);
+ }
+ }
+
private ArrayMap<NetworkRequestInfo, NetworkAgentInfo> computeRequestReassignmentForNetwork(
@NonNull final NetworkAgentInfo newNetwork) {
final int score = newNetwork.getCurrentScore();
@@ -6320,8 +6331,8 @@
// needed. A network is needed if it is the best network for
// one or more NetworkRequests, or if it is a VPN.
//
- // - Tears down newNetwork if it just became validated
- // but turns out to be unneeded.
+ // - Writes into the passed reassignment object all changes that should be done for
+ // rematching this network with all requests, to be applied later.
//
// NOTE: This function only adds NetworkRequests that "newNetwork" could satisfy,
// it does not remove NetworkRequests that other Networks could better satisfy.
@@ -6329,15 +6340,22 @@
// This function should be used when possible instead of {@code rematchAllNetworksAndRequests}
// as it performs better by a factor of the number of Networks.
//
+ // TODO : stop writing to the passed reassignment. This is temporarily more useful, but
+ // it's unidiomatic Java and it's hard to read.
+ //
+ // @param changes a currently-building list of changes to write to
// @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(NetworkAgentInfo newNetwork, long now) {
+ private void rematchNetworkAndRequests(@NonNull final NetworkReassignment changes,
+ @NonNull final NetworkAgentInfo newNetwork, final long now) {
ensureRunningOnConnectivityServiceThread();
if (!newNetwork.everConnected) return;
boolean isNewDefault = false;
NetworkAgentInfo oldDefaultNetwork = null;
- final boolean wasBackgroundNetwork = newNetwork.isBackgroundNetwork();
+ changes.addRematchedNetwork(new NetworkReassignment.NetworkBgStatePair(newNetwork,
+ newNetwork.isBackgroundNetwork()));
+
final int score = newNetwork.getCurrentScore();
if (VDBG || DDBG) log("rematching " + newNetwork.name());
@@ -6440,39 +6458,12 @@
if (newNetwork.getCurrentScore() != score) {
Slog.wtf(TAG, String.format(
"BUG: %s changed score during rematch: %d -> %d",
- newNetwork.name(), score, newNetwork.getCurrentScore()));
+ newNetwork.name(), score, newNetwork.getCurrentScore()));
}
// Notify requested networks are available after the default net is switched, but
// before LegacyTypeTracker sends legacy broadcasts
for (NetworkRequestInfo nri : addedRequests) notifyNetworkAvailable(newNetwork, nri);
-
- // Finally, process listen requests and update capabilities if the background state has
- // changed for this network. For consistency with previous behavior, send onLost callbacks
- // before onAvailable.
- processNewlyLostListenRequests(newNetwork);
-
- // Maybe the network changed background states. Update its capabilities.
- final boolean backgroundChanged = wasBackgroundNetwork != newNetwork.isBackgroundNetwork();
- if (backgroundChanged) {
- final NetworkCapabilities newNc = mixInCapabilities(newNetwork,
- newNetwork.networkCapabilities);
-
- final int oldPermission = getNetworkPermission(newNetwork.networkCapabilities);
- final int newPermission = getNetworkPermission(newNc);
- if (oldPermission != newPermission) {
- try {
- mNMS.setNetworkPermission(newNetwork.network.netId, newPermission);
- } catch (RemoteException e) {
- loge("Exception in setNetworkPermission: " + e);
- }
- }
-
- newNetwork.getAndSetNetworkCapabilities(newNc);
- notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_CAP_CHANGED);
- }
-
- processNewlySatisfiedListenRequests(newNetwork);
}
/**
@@ -6494,12 +6485,24 @@
// scoring network and then a higher scoring network, which could produce multiple
// callbacks.
Arrays.sort(nais);
+ final NetworkReassignment changes = new NetworkReassignment();
for (final NetworkAgentInfo nai : nais) {
- rematchNetworkAndRequests(nai, now);
+ rematchNetworkAndRequests(changes, nai, now);
}
final NetworkAgentInfo newDefaultNetwork = getDefaultNetwork();
+ for (final NetworkReassignment.NetworkBgStatePair event : changes.getRematchedNetworks()) {
+ // Process listen requests and update capabilities if the background state has
+ // changed for this network. For consistency with previous behavior, send onLost
+ // callbacks before onAvailable.
+ processNewlyLostListenRequests(event.mNetwork);
+ if (event.mOldBackground != event.mNetwork.isBackgroundNetwork()) {
+ applyBackgroundChangeForRematch(event.mNetwork);
+ }
+ processNewlySatisfiedListenRequests(event.mNetwork);
+ }
+
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
@@ -6531,6 +6534,24 @@
}
}
+ /**
+ * Apply a change in background state resulting from rematching networks with requests.
+ *
+ * During rematch, a network may change background states by starting to satisfy or stopping
+ * to satisfy a foreground request. Listens don't count for this. When a network changes
+ * background states, its capabilities need to be updated and callbacks fired for the
+ * capability change.
+ *
+ * @param nai The network that changed background states
+ */
+ private void applyBackgroundChangeForRematch(@NonNull final NetworkAgentInfo nai) {
+ final NetworkCapabilities newNc = mixInCapabilities(nai, nai.networkCapabilities);
+ if (Objects.equals(nai.networkCapabilities, newNc)) return;
+ updateNetworkPermissions(nai, newNc);
+ nai.getAndSetNetworkCapabilities(newNc);
+ notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
+ }
+
private void updateLegacyTypeTrackerAndVpnLockdownForRematch(
@Nullable final NetworkAgentInfo oldDefaultNetwork,
@Nullable final NetworkAgentInfo newDefaultNetwork,