diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 5b415c835c..abe4056b8e 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -1023,6 +1023,8 @@ public class ConnectivityService extends IConnectivityManager.Stub private final LingerMonitor mLingerMonitor; private final SatelliteAccessController mSatelliteAccessController; + private final L2capNetworkProvider mL2capNetworkProvider; + // sequence number of NetworkRequests private int mNextNetworkRequestId = NetworkRequest.FIRST_REQUEST_ID; @@ -1623,6 +1625,11 @@ public class ConnectivityService extends IConnectivityManager.Stub connectivityServiceInternalHandler); } + /** Creates an L2capNetworkProvider */ + public L2capNetworkProvider makeL2capNetworkProvider(Context context) { + return new L2capNetworkProvider(context); + } + /** Returns the data inactivity timeout to be used for cellular networks */ public int getDefaultCellularDataInactivityTimeout() { return DeviceConfigUtils.getDeviceConfigPropertyInt(NAMESPACE_TETHERING_BOOT, @@ -2094,6 +2101,8 @@ public class ConnectivityService extends IConnectivityManager.Stub } mIngressToVpnAddressFiltering = mDeps.isAtLeastT() && mDeps.isFeatureNotChickenedOut(mContext, INGRESS_TO_VPN_ADDRESS_FILTERING); + + mL2capNetworkProvider = mDeps.makeL2capNetworkProvider(mContext); } /** @@ -4129,6 +4138,10 @@ public class ConnectivityService extends IConnectivityManager.Stub mCarrierPrivilegeAuthenticator.start(); } + if (mL2capNetworkProvider != null) { + mL2capNetworkProvider.start(); + } + // On T+ devices, register callback for statsd to pull NETWORK_BPF_MAP_INFO atom if (mDeps.isAtLeastT()) { mBpfNetMaps.setPullAtomCallback(mContext); diff --git a/tests/cts/net/src/android/net/cts/NetworkReservationTest.kt b/tests/cts/net/src/android/net/cts/NetworkReservationTest.kt index f05bf157e4..d4d4264e65 100644 --- a/tests/cts/net/src/android/net/cts/NetworkReservationTest.kt +++ b/tests/cts/net/src/android/net/cts/NetworkReservationTest.kt @@ -16,15 +16,22 @@ package android.net.cts +import android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS import android.Manifest.permission.MANAGE_TEST_NETWORKS import android.Manifest.permission.NETWORK_SETTINGS import android.net.ConnectivityManager +import android.net.L2capNetworkSpecifier +import android.net.L2capNetworkSpecifier.HEADER_COMPRESSION_6LOWPAN +import android.net.L2capNetworkSpecifier.PSM_ANY +import android.net.L2capNetworkSpecifier.ROLE_SERVER import android.net.NetworkCapabilities import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED +import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED import android.net.NetworkCapabilities.RES_ID_MATCH_ALL_RESERVATIONS +import android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH import android.net.NetworkCapabilities.TRANSPORT_ETHERNET import android.net.NetworkCapabilities.TRANSPORT_TEST import android.net.NetworkProvider @@ -44,6 +51,9 @@ import com.android.testutils.TestableNetworkCallback import com.android.testutils.TestableNetworkOfferCallback import com.android.testutils.runAsShell import kotlin.test.assertEquals +import kotlin.test.assertNotEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue import org.junit.After import org.junit.Before import org.junit.Test @@ -137,4 +147,29 @@ class NetworkReservationTest { provider.unregisterNetworkOffer(reservedOffer) cb.expect() } + + @Test + fun testReserveL2capNetwork() { + val l2capReservationSpecifier = L2capNetworkSpecifier.Builder() + .setRole(ROLE_SERVER) + .setHeaderCompression(HEADER_COMPRESSION_6LOWPAN) + .build() + val l2capRequest = NetworkRequest.Builder() + .addTransportType(TRANSPORT_BLUETOOTH) + .removeCapability(NET_CAPABILITY_TRUSTED) + .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) + .setNetworkSpecifier(l2capReservationSpecifier) + .build() + val cb = TestableNetworkCallback() + runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS) { + cm.reserveNetwork(l2capRequest, handler, cb) + } + + val caps = cb.expect().caps + val reservedSpec = caps.networkSpecifier + assertTrue(reservedSpec is L2capNetworkSpecifier) + assertNotEquals(PSM_ANY, reservedSpec.psm) + assertEquals(HEADER_COMPRESSION_6LOWPAN, reservedSpec.headerCompression) + assertNull(reservedSpec.remoteAddress) + } } diff --git a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt index 375d604ebb..cc9445da88 100644 --- a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt +++ b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt @@ -55,6 +55,7 @@ import com.android.net.module.util.BpfUtils import com.android.networkstack.apishim.TelephonyManagerShimImpl import com.android.server.BpfNetMaps import com.android.server.ConnectivityService +import com.android.server.L2capNetworkProvider import com.android.server.NetworkAgentWrapper import com.android.server.TestNetIdManager import com.android.server.connectivity.CarrierPrivilegeAuthenticator @@ -272,6 +273,8 @@ class ConnectivityServiceIntegrationTest { connectivityServiceInternalHandler: Handler ): SatelliteAccessController? = mock( SatelliteAccessController::class.java) + + override fun makeL2capNetworkProvider(context: Context) = null } @After diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index f7d7c87882..1562dad55f 100755 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -412,6 +412,7 @@ import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInf import com.android.server.ConnectivityService.NetworkRequestInfo; import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.DestroySocketsWrapper; import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.ReportedInterfaces; +import com.android.server.L2capNetworkProvider; import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities; import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker; import com.android.server.connectivity.CarrierPrivilegeAuthenticator; @@ -2381,6 +2382,11 @@ public class ConnectivityServiceTest { // Needed to mock out the dependency on DeviceConfig return 15; } + + @Override + public L2capNetworkProvider makeL2capNetworkProvider(Context context) { + return null; + } } private class AutomaticOnOffKeepaliveTrackerDependencies diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt index ae196a624b..77c7fe6285 100644 --- a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt +++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt @@ -393,6 +393,8 @@ open class CSTest { // Call mocked destroyLiveTcpSocketsByOwnerUids so that test can verify this method call destroySocketsWrapper.destroyLiveTcpSocketsByOwnerUids(ownerUids) } + + override fun makeL2capNetworkProvider(context: Context) = null } inner class CSContext(base: Context) : BroadcastInterceptingContext(base) {