diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 11d338d05c..2e701329db 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -112,8 +112,14 @@ public class ConnectivityManager { *
* For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY * is set to {@code true} if there are no connected networks at all. + * + * @deprecated apps should use the more versatile {@link #requestNetwork}, + * {@link #registerNetworkCallback} or {@link #registerDefaultNetworkCallback} + * functions instead for faster and more detailed updates about the network + * changes they care about. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @Deprecated public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; /** @@ -2685,6 +2691,32 @@ public class ConnectivityManager { * satisfying the request changes. * * @param network The {@link Network} of the satisfying network. + * @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network. + * @param linkProperties The {@link LinkProperties} of the satisfying network. + * @hide + */ + public void onAvailable(Network network, NetworkCapabilities networkCapabilities, + LinkProperties linkProperties) { + // Internally only this method is called when a new network is available, and + // it calls the callback in the same way and order that older versions used + // to call so as not to change the behavior. + onAvailable(network); + if (!networkCapabilities.hasCapability( + NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) { + onNetworkSuspended(network); + } + onCapabilitiesChanged(network, networkCapabilities); + onLinkPropertiesChanged(network, linkProperties); + } + + /** + * Called when the framework connects and has declared a new network ready for use. + * This callback may be called more than once if the {@link Network} that is + * satisfying the request changes. This will always immediately be followed by a + * call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a + * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}. + * + * @param network The {@link Network} of the satisfying network. */ public void onAvailable(Network network) {} @@ -2727,7 +2759,8 @@ public class ConnectivityManager { * changes capabilities but still satisfies the stated need. * * @param network The {@link Network} whose capabilities have changed. - * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this network. + * @param networkCapabilities The new {@link android.net.NetworkCapabilities} for this + * network. */ public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {} @@ -2743,7 +2776,7 @@ public class ConnectivityManager { /** * Called when the network the framework connected to for this request - * goes into {@link NetworkInfo.DetailedState.SUSPENDED}. + * goes into {@link NetworkInfo.State#SUSPENDED}. * This generally means that while the TCP connections are still live, * temporarily network data fails to transfer. Specifically this is used * on cellular networks to mask temporary outages when driving through @@ -2754,9 +2787,8 @@ public class ConnectivityManager { /** * Called when the network the framework connected to for this request - * returns from a {@link NetworkInfo.DetailedState.SUSPENDED} state. - * This should always be preceeded by a matching {@code onNetworkSuspended} - * call. + * returns from a {@link NetworkInfo.State#SUSPENDED} state. This should always be + * preceded by a matching {@link NetworkCallback#onNetworkSuspended} call. * @hide */ public void onNetworkResumed(Network network) {} @@ -2865,7 +2897,9 @@ public class ConnectivityManager { break; } case CALLBACK_AVAILABLE: { - callback.onAvailable(network); + NetworkCapabilities cap = getObject(message, NetworkCapabilities.class); + LinkProperties lp = getObject(message, LinkProperties.class); + callback.onAvailable(network, cap, lp); break; } case CALLBACK_LOSING: { diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index e81ed9a21c..bc4d9555c9 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -116,6 +116,7 @@ public final class NetworkCapabilities implements Parcelable { NET_CAPABILITY_NOT_ROAMING, NET_CAPABILITY_FOREGROUND, NET_CAPABILITY_NOT_CONGESTED, + NET_CAPABILITY_NOT_SUSPENDED, }) public @interface NetCapability { } @@ -239,7 +240,6 @@ public final class NetworkCapabilities implements Parcelable { /** * 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 = 19; @@ -252,8 +252,20 @@ public final class NetworkCapabilities implements Parcelable { */ public static final int NET_CAPABILITY_NOT_CONGESTED = 20; + /** + * Indicates that this network is not currently suspended. + *
+ * When a network is suspended, the network's IP addresses and any connections
+ * established on the network remain valid, but the network is temporarily unable
+ * to transfer data. This can happen, for example, if a cellular network experiences
+ * a temporary loss of signal, such as when driving through a tunnel, etc.
+ * A network with this capability is not suspended, so is expected to be able to
+ * transfer data.
+ */
+ public static final int NET_CAPABILITY_NOT_SUSPENDED = 21;
+
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_CONGESTED;
+ private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_SUSPENDED;
/**
* Network capabilities that are expected to be mutable, i.e., can change while a particular
@@ -262,12 +274,13 @@ public final class NetworkCapabilities implements Parcelable {
private static final long MUTABLE_CAPABILITIES =
// TRUSTED can change when user explicitly connects to an untrusted network in Settings.
// http://b/18206275
- (1 << NET_CAPABILITY_TRUSTED) |
- (1 << NET_CAPABILITY_VALIDATED) |
- (1 << NET_CAPABILITY_CAPTIVE_PORTAL) |
- (1 << NET_CAPABILITY_NOT_ROAMING) |
- (1 << NET_CAPABILITY_FOREGROUND) |
- (1 << NET_CAPABILITY_NOT_CONGESTED);
+ (1 << NET_CAPABILITY_TRUSTED)
+ | (1 << NET_CAPABILITY_VALIDATED)
+ | (1 << NET_CAPABILITY_CAPTIVE_PORTAL)
+ | (1 << NET_CAPABILITY_NOT_ROAMING)
+ | (1 << NET_CAPABILITY_FOREGROUND)
+ | (1 << NET_CAPABILITY_NOT_CONGESTED)
+ | (1 << NET_CAPABILITY_NOT_SUSPENDED);
/**
* Network capabilities that are not allowed in NetworkRequests. This exists because the
@@ -1276,6 +1289,7 @@ public final class NetworkCapabilities implements Parcelable {
case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING";
case NET_CAPABILITY_FOREGROUND: return "FOREGROUND";
case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED";
+ case NET_CAPABILITY_NOT_SUSPENDED: return "NOT_SUSPENDED";
default: return Integer.toString(capability);
}
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index bff5c10d4e..fd2ef18d62 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -30,6 +30,7 @@ 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;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
@@ -1260,11 +1261,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
for (Network network : networks) {
nai = getNetworkAgentInfoForNetwork(network);
nc = getNetworkCapabilitiesInternal(nai);
- // nc is a copy of the capabilities in nai, so it's fine to mutate it
- // TODO : don't remove the UIDs when communicating with processes
- // that have the NETWORK_SETTINGS permission.
if (nc != null) {
- nc.setSingleUid(userId);
result.put(network, nc);
}
}
@@ -1332,7 +1329,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (nai != null) {
synchronized (nai) {
if (nai.networkCapabilities != null) {
- return new NetworkCapabilities(nai.networkCapabilities);
+ // TODO : don't remove the UIDs when communicating with processes
+ // that have the NETWORK_SETTINGS permission.
+ return networkCapabilitiesWithoutUids(nai.networkCapabilities);
}
}
}
@@ -1345,6 +1344,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
}
+ private NetworkCapabilities networkCapabilitiesWithoutUids(NetworkCapabilities nc) {
+ return new NetworkCapabilities(nc).setUids(null);
+ }
+
@Override
public NetworkState[] getAllNetworkState() {
// Require internal since we're handing out IMSI details
@@ -1354,6 +1357,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
for (Network network : getAllNetworks()) {
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai != null) {
+ // TODO (b/73321673) : NetworkState contains a copy of the
+ // NetworkCapabilities, which may contain UIDs of apps to which the
+ // network applies. Should the UIDs be cleared so as not to leak or
+ // interfere ?
result.add(nai.getNetworkState());
}
}
@@ -4497,10 +4504,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
lp.ensureDirectlyConnectedRoutes();
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
// satisfies mDefaultRequest.
+ final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
- new Network(reserveNetId()), new NetworkInfo(networkInfo), lp,
- new NetworkCapabilities(networkCapabilities), currentScore,
+ new Network(reserveNetId()), new NetworkInfo(networkInfo), lp, nc, currentScore,
mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest, this);
+ // Make sure the network capabilities reflect what the agent info says.
+ nai.networkCapabilities = mixInCapabilities(nai, nc);
synchronized (this) {
nai.networkMonitor.systemReady = mSystemReady;
}
@@ -4729,6 +4738,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
} else {
newNc.addCapability(NET_CAPABILITY_FOREGROUND);
}
+ if (nai.isSuspended()) {
+ newNc.removeCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ } else {
+ newNc.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
+ }
return newNc;
}
@@ -4909,7 +4923,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
releasePendingNetworkRequestWithDelay(pendingIntent);
}
- private static void callCallbackForRequest(NetworkRequestInfo nri,
+ private void callCallbackForRequest(NetworkRequestInfo nri,
NetworkAgentInfo networkAgent, int notificationType, int arg1) {
if (nri.messenger == null) {
return; // Default request has no msgr
@@ -4922,16 +4936,19 @@ public class ConnectivityService extends IConnectivityManager.Stub
putParcelable(bundle, networkAgent.network);
}
switch (notificationType) {
+ case ConnectivityManager.CALLBACK_AVAILABLE: {
+ putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
+ putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
+ break;
+ }
case ConnectivityManager.CALLBACK_LOSING: {
msg.arg1 = arg1;
break;
}
case ConnectivityManager.CALLBACK_CAP_CHANGED: {
+ // networkAgent can't be null as it has been accessed a few lines above.
final NetworkCapabilities nc =
- new NetworkCapabilities(networkAgent.networkCapabilities);
- // TODO : don't remove the UIDs when communicating with processes
- // that have the NETWORK_SETTINGS permission.
- nc.setSingleUid(nri.mUid);
+ networkCapabilitiesWithoutUids(networkAgent.networkCapabilities);
putParcelable(bundle, nc);
break;
}
@@ -5464,6 +5481,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (networkAgent.getCurrentScore() != oldScore) {
rematchAllNetworksAndRequests(networkAgent, oldScore);
}
+ updateCapabilities(networkAgent.getCurrentScore(), networkAgent,
+ networkAgent.networkCapabilities);
+ // TODO (b/73132094) : remove this call once the few users of onSuspended and
+ // onResumed have been removed.
notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ?
ConnectivityManager.CALLBACK_SUSPENDED :
ConnectivityManager.CALLBACK_RESUMED));
@@ -5500,14 +5521,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0);
- // Whether a network is currently suspended is also an important
- // element of state to be transferred (it would not otherwise be
- // delivered by any currently available mechanism).
- if (nai.networkInfo.getState() == NetworkInfo.State.SUSPENDED) {
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_SUSPENDED, 0);
- }
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_CAP_CHANGED, 0);
- callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_IP_CHANGED, 0);
}
private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 85b70ca0ff..a24f97e535 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -392,6 +392,15 @@ public class NetworkAgentInfo implements Comparable