Add "not congested" network capability.
Can be used by a network to indicate when it's congested, meaning that
apps should defer network traffic that could be done at a later time.
Test: bit FrameworksNetTests:android.net.,com.android.server.net.,com.android.server.connectivity.VpnTest,com.android.server.ConnectivityServiceTest
Bug: 64133169
Change-Id: I8a60b6f02dd0f42268b59690556c16335d34e220
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 7c897de..be85583 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -107,6 +107,7 @@
NET_CAPABILITY_CAPTIVE_PORTAL,
NET_CAPABILITY_NOT_ROAMING,
NET_CAPABILITY_FOREGROUND,
+ NET_CAPABILITY_NOT_CONGESTED,
})
public @interface NetCapability { }
@@ -234,8 +235,17 @@
*/
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 @@
(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 @@
* @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 @@
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 7715727..9f92aaf 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 @@
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;
@@ -297,11 +298,13 @@
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);
@@ -317,22 +320,16 @@
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 c29363c..1dbf9b2 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_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 @@
.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 @@
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 @@
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 @@
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 @@
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));
}
/**