Loading core/java/android/net/NetworkCapabilities.java +31 −4 Original line number Diff line number Diff line Loading @@ -182,8 +182,15 @@ public final class NetworkCapabilities implements Parcelable { */ public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; /** * Indicates that this network is available for use by apps, and not a network that is being * kept up in the background to facilitate fast network switching. * @hide */ public static final int NET_CAPABILITY_FOREGROUND = 18; private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL; private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND; /** * Network capabilities that are expected to be mutable, i.e., can change while a particular Loading @@ -194,7 +201,8 @@ public final class NetworkCapabilities implements Parcelable { // http://b/18206275 (1 << NET_CAPABILITY_TRUSTED) | (1 << NET_CAPABILITY_VALIDATED) | (1 << NET_CAPABILITY_CAPTIVE_PORTAL); (1 << NET_CAPABILITY_CAPTIVE_PORTAL) | (1 << NET_CAPABILITY_FOREGROUND); /** * Network specifier for factories which want to match any network specifier Loading @@ -217,8 +225,7 @@ public final class NetworkCapabilities implements Parcelable { * get immediately torn down because they do not have the requested capability. */ private static final long NON_REQUESTABLE_CAPABILITIES = (1 << NET_CAPABILITY_VALIDATED) | (1 << NET_CAPABILITY_CAPTIVE_PORTAL); MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED); /** * Capabilities that are set by default when the object is constructed. Loading Loading @@ -325,6 +332,7 @@ public final class NetworkCapabilities implements Parcelable { public String describeFirstNonRequestableCapability() { if (hasCapability(NET_CAPABILITY_VALIDATED)) return "NET_CAPABILITY_VALIDATED"; if (hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return "NET_CAPABILITY_CAPTIVE_PORTAL"; if (hasCapability(NET_CAPABILITY_FOREGROUND)) return "NET_CAPABILITY_FOREGROUND"; // This cannot happen unless the preceding checks are incomplete. if ((mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES) != 0) { return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities); Loading Loading @@ -352,6 +360,11 @@ public final class NetworkCapabilities implements Parcelable { (that.mNetworkCapabilities & ~MUTABLE_CAPABILITIES)); } private boolean equalsNetCapabilitiesRequestable(NetworkCapabilities that) { return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)); } /** * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are * typically provided by restricted networks. Loading Loading @@ -749,6 +762,19 @@ public final class NetworkCapabilities implements Parcelable { equalsSpecifier(nc)); } /** * Checks that our requestable capabilities are the same as those of the given * {@code NetworkCapabilities}. * * @hide */ public boolean equalRequestableCapabilities(NetworkCapabilities nc) { if (nc == null) return false; return (equalsNetCapabilitiesRequestable(nc) && equalsTransportTypes(nc) && equalsSpecifier(nc)); } @Override public boolean equals(Object obj) { if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; Loading Loading @@ -833,6 +859,7 @@ public final class NetworkCapabilities implements Parcelable { case NET_CAPABILITY_NOT_VPN: capabilities += "NOT_VPN"; break; case NET_CAPABILITY_VALIDATED: capabilities += "VALIDATED"; break; case NET_CAPABILITY_CAPTIVE_PORTAL: capabilities += "CAPTIVE_PORTAL"; break; case NET_CAPABILITY_FOREGROUND: capabilities += "FOREGROUND"; break; } if (++i < types.length) capabilities += "&"; } Loading services/core/java/com/android/server/ConnectivityService.java +92 −27 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; Loading Loading @@ -2139,14 +2140,10 @@ public class ConnectivityService extends IConnectivityManager.Stub case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: { final NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj; if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL) || networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED) || networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) { Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability."); } if (nai.everConnected && !nai.networkCapabilities.equalImmutableCapabilities( networkCapabilities)) { Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities: " + nai.networkCapabilities + " -> " + networkCapabilities); } updateCapabilities(nai, networkCapabilities); break; } Loading Loading @@ -2604,6 +2601,7 @@ public class ConnectivityService extends IConnectivityManager.Stub boolean wasKept = false; NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId); if (nai != null) { boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); nai.removeRequest(nri.request.requestId); if (VDBG) { log(" Removing from current network " + nai.name() + Loading @@ -2619,6 +2617,10 @@ public class ConnectivityService extends IConnectivityManager.Stub wasKept = true; } mNetworkForRequestId.remove(nri.request.requestId); if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) { // Went from foreground to background. updateCapabilities(nai, nai.networkCapabilities); } } // TODO: remove this code once we know that the Slog.wtf is never hit. Loading Loading @@ -4492,6 +4494,12 @@ public class ConnectivityService extends IConnectivityManager.Stub * @param networkCapabilities the new network capabilities. */ private void updateCapabilities(NetworkAgentInfo nai, NetworkCapabilities networkCapabilities) { if (nai.everConnected && !nai.networkCapabilities.equalImmutableCapabilities( networkCapabilities)) { Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities: " + nai.networkCapabilities + " -> " + networkCapabilities); } // Don't modify caller's NetworkCapabilities. networkCapabilities = new NetworkCapabilities(networkCapabilities); if (nai.lastValidated) { Loading @@ -4504,8 +4512,14 @@ public class ConnectivityService extends IConnectivityManager.Stub } else { networkCapabilities.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); } if (!Objects.equals(nai.networkCapabilities, networkCapabilities)) { final int oldScore = nai.getCurrentScore(); if (nai.isBackgroundNetwork()) { networkCapabilities.removeCapability(NET_CAPABILITY_FOREGROUND); } else { networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); } if (Objects.equals(nai.networkCapabilities, networkCapabilities)) return; if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) != networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { try { Loading @@ -4516,9 +4530,22 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("Exception in setNetworkPermission: " + e); } } final int oldScore = nai.getCurrentScore(); final NetworkCapabilities prevNc = nai.networkCapabilities; synchronized (nai) { nai.networkCapabilities = networkCapabilities; } if (nai.getCurrentScore() == oldScore && networkCapabilities.equalRequestableCapabilities(prevNc)) { // If the requestable capabilities haven't changed, and the score hasn't changed, then // the change we're processing can't affect any requests, it can only affect the listens // on this network. We might have been called by rematchNetworkAndRequests when a // network changed foreground state. processListenRequests(nai, true); } else { // If the requestable capabilities have changed or the score changed, we can't have been // called by rematchNetworkAndRequests, so it's safe to start a rematch. rematchAllNetworksAndRequests(nai, oldScore); notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); } Loading Loading @@ -4642,7 +4669,11 @@ public class ConnectivityService extends IConnectivityManager.Stub oldNetwork.clearLingerState(); if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) { // Tear the network down. teardownUnneededNetwork(oldNetwork); } else { // Put the network in the background. updateCapabilities(oldNetwork, oldNetwork.networkCapabilities); } } Loading @@ -4660,7 +4691,7 @@ public class ConnectivityService extends IConnectivityManager.Stub setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers()); } private void processListenRequests(NetworkAgentInfo nai) { private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) { // For consistency with previous behaviour, send onLost callbacks before onAvailable. for (NetworkRequestInfo nri : mNetworkRequests.values()) { NetworkRequest nr = nri.request; Loading @@ -4671,6 +4702,10 @@ public class ConnectivityService extends IConnectivityManager.Stub } } if (capabilitiesChanged) { notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); } for (NetworkRequestInfo nri : mNetworkRequests.values()) { NetworkRequest nr = nri.request; if (!nr.isListen()) continue; Loading Loading @@ -4714,12 +4749,18 @@ public class ConnectivityService extends IConnectivityManager.Stub boolean keep = newNetwork.isVPN(); boolean isNewDefault = false; NetworkAgentInfo oldDefaultNetwork = null; final boolean wasBackgroundNetwork = newNetwork.isBackgroundNetwork(); final int score = newNetwork.getCurrentScore(); if (VDBG) log("rematching " + newNetwork.name()); // Find and migrate to this Network any NetworkRequests for // which this network is now the best. ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>(); ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<NetworkRequestInfo>(); if (VDBG) log(" network has: " + newNetwork.networkCapabilities); NetworkCapabilities nc = newNetwork.networkCapabilities; if (VDBG) log(" network has: " + nc); 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 Loading @@ -4746,10 +4787,9 @@ public class ConnectivityService extends IConnectivityManager.Stub if (VDBG) { log("currentScore = " + (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) + ", newScore = " + newNetwork.getCurrentScore()); ", newScore = " + score); } if (currentNetwork == null || currentNetwork.getCurrentScore() < newNetwork.getCurrentScore()) { if (currentNetwork == null || currentNetwork.getCurrentScore() < score) { if (VDBG) log("rematch for " + newNetwork.name()); if (currentNetwork != null) { if (VDBG) log(" accepting network in place of " + currentNetwork.name()); Loading @@ -4771,7 +4811,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // TODO - this could get expensive if we have alot of requests for this // network. Think about if there is a way to reduce this. Push // netid->request mapping to each factory? sendUpdatedScoreToFactories(nri.request, newNetwork.getCurrentScore()); sendUpdatedScoreToFactories(nri.request, score); if (isDefaultRequest(nri)) { isNewDefault = true; oldDefaultNetwork = currentNetwork; Loading Loading @@ -4829,8 +4869,27 @@ public class ConnectivityService extends IConnectivityManager.Stub } } if (!newNetwork.networkCapabilities.equalRequestableCapabilities(nc)) { Slog.wtf(TAG, String.format( "BUG: %s changed requestable capabilities during rematch: %s -> %s", nc, newNetwork.networkCapabilities)); } if (newNetwork.getCurrentScore() != score) { Slog.wtf(TAG, String.format( "BUG: %s changed score during rematch: %d -> %d", score, newNetwork.getCurrentScore())); } // Second pass: process all listens. processListenRequests(newNetwork); if (wasBackgroundNetwork != newNetwork.isBackgroundNetwork()) { // If the network went from background to foreground or vice versa, we need to update // its foreground state. It is safe to do this after rematching the requests because // NET_CAPABILITY_FOREGROUND does not affect requests, as is not a requestable // capability and does not affect the network's score (see the Slog.wtf call above). updateCapabilities(newNetwork, newNetwork.networkCapabilities); } else { processListenRequests(newNetwork, false); } // do this after the default net is switched, but // before LegacyTypeTracker sends legacy broadcasts Loading Loading @@ -5023,6 +5082,10 @@ public class ConnectivityService extends IConnectivityManager.Stub if (!networkAgent.created && (state == NetworkInfo.State.CONNECTED || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) { // A network that has just connected has zero requests and is thus a foreground network. networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); try { // This should never fail. Specifying an already in use NetID will cause failure. if (networkAgent.isVPN()) { Loading Loading @@ -5184,6 +5247,8 @@ public class ConnectivityService extends IConnectivityManager.Stub NetworkRequest nr = networkAgent.requestAt(i); NetworkRequestInfo nri = mNetworkRequests.get(nr); if (VDBG) log(" sending notification for " + nr); // TODO: if we're in the middle of a rematch, can we send a CAP_CHANGED callback for // a network that no longer satisfies the listen? if (nri.mPendingIntent == null) { callCallbackForRequest(nri, networkAgent, notifyType, arg1); } else { Loading services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +1 −1 Original line number Diff line number Diff line Loading @@ -380,7 +380,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { * it might satisfy a request if it validated). */ public boolean isBackgroundNetwork() { return numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0; return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0; } // Does this network satisfy request? Loading Loading
core/java/android/net/NetworkCapabilities.java +31 −4 Original line number Diff line number Diff line Loading @@ -182,8 +182,15 @@ public final class NetworkCapabilities implements Parcelable { */ public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; /** * Indicates that this network is available for use by apps, and not a network that is being * kept up in the background to facilitate fast network switching. * @hide */ public static final int NET_CAPABILITY_FOREGROUND = 18; private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL; private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND; /** * Network capabilities that are expected to be mutable, i.e., can change while a particular Loading @@ -194,7 +201,8 @@ public final class NetworkCapabilities implements Parcelable { // http://b/18206275 (1 << NET_CAPABILITY_TRUSTED) | (1 << NET_CAPABILITY_VALIDATED) | (1 << NET_CAPABILITY_CAPTIVE_PORTAL); (1 << NET_CAPABILITY_CAPTIVE_PORTAL) | (1 << NET_CAPABILITY_FOREGROUND); /** * Network specifier for factories which want to match any network specifier Loading @@ -217,8 +225,7 @@ public final class NetworkCapabilities implements Parcelable { * get immediately torn down because they do not have the requested capability. */ private static final long NON_REQUESTABLE_CAPABILITIES = (1 << NET_CAPABILITY_VALIDATED) | (1 << NET_CAPABILITY_CAPTIVE_PORTAL); MUTABLE_CAPABILITIES & ~(1 << NET_CAPABILITY_TRUSTED); /** * Capabilities that are set by default when the object is constructed. Loading Loading @@ -325,6 +332,7 @@ public final class NetworkCapabilities implements Parcelable { public String describeFirstNonRequestableCapability() { if (hasCapability(NET_CAPABILITY_VALIDATED)) return "NET_CAPABILITY_VALIDATED"; if (hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return "NET_CAPABILITY_CAPTIVE_PORTAL"; if (hasCapability(NET_CAPABILITY_FOREGROUND)) return "NET_CAPABILITY_FOREGROUND"; // This cannot happen unless the preceding checks are incomplete. if ((mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES) != 0) { return "unknown non-requestable capabilities " + Long.toHexString(mNetworkCapabilities); Loading Loading @@ -352,6 +360,11 @@ public final class NetworkCapabilities implements Parcelable { (that.mNetworkCapabilities & ~MUTABLE_CAPABILITIES)); } private boolean equalsNetCapabilitiesRequestable(NetworkCapabilities that) { return ((this.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES) == (that.mNetworkCapabilities & ~NON_REQUESTABLE_CAPABILITIES)); } /** * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are * typically provided by restricted networks. Loading Loading @@ -749,6 +762,19 @@ public final class NetworkCapabilities implements Parcelable { equalsSpecifier(nc)); } /** * Checks that our requestable capabilities are the same as those of the given * {@code NetworkCapabilities}. * * @hide */ public boolean equalRequestableCapabilities(NetworkCapabilities nc) { if (nc == null) return false; return (equalsNetCapabilitiesRequestable(nc) && equalsTransportTypes(nc) && equalsSpecifier(nc)); } @Override public boolean equals(Object obj) { if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; Loading Loading @@ -833,6 +859,7 @@ public final class NetworkCapabilities implements Parcelable { case NET_CAPABILITY_NOT_VPN: capabilities += "NOT_VPN"; break; case NET_CAPABILITY_VALIDATED: capabilities += "VALIDATED"; break; case NET_CAPABILITY_CAPTIVE_PORTAL: capabilities += "CAPTIVE_PORTAL"; break; case NET_CAPABILITY_FOREGROUND: capabilities += "FOREGROUND"; break; } if (++i < types.length) capabilities += "&"; } Loading
services/core/java/com/android/server/ConnectivityService.java +92 −27 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; Loading Loading @@ -2139,14 +2140,10 @@ public class ConnectivityService extends IConnectivityManager.Stub case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: { final NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj; if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL) || networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED) || networkCapabilities.hasCapability(NET_CAPABILITY_FOREGROUND)) { Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability."); } if (nai.everConnected && !nai.networkCapabilities.equalImmutableCapabilities( networkCapabilities)) { Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities: " + nai.networkCapabilities + " -> " + networkCapabilities); } updateCapabilities(nai, networkCapabilities); break; } Loading Loading @@ -2604,6 +2601,7 @@ public class ConnectivityService extends IConnectivityManager.Stub boolean wasKept = false; NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId); if (nai != null) { boolean wasBackgroundNetwork = nai.isBackgroundNetwork(); nai.removeRequest(nri.request.requestId); if (VDBG) { log(" Removing from current network " + nai.name() + Loading @@ -2619,6 +2617,10 @@ public class ConnectivityService extends IConnectivityManager.Stub wasKept = true; } mNetworkForRequestId.remove(nri.request.requestId); if (!wasBackgroundNetwork && nai.isBackgroundNetwork()) { // Went from foreground to background. updateCapabilities(nai, nai.networkCapabilities); } } // TODO: remove this code once we know that the Slog.wtf is never hit. Loading Loading @@ -4492,6 +4494,12 @@ public class ConnectivityService extends IConnectivityManager.Stub * @param networkCapabilities the new network capabilities. */ private void updateCapabilities(NetworkAgentInfo nai, NetworkCapabilities networkCapabilities) { if (nai.everConnected && !nai.networkCapabilities.equalImmutableCapabilities( networkCapabilities)) { Slog.wtf(TAG, "BUG: " + nai + " changed immutable capabilities: " + nai.networkCapabilities + " -> " + networkCapabilities); } // Don't modify caller's NetworkCapabilities. networkCapabilities = new NetworkCapabilities(networkCapabilities); if (nai.lastValidated) { Loading @@ -4504,8 +4512,14 @@ public class ConnectivityService extends IConnectivityManager.Stub } else { networkCapabilities.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); } if (!Objects.equals(nai.networkCapabilities, networkCapabilities)) { final int oldScore = nai.getCurrentScore(); if (nai.isBackgroundNetwork()) { networkCapabilities.removeCapability(NET_CAPABILITY_FOREGROUND); } else { networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); } if (Objects.equals(nai.networkCapabilities, networkCapabilities)) return; if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) != networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) { try { Loading @@ -4516,9 +4530,22 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("Exception in setNetworkPermission: " + e); } } final int oldScore = nai.getCurrentScore(); final NetworkCapabilities prevNc = nai.networkCapabilities; synchronized (nai) { nai.networkCapabilities = networkCapabilities; } if (nai.getCurrentScore() == oldScore && networkCapabilities.equalRequestableCapabilities(prevNc)) { // If the requestable capabilities haven't changed, and the score hasn't changed, then // the change we're processing can't affect any requests, it can only affect the listens // on this network. We might have been called by rematchNetworkAndRequests when a // network changed foreground state. processListenRequests(nai, true); } else { // If the requestable capabilities have changed or the score changed, we can't have been // called by rematchNetworkAndRequests, so it's safe to start a rematch. rematchAllNetworksAndRequests(nai, oldScore); notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); } Loading Loading @@ -4642,7 +4669,11 @@ public class ConnectivityService extends IConnectivityManager.Stub oldNetwork.clearLingerState(); if (unneeded(oldNetwork, UnneededFor.TEARDOWN)) { // Tear the network down. teardownUnneededNetwork(oldNetwork); } else { // Put the network in the background. updateCapabilities(oldNetwork, oldNetwork.networkCapabilities); } } Loading @@ -4660,7 +4691,7 @@ public class ConnectivityService extends IConnectivityManager.Stub setDefaultDnsSystemProperties(newNetwork.linkProperties.getDnsServers()); } private void processListenRequests(NetworkAgentInfo nai) { private void processListenRequests(NetworkAgentInfo nai, boolean capabilitiesChanged) { // For consistency with previous behaviour, send onLost callbacks before onAvailable. for (NetworkRequestInfo nri : mNetworkRequests.values()) { NetworkRequest nr = nri.request; Loading @@ -4671,6 +4702,10 @@ public class ConnectivityService extends IConnectivityManager.Stub } } if (capabilitiesChanged) { notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); } for (NetworkRequestInfo nri : mNetworkRequests.values()) { NetworkRequest nr = nri.request; if (!nr.isListen()) continue; Loading Loading @@ -4714,12 +4749,18 @@ public class ConnectivityService extends IConnectivityManager.Stub boolean keep = newNetwork.isVPN(); boolean isNewDefault = false; NetworkAgentInfo oldDefaultNetwork = null; final boolean wasBackgroundNetwork = newNetwork.isBackgroundNetwork(); final int score = newNetwork.getCurrentScore(); if (VDBG) log("rematching " + newNetwork.name()); // Find and migrate to this Network any NetworkRequests for // which this network is now the best. ArrayList<NetworkAgentInfo> affectedNetworks = new ArrayList<NetworkAgentInfo>(); ArrayList<NetworkRequestInfo> addedRequests = new ArrayList<NetworkRequestInfo>(); if (VDBG) log(" network has: " + newNetwork.networkCapabilities); NetworkCapabilities nc = newNetwork.networkCapabilities; if (VDBG) log(" network has: " + nc); 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 Loading @@ -4746,10 +4787,9 @@ public class ConnectivityService extends IConnectivityManager.Stub if (VDBG) { log("currentScore = " + (currentNetwork != null ? currentNetwork.getCurrentScore() : 0) + ", newScore = " + newNetwork.getCurrentScore()); ", newScore = " + score); } if (currentNetwork == null || currentNetwork.getCurrentScore() < newNetwork.getCurrentScore()) { if (currentNetwork == null || currentNetwork.getCurrentScore() < score) { if (VDBG) log("rematch for " + newNetwork.name()); if (currentNetwork != null) { if (VDBG) log(" accepting network in place of " + currentNetwork.name()); Loading @@ -4771,7 +4811,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // TODO - this could get expensive if we have alot of requests for this // network. Think about if there is a way to reduce this. Push // netid->request mapping to each factory? sendUpdatedScoreToFactories(nri.request, newNetwork.getCurrentScore()); sendUpdatedScoreToFactories(nri.request, score); if (isDefaultRequest(nri)) { isNewDefault = true; oldDefaultNetwork = currentNetwork; Loading Loading @@ -4829,8 +4869,27 @@ public class ConnectivityService extends IConnectivityManager.Stub } } if (!newNetwork.networkCapabilities.equalRequestableCapabilities(nc)) { Slog.wtf(TAG, String.format( "BUG: %s changed requestable capabilities during rematch: %s -> %s", nc, newNetwork.networkCapabilities)); } if (newNetwork.getCurrentScore() != score) { Slog.wtf(TAG, String.format( "BUG: %s changed score during rematch: %d -> %d", score, newNetwork.getCurrentScore())); } // Second pass: process all listens. processListenRequests(newNetwork); if (wasBackgroundNetwork != newNetwork.isBackgroundNetwork()) { // If the network went from background to foreground or vice versa, we need to update // its foreground state. It is safe to do this after rematching the requests because // NET_CAPABILITY_FOREGROUND does not affect requests, as is not a requestable // capability and does not affect the network's score (see the Slog.wtf call above). updateCapabilities(newNetwork, newNetwork.networkCapabilities); } else { processListenRequests(newNetwork, false); } // do this after the default net is switched, but // before LegacyTypeTracker sends legacy broadcasts Loading Loading @@ -5023,6 +5082,10 @@ public class ConnectivityService extends IConnectivityManager.Stub if (!networkAgent.created && (state == NetworkInfo.State.CONNECTED || (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) { // A network that has just connected has zero requests and is thus a foreground network. networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_FOREGROUND); try { // This should never fail. Specifying an already in use NetID will cause failure. if (networkAgent.isVPN()) { Loading Loading @@ -5184,6 +5247,8 @@ public class ConnectivityService extends IConnectivityManager.Stub NetworkRequest nr = networkAgent.requestAt(i); NetworkRequestInfo nri = mNetworkRequests.get(nr); if (VDBG) log(" sending notification for " + nr); // TODO: if we're in the middle of a rematch, can we send a CAP_CHANGED callback for // a network that no longer satisfies the listen? if (nri.mPendingIntent == null) { callCallbackForRequest(nri, networkAgent, notifyType, arg1); } else { Loading
services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +1 −1 Original line number Diff line number Diff line Loading @@ -380,7 +380,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { * it might satisfy a request if it validated). */ public boolean isBackgroundNetwork() { return numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0; return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0; } // Does this network satisfy request? Loading