diff options
3 files changed, 31 insertions, 18 deletions
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 7c897de9b5e9..be85583a823f 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -107,6 +107,7 @@ public final class NetworkCapabilities implements Parcelable { NET_CAPABILITY_CAPTIVE_PORTAL, NET_CAPABILITY_NOT_ROAMING, NET_CAPABILITY_FOREGROUND, + NET_CAPABILITY_NOT_CONGESTED, }) public @interface NetCapability { } @@ -234,8 +235,17 @@ public final class NetworkCapabilities implements Parcelable { */ public static final int NET_CAPABILITY_FOREGROUND = 19; + /** + * Indicates that this network is not congested. + * <p> + * When a network is congested, the device should defer network traffic that + * can be done at a later time without breaking developer contracts. + * @hide + */ + public static final int NET_CAPABILITY_NOT_CONGESTED = 20; + private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; - private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_FOREGROUND; + private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_CONGESTED; /** * Network capabilities that are expected to be mutable, i.e., can change while a particular @@ -248,7 +258,8 @@ public final class NetworkCapabilities implements Parcelable { (1 << NET_CAPABILITY_VALIDATED) | (1 << NET_CAPABILITY_CAPTIVE_PORTAL) | (1 << NET_CAPABILITY_NOT_ROAMING) | - (1 << NET_CAPABILITY_FOREGROUND); + (1 << NET_CAPABILITY_FOREGROUND) | + (1 << NET_CAPABILITY_NOT_CONGESTED); /** * Network capabilities that are not allowed in NetworkRequests. This exists because the @@ -386,12 +397,9 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ 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); + final long nonRequestable = (mNetworkCapabilities & NON_REQUESTABLE_CAPABILITIES); + if (nonRequestable != 0) { + return capabilityNameOf(BitUtils.unpackBits(nonRequestable)[0]); } if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth"; if (hasSignalStrength()) return "signalStrength"; @@ -1056,6 +1064,7 @@ public final class NetworkCapabilities implements Parcelable { case NET_CAPABILITY_CAPTIVE_PORTAL: return "CAPTIVE_PORTAL"; case NET_CAPABILITY_NOT_ROAMING: return "NOT_ROAMING"; case NET_CAPABILITY_FOREGROUND: return "FOREGROUND"; + case NET_CAPABILITY_NOT_CONGESTED: return "NOT_CONGESTED"; default: return Integer.toString(capability); } } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 3c2d72407b4e..aa174e3ad715 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -18,6 +18,7 @@ package com.android.server.connectivity; import static android.Manifest.permission.BIND_VPN_SERVICE; import static android.net.ConnectivityManager.NETID_UNSET; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.RouteInfo.RTN_THROW; @@ -298,11 +299,13 @@ public class Vpn { int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; boolean metered = false; boolean roaming = false; + boolean congested = false; if (ArrayUtils.isEmpty(underlyingNetworks)) { // No idea what the underlying networks are; assume sane defaults metered = true; roaming = false; + congested = false; } else { for (Network underlying : underlyingNetworks) { final NetworkCapabilities underlyingCaps = cm.getNetworkCapabilities(underlying); @@ -319,22 +322,16 @@ public class Vpn { underlyingCaps.getLinkUpstreamBandwidthKbps()); metered |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_METERED); roaming |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING); + congested |= !underlyingCaps.hasCapability(NET_CAPABILITY_NOT_CONGESTED); } } caps.setTransportTypes(transportTypes); caps.setLinkDownstreamBandwidthKbps(downKbps); caps.setLinkUpstreamBandwidthKbps(upKbps); - if (metered) { - caps.removeCapability(NET_CAPABILITY_NOT_METERED); - } else { - caps.addCapability(NET_CAPABILITY_NOT_METERED); - } - if (roaming) { - caps.removeCapability(NET_CAPABILITY_NOT_ROAMING); - } else { - caps.addCapability(NET_CAPABILITY_NOT_ROAMING); - } + caps.setCapability(NET_CAPABILITY_NOT_METERED, !metered); + caps.setCapability(NET_CAPABILITY_NOT_ROAMING, !roaming); + caps.setCapability(NET_CAPABILITY_NOT_CONGESTED, !congested); } /** diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index c29363cd1a4f..1dbf9b2dfced 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -22,6 +22,7 @@ import static android.content.pm.UserInfo.FLAG_PRIMARY; import static android.content.pm.UserInfo.FLAG_RESTRICTED; import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; @@ -436,11 +437,13 @@ public class VpnTest { .addTransportType(TRANSPORT_CELLULAR) .addCapability(NET_CAPABILITY_INTERNET) .addCapability(NET_CAPABILITY_NOT_METERED) + .addCapability(NET_CAPABILITY_NOT_CONGESTED) .setLinkDownstreamBandwidthKbps(10)); networks.put(wifi, new NetworkCapabilities() .addTransportType(TRANSPORT_WIFI) .addCapability(NET_CAPABILITY_INTERNET) .addCapability(NET_CAPABILITY_NOT_ROAMING) + .addCapability(NET_CAPABILITY_NOT_CONGESTED) .setLinkUpstreamBandwidthKbps(20)); setMockedNetworks(networks); @@ -454,6 +457,7 @@ public class VpnTest { assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps()); assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); + assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); Vpn.updateCapabilities(mConnectivityManager, new Network[] { mobile }, caps); assertTrue(caps.hasTransport(TRANSPORT_VPN)); @@ -463,6 +467,7 @@ public class VpnTest { assertEquals(LINK_BANDWIDTH_UNSPECIFIED, caps.getLinkUpstreamBandwidthKbps()); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); + assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); Vpn.updateCapabilities(mConnectivityManager, new Network[] { wifi }, caps); assertTrue(caps.hasTransport(TRANSPORT_VPN)); @@ -472,6 +477,7 @@ public class VpnTest { assertEquals(20, caps.getLinkUpstreamBandwidthKbps()); assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); + assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); Vpn.updateCapabilities(mConnectivityManager, new Network[] { mobile, wifi }, caps); assertTrue(caps.hasTransport(TRANSPORT_VPN)); @@ -481,6 +487,7 @@ public class VpnTest { assertEquals(20, caps.getLinkUpstreamBandwidthKbps()); assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_METERED)); assertFalse(caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); + assertTrue(caps.hasCapability(NET_CAPABILITY_NOT_CONGESTED)); } /** |