Introduce NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED
On V+, this capability is set by default.
Constrained satellite networks never become the system default network.
Test: CSSatelliteNetworkTest
Bug: 343823469
Change-Id: I020ba48e74f1f180e1807cbe1c066209bedb0454
diff --git a/common/flags.aconfig b/common/flags.aconfig
index 6c3e89d..bc4168b 100644
--- a/common/flags.aconfig
+++ b/common/flags.aconfig
@@ -107,3 +107,11 @@
description: "Flag for BLOCKED_REASON_NETWORK_RESTRICTED API"
bug: "339559837"
}
+
+flag {
+ name: "net_capability_not_bandwidth_constrained"
+ is_exported: true
+ namespace: "android_core_networking"
+ description: "Flag for NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED API"
+ bug: "343823469"
+}
diff --git a/framework/api/current.txt b/framework/api/current.txt
index ef8415c..7bc0cf3 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -337,6 +337,7 @@
field public static final int NET_CAPABILITY_MCX = 23; // 0x17
field public static final int NET_CAPABILITY_MMS = 0; // 0x0
field public static final int NET_CAPABILITY_MMTEL = 33; // 0x21
+ field @FlaggedApi("com.android.net.flags.net_capability_not_bandwidth_constrained") public static final int NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED = 37; // 0x25
field public static final int NET_CAPABILITY_NOT_CONGESTED = 20; // 0x14
field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index a5a6723..6a14bde 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -40,6 +40,7 @@
import android.util.Range;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.BitUtils;
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.NetworkCapabilitiesUtils;
@@ -135,6 +136,8 @@
"com.android.net.flags.request_restricted_wifi";
static final String SUPPORT_TRANSPORT_SATELLITE =
"com.android.net.flags.support_transport_satellite";
+ static final String NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED =
+ "com.android.net.flags.net_capability_not_bandwidth_constrained";
}
/**
@@ -459,6 +462,7 @@
NET_CAPABILITY_PRIORITIZE_LATENCY,
NET_CAPABILITY_PRIORITIZE_BANDWIDTH,
NET_CAPABILITY_LOCAL_NETWORK,
+ NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED,
})
public @interface NetCapability { }
@@ -741,7 +745,26 @@
@FlaggedApi(Flags.FLAG_NET_CAPABILITY_LOCAL_NETWORK)
public static final int NET_CAPABILITY_LOCAL_NETWORK = 36;
- private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_LOCAL_NETWORK;
+ /**
+ * Indicates that this is not a bandwidth-constrained network.
+ *
+ * Starting from {@link Build.VERSION_CODES.VANILLA_ICE_CREAM}, this capability is by default
+ * set in {@link NetworkRequest}s and true for most networks.
+ *
+ * If a network lacks this capability, it is bandwidth-constrained. Bandwidth constrained
+ * networks cannot support high-bandwidth data transfers and applications that request and use
+ * them must ensure that they limit bandwidth usage to below the values returned by
+ * {@link #getLinkDownstreamBandwidthKbps()} and {@link #getLinkUpstreamBandwidthKbps()} and
+ * limit the frequency of their network usage. If applications perform high-bandwidth data
+ * transfers on constrained networks or perform network access too frequently, the system may
+ * block the app's access to the network. The system may take other measures to reduce network
+ * usage on constrained networks, such as disabling network access to apps that are not in the
+ * foreground.
+ */
+ @FlaggedApi(Flags.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)
+ public static final int NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED = 37;
+
+ private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED;
// Set all bits up to the MAX_NET_CAPABILITY-th bit
private static final long ALL_VALID_CAPABILITIES = (2L << MAX_NET_CAPABILITY) - 1;
@@ -785,10 +808,17 @@
/**
* Capabilities that are set by default when the object is constructed.
*/
- private static final long DEFAULT_CAPABILITIES =
- (1L << NET_CAPABILITY_NOT_RESTRICTED) |
- (1L << NET_CAPABILITY_TRUSTED) |
- (1L << NET_CAPABILITY_NOT_VPN);
+ private static final long DEFAULT_CAPABILITIES;
+ static {
+ long defaultCapabilities =
+ (1L << NET_CAPABILITY_NOT_RESTRICTED)
+ | (1L << NET_CAPABILITY_TRUSTED)
+ | (1L << NET_CAPABILITY_NOT_VPN);
+ if (SdkLevel.isAtLeastV()) {
+ defaultCapabilities |= (1L << NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
+ }
+ DEFAULT_CAPABILITIES = defaultCapabilities;
+ }
/**
* Capabilities that are managed by ConnectivityService.
@@ -815,7 +845,9 @@
(1L << NET_CAPABILITY_NOT_ROAMING) |
(1L << NET_CAPABILITY_NOT_CONGESTED) |
(1L << NET_CAPABILITY_NOT_SUSPENDED) |
- (1L << NET_CAPABILITY_NOT_VCN_MANAGED);
+ (1L << NET_CAPABILITY_NOT_VCN_MANAGED) |
+ (1L << NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
+
/**
* Extra allowed capabilities for test networks that do not have TRANSPORT_CELLULAR. Test
@@ -2603,6 +2635,7 @@
case NET_CAPABILITY_PRIORITIZE_LATENCY: return "PRIORITIZE_LATENCY";
case NET_CAPABILITY_PRIORITIZE_BANDWIDTH: return "PRIORITIZE_BANDWIDTH";
case NET_CAPABILITY_LOCAL_NETWORK: return "LOCAL_NETWORK";
+ case NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED: return "NOT_BANDWIDTH_CONSTRAINED";
default: return Integer.toString(capability);
}
}
diff --git a/framework/src/android/net/NetworkRequest.java b/framework/src/android/net/NetworkRequest.java
index f7600b2..502ac6f 100644
--- a/framework/src/android/net/NetworkRequest.java
+++ b/framework/src/android/net/NetworkRequest.java
@@ -20,6 +20,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED;
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_RESTRICTED;
@@ -286,7 +287,8 @@
NET_CAPABILITY_PARTIAL_CONNECTIVITY,
NET_CAPABILITY_TEMPORARILY_NOT_METERED,
NET_CAPABILITY_TRUSTED,
- NET_CAPABILITY_VALIDATED);
+ NET_CAPABILITY_VALIDATED,
+ NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
private final NetworkCapabilities mNetworkCapabilities;
diff --git a/service/src/com/android/server/TestNetworkService.java b/service/src/com/android/server/TestNetworkService.java
index 843b7b3..4d39d7d 100644
--- a/service/src/com/android/server/TestNetworkService.java
+++ b/service/src/com/android/server/TestNetworkService.java
@@ -267,6 +267,7 @@
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
+ nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
nc.setNetworkSpecifier(new TestNetworkSpecifier(iface));
nc.setAdministratorUids(administratorUids);
if (!isMetered) {
diff --git a/tests/unit/java/com/android/server/connectivityservice/CSSatelliteNetworkTest.kt b/tests/unit/java/com/android/server/connectivityservice/CSSatelliteNetworkTest.kt
index 45de4a7..e99afe3 100644
--- a/tests/unit/java/com/android/server/connectivityservice/CSSatelliteNetworkTest.kt
+++ b/tests/unit/java/com/android/server/connectivityservice/CSSatelliteNetworkTest.kt
@@ -24,6 +24,7 @@
import android.net.NativeNetworkType
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
+import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED
@@ -41,10 +42,14 @@
import android.util.ArraySet
import com.android.net.module.util.CollectionUtils
import com.android.server.ConnectivityService.PREFERENCE_ORDER_SATELLITE_FALLBACK
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.TestableNetworkCallback
import com.android.testutils.visibleOnHandlerThread
import org.junit.Assert
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
@@ -62,6 +67,9 @@
@RunWith(DevSdkIgnoreRunner::class)
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
class CSSatelliteNetworkTest : CSTest() {
+ @get:Rule
+ val ignoreRule = DevSdkIgnoreRule()
+
/**
* Test createMultiLayerNrisFromSatelliteNetworkPreferredUids returns correct
* NetworkRequestInfo.
@@ -83,7 +91,9 @@
* Test that SATELLITE_NETWORK_PREFERENCE_UIDS changes will send correct net id and uid ranges
* to netd.
*/
- @Test
+ // TODO(aosp/3109163): Run on V+ where NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED is set by
+ // default
+ @Test @IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
fun testSatelliteNetworkPreferredUidsChanged() {
val netdInOrder = inOrder(netd)
@@ -128,6 +138,25 @@
netdInOrder.verify(netd).networkAddUidRangesParcel(config2)
}
+ private fun doTestSatelliteNeverBecomeDefaultNetwork(restricted: Boolean) {
+ val agent = createSatelliteAgent("satellite0", restricted)
+ agent.connect()
+ val defaultCb = TestableNetworkCallback()
+ cm.registerDefaultNetworkCallback(defaultCb)
+ // Satellite network must not become the default network
+ defaultCb.assertNoCallback()
+ }
+
+ @Test
+ fun testSatelliteNeverBecomeDefaultNetwork_restricted() {
+ doTestSatelliteNeverBecomeDefaultNetwork(restricted = true)
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ fun testSatelliteNeverBecomeDefaultNetwork_notRestricted() {
+ doTestSatelliteNeverBecomeDefaultNetwork(restricted = false)
+ }
+
private fun assertCreateMultiLayerNrisFromSatelliteNetworkPreferredUids(uids: Set<Int>) {
val nris: Set<ConnectivityService.NetworkRequestInfo> =
service.createMultiLayerNrisFromSatelliteNetworkFallbackUids(uids)
@@ -150,9 +179,9 @@
NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission,
false /* secure */, VpnManager.TYPE_VPN_NONE, false /* excludeLocalRoutes */)
- private fun createSatelliteAgent(name: String): CSAgentWrapper {
+ private fun createSatelliteAgent(name: String, restricted: Boolean = true): CSAgentWrapper {
return Agent(score = keepScore(), lp = lp(name),
- nc = satelliteNc()
+ nc = satelliteNc(restricted)
)
}
@@ -176,7 +205,7 @@
return uidRangesForUids(*CollectionUtils.toIntArray(uids))
}
- private fun satelliteNc() =
+ private fun satelliteNc(restricted: Boolean) =
NetworkCapabilities.Builder().apply {
addTransportType(TRANSPORT_SATELLITE)
@@ -184,7 +213,10 @@
addCapability(NET_CAPABILITY_NOT_SUSPENDED)
addCapability(NET_CAPABILITY_NOT_ROAMING)
addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
- removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ if (restricted) {
+ removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ }
+ removeCapability(NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)
}.build()
private fun lp(iface: String) = LinkProperties().apply {