Start L2capNetworkProvider in CS

Starts L2capNetworkProvider in ConnectivityService. Alternatively, this
could be moved to ConnectivityServiceInitializer instead in a follow up.

When L2capNetworkProvider is created, it starts a handler thread, so
makeL2capNetworkProvider must return null in tests as otherwise the
thread leaks.

Test: atest NetworkReservationTest
Change-Id: I35c14815b1a71f0739c1bf63ad466763d611434c
This commit is contained in:
Patrick Rohr 2025-01-10 14:20:27 -08:00
commit 611ce3f57c
5 changed files with 59 additions and 0 deletions

View file

@ -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);

View file

@ -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<Unavailable>()
}
@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<Reserved>().caps
val reservedSpec = caps.networkSpecifier
assertTrue(reservedSpec is L2capNetworkSpecifier)
assertNotEquals(PSM_ANY, reservedSpec.psm)
assertEquals(HEADER_COMPRESSION_6LOWPAN, reservedSpec.headerCompression)
assertNull(reservedSpec.remoteAddress)
}
}

View file

@ -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

View file

@ -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

View file

@ -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) {