• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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