diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java index abda1fa71f1f180544534c3456b48df33544398a..5d70857aa652d575067b6f02ab098e9448604030 100644 --- a/framework/src/android/net/NetworkCapabilities.java +++ b/framework/src/android/net/NetworkCapabilities.java @@ -3235,4 +3235,4 @@ public final class NetworkCapabilities implements Parcelable { return new NetworkCapabilities(mCaps); } } -} \ No newline at end of file +} diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSAgentWrapper.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSAgentWrapper.kt index c558586b152c91f4d35a1dd24213a61ed44c9c0c..51a065893979eb23905f34ec59de5d492306f371 100644 --- a/tests/unit/java/com/android/server/connectivityservice/base/CSAgentWrapper.kt +++ b/tests/unit/java/com/android/server/connectivityservice/base/CSAgentWrapper.kt @@ -35,6 +35,7 @@ import android.net.networkstack.NetworkStackClientBase import android.os.HandlerThread import com.android.modules.utils.build.SdkLevel import com.android.testutils.RecorderCallback.CallbackEntry.Available +import com.android.testutils.RecorderCallback.CallbackEntry.Lost import com.android.testutils.TestableNetworkCallback import org.mockito.ArgumentCaptor import org.mockito.ArgumentMatchers.any @@ -47,6 +48,8 @@ import java.util.concurrent.atomic.AtomicInteger import kotlin.test.assertEquals import kotlin.test.fail +const val SHORT_TIMEOUT_MS = 200L + private inline fun <reified T> ArgumentCaptor() = ArgumentCaptor.forClass(T::class.java) private val agentCounter = AtomicInteger(1) @@ -60,6 +63,7 @@ private fun nextAgentId() = agentCounter.getAndIncrement() */ class CSAgentWrapper( val context: Context, + val deps: ConnectivityService.Dependencies, csHandlerThread: HandlerThread, networkStack: NetworkStackClientBase, nac: NetworkAgentConfig, @@ -149,6 +153,15 @@ class CSAgentWrapper( } fun disconnect() { + val mgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val request = NetworkRequest.Builder().apply { + clearCapabilities() + if (nc.transportTypes.isNotEmpty()) addTransportType(nc.transportTypes[0]) + }.build() + val cb = TestableNetworkCallback(timeoutMs = SHORT_TIMEOUT_MS) + mgr.registerNetworkCallback(request, cb) + cb.eventuallyExpect<Available> { it.network == agent.network } agent.unregister() + cb.eventuallyExpect<Lost> { it.network == agent.network } } } 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 9a1e509b4f065b5b9b2b32b81a567ef61e2685c7..2f78212768b647eeff7255c04c6fd33a39faf7d1 100644 --- a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt +++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt @@ -30,6 +30,12 @@ import android.net.LinkProperties import android.net.NetworkAgentConfig import android.net.NetworkCapabilities import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED +import android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH +import android.net.NetworkCapabilities.TRANSPORT_CELLULAR +import android.net.NetworkCapabilities.TRANSPORT_ETHERNET +import android.net.NetworkCapabilities.TRANSPORT_TEST +import android.net.NetworkCapabilities.TRANSPORT_VPN +import android.net.NetworkCapabilities.TRANSPORT_WIFI import android.net.NetworkPolicyManager import android.net.NetworkProvider import android.net.NetworkScore @@ -79,6 +85,17 @@ internal const val VERSION_U = 4 internal const val VERSION_V = 5 internal const val VERSION_MAX = VERSION_V +private fun NetworkCapabilities.getLegacyType() = + when (transportTypes.getOrElse(0) { TRANSPORT_WIFI }) { + TRANSPORT_BLUETOOTH -> ConnectivityManager.TYPE_BLUETOOTH + TRANSPORT_CELLULAR -> ConnectivityManager.TYPE_MOBILE + TRANSPORT_ETHERNET -> ConnectivityManager.TYPE_ETHERNET + TRANSPORT_TEST -> ConnectivityManager.TYPE_TEST + TRANSPORT_VPN -> ConnectivityManager.TYPE_VPN + TRANSPORT_WIFI -> ConnectivityManager.TYPE_WIFI + else -> ConnectivityManager.TYPE_NONE + } + /** * Base class for tests testing ConnectivityService and its satellites. * @@ -127,7 +144,7 @@ open class CSTest { val networkStack = mock<NetworkStackClientBase>() val csHandlerThread = HandlerThread("CSTestHandler") val sysResources = mock<Resources>().also { initMockedResources(it) } - val packageManager = makeMockPackageManager() + val packageManager = makeMockPackageManager(instrumentationContext) val connResources = makeMockConnResources(sysResources, packageManager) val netd = mock<INetd>() @@ -272,12 +289,12 @@ open class CSTest { // Network agents. See CSAgentWrapper. This class contains utility methods to simplify // creation. fun Agent( - nac: NetworkAgentConfig = emptyAgentConfig(), nc: NetworkCapabilities = defaultNc(), + nac: NetworkAgentConfig = emptyAgentConfig(nc.getLegacyType()), lp: LinkProperties = defaultLp(), score: FromS<NetworkScore> = defaultScore(), provider: NetworkProvider? = null - ) = CSAgentWrapper(context, csHandlerThread, networkStack, nac, nc, lp, score, provider) + ) = CSAgentWrapper(context, deps, csHandlerThread, networkStack, nac, nc, lp, score, provider) fun Agent(vararg transports: Int, lp: LinkProperties = defaultLp()): CSAgentWrapper { val nc = NetworkCapabilities.Builder().apply { diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTestHelpers.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTestHelpers.kt index 2d8607bad58f742e5904c3578c1c050e70033238..c1828b230082849231c0ba8a5891ed81c07d669f 100644 --- a/tests/unit/java/com/android/server/connectivityservice/base/CSTestHelpers.kt +++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTestHelpers.kt @@ -38,6 +38,7 @@ import android.net.NetworkCapabilities import android.net.NetworkScore import android.net.RouteInfo import android.net.metrics.IpConnectivityLog +import android.os.Binder import android.os.Handler import android.os.HandlerThread import android.os.SystemClock @@ -54,20 +55,23 @@ import com.android.server.ConnectivityService.Dependencies import com.android.server.connectivity.ConnectivityResources import org.mockito.ArgumentMatchers import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyLong import org.mockito.ArgumentMatchers.anyString import org.mockito.ArgumentMatchers.argThat import org.mockito.ArgumentMatchers.eq import org.mockito.Mockito import org.mockito.Mockito.doAnswer -import org.mockito.Mockito.doReturn import org.mockito.Mockito.doNothing +import org.mockito.Mockito.doReturn import kotlin.test.fail internal inline fun <reified T> mock() = Mockito.mock(T::class.java) internal inline fun <reified T> any() = any(T::class.java) -internal fun emptyAgentConfig() = NetworkAgentConfig.Builder().build() +internal fun emptyAgentConfig(legacyType: Int) = NetworkAgentConfig.Builder() + .setLegacyType(legacyType) + .build() internal fun defaultNc() = NetworkCapabilities.Builder() // Add sensible defaults for agents that don't want to care @@ -98,9 +102,22 @@ internal fun makeActivityManager() = mock<ActivityManager>().also { } } -internal fun makeMockPackageManager() = mock<PackageManager>().also { pm -> +internal fun makeMockPackageManager(realContext: Context) = mock<PackageManager>().also { pm -> val supported = listOf(FEATURE_WIFI, FEATURE_WIFI_DIRECT, FEATURE_BLUETOOTH, FEATURE_ETHERNET) doReturn(true).`when`(pm).hasSystemFeature(argThat { supported.contains(it) }) + val myPackageName = realContext.packageName + val myPackageInfo = realContext.packageManager.getPackageInfo(myPackageName, + PackageManager.GET_PERMISSIONS) + // Very high version code so that the checks for the module version will always + // say that it is recent enough. This is the most sensible default, but if some + // test needs to test with different version codes they can re-mock this with a + // different value. + myPackageInfo.longVersionCode = 9999999L + doReturn(arrayOf(myPackageName)).`when`(pm).getPackagesForUid(Binder.getCallingUid()) + doReturn(myPackageInfo).`when`(pm).getPackageInfoAsUser( + eq(myPackageName), anyInt(), eq(UserHandle.getCallingUserId())) + doReturn(listOf(myPackageInfo)).`when`(pm) + .getInstalledPackagesAsUser(eq(PackageManager.GET_PERMISSIONS), anyInt()) } internal fun makeMockConnResources(resources: Resources, pm: PackageManager) = mock<Context>().let {