1 /* <lambda>null2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.net.cts 17 18 import android.Manifest.permission.NETWORK_SETTINGS 19 import android.app.Instrumentation 20 import android.content.Context 21 import android.net.ConnectivityManager 22 import android.net.EthernetNetworkSpecifier 23 import android.net.INetworkAgent 24 import android.net.INetworkAgentRegistry 25 import android.net.InetAddresses 26 import android.net.IpPrefix 27 import android.net.LinkAddress 28 import android.net.LinkProperties 29 import android.net.NattKeepalivePacketData 30 import android.net.Network 31 import android.net.NetworkAgent 32 import android.net.NetworkAgent.INVALID_NETWORK 33 import android.net.NetworkAgent.VALID_NETWORK 34 import android.net.NetworkAgentConfig 35 import android.net.NetworkCapabilities 36 import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET 37 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED 38 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED 39 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED 40 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING 41 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED 42 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED 43 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN 44 import android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED 45 import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED 46 import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED 47 import android.net.NetworkCapabilities.TRANSPORT_CELLULAR 48 import android.net.NetworkCapabilities.TRANSPORT_TEST 49 import android.net.NetworkCapabilities.TRANSPORT_VPN 50 import android.net.NetworkCapabilities.TRANSPORT_WIFI 51 import android.net.NetworkInfo 52 import android.net.NetworkProvider 53 import android.net.NetworkReleasedException 54 import android.net.NetworkRequest 55 import android.net.NetworkScore 56 import android.net.QosCallback 57 import android.net.QosCallback.QosCallbackRegistrationException 58 import android.net.QosCallbackException 59 import android.net.QosSession 60 import android.net.QosSessionAttributes 61 import android.net.QosSocketInfo 62 import android.net.RouteInfo 63 import android.net.SocketKeepalive 64 import android.net.TestNetworkInterface 65 import android.net.TestNetworkManager 66 import android.net.Uri 67 import android.net.VpnManager 68 import android.net.VpnTransportInfo 69 import android.net.cts.NetworkAgentTest.TestableQosCallback.CallbackEntry.OnError 70 import android.net.cts.NetworkAgentTest.TestableQosCallback.CallbackEntry.OnQosSessionAvailable 71 import android.net.cts.NetworkAgentTest.TestableQosCallback.CallbackEntry.OnQosSessionLost 72 import android.os.Build 73 import android.os.Handler 74 import android.os.HandlerThread 75 import android.os.Message 76 import android.os.Process 77 import android.os.SystemClock 78 import android.platform.test.annotations.AppModeFull 79 import android.system.OsConstants.IPPROTO_TCP 80 import android.system.OsConstants.IPPROTO_UDP 81 import android.telephony.TelephonyManager 82 import android.telephony.data.EpsBearerQosSessionAttributes 83 import android.util.DebugUtils.valueToString 84 import androidx.test.InstrumentationRegistry 85 import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity 86 import com.android.compatibility.common.util.ThrowingSupplier 87 import com.android.modules.utils.build.SdkLevel 88 import com.android.net.module.util.ArrayTrackRecord 89 import com.android.testutils.CompatUtil 90 import com.android.testutils.ConnectivityModuleTest 91 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo 92 import com.android.testutils.DevSdkIgnoreRunner 93 import com.android.testutils.RecorderCallback.CallbackEntry.Available 94 import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatus 95 import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged 96 import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged 97 import com.android.testutils.RecorderCallback.CallbackEntry.Losing 98 import com.android.testutils.RecorderCallback.CallbackEntry.Lost 99 import com.android.testutils.TestableNetworkAgent 100 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter 101 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled 102 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested 103 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkCreated 104 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkDestroyed 105 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted 106 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnRegisterQosCallback 107 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter 108 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated 109 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive 110 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive 111 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnUnregisterQosCallback 112 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnValidationStatus 113 import com.android.testutils.TestableNetworkCallback 114 import com.android.testutils.assertThrows 115 import java.io.Closeable 116 import java.io.IOException 117 import java.net.DatagramSocket 118 import java.net.InetAddress 119 import java.net.InetSocketAddress 120 import java.net.Socket 121 import java.time.Duration 122 import java.util.Arrays 123 import java.util.UUID 124 import java.util.concurrent.Executors 125 import kotlin.test.assertEquals 126 import kotlin.test.assertFailsWith 127 import kotlin.test.assertFalse 128 import kotlin.test.assertNotNull 129 import kotlin.test.assertNull 130 import kotlin.test.assertTrue 131 import kotlin.test.fail 132 import org.junit.After 133 import org.junit.Assume.assumeFalse 134 import org.junit.Before 135 import org.junit.Test 136 import org.junit.runner.RunWith 137 import org.mockito.ArgumentMatchers.any 138 import org.mockito.ArgumentMatchers.argThat 139 import org.mockito.ArgumentMatchers.eq 140 import org.mockito.Mockito.doReturn 141 import org.mockito.Mockito.mock 142 import org.mockito.Mockito.timeout 143 import org.mockito.Mockito.verify 144 145 // This test doesn't really have a constraint on how fast the methods should return. If it's 146 // going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio 147 // without affecting the run time of successful runs. Thus, set a very high timeout. 148 private const val DEFAULT_TIMEOUT_MS = 5000L 149 // When waiting for a NetworkCallback to determine there was no timeout, waiting is the 150 // only possible thing (the relevant handler is the one in the real ConnectivityService, 151 // and then there is the Binder call), so have a short timeout for this as it will be 152 // exhausted every time. 153 private const val NO_CALLBACK_TIMEOUT = 200L 154 private const val WORSE_NETWORK_SCORE = 65 155 private const val BETTER_NETWORK_SCORE = 75 156 private const val FAKE_NET_ID = 1098 157 private val instrumentation: Instrumentation 158 get() = InstrumentationRegistry.getInstrumentation() 159 private val realContext: Context 160 get() = InstrumentationRegistry.getContext() 161 private fun Message(what: Int, arg1: Int, arg2: Int, obj: Any?) = Message.obtain().also { 162 it.what = what 163 it.arg1 = arg1 164 it.arg2 = arg2 165 it.obj = obj 166 } 167 168 // On T and below, the native network is only created when the agent connects. 169 // Starting in U, the native network was to be created as soon as the agent is registered, 170 // but this has been flagged off for now pending resolution of race conditions. 171 // TODO : enable this in a Mainline update or in V. 172 private const val SHOULD_CREATE_NETWORKS_IMMEDIATELY = false 173 174 @RunWith(DevSdkIgnoreRunner::class) 175 // NetworkAgent is not updatable in R-, so this test does not need to be compatible with older 176 // versions. NetworkAgent was also based on AsyncChannel before S so cannot be tested the same way. 177 @IgnoreUpTo(Build.VERSION_CODES.R) 178 // NetworkAgent is updated as part of the connectivity module, and running NetworkAgent tests in MTS 179 // for modules other than Connectivity does not provide much value. Only run them in connectivity 180 // module MTS, so the tests only need to cover the case of an updated NetworkAgent. 181 @ConnectivityModuleTest 182 @AppModeFull(reason = "Instant apps can't use NetworkAgent because it needs NETWORK_FACTORY'.") 183 class NetworkAgentTest { 184 private val LOCAL_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1") 185 private val REMOTE_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.2") 186 187 private val mCM = realContext.getSystemService(ConnectivityManager::class.java)!! 188 private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread") 189 private val mFakeConnectivityService = FakeConnectivityService() 190 private val agentsToCleanUp = mutableListOf<NetworkAgent>() 191 private val callbacksToCleanUp = mutableListOf<TestableNetworkCallback>() 192 private var qosTestSocket: Closeable? = null // either Socket or DatagramSocket 193 private val ifacesToCleanUp = mutableListOf<TestNetworkInterface>() 194 195 @Before setUpnull196 fun setUp() { 197 instrumentation.getUiAutomation().adoptShellPermissionIdentity() 198 mHandlerThread.start() 199 } 200 201 @After tearDownnull202 fun tearDown() { 203 agentsToCleanUp.forEach { it.unregister() } 204 callbacksToCleanUp.forEach { mCM.unregisterNetworkCallback(it) } 205 ifacesToCleanUp.forEach { it.fileDescriptor.close() } 206 qosTestSocket?.close() 207 mHandlerThread.quitSafely() 208 mHandlerThread.join() 209 instrumentation.getUiAutomation().dropShellPermissionIdentity() 210 } 211 212 /** 213 * A fake that helps simulating ConnectivityService talking to a harnessed agent. 214 * This fake only supports speaking to one harnessed agent at a time because it 215 * only keeps track of one async channel. 216 */ 217 private class FakeConnectivityService { 218 val mockRegistry = mock(INetworkAgentRegistry::class.java) 219 private var agentField: INetworkAgent? = null 220 private val registry = object : INetworkAgentRegistry.Stub(), <lambda>null221 INetworkAgentRegistry by mockRegistry { 222 // asBinder has implementations in both INetworkAgentRegistry.Stub and mockRegistry, so 223 // it needs to be disambiguated. Just fail the test as it should be unused here. 224 // asBinder is used when sending the registry in binder transactions, so not in this 225 // test (the test just uses in-process direct calls). If it were used across processes, 226 // using the Stub super.asBinder() implementation would allow sending the registry in 227 // binder transactions, while recording incoming calls on the other mockito-generated 228 // methods. 229 override fun asBinder() = fail("asBinder should be unused in this test") 230 } 231 232 val agent: INetworkAgent 233 get() = agentField ?: fail("No INetworkAgent") 234 connectnull235 fun connect(agent: INetworkAgent) { 236 this.agentField = agent 237 agent.onRegistered(registry) 238 } 239 disconnectnull240 fun disconnect() = agent.onDisconnected() 241 } 242 243 private fun requestNetwork(request: NetworkRequest, callback: TestableNetworkCallback) { 244 mCM.requestNetwork(request, callback) 245 callbacksToCleanUp.add(callback) 246 } 247 registerNetworkCallbacknull248 private fun registerNetworkCallback( 249 request: NetworkRequest, 250 callback: TestableNetworkCallback 251 ) { 252 mCM.registerNetworkCallback(request, callback) 253 callbacksToCleanUp.add(callback) 254 } 255 registerBestMatchingNetworkCallbacknull256 private fun registerBestMatchingNetworkCallback( 257 request: NetworkRequest, 258 callback: TestableNetworkCallback, 259 handler: Handler 260 ) { 261 mCM!!.registerBestMatchingNetworkCallback(request, callback, handler) 262 callbacksToCleanUp.add(callback) 263 } 264 makeTestNetworkRequestnull265 private fun makeTestNetworkRequest(specifier: String? = null): NetworkRequest { 266 return NetworkRequest.Builder() 267 .clearCapabilities() 268 .addTransportType(TRANSPORT_TEST) 269 .also { 270 if (specifier != null) { 271 it.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifier)) 272 } 273 } 274 .build() 275 } 276 makeTestNetworkCapabilitiesnull277 private fun makeTestNetworkCapabilities( 278 specifier: String? = null, 279 transports: IntArray = intArrayOf() 280 ) = NetworkCapabilities().apply { 281 addTransportType(TRANSPORT_TEST) 282 removeCapability(NET_CAPABILITY_TRUSTED) 283 removeCapability(NET_CAPABILITY_INTERNET) 284 addCapability(NET_CAPABILITY_NOT_SUSPENDED) 285 addCapability(NET_CAPABILITY_NOT_ROAMING) 286 if (!transports.contains(TRANSPORT_VPN)) addCapability(NET_CAPABILITY_NOT_VPN) 287 if (SdkLevel.isAtLeastS()) { 288 addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 289 } 290 if (null != specifier) { 291 setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifier)) 292 } 293 for (t in transports) { addTransportType(t) } 294 // Most transports are not allowed on test networks unless the network is marked restricted. 295 // This test does not need 296 if (transports.size > 0) removeCapability(NET_CAPABILITY_NOT_RESTRICTED) 297 } 298 createNetworkAgentnull299 private fun createNetworkAgent( 300 context: Context = realContext, 301 specifier: String? = null, 302 initialNc: NetworkCapabilities? = null, 303 initialLp: LinkProperties? = null, 304 initialConfig: NetworkAgentConfig? = null 305 ): TestableNetworkAgent { 306 val nc = initialNc ?: makeTestNetworkCapabilities(specifier) 307 val lp = initialLp ?: LinkProperties().apply { 308 addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 32)) 309 addRoute(RouteInfo(IpPrefix("0.0.0.0/0"), null, null)) 310 } 311 val config = initialConfig ?: NetworkAgentConfig.Builder().build() 312 return TestableNetworkAgent(context, mHandlerThread.looper, nc, lp, config).also { 313 agentsToCleanUp.add(it) 314 } 315 } 316 createConnectedNetworkAgentnull317 private fun createConnectedNetworkAgent( 318 context: Context = realContext, 319 specifier: String? = UUID.randomUUID().toString(), 320 initialConfig: NetworkAgentConfig? = null, 321 expectedInitSignalStrengthThresholds: IntArray = intArrayOf(), 322 transports: IntArray = intArrayOf() 323 ): Pair<TestableNetworkAgent, TestableNetworkCallback> { 324 val callback = TestableNetworkCallback() 325 // Ensure this NetworkAgent is never unneeded by filing a request with its specifier. 326 requestNetwork(makeTestNetworkRequest(specifier = specifier), callback) 327 val nc = makeTestNetworkCapabilities(specifier, transports) 328 val agent = createNetworkAgent(context, initialConfig = initialConfig, initialNc = nc) 329 agent.setTeardownDelayMillis(0) 330 // Connect the agent and verify initial status callbacks. 331 agent.register() 332 agent.markConnected() 333 agent.expectCallback<OnNetworkCreated>() 334 agent.expectPostConnectionCallbacks(expectedInitSignalStrengthThresholds) 335 callback.expectAvailableThenValidatedCallbacks(agent.network!!) 336 return agent to callback 337 } 338 connectNetworknull339 private fun connectNetwork(vararg transports: Int): Pair<TestableNetworkAgent, Network> { 340 val (agent, callback) = createConnectedNetworkAgent(transports = transports) 341 val network = agent.network!! 342 // createConnectedNetworkAgent internally files a request; release it so that the network 343 // will be torn down if unneeded. 344 mCM.unregisterNetworkCallback(callback) 345 return agent to network 346 } 347 <lambda>null348 private fun createNetworkAgentWithFakeCS() = createNetworkAgent().also { 349 mFakeConnectivityService.connect(it.registerForTest(Network(FAKE_NET_ID))) 350 } 351 expectPostConnectionCallbacksnull352 private fun TestableNetworkAgent.expectPostConnectionCallbacks( 353 thresholds: IntArray = intArrayOf() 354 ) { 355 expectSignalStrengths(thresholds) 356 expectValidationBypassedStatus() 357 assertNoCallback() 358 } 359 createTunInterfacenull360 private fun createTunInterface(): TestNetworkInterface = realContext.getSystemService( 361 TestNetworkManager::class.java)!!.createTunInterface(emptyList()).also { 362 ifacesToCleanUp.add(it) 363 } 364 assertLinkPropertiesEventuallynull365 fun assertLinkPropertiesEventually( 366 n: Network, 367 description: String, 368 condition: (LinkProperties?) -> Boolean 369 ): LinkProperties? { 370 val deadline = SystemClock.elapsedRealtime() + DEFAULT_TIMEOUT_MS 371 do { 372 val lp = mCM.getLinkProperties(n) 373 if (condition(lp)) return lp 374 SystemClock.sleep(10 /* ms */) 375 } while (SystemClock.elapsedRealtime() < deadline) 376 fail("Network $n LinkProperties did not $description after $DEFAULT_TIMEOUT_MS ms") 377 } 378 assertLinkPropertiesEventuallyNotNullnull379 fun assertLinkPropertiesEventuallyNotNull(n: Network) { 380 assertLinkPropertiesEventually(n, "become non-null") { it != null } 381 } 382 assertLinkPropertiesEventuallyNullnull383 fun assertLinkPropertiesEventuallyNull(n: Network) { 384 assertLinkPropertiesEventually(n, "become null") { it == null } 385 } 386 387 @Test testSetSubtypeNameAndExtraInfoByAgentConfignull388 fun testSetSubtypeNameAndExtraInfoByAgentConfig() { 389 val subtypeLTE = TelephonyManager.NETWORK_TYPE_LTE 390 val subtypeNameLTE = "LTE" 391 val legacyExtraInfo = "mylegacyExtraInfo" 392 val config = NetworkAgentConfig.Builder() 393 .setLegacySubType(subtypeLTE) 394 .setLegacySubTypeName(subtypeNameLTE) 395 .setLegacyExtraInfo(legacyExtraInfo).build() 396 val (agent, callback) = createConnectedNetworkAgent(initialConfig = config) 397 val networkInfo = mCM.getNetworkInfo(agent.network) 398 assertEquals(subtypeLTE, networkInfo.getSubtype()) 399 assertEquals(subtypeNameLTE, networkInfo.getSubtypeName()) 400 assertEquals(legacyExtraInfo, config.getLegacyExtraInfo()) 401 } 402 403 @Test testSetLegacySubtypeInNetworkAgentnull404 fun testSetLegacySubtypeInNetworkAgent() { 405 val subtypeLTE = TelephonyManager.NETWORK_TYPE_LTE 406 val subtypeUMTS = TelephonyManager.NETWORK_TYPE_UMTS 407 val subtypeNameLTE = "LTE" 408 val subtypeNameUMTS = "UMTS" 409 val config = NetworkAgentConfig.Builder() 410 .setLegacySubType(subtypeLTE) 411 .setLegacySubTypeName(subtypeNameLTE).build() 412 val (agent, callback) = createConnectedNetworkAgent(initialConfig = config) 413 agent.setLegacySubtype(subtypeUMTS, subtypeNameUMTS) 414 415 // There is no callback when networkInfo changes, 416 // so use the NetworkCapabilities callback to ensure 417 // that networkInfo is ready for verification. 418 val nc = NetworkCapabilities(agent.nc) 419 nc.addCapability(NET_CAPABILITY_NOT_METERED) 420 agent.sendNetworkCapabilities(nc) 421 callback.expectCaps(agent.network) { it.hasCapability(NET_CAPABILITY_NOT_METERED) } 422 val networkInfo = mCM.getNetworkInfo(agent.network) 423 assertEquals(subtypeUMTS, networkInfo.getSubtype()) 424 assertEquals(subtypeNameUMTS, networkInfo.getSubtypeName()) 425 } 426 427 @Test testConnectAndUnregisternull428 fun testConnectAndUnregister() { 429 val (agent, callback) = createConnectedNetworkAgent() 430 unregister(agent) 431 callback.expect<Lost>(agent.network!!) 432 assertFailsWith<IllegalStateException>("Must not be able to register an agent twice") { 433 agent.register() 434 } 435 } 436 437 @Test testOnBandwidthUpdateRequestednull438 fun testOnBandwidthUpdateRequested() { 439 val (agent, _) = createConnectedNetworkAgent() 440 mCM.requestBandwidthUpdate(agent.network!!) 441 agent.expectCallback<OnBandwidthUpdateRequested>() 442 unregister(agent) 443 } 444 445 @Test testSignalStrengthThresholdsnull446 fun testSignalStrengthThresholds() { 447 val thresholds = intArrayOf(30, 50, 65) 448 val callbacks = thresholds.map { strength -> 449 val request = NetworkRequest.Builder() 450 .clearCapabilities() 451 .addTransportType(TRANSPORT_TEST) 452 .setSignalStrength(strength) 453 .build() 454 TestableNetworkCallback(DEFAULT_TIMEOUT_MS).also { 455 registerNetworkCallback(request, it) 456 } 457 } 458 createConnectedNetworkAgent(expectedInitSignalStrengthThresholds = thresholds).let { 459 (agent, callback) -> 460 // Send signal strength and check that the callbacks are called appropriately. 461 val nc = NetworkCapabilities(agent.nc) 462 val net = agent.network!! 463 nc.setSignalStrength(20) 464 agent.sendNetworkCapabilities(nc) 465 callbacks.forEach { it.assertNoCallback(NO_CALLBACK_TIMEOUT) } 466 467 nc.setSignalStrength(40) 468 agent.sendNetworkCapabilities(nc) 469 callbacks[0].expectAvailableCallbacks(net) 470 callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT) 471 callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT) 472 473 nc.setSignalStrength(80) 474 agent.sendNetworkCapabilities(nc) 475 callbacks[0].expectCaps(net) { it.signalStrength == 80 } 476 callbacks[1].expectAvailableCallbacks(net) 477 callbacks[2].expectAvailableCallbacks(net) 478 479 nc.setSignalStrength(55) 480 agent.sendNetworkCapabilities(nc) 481 callbacks[0].expectCaps(net) { it.signalStrength == 55 } 482 callbacks[1].expectCaps(net) { it.signalStrength == 55 } 483 callbacks[2].expect<Lost>(net) 484 } 485 callbacks.forEach { 486 mCM.unregisterNetworkCallback(it) 487 } 488 } 489 490 @Test agentnull491 fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent -> 492 val packet = NattKeepalivePacketData( 493 LOCAL_IPV4_ADDRESS /* srcAddress */, 1234 /* srcPort */, 494 REMOTE_IPV4_ADDRESS /* dstAddress */, 4567 /* dstPort */, 495 ByteArray(100 /* size */)) 496 val slot = 4 497 val interval = 37 498 499 mFakeConnectivityService.agent.onAddNattKeepalivePacketFilter(slot, packet) 500 mFakeConnectivityService.agent.onStartNattSocketKeepalive(slot, interval, packet) 501 502 agent.expectCallback<OnAddKeepalivePacketFilter>().let { 503 assertEquals(it.slot, slot) 504 assertEquals(it.packet, packet) 505 } 506 agent.expectCallback<OnStartSocketKeepalive>().let { 507 assertEquals(it.slot, slot) 508 assertEquals(it.interval, interval) 509 assertEquals(it.packet, packet) 510 } 511 512 agent.assertNoCallback() 513 514 // Check that when the agent sends a keepalive event, ConnectivityService receives the 515 // expected message. 516 agent.sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED) 517 verify(mFakeConnectivityService.mockRegistry, timeout(DEFAULT_TIMEOUT_MS)) 518 .sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED) 519 520 mFakeConnectivityService.agent.onStopSocketKeepalive(slot) 521 mFakeConnectivityService.agent.onRemoveKeepalivePacketFilter(slot) 522 agent.expectCallback<OnStopSocketKeepalive>().let { 523 assertEquals(it.slot, slot) 524 } 525 agent.expectCallback<OnRemoveKeepalivePacketFilter>().let { 526 assertEquals(it.slot, slot) 527 } 528 } 529 530 @Test agentnull531 fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) -> 532 val ifaceName = "adhocIface" 533 val lp = LinkProperties(agent.lp) 534 lp.setInterfaceName(ifaceName) 535 agent.sendLinkProperties(lp) 536 callback.expect<LinkPropertiesChanged>(agent.network!!) { it.lp.interfaceName == ifaceName } 537 val nc = NetworkCapabilities(agent.nc) 538 nc.addCapability(NET_CAPABILITY_NOT_METERED) 539 agent.sendNetworkCapabilities(nc) 540 callback.expectCaps(agent.network!!) { it.hasCapability(NET_CAPABILITY_NOT_METERED) } 541 } 542 ncWithAllowedUidsnull543 private fun ncWithAllowedUids(vararg uids: Int) = NetworkCapabilities.Builder() 544 .addTransportType(TRANSPORT_TEST) 545 .setAllowedUids(uids.toSet()).build() 546 547 @Test 548 fun testRejectedUpdates() { 549 val callback = TestableNetworkCallback(DEFAULT_TIMEOUT_MS) 550 // will be cleaned up in tearDown 551 registerNetworkCallback(makeTestNetworkRequest(), callback) 552 val agent = createNetworkAgent(initialNc = ncWithAllowedUids(200)) 553 agent.register() 554 agent.markConnected() 555 556 // Make sure the UIDs have been ignored. 557 callback.expect<Available>(agent.network!!) 558 callback.expectCaps(agent.network!!) { 559 it.allowedUids.isEmpty() && !it.hasCapability(NET_CAPABILITY_VALIDATED) 560 } 561 callback.expect<LinkPropertiesChanged>(agent.network!!) 562 callback.expect<BlockedStatus>(agent.network!!) 563 callback.expectCaps(agent.network!!) { 564 it.allowedUids.isEmpty() && it.hasCapability(NET_CAPABILITY_VALIDATED) 565 } 566 callback.assertNoCallback(NO_CALLBACK_TIMEOUT) 567 568 // Make sure that the UIDs are also ignored upon update 569 agent.sendNetworkCapabilities(ncWithAllowedUids(200, 300)) 570 callback.assertNoCallback(NO_CALLBACK_TIMEOUT) 571 } 572 573 @Test testSendScorenull574 fun testSendScore() { 575 // This test will create two networks and check that the one with the stronger 576 // score wins out for a request that matches them both. 577 578 // File the interesting request 579 val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) 580 requestNetwork(makeTestNetworkRequest(), callback) 581 582 // Connect the first Network, with an unused callback that kept the network up. 583 val (agent1, _) = createConnectedNetworkAgent() 584 callback.expectAvailableThenValidatedCallbacks(agent1.network!!) 585 // If using the int ranking, agent1 must be upgraded to a better score so that there is 586 // no ambiguity when agent2 connects that agent1 is still better. If using policy 587 // ranking, this is not necessary. 588 agent1.sendNetworkScore(NetworkScore.Builder().setLegacyInt(BETTER_NETWORK_SCORE) 589 .build()) 590 591 // Connect the second agent. 592 val (agent2, _) = createConnectedNetworkAgent() 593 // The callback should not see anything yet. With int ranking, agent1 was upgraded 594 // to a stronger score beforehand. With policy ranking, agent1 is preferred by 595 // virtue of already satisfying the request. 596 callback.assertNoCallback(NO_CALLBACK_TIMEOUT) 597 // Now downgrade the score and expect the callback now prefers agent2 598 agent1.sendNetworkScore(NetworkScore.Builder() 599 .setLegacyInt(WORSE_NETWORK_SCORE) 600 .setExiting(true) 601 .build()) 602 callback.expect<Available>(agent2.network!!) 603 604 // tearDown() will unregister the requests and agents 605 } 606 hasAllTransportsnull607 private fun NetworkCapabilities?.hasAllTransports(transports: IntArray) = 608 this != null && transports.all { hasTransport(it) } 609 610 @Test 611 @IgnoreUpTo(Build.VERSION_CODES.R) testSetUnderlyingNetworksAndVpnSpecifiernull612 fun testSetUnderlyingNetworksAndVpnSpecifier() { 613 val mySessionId = "MySession12345" 614 val request = NetworkRequest.Builder() 615 .addTransportType(TRANSPORT_TEST) 616 .addTransportType(TRANSPORT_VPN) 617 .removeCapability(NET_CAPABILITY_NOT_VPN) 618 .removeCapability(NET_CAPABILITY_TRUSTED) // TODO: add to VPN! 619 .build() 620 val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) 621 registerNetworkCallback(request, callback) 622 623 val nc = NetworkCapabilities().apply { 624 addTransportType(TRANSPORT_TEST) 625 addTransportType(TRANSPORT_VPN) 626 removeCapability(NET_CAPABILITY_NOT_VPN) 627 setTransportInfo(VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE, mySessionId)) 628 if (SdkLevel.isAtLeastS()) { 629 addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 630 } 631 } 632 val defaultNetwork = mCM.activeNetwork 633 assertNotNull(defaultNetwork) 634 val defaultNetworkCapabilities = mCM.getNetworkCapabilities(defaultNetwork) 635 val defaultNetworkTransports = defaultNetworkCapabilities.transportTypes 636 637 val agent = createNetworkAgent(initialNc = nc) 638 agent.register() 639 agent.markConnected() 640 callback.expectAvailableThenValidatedCallbacks(agent.network!!) 641 642 // Check that the default network's transport is propagated to the VPN. 643 var vpnNc = mCM.getNetworkCapabilities(agent.network!!) 644 assertNotNull(vpnNc) 645 assertEquals(VpnManager.TYPE_VPN_SERVICE, 646 (vpnNc.transportInfo as VpnTransportInfo).type) 647 assertEquals(mySessionId, (vpnNc.transportInfo as VpnTransportInfo).sessionId) 648 649 val testAndVpn = intArrayOf(TRANSPORT_TEST, TRANSPORT_VPN) 650 assertTrue(vpnNc.hasAllTransports(testAndVpn)) 651 assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_VPN)) 652 assertTrue(vpnNc.hasAllTransports(defaultNetworkTransports), 653 "VPN transports ${Arrays.toString(vpnNc.transportTypes)}" + 654 " lacking transports from ${Arrays.toString(defaultNetworkTransports)}") 655 656 // Check that when no underlying networks are announced the underlying transport disappears. 657 agent.setUnderlyingNetworks(listOf<Network>()) 658 callback.expectCaps(agent.network!!) { 659 it.transportTypes.size == 2 && it.hasAllTransports(testAndVpn) 660 } 661 662 // Put the underlying network back and check that the underlying transport reappears. 663 val expectedTransports = (defaultNetworkTransports.toSet() + TRANSPORT_TEST + TRANSPORT_VPN) 664 .toIntArray() 665 agent.setUnderlyingNetworks(null) 666 callback.expectCaps(agent.network!!) { 667 it.transportTypes.size == expectedTransports.size && 668 it.hasAllTransports(expectedTransports) 669 } 670 671 // Check that some underlying capabilities are propagated. 672 // This is not very accurate because the test does not control the capabilities of the 673 // underlying networks, and because not congested, not roaming, and not suspended are the 674 // default anyway. It's still useful as an extra check though. 675 vpnNc = mCM.getNetworkCapabilities(agent.network!!) 676 for (cap in listOf(NET_CAPABILITY_NOT_CONGESTED, 677 NET_CAPABILITY_NOT_ROAMING, 678 NET_CAPABILITY_NOT_SUSPENDED)) { 679 val capStr = valueToString(NetworkCapabilities::class.java, "NET_CAPABILITY_", cap) 680 if (defaultNetworkCapabilities.hasCapability(cap) && !vpnNc.hasCapability(cap)) { 681 fail("$capStr not propagated from underlying: $defaultNetworkCapabilities") 682 } 683 } 684 685 unregister(agent) 686 callback.expect<Lost>(agent.network!!) 687 } 688 unregisternull689 private fun unregister(agent: TestableNetworkAgent) { 690 agent.unregister() 691 agent.eventuallyExpect<OnNetworkUnwanted>() 692 agent.eventuallyExpect<OnNetworkDestroyed>() 693 } 694 695 @Test 696 @IgnoreUpTo(Build.VERSION_CODES.R) testAgentStartsInConnectingnull697 fun testAgentStartsInConnecting() { 698 val mockContext = mock(Context::class.java) 699 val mockCm = mock(ConnectivityManager::class.java) 700 doReturn(mockCm).`when`(mockContext).getSystemService(Context.CONNECTIVITY_SERVICE) 701 val agent = createNetworkAgent(mockContext) 702 agent.register() 703 verify(mockCm).registerNetworkAgent(any(), 704 argThat<NetworkInfo> { it.detailedState == NetworkInfo.DetailedState.CONNECTING }, 705 any(LinkProperties::class.java), 706 any(NetworkCapabilities::class.java), 707 any(NetworkScore::class.java), 708 any(NetworkAgentConfig::class.java), 709 eq(NetworkProvider.ID_NONE)) 710 } 711 712 @Test testSetAcceptUnvalidatednull713 fun testSetAcceptUnvalidated() { 714 createNetworkAgentWithFakeCS().let { agent -> 715 mFakeConnectivityService.agent.onSaveAcceptUnvalidated(true) 716 agent.expectCallback<OnSaveAcceptUnvalidated>().let { 717 assertTrue(it.accept) 718 } 719 agent.assertNoCallback() 720 } 721 } 722 723 @Test testSetAcceptUnvalidatedPreventAutomaticReconnectnull724 fun testSetAcceptUnvalidatedPreventAutomaticReconnect() { 725 createNetworkAgentWithFakeCS().let { agent -> 726 mFakeConnectivityService.agent.onSaveAcceptUnvalidated(false) 727 mFakeConnectivityService.agent.onPreventAutomaticReconnect() 728 agent.expectCallback<OnSaveAcceptUnvalidated>().let { 729 assertFalse(it.accept) 730 } 731 agent.expectCallback<OnAutomaticReconnectDisabled>() 732 agent.assertNoCallback() 733 // When automatic reconnect is turned off, the network is torn down and 734 // ConnectivityService disconnects. As part of the disconnect, ConnectivityService will 735 // also send itself a message to unregister the NetworkAgent from its internal 736 // structure. 737 mFakeConnectivityService.disconnect() 738 agent.expectCallback<OnNetworkUnwanted>() 739 } 740 } 741 742 @Test testPreventAutomaticReconnectnull743 fun testPreventAutomaticReconnect() { 744 createNetworkAgentWithFakeCS().let { agent -> 745 mFakeConnectivityService.agent.onPreventAutomaticReconnect() 746 agent.expectCallback<OnAutomaticReconnectDisabled>() 747 agent.assertNoCallback() 748 mFakeConnectivityService.disconnect() 749 agent.expectCallback<OnNetworkUnwanted>() 750 } 751 } 752 753 @Test agentnull754 fun testValidationStatus() = createNetworkAgentWithFakeCS().let { agent -> 755 val uri = Uri.parse("http://www.google.com") 756 mFakeConnectivityService.agent.onValidationStatusChanged(VALID_NETWORK, 757 uri.toString()) 758 agent.expectCallback<OnValidationStatus>().let { 759 assertEquals(it.status, VALID_NETWORK) 760 assertEquals(it.uri, uri) 761 } 762 763 mFakeConnectivityService.agent.onValidationStatusChanged(INVALID_NETWORK, null) 764 agent.expectCallback<OnValidationStatus>().let { 765 assertEquals(it.status, INVALID_NETWORK) 766 assertNull(it.uri) 767 } 768 } 769 770 @Test testTemporarilyUnmeteredCapabilitynull771 fun testTemporarilyUnmeteredCapability() { 772 // This test will create a networks with/without NET_CAPABILITY_TEMPORARILY_NOT_METERED 773 // and check that the callback reflects the capability changes. 774 775 // Connect the network 776 val (agent, callback) = createConnectedNetworkAgent() 777 778 // Send TEMP_NOT_METERED and check that the callback is called appropriately. 779 val nc1 = NetworkCapabilities(agent.nc) 780 .addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) 781 agent.sendNetworkCapabilities(nc1) 782 callback.expectCaps(agent.network!!) { 783 it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) 784 } 785 786 // Remove TEMP_NOT_METERED and check that the callback is called appropriately. 787 val nc2 = NetworkCapabilities(agent.nc) 788 .removeCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) 789 agent.sendNetworkCapabilities(nc2) 790 callback.expectCaps(agent.network!!) { 791 !it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) 792 } 793 794 // tearDown() will unregister the requests and agents 795 } 796 797 @Test 798 @IgnoreUpTo(Build.VERSION_CODES.R) testSetLingerDurationnull799 fun testSetLingerDuration() { 800 // This test will create two networks and check that the one with the stronger 801 // score wins out for a request that matches them both. And the weaker agent will 802 // be disconnected after customized linger duration. 803 804 // Request the first Network, with a request that could moved to agentStronger in order to 805 // make agentWeaker linger later. 806 val specifierWeaker = UUID.randomUUID().toString() 807 val specifierStronger = UUID.randomUUID().toString() 808 val commonCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) 809 requestNetwork(makeTestNetworkRequest(), commonCallback) 810 val agentWeaker = createNetworkAgent(specifier = specifierWeaker) 811 agentWeaker.register() 812 agentWeaker.markConnected() 813 commonCallback.expectAvailableThenValidatedCallbacks(agentWeaker.network!!) 814 // Downgrade agentWeaker to a worse score so that there is no ambiguity when 815 // agentStronger connects. 816 agentWeaker.sendNetworkScore(NetworkScore.Builder().setLegacyInt(WORSE_NETWORK_SCORE) 817 .setExiting(true).build()) 818 819 // Verify invalid linger duration cannot be set. 820 assertFailsWith<IllegalArgumentException> { 821 agentWeaker.setLingerDuration(Duration.ofMillis(-1)) 822 } 823 assertFailsWith<IllegalArgumentException> { agentWeaker.setLingerDuration(Duration.ZERO) } 824 assertFailsWith<IllegalArgumentException> { 825 agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MIN_VALUE.toLong())) 826 } 827 assertFailsWith<IllegalArgumentException> { 828 agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong() + 1)) 829 } 830 assertFailsWith<IllegalArgumentException> { 831 agentWeaker.setLingerDuration(Duration.ofMillis( 832 NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - 1)) 833 } 834 // Verify valid linger timer can be set, but it should not take effect since the network 835 // is still needed. 836 agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong())) 837 commonCallback.assertNoCallback(NO_CALLBACK_TIMEOUT) 838 // Set to the value we want to verify the functionality. 839 agentWeaker.setLingerDuration(Duration.ofMillis(NetworkAgent.MIN_LINGER_TIMER_MS.toLong())) 840 // Make a listener which can observe agentWeaker lost later. 841 val callbackWeaker = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) 842 registerNetworkCallback(NetworkRequest.Builder() 843 .clearCapabilities() 844 .addTransportType(TRANSPORT_TEST) 845 .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifierWeaker)) 846 .build(), callbackWeaker) 847 callbackWeaker.expectAvailableCallbacks(agentWeaker.network!!) 848 849 // Connect the agentStronger with a score better than agentWeaker. Verify the callback for 850 // agentWeaker sees the linger expiry while the callback for both sees the winner. 851 // Record linger start timestamp prior to send score to prevent possible race, the actual 852 // timestamp should be slightly late than this since the service handles update 853 // network score asynchronously. 854 val lingerStart = SystemClock.elapsedRealtime() 855 val agentStronger = createNetworkAgent(specifier = specifierStronger) 856 agentStronger.register() 857 agentStronger.markConnected() 858 commonCallback.expectAvailableCallbacks(agentStronger.network!!) 859 callbackWeaker.expect<Losing>(agentWeaker.network!!) 860 val expectedRemainingLingerDuration = lingerStart + 861 NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - SystemClock.elapsedRealtime() 862 // If the available callback is too late. The remaining duration will be reduced. 863 assertTrue(expectedRemainingLingerDuration > 0, 864 "expected remaining linger duration is $expectedRemainingLingerDuration") 865 callbackWeaker.assertNoCallback(expectedRemainingLingerDuration) 866 callbackWeaker.expect<Lost>(agentWeaker.network!!) 867 } 868 869 @Test 870 @IgnoreUpTo(Build.VERSION_CODES.R) testSetSubscriberIdnull871 fun testSetSubscriberId() { 872 val imsi = UUID.randomUUID().toString() 873 val config = NetworkAgentConfig.Builder().setSubscriberId(imsi).build() 874 875 val (agent, _) = createConnectedNetworkAgent(initialConfig = config) 876 val snapshots = runWithShellPermissionIdentity(ThrowingSupplier { 877 mCM!!.allNetworkStateSnapshots }, NETWORK_SETTINGS) 878 val testNetworkSnapshot = snapshots.findLast { it.network == agent.network } 879 assertEquals(imsi, testNetworkSnapshot!!.subscriberId) 880 } 881 882 @Test 883 @IgnoreUpTo(Build.VERSION_CODES.R) 884 // TODO: Refactor helper functions to util class and move this test case to 885 // {@link android.net.cts.ConnectivityManagerTest}. testRegisterBestMatchingNetworkCallbacknull886 fun testRegisterBestMatchingNetworkCallback() { 887 // Register best matching network callback with additional condition that will be 888 // exercised later. This assumes the test network agent has NOT_VCN_MANAGED in it and 889 // does not have NET_CAPABILITY_TEMPORARILY_NOT_METERED. 890 val bestMatchingCb = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) 891 registerBestMatchingNetworkCallback(NetworkRequest.Builder() 892 .clearCapabilities() 893 .addTransportType(TRANSPORT_TEST) 894 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 895 .build(), bestMatchingCb, mHandlerThread.threadHandler) 896 897 val (agent1, _) = createConnectedNetworkAgent(specifier = "AGENT-1") 898 bestMatchingCb.expectAvailableThenValidatedCallbacks(agent1.network!!) 899 // Make agent1 worse so when agent2 shows up, the callback will see that. 900 agent1.sendNetworkScore(NetworkScore.Builder().setExiting(true).build()) 901 bestMatchingCb.assertNoCallback(NO_CALLBACK_TIMEOUT) 902 903 val (agent2, _) = createConnectedNetworkAgent(specifier = "AGENT-2") 904 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(agent2.network!!) 905 906 // Change something on agent1 to trigger capabilities changed, since the callback 907 // only cares about the best network, verify it received nothing from agent1. 908 val ncAgent1 = agent1.nc 909 ncAgent1.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) 910 agent1.sendNetworkCapabilities(ncAgent1) 911 bestMatchingCb.assertNoCallback(NO_CALLBACK_TIMEOUT) 912 913 // Make agent1 the best network again, verify the callback now tracks agent1. 914 agent1.sendNetworkScore(NetworkScore.Builder() 915 .setExiting(false).setTransportPrimary(true).build()) 916 bestMatchingCb.expectAvailableCallbacks(agent1.network!!) 917 918 // Make agent1 temporary vcn managed, which will not satisfying the request. 919 // Verify the callback switch from/to the other network accordingly. 920 ncAgent1.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 921 agent1.sendNetworkCapabilities(ncAgent1) 922 bestMatchingCb.expectAvailableCallbacks(agent2.network!!) 923 ncAgent1.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) 924 agent1.sendNetworkCapabilities(ncAgent1) 925 bestMatchingCb.expectAvailableDoubleValidatedCallbacks(agent1.network!!) 926 927 // Verify the callback doesn't care about agent2 disconnect. 928 agent2.unregister() 929 agentsToCleanUp.remove(agent2) 930 bestMatchingCb.assertNoCallback() 931 agent1.unregister() 932 agentsToCleanUp.remove(agent1) 933 bestMatchingCb.expect<Lost>(agent1.network!!) 934 935 // tearDown() will unregister the requests and agents 936 } 937 938 private class TestableQosCallback : QosCallback() { 939 val history = ArrayTrackRecord<CallbackEntry>().newReadHead() 940 941 sealed class CallbackEntry { 942 data class OnQosSessionAvailable(val sess: QosSession, val attr: QosSessionAttributes) : 943 CallbackEntry() 944 data class OnQosSessionLost(val sess: QosSession) : CallbackEntry() 945 data class OnError(val ex: QosCallbackException) : CallbackEntry() 946 } 947 onQosSessionAvailablenull948 override fun onQosSessionAvailable(sess: QosSession, attr: QosSessionAttributes) { 949 history.add(OnQosSessionAvailable(sess, attr)) 950 } 951 onQosSessionLostnull952 override fun onQosSessionLost(sess: QosSession) { 953 history.add(OnQosSessionLost(sess)) 954 } 955 onErrornull956 override fun onError(ex: QosCallbackException) { 957 history.add(OnError(ex)) 958 } 959 expectCallbacknull960 inline fun <reified T : CallbackEntry> expectCallback(): T { 961 val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) 962 assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") 963 return foundCallback 964 } 965 expectCallbacknull966 inline fun <reified T : CallbackEntry> expectCallback(valid: (T) -> Boolean) { 967 val foundCallback = history.poll(DEFAULT_TIMEOUT_MS) 968 assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback") 969 assertTrue(valid(foundCallback), "Unexpected callback : $foundCallback") 970 } 971 assertNoCallbacknull972 fun assertNoCallback() { 973 assertNull(history.poll(NO_CALLBACK_TIMEOUT), 974 "Callback received") 975 } 976 } 977 setupForQosCallbackTestnull978 private fun <T : Closeable> setupForQosCallbackTest(creator: (TestableNetworkAgent) -> T) = 979 createConnectedNetworkAgent().first.let { Pair(it, creator(it)) } 980 setupForQosSocketnull981 private fun setupForQosSocket() = setupForQosCallbackTest { 982 agent: TestableNetworkAgent -> Socket() 983 .also { assertNotNull(agent.network?.bindSocket(it)) 984 it.bind(InetSocketAddress(InetAddress.getLoopbackAddress(), 0)) } 985 } 986 setupForQosDatagramnull987 private fun setupForQosDatagram() = setupForQosCallbackTest { 988 agent: TestableNetworkAgent -> DatagramSocket( 989 InetSocketAddress(InetAddress.getLoopbackAddress(), 0)) 990 .also { assertNotNull(agent.network?.bindSocket(it)) } 991 } 992 993 @Test testQosCallbackRegisterAndUnregisternull994 fun testQosCallbackRegisterAndUnregister() { 995 validateQosCallbackRegisterAndUnregister(IPPROTO_TCP) 996 } 997 998 @Test testQosCallbackRegisterAndUnregisterWithDatagramSocketnull999 fun testQosCallbackRegisterAndUnregisterWithDatagramSocket() { 1000 validateQosCallbackRegisterAndUnregister(IPPROTO_UDP) 1001 } 1002 validateQosCallbackRegisterAndUnregisternull1003 private fun validateQosCallbackRegisterAndUnregister(proto: Int) { 1004 val (agent, qosTestSocket) = when (proto) { 1005 IPPROTO_TCP -> setupForQosSocket() 1006 IPPROTO_UDP -> setupForQosDatagram() 1007 else -> fail("unsupported protocol") 1008 } 1009 val qosCallback = TestableQosCallback() 1010 var callbackId = -1 1011 Executors.newSingleThreadExecutor().let { executor -> 1012 try { 1013 val info = QosSocketInfo(agent, qosTestSocket) 1014 mCM.registerQosCallback(info, executor, qosCallback) 1015 agent.expectCallback<OnRegisterQosCallback>().let { 1016 callbackId = it.callbackId 1017 assertTrue(it.filter.matchesProtocol(proto)) 1018 } 1019 1020 assertFailsWith<QosCallbackRegistrationException>( 1021 "The same callback cannot be " + 1022 "registered more than once without first being unregistered") { 1023 mCM.registerQosCallback(info, executor, qosCallback) 1024 } 1025 } finally { 1026 qosTestSocket.close() 1027 mCM.unregisterQosCallback(qosCallback) 1028 agent.expectCallback<OnUnregisterQosCallback> { it.callbackId == callbackId } 1029 executor.shutdown() 1030 } 1031 } 1032 } 1033 1034 @Test testQosCallbackOnQosSessionnull1035 fun testQosCallbackOnQosSession() { 1036 validateQosCallbackOnQosSession(IPPROTO_TCP) 1037 } 1038 1039 @Test testQosCallbackOnQosSessionWithDatagramSocketnull1040 fun testQosCallbackOnQosSessionWithDatagramSocket() { 1041 validateQosCallbackOnQosSession(IPPROTO_UDP) 1042 } 1043 QosSocketInfonull1044 fun QosSocketInfo(agent: NetworkAgent, socket: Closeable) = when (socket) { 1045 is Socket -> QosSocketInfo(agent.network, socket) 1046 is DatagramSocket -> QosSocketInfo(agent.network, socket) 1047 else -> fail("unexpected socket type") 1048 } 1049 validateQosCallbackOnQosSessionnull1050 private fun validateQosCallbackOnQosSession(proto: Int) { 1051 val (agent, qosTestSocket) = when (proto) { 1052 IPPROTO_TCP -> setupForQosSocket() 1053 IPPROTO_UDP -> setupForQosDatagram() 1054 else -> fail("unsupported protocol") 1055 } 1056 val qosCallback = TestableQosCallback() 1057 Executors.newSingleThreadExecutor().let { executor -> 1058 try { 1059 val info = QosSocketInfo(agent, qosTestSocket) 1060 assertEquals(agent.network, info.getNetwork()) 1061 mCM.registerQosCallback(info, executor, qosCallback) 1062 val callbackId = agent.expectCallback<OnRegisterQosCallback>().callbackId 1063 1064 val uniqueSessionId = 4294967397 1065 val sessId = 101 1066 1067 val attributes = createEpsAttributes(5) 1068 assertEquals(attributes.qosIdentifier, 5) 1069 agent.sendQosSessionAvailable(callbackId, sessId, attributes) 1070 qosCallback.expectCallback<OnQosSessionAvailable> { 1071 it.sess.sessionId == sessId && it.sess.uniqueId == uniqueSessionId && 1072 it.sess.sessionType == QosSession.TYPE_EPS_BEARER 1073 } 1074 1075 agent.sendQosSessionLost(callbackId, sessId, QosSession.TYPE_EPS_BEARER) 1076 qosCallback.expectCallback<OnQosSessionLost> { 1077 it.sess.sessionId == sessId && it.sess.uniqueId == uniqueSessionId && 1078 it.sess.sessionType == QosSession.TYPE_EPS_BEARER 1079 } 1080 1081 // Make sure that we don't get more qos callbacks 1082 mCM.unregisterQosCallback(qosCallback) 1083 agent.expectCallback<OnUnregisterQosCallback>() 1084 1085 agent.sendQosSessionLost(callbackId, sessId, QosSession.TYPE_EPS_BEARER) 1086 qosCallback.assertNoCallback() 1087 } finally { 1088 qosTestSocket.close() 1089 // safety precaution 1090 mCM.unregisterQosCallback(qosCallback) 1091 1092 executor.shutdown() 1093 } 1094 } 1095 } 1096 1097 @Test testQosCallbackOnErrornull1098 fun testQosCallbackOnError() { 1099 val (agent, qosTestSocket) = setupForQosSocket() 1100 val qosCallback = TestableQosCallback() 1101 Executors.newSingleThreadExecutor().let { executor -> 1102 try { 1103 val info = QosSocketInfo(agent.network!!, qosTestSocket) 1104 mCM.registerQosCallback(info, executor, qosCallback) 1105 val callbackId = agent.expectCallback<OnRegisterQosCallback>().callbackId 1106 1107 val sessId = 101 1108 val attributes = createEpsAttributes() 1109 1110 // Double check that this is wired up and ready to go 1111 agent.sendQosSessionAvailable(callbackId, sessId, attributes) 1112 qosCallback.expectCallback<OnQosSessionAvailable>() 1113 1114 // Check that onError is coming through correctly 1115 agent.sendQosCallbackError(callbackId, 1116 QosCallbackException.EX_TYPE_FILTER_NOT_SUPPORTED) 1117 qosCallback.expectCallback<OnError> { 1118 it.ex.cause is UnsupportedOperationException 1119 } 1120 1121 // Ensure that when an error occurs the callback was also unregistered 1122 agent.sendQosSessionLost(callbackId, sessId, QosSession.TYPE_EPS_BEARER) 1123 qosCallback.assertNoCallback() 1124 } finally { 1125 qosTestSocket.close() 1126 1127 // Make sure that the callback is fully unregistered 1128 mCM.unregisterQosCallback(qosCallback) 1129 1130 executor.shutdown() 1131 } 1132 } 1133 } 1134 1135 @Test testQosCallbackIdsAreMappedCorrectlynull1136 fun testQosCallbackIdsAreMappedCorrectly() { 1137 val (agent, qosTestSocket) = setupForQosSocket() 1138 val qosCallback1 = TestableQosCallback() 1139 val qosCallback2 = TestableQosCallback() 1140 Executors.newSingleThreadExecutor().let { executor -> 1141 try { 1142 val info = QosSocketInfo(agent.network!!, qosTestSocket) 1143 mCM.registerQosCallback(info, executor, qosCallback1) 1144 val callbackId1 = agent.expectCallback<OnRegisterQosCallback>().callbackId 1145 1146 mCM.registerQosCallback(info, executor, qosCallback2) 1147 val callbackId2 = agent.expectCallback<OnRegisterQosCallback>().callbackId 1148 1149 val sessId1 = 101 1150 val attributes1 = createEpsAttributes(1) 1151 1152 // Check #1 1153 agent.sendQosSessionAvailable(callbackId1, sessId1, attributes1) 1154 qosCallback1.expectCallback<OnQosSessionAvailable>() 1155 qosCallback2.assertNoCallback() 1156 1157 // Check #2 1158 val sessId2 = 102 1159 val attributes2 = createEpsAttributes(2) 1160 agent.sendQosSessionAvailable(callbackId2, sessId2, attributes2) 1161 qosCallback1.assertNoCallback() 1162 qosCallback2.expectCallback<OnQosSessionAvailable> { sessId2 == it.sess.sessionId } 1163 } finally { 1164 qosTestSocket.close() 1165 1166 // Make sure that the callback is fully unregistered 1167 mCM.unregisterQosCallback(qosCallback1) 1168 mCM.unregisterQosCallback(qosCallback2) 1169 1170 executor.shutdown() 1171 } 1172 } 1173 } 1174 1175 @Test testQosCallbackWhenNetworkReleasednull1176 fun testQosCallbackWhenNetworkReleased() { 1177 val (agent, qosTestSocket) = setupForQosSocket() 1178 Executors.newSingleThreadExecutor().let { executor -> 1179 try { 1180 val qosCallback1 = TestableQosCallback() 1181 val qosCallback2 = TestableQosCallback() 1182 try { 1183 val info = QosSocketInfo(agent.network!!, qosTestSocket) 1184 mCM.registerQosCallback(info, executor, qosCallback1) 1185 mCM.registerQosCallback(info, executor, qosCallback2) 1186 agent.unregister() 1187 1188 qosCallback1.expectCallback<OnError> { 1189 it.ex.cause is NetworkReleasedException 1190 } 1191 1192 qosCallback2.expectCallback<OnError> { 1193 it.ex.cause is NetworkReleasedException 1194 } 1195 } finally { 1196 qosTestSocket.close() 1197 mCM.unregisterQosCallback(qosCallback1) 1198 mCM.unregisterQosCallback(qosCallback2) 1199 } 1200 } finally { 1201 qosTestSocket.close() 1202 executor.shutdown() 1203 } 1204 } 1205 } 1206 createEpsAttributesnull1207 private fun createEpsAttributes(qci: Int = 1): EpsBearerQosSessionAttributes { 1208 val remoteAddresses = ArrayList<InetSocketAddress>() 1209 remoteAddresses.add(InetSocketAddress("2001:db8::123", 80)) 1210 return EpsBearerQosSessionAttributes( 1211 qci, 2, 3, 4, 5, 1212 remoteAddresses 1213 ) 1214 } 1215 1216 @Test testUnregisterAfterReplacementnull1217 fun testUnregisterAfterReplacement() { 1218 assumeFalse(Build.isDebuggable()) // Disabled presubmit pending prebuilt update on U 1219 // Keeps an eye on all test networks. 1220 val matchAllCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) 1221 registerNetworkCallback(makeTestNetworkRequest(), matchAllCallback) 1222 1223 // File a request that matches and keeps up the best-scoring test network. 1224 val testCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS) 1225 requestNetwork(makeTestNetworkRequest(), testCallback) 1226 1227 // Connect the first network. This should satisfy the request. 1228 val (agent1, network1) = connectNetwork() 1229 matchAllCallback.expectAvailableThenValidatedCallbacks(network1) 1230 testCallback.expectAvailableThenValidatedCallbacks(network1) 1231 // Check that network1 exists by binding a socket to it and getting no exceptions. 1232 network1.bindSocket(DatagramSocket()) 1233 1234 // Connect a second agent. network1 is preferred because it was already registered, so 1235 // testCallback will not see any events. agent2 is be torn down because it has no requests. 1236 val (agent2, network2) = connectNetwork() 1237 matchAllCallback.expectAvailableThenValidatedCallbacks(network2) 1238 matchAllCallback.expect<Lost>(network2) 1239 agent2.expectCallback<OnNetworkUnwanted>() 1240 agent2.expectCallback<OnNetworkDestroyed>() 1241 assertNull(mCM.getLinkProperties(network2)) 1242 1243 // Mark the first network as awaiting replacement. This should destroy the underlying 1244 // native network and send onNetworkDestroyed, but will not send any NetworkCallbacks, 1245 // because for callback and scoring purposes network1 is still connected. 1246 agent1.unregisterAfterReplacement(5_000 /* timeoutMillis */) 1247 agent1.expectCallback<OnNetworkDestroyed>() 1248 assertThrows(IOException::class.java) { network1.bindSocket(DatagramSocket()) } 1249 assertNotNull(mCM.getLinkProperties(network1)) 1250 1251 // Calling unregisterAfterReplacement more than once has no effect. 1252 // If it did, this test would fail because the 1ms timeout means that the network would be 1253 // torn down before the replacement arrives. 1254 agent1.unregisterAfterReplacement(1 /* timeoutMillis */) 1255 1256 // Connect a third network. Because network1 is awaiting replacement, network3 is preferred 1257 // as soon as it validates (until then, it is outscored by network1). 1258 // The fact that the first events seen by matchAllCallback is the connection of network3 1259 // implicitly ensures that no callbacks are sent since network1 was lost. 1260 val (agent3, network3) = connectNetwork() 1261 matchAllCallback.expectAvailableThenValidatedCallbacks(network3) 1262 testCallback.expectAvailableDoubleValidatedCallbacks(network3) 1263 1264 // As soon as the replacement arrives, network1 is disconnected. 1265 // Check that this happens before the replacement timeout (5 seconds) fires. 1266 matchAllCallback.expect<Lost>(network1, 2_000 /* timeoutMs */) 1267 agent1.expectCallback<OnNetworkUnwanted>() 1268 1269 // Test lingering: 1270 // - Connect a higher-scoring network and check that network3 starts lingering. 1271 // - Mark network3 awaiting replacement. 1272 // - Check that network3 is torn down immediately without waiting for the linger timer or 1273 // the replacement timer to fire. This is a regular teardown, so it results in 1274 // onNetworkUnwanted before onNetworkDestroyed. 1275 val (agent4, agent4callback) = createConnectedNetworkAgent() 1276 val network4 = agent4.network!! 1277 matchAllCallback.expectAvailableThenValidatedCallbacks(network4) 1278 agent4.sendNetworkScore(NetworkScore.Builder().setTransportPrimary(true).build()) 1279 matchAllCallback.expect<Losing>(network3) 1280 testCallback.expectAvailableCallbacks(network4, validated = true) 1281 mCM.unregisterNetworkCallback(agent4callback) 1282 agent3.unregisterAfterReplacement(5_000) 1283 agent3.expectCallback<OnNetworkUnwanted>() 1284 matchAllCallback.expect<Lost>(network3, 1000L) 1285 agent3.expectCallback<OnNetworkDestroyed>() 1286 1287 // Now mark network4 awaiting replacement with a low timeout, and check that if no 1288 // replacement arrives, it is torn down. 1289 agent4.unregisterAfterReplacement(100 /* timeoutMillis */) 1290 matchAllCallback.expect<Lost>(network4, 1000L /* timeoutMs */) 1291 testCallback.expect<Lost>(network4, 1000L /* timeoutMs */) 1292 agent4.expectCallback<OnNetworkDestroyed>() 1293 agent4.expectCallback<OnNetworkUnwanted>() 1294 1295 // If a network that is awaiting replacement is unregistered, it disconnects immediately, 1296 // before the replacement timeout fires. 1297 val (agent5, network5) = connectNetwork() 1298 matchAllCallback.expectAvailableThenValidatedCallbacks(network5) 1299 testCallback.expectAvailableThenValidatedCallbacks(network5) 1300 agent5.unregisterAfterReplacement(5_000 /* timeoutMillis */) 1301 agent5.unregister() 1302 matchAllCallback.expect<Lost>(network5, 1000L /* timeoutMs */) 1303 testCallback.expect<Lost>(network5, 1000L /* timeoutMs */) 1304 agent5.expectCallback<OnNetworkDestroyed>() 1305 agent5.expectCallback<OnNetworkUnwanted>() 1306 1307 // If unregisterAfterReplacement is called before markConnected, the network disconnects. 1308 val specifier6 = UUID.randomUUID().toString() 1309 val callback = TestableNetworkCallback() 1310 requestNetwork(makeTestNetworkRequest(specifier = specifier6), callback) 1311 val agent6 = createNetworkAgent(specifier = specifier6) 1312 val network6 = agent6.register() 1313 if (SHOULD_CREATE_NETWORKS_IMMEDIATELY) { 1314 agent6.expectCallback<OnNetworkCreated>() 1315 } else { 1316 // No callbacks are sent, so check LinkProperties to wait for the network to be created. 1317 assertLinkPropertiesEventuallyNotNull(agent6.network!!) 1318 } 1319 1320 // unregisterAfterReplacement tears down the network immediately. 1321 // Approximately check that this is the case by picking an unregister timeout that's longer 1322 // than the timeout of the expectCallback<OnNetworkUnwanted> below. 1323 // TODO: consider adding configurable timeouts to TestableNetworkAgent expectations. 1324 val timeoutMs = agent6.DEFAULT_TIMEOUT_MS.toInt() + 1_000 1325 agent6.unregisterAfterReplacement(timeoutMs) 1326 agent6.expectCallback<OnNetworkUnwanted>() 1327 if (!SdkLevel.isAtLeastT() || SHOULD_CREATE_NETWORKS_IMMEDIATELY) { 1328 // Before T, onNetworkDestroyed is called even if the network was never created. 1329 // If immediate native network creation is supported, the network was created by 1330 // register(). Destroying it sends onNetworkDestroyed. 1331 agent6.expectCallback<OnNetworkDestroyed>() 1332 } 1333 // Poll for LinkProperties becoming null, because when onNetworkUnwanted is called, the 1334 // network has not yet been removed from the CS data structures. 1335 assertLinkPropertiesEventuallyNull(agent6.network!!) 1336 assertFalse(mCM.getAllNetworks().contains(agent6.network!!)) 1337 1338 // After unregisterAfterReplacement is called, the network is no longer usable and 1339 // markConnected has no effect. 1340 agent6.markConnected() 1341 agent6.assertNoCallback() 1342 assertNull(mCM.getLinkProperties(agent6.network!!)) 1343 matchAllCallback.assertNoCallback(200 /* timeoutMs */) 1344 1345 // If wifi is replaced within the timeout, the device does not switch to cellular. 1346 val (_, cellNetwork) = connectNetwork(TRANSPORT_CELLULAR) 1347 testCallback.expectAvailableThenValidatedCallbacks(cellNetwork) 1348 matchAllCallback.expectAvailableThenValidatedCallbacks(cellNetwork) 1349 1350 val (wifiAgent, wifiNetwork) = connectNetwork(TRANSPORT_WIFI) 1351 testCallback.expectAvailableCallbacks(wifiNetwork, validated = true) 1352 testCallback.expectCaps(wifiNetwork) { it.hasCapability(NET_CAPABILITY_VALIDATED) } 1353 matchAllCallback.expectAvailableCallbacks(wifiNetwork, validated = false) 1354 matchAllCallback.expect<Losing>(cellNetwork) 1355 matchAllCallback.expectCaps(wifiNetwork) { it.hasCapability(NET_CAPABILITY_VALIDATED) } 1356 1357 wifiAgent.unregisterAfterReplacement(5_000 /* timeoutMillis */) 1358 wifiAgent.expectCallback<OnNetworkDestroyed>() 1359 1360 // Once the network is awaiting replacement, changing LinkProperties, NetworkCapabilities or 1361 // score, or calling reportNetworkConnectivity, have no effect. 1362 val wifiSpecifier = mCM.getNetworkCapabilities(wifiNetwork)!!.networkSpecifier 1363 assertNotNull(wifiSpecifier) 1364 assertTrue(wifiSpecifier is EthernetNetworkSpecifier) 1365 1366 val wifiNc = makeTestNetworkCapabilities(wifiSpecifier.interfaceName, 1367 intArrayOf(TRANSPORT_WIFI)) 1368 wifiAgent.sendNetworkCapabilities(wifiNc) 1369 val wifiLp = mCM.getLinkProperties(wifiNetwork)!! 1370 val newRoute = RouteInfo(IpPrefix("192.0.2.42/24")) 1371 assertFalse(wifiLp.getRoutes().contains(newRoute)) 1372 wifiLp.addRoute(newRoute) 1373 wifiAgent.sendLinkProperties(wifiLp) 1374 mCM.reportNetworkConnectivity(wifiNetwork, false) 1375 // The test implicitly checks that no callbacks are sent here, because the next events seen 1376 // by the callbacks are for the new network connecting. 1377 1378 val (newWifiAgent, newWifiNetwork) = connectNetwork(TRANSPORT_WIFI) 1379 testCallback.expectAvailableCallbacks(newWifiNetwork, validated = true) 1380 matchAllCallback.expectAvailableThenValidatedCallbacks(newWifiNetwork) 1381 matchAllCallback.expect<Lost>(wifiNetwork) 1382 wifiAgent.expectCallback<OnNetworkUnwanted>() 1383 } 1384 1385 @Test testUnregisterAgentBeforeAgentFullyConnectednull1386 fun testUnregisterAgentBeforeAgentFullyConnected() { 1387 val specifier = UUID.randomUUID().toString() 1388 val callback = TestableNetworkCallback() 1389 val transports = intArrayOf(TRANSPORT_CELLULAR) 1390 // Ensure this NetworkAgent is never unneeded by filing a request with its specifier. 1391 requestNetwork(makeTestNetworkRequest(specifier = specifier), callback) 1392 val nc = makeTestNetworkCapabilities(specifier, transports) 1393 val agent = createNetworkAgent(realContext, initialNc = nc) 1394 // Connect the agent 1395 agent.register() 1396 // Mark agent connected then unregister agent immediately. Verify that both available and 1397 // lost callback should be sent still. 1398 agent.markConnected() 1399 agent.unregister() 1400 callback.expect<Available>(agent.network!!) 1401 callback.eventuallyExpect<Lost> { it.network == agent.network } 1402 } 1403 doTestNativeNetworkCreationnull1404 fun doTestNativeNetworkCreation(expectCreatedImmediately: Boolean, transports: IntArray) { 1405 val iface = createTunInterface() 1406 val ifName = iface.interfaceName 1407 val nc = makeTestNetworkCapabilities(ifName, transports).also { 1408 if (transports.contains(TRANSPORT_VPN)) { 1409 val sessionId = "NetworkAgentTest-${Process.myPid()}" 1410 it.transportInfo = VpnTransportInfo(VpnManager.TYPE_VPN_PLATFORM, sessionId, 1411 /*bypassable=*/ false, /*longLivedTcpConnectionsExpensive=*/ false) 1412 it.underlyingNetworks = listOf() 1413 } 1414 } 1415 val lp = LinkProperties().apply { 1416 interfaceName = ifName 1417 addLinkAddress(LinkAddress("2001:db8::1/64")) 1418 addRoute(RouteInfo(IpPrefix("2001:db8::/64"), null /* nextHop */, ifName)) 1419 addRoute(RouteInfo(IpPrefix("::/0"), 1420 InetAddresses.parseNumericAddress("fe80::abcd"), 1421 ifName)) 1422 } 1423 1424 // File a request containing the agent's specifier to receive callbacks and to ensure that 1425 // the agent is not torn down due to being unneeded. 1426 val request = makeTestNetworkRequest(specifier = ifName) 1427 val requestCallback = TestableNetworkCallback() 1428 requestNetwork(request, requestCallback) 1429 1430 val listenCallback = TestableNetworkCallback() 1431 registerNetworkCallback(request, listenCallback) 1432 1433 // Register the NetworkAgent... 1434 val agent = createNetworkAgent(realContext, initialNc = nc, initialLp = lp) 1435 val network = agent.register() 1436 1437 // ... and then change the NetworkCapabilities and LinkProperties. 1438 nc.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED) 1439 agent.sendNetworkCapabilities(nc) 1440 lp.addLinkAddress(LinkAddress("192.0.2.2/25")) 1441 lp.addRoute(RouteInfo(IpPrefix("192.0.2.0/25"), null /* nextHop */, ifName)) 1442 agent.sendLinkProperties(lp) 1443 1444 requestCallback.assertNoCallback() 1445 listenCallback.assertNoCallback() 1446 if (!expectCreatedImmediately) { 1447 agent.assertNoCallback() 1448 agent.markConnected() 1449 agent.expectCallback<OnNetworkCreated>() 1450 } else { 1451 agent.expectCallback<OnNetworkCreated>() 1452 agent.markConnected() 1453 } 1454 agent.expectPostConnectionCallbacks() 1455 1456 // onAvailable must be called only when the network connects, and no other callbacks may be 1457 // called before that happens. The callbacks report the state of the network as it was when 1458 // it connected, so they reflect the NC and LP changes made after registration. 1459 requestCallback.expect<Available>(network) 1460 listenCallback.expect<Available>(network) 1461 1462 requestCallback.expect<CapabilitiesChanged>(network) { it.caps.hasCapability( 1463 NET_CAPABILITY_TEMPORARILY_NOT_METERED) } 1464 listenCallback.expect<CapabilitiesChanged>(network) { it.caps.hasCapability( 1465 NET_CAPABILITY_TEMPORARILY_NOT_METERED) } 1466 1467 requestCallback.expect<LinkPropertiesChanged>(network) { it.lp.equals(lp) } 1468 listenCallback.expect<LinkPropertiesChanged>(network) { it.lp.equals(lp) } 1469 1470 requestCallback.expect<BlockedStatus>() 1471 listenCallback.expect<BlockedStatus>() 1472 1473 // Except for network validation, ensure no more callbacks are sent. 1474 requestCallback.expectCaps(network) { 1475 it.hasCapability(NET_CAPABILITY_VALIDATED) 1476 } 1477 listenCallback.expectCaps(network) { 1478 it.hasCapability(NET_CAPABILITY_VALIDATED) 1479 } 1480 unregister(agent) 1481 // Lost implicitly checks that no further callbacks happened after connect. 1482 requestCallback.expect<Lost>(network) 1483 listenCallback.expect<Lost>(network) 1484 assertNull(mCM.getLinkProperties(network)) 1485 } 1486 1487 @Test testNativeNetworkCreation_PhysicalNetworknull1488 fun testNativeNetworkCreation_PhysicalNetwork() { 1489 assumeFalse(Build.isDebuggable()) // Disabled presubmit pending prebuilt update on U 1490 doTestNativeNetworkCreation( 1491 expectCreatedImmediately = SHOULD_CREATE_NETWORKS_IMMEDIATELY, 1492 intArrayOf(TRANSPORT_CELLULAR)) 1493 } 1494 1495 @Test testNativeNetworkCreation_Vpnnull1496 fun testNativeNetworkCreation_Vpn() { 1497 // VPN networks are always created as soon as the agent is registered. 1498 doTestNativeNetworkCreation(expectCreatedImmediately = true, intArrayOf(TRANSPORT_VPN)) 1499 } 1500 } 1501