• 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.NEARBY_WIFI_DEVICES
19 import android.Manifest.permission.NETWORK_SETTINGS
20 import android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
21 import android.app.Instrumentation
22 import android.content.Context
23 import android.content.pm.PackageManager
24 import android.content.pm.PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION
25 import android.net.ConnectivityManager
26 import android.net.EthernetNetworkSpecifier
27 import android.net.INetworkAgent
28 import android.net.INetworkAgentRegistry
29 import android.net.InetAddresses
30 import android.net.IpPrefix
31 import android.net.LinkAddress
32 import android.net.LinkProperties
33 import android.net.NattKeepalivePacketData
34 import android.net.Network
35 import android.net.NetworkAgent
36 import android.net.NetworkAgent.INVALID_NETWORK
37 import android.net.NetworkAgent.VALID_NETWORK
38 import android.net.NetworkAgentConfig
39 import android.net.NetworkCapabilities
40 import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
41 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED
42 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED
43 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED
44 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING
45 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED
46 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED
47 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN
48 import android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED
49 import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
50 import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
51 import android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH
52 import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
53 import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
54 import android.net.NetworkCapabilities.TRANSPORT_TEST
55 import android.net.NetworkCapabilities.TRANSPORT_VPN
56 import android.net.NetworkCapabilities.TRANSPORT_WIFI
57 import android.net.NetworkInfo
58 import android.net.NetworkProvider
59 import android.net.NetworkReleasedException
60 import android.net.NetworkRequest
61 import android.net.NetworkScore
62 import android.net.NetworkSpecifier
63 import android.net.QosCallback
64 import android.net.QosCallback.QosCallbackRegistrationException
65 import android.net.QosCallbackException
66 import android.net.QosSession
67 import android.net.QosSessionAttributes
68 import android.net.QosSocketInfo
69 import android.net.RouteInfo
70 import android.net.SocketKeepalive
71 import android.net.TelephonyNetworkSpecifier
72 import android.net.TestNetworkInterface
73 import android.net.TestNetworkManager
74 import android.net.TransportInfo
75 import android.net.Uri
76 import android.net.VpnManager
77 import android.net.VpnTransportInfo
78 import android.net.cts.NetworkAgentTest.TestableQosCallback.CallbackEntry.OnError
79 import android.net.cts.NetworkAgentTest.TestableQosCallback.CallbackEntry.OnQosSessionAvailable
80 import android.net.cts.NetworkAgentTest.TestableQosCallback.CallbackEntry.OnQosSessionLost
81 import android.net.wifi.WifiInfo
82 import android.os.Build
83 import android.os.Handler
84 import android.os.HandlerThread
85 import android.os.Looper
86 import android.os.Message
87 import android.os.Process
88 import android.os.SystemClock
89 import android.platform.test.annotations.AppModeFull
90 import android.system.Os
91 import android.system.OsConstants.AF_INET6
92 import android.system.OsConstants.IPPROTO_TCP
93 import android.system.OsConstants.IPPROTO_UDP
94 import android.system.OsConstants.SOCK_DGRAM
95 import android.telephony.SubscriptionManager
96 import android.telephony.TelephonyManager
97 import android.telephony.data.EpsBearerQosSessionAttributes
98 import android.util.ArraySet
99 import android.util.DebugUtils.valueToString
100 import androidx.test.InstrumentationRegistry
101 import com.android.compatibility.common.util.SystemUtil.runShellCommand
102 import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
103 import com.android.compatibility.common.util.ThrowingSupplier
104 import com.android.modules.utils.build.SdkLevel
105 import com.android.net.module.util.ArrayTrackRecord
106 import com.android.net.module.util.NetworkStackConstants.ETHER_MTU
107 import com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN
108 import com.android.net.module.util.NetworkStackConstants.IPV6_PROTOCOL_OFFSET
109 import com.android.net.module.util.NetworkStackConstants.UDP_HEADER_LEN
110 import com.android.testutils.CompatUtil
111 import com.android.testutils.ConnectivityModuleTest
112 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
113 import com.android.testutils.DevSdkIgnoreRunner
114 import com.android.testutils.PollPacketReader
115 import com.android.testutils.RecorderCallback.CallbackEntry.Available
116 import com.android.testutils.RecorderCallback.CallbackEntry.BlockedStatus
117 import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
118 import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
119 import com.android.testutils.RecorderCallback.CallbackEntry.Losing
120 import com.android.testutils.RecorderCallback.CallbackEntry.Lost
121 import com.android.testutils.TestableNetworkAgent
122 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnAddKeepalivePacketFilter
123 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnAutomaticReconnectDisabled
124 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnBandwidthUpdateRequested
125 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkCreated
126 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkDestroyed
127 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnNetworkUnwanted
128 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnRegisterQosCallback
129 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnRemoveKeepalivePacketFilter
130 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnSaveAcceptUnvalidated
131 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnStartSocketKeepalive
132 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnStopSocketKeepalive
133 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnUnregisterQosCallback
134 import com.android.testutils.TestableNetworkAgent.CallbackEntry.OnValidationStatus
135 import com.android.testutils.TestableNetworkCallback
136 import com.android.testutils.assertThrows
137 import com.android.testutils.com.android.testutils.CarrierConfigRule
138 import com.android.testutils.runAsShell
139 import com.android.testutils.tryTest
140 import com.android.testutils.waitForIdle
141 import java.io.Closeable
142 import java.io.IOException
143 import java.net.DatagramSocket
144 import java.net.InetAddress
145 import java.net.InetSocketAddress
146 import java.net.Socket
147 import java.nio.ByteBuffer
148 import java.time.Duration
149 import java.util.Arrays
150 import java.util.UUID
151 import java.util.concurrent.Executors
152 import kotlin.collections.ArrayList
153 import kotlin.random.Random
154 import kotlin.test.assertEquals
155 import kotlin.test.assertFailsWith
156 import kotlin.test.assertFalse
157 import kotlin.test.assertNotNull
158 import kotlin.test.assertNull
159 import kotlin.test.assertTrue
160 import kotlin.test.fail
161 import org.junit.After
162 import org.junit.Assume.assumeTrue
163 import org.junit.Before
164 import org.junit.Rule
165 import org.junit.Test
166 import org.junit.runner.RunWith
167 import org.mockito.ArgumentMatchers.any
168 import org.mockito.ArgumentMatchers.anyInt
169 import org.mockito.ArgumentMatchers.argThat
170 import org.mockito.ArgumentMatchers.eq
171 import org.mockito.Mockito.doReturn
172 import org.mockito.Mockito.mock
173 import org.mockito.Mockito.timeout
174 import org.mockito.Mockito.verify
175 
176 private const val TAG = "NetworkAgentTest"
177 
178 // This test doesn't really have a constraint on how fast the methods should return. If it's
179 // going to fail, it will simply wait forever, so setting a high timeout lowers the flake ratio
180 // without affecting the run time of successful runs. Thus, set a very high timeout.
181 private const val DEFAULT_TIMEOUT_MS = 5000L
182 
183 private const val QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER =
184     "queue_network_agent_events_in_system_server"
185 
186 
187 // When waiting for a NetworkCallback to determine there was no timeout, waiting is the
188 // only possible thing (the relevant handler is the one in the real ConnectivityService,
189 // and then there is the Binder call), so have a short timeout for this as it will be
190 // exhausted every time.
191 private const val NO_CALLBACK_TIMEOUT = 200L
192 private const val WORSE_NETWORK_SCORE = 65
193 private const val BETTER_NETWORK_SCORE = 75
194 private const val FAKE_NET_ID = 1098
195 private val instrumentation: Instrumentation
196     get() = InstrumentationRegistry.getInstrumentation()
197 private val realContext: Context
198     get() = InstrumentationRegistry.getContext()
199 private fun Message(what: Int, arg1: Int, arg2: Int, obj: Any?) = Message.obtain().also {
200     it.what = what
201     it.arg1 = arg1
202     it.arg2 = arg2
203     it.obj = obj
204 }
205 
206 private val LINK_ADDRESS = LinkAddress("2001:db8::1/64")
207 private val REMOTE_ADDRESS = InetAddresses.parseNumericAddress("2001:db8::123")
208 private val PREFIX = IpPrefix("2001:db8::/64")
209 private val NEXTHOP = InetAddresses.parseNumericAddress("fe80::abcd")
210 
211 @AppModeFull(reason = "Instant apps can't use NetworkAgent because it needs NETWORK_FACTORY'.")
212 // NetworkAgent is updated as part of the connectivity module, and running NetworkAgent tests in MTS
213 // for modules other than Connectivity does not provide much value. Only run them in connectivity
214 // module MTS, so the tests only need to cover the case of an updated NetworkAgent.
215 @ConnectivityModuleTest
216 @DevSdkIgnoreRunner.RestoreDefaultNetwork
217 // NetworkAgent is not updatable in R-, so this test does not need to be compatible with older
218 // versions. NetworkAgent was also based on AsyncChannel before S so cannot be tested the same way.
219 @IgnoreUpTo(Build.VERSION_CODES.R)
220 @RunWith(DevSdkIgnoreRunner::class)
221 class NetworkAgentTest {
222     @get:Rule
223     val carrierConfigRule = CarrierConfigRule()
224 
225     private val LOCAL_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1")
226     private val REMOTE_IPV4_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.2")
227 
228     private val mCM = realContext.getSystemService(ConnectivityManager::class.java)!!
229     private val mHandlerThread = HandlerThread("${javaClass.simpleName} handler thread")
230     private val mFakeConnectivityService = FakeConnectivityService()
231     private val agentsToCleanUp = mutableListOf<NetworkAgent>()
232     private val callbacksToCleanUp = mutableListOf<TestableNetworkCallback>()
233     private var qosTestSocket: Closeable? = null // either Socket or DatagramSocket
234     private val ifacesToCleanUp = mutableListOf<TestNetworkInterface>()
235 
236     // Unless the queuing in system server feature is chickened out, native networks are created
237     // immediately. Historically they would only created as they'd connect, which would force
238     // the code to apply link properties multiple times and suffer errors early on. Creating
239     // them early required that ordering between the client and the system server is guaranteed
240     // (at least to some extent), which has been done by moving the event queue from the client
241     // to the system server. When that feature is not chickened out, create networks immediately.
242     private val SHOULD_CREATE_NETWORKS_IMMEDIATELY
243         get() = mCM.isConnectivityServiceFeatureEnabledForTesting(
244             QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER
245         )
246 
247 
248     @Before
setUpnull249     fun setUp() {
250         instrumentation.getUiAutomation().adoptShellPermissionIdentity()
251         if (SdkLevel.isAtLeastT()) {
252             instrumentation.getUiAutomation().grantRuntimePermission(
253                 "android.net.cts",
254                 NEARBY_WIFI_DEVICES
255             )
256         }
257         mHandlerThread.start()
258     }
259 
260     @After
tearDownnull261     fun tearDown() {
262         agentsToCleanUp.forEach { it.unregister() }
263         callbacksToCleanUp.forEach { mCM.unregisterNetworkCallback(it) }
264         ifacesToCleanUp.forEach { it.fileDescriptor.close() }
265         qosTestSocket?.close()
266         mHandlerThread.quitSafely()
267         mHandlerThread.join()
268         instrumentation.getUiAutomation().dropShellPermissionIdentity()
269     }
270 
271     /**
272      * A fake that helps simulating ConnectivityService talking to a harnessed agent.
273      * This fake only supports speaking to one harnessed agent at a time because it
274      * only keeps track of one async channel.
275      */
276     private class FakeConnectivityService {
277         val mockRegistry = mock(INetworkAgentRegistry::class.java)
278         private var agentField: INetworkAgent? = null
279         val registry: INetworkAgentRegistry = object : INetworkAgentRegistry.Stub(),
<lambda>null280                 INetworkAgentRegistry by mockRegistry {
281             // asBinder has implementations in both INetworkAgentRegistry.Stub and mockRegistry, so
282             // it needs to be disambiguated. Just fail the test as it should be unused here.
283             // asBinder is used when sending the registry in binder transactions, so not in this
284             // test (the test just uses in-process direct calls). If it were used across processes,
285             // using the Stub super.asBinder() implementation would allow sending the registry in
286             // binder transactions, while recording incoming calls on the other mockito-generated
287             // methods.
288             override fun asBinder() = fail("asBinder should be unused in this test")
289         }
290 
291         val agent: INetworkAgent
292             get() = agentField ?: fail("No INetworkAgent")
293 
connectnull294         fun connect(agent: INetworkAgent) {
295             this.agentField = agent
296             agent.onRegistered()
297         }
298 
disconnectnull299         fun disconnect() = agent.onDisconnected()
300     }
301 
302     private fun requestNetwork(request: NetworkRequest, callback: TestableNetworkCallback) {
303         mCM.requestNetwork(request, callback)
304         callbacksToCleanUp.add(callback)
305     }
306 
registerNetworkCallbacknull307     private fun registerNetworkCallback(
308         request: NetworkRequest,
309         callback: TestableNetworkCallback
310     ) {
311         mCM.registerNetworkCallback(request, callback)
312         callbacksToCleanUp.add(callback)
313     }
314 
registerBestMatchingNetworkCallbacknull315     private fun registerBestMatchingNetworkCallback(
316         request: NetworkRequest,
317         callback: TestableNetworkCallback,
318         handler: Handler
319     ) {
320         mCM.registerBestMatchingNetworkCallback(request, callback, handler)
321         callbacksToCleanUp.add(callback)
322     }
323 
asEthSpecifiernull324     private fun String?.asEthSpecifier(): NetworkSpecifier? =
325             if (null == this) null else CompatUtil.makeEthernetNetworkSpecifier(this)
326     private fun makeTestNetworkRequest(specifier: NetworkSpecifier? = null) =
327             NetworkRequest.Builder().run {
328                 clearCapabilities()
329                 addTransportType(TRANSPORT_TEST)
330                 if (specifier != null) setNetworkSpecifier(specifier)
331                 build()
332             }
333 
makeTestNetworkRequestnull334     private fun makeTestNetworkRequest(specifier: String?) =
335             makeTestNetworkRequest(specifier.asEthSpecifier())
336 
337     private fun makeTestNetworkCapabilities(
338         specifier: String? = null,
339         transports: IntArray = intArrayOf()
340     ) = NetworkCapabilities().apply {
341         addTransportType(TRANSPORT_TEST)
342         removeCapability(NET_CAPABILITY_TRUSTED)
343         removeCapability(NET_CAPABILITY_INTERNET)
344         addCapability(NET_CAPABILITY_NOT_SUSPENDED)
345         addCapability(NET_CAPABILITY_NOT_ROAMING)
346         if (!transports.contains(TRANSPORT_VPN)) addCapability(NET_CAPABILITY_NOT_VPN)
347         if (SdkLevel.isAtLeastS()) {
348             addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
349         }
350         if (null != specifier) {
351             setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifier))
352         }
353         for (t in transports) { addTransportType(t) }
354         // Most transports are not allowed on test networks unless the network is marked restricted.
355         // This test does not need
356         if (transports.size > 0) removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
357     }
358 
makeTestLinkPropertiesnull359     private fun makeTestLinkProperties(ifName: String): LinkProperties {
360         return LinkProperties().apply {
361             interfaceName = ifName
362             addLinkAddress(LINK_ADDRESS)
363             addRoute(RouteInfo(PREFIX, null /* nextHop */, ifName))
364             addRoute(RouteInfo(IpPrefix("::/0"), NEXTHOP, ifName))
365         }
366     }
367 
createNetworkAgentnull368     private fun createNetworkAgent(
369         context: Context = realContext,
370         specifier: String? = null,
371         initialNc: NetworkCapabilities? = null,
372         initialLp: LinkProperties? = null,
373         initialConfig: NetworkAgentConfig? = null
374     ): TestableNetworkAgent {
375         val nc = initialNc ?: makeTestNetworkCapabilities(specifier)
376         val lp = initialLp ?: LinkProperties().apply {
377             addLinkAddress(LinkAddress(LOCAL_IPV4_ADDRESS, 32))
378             addRoute(RouteInfo(IpPrefix("0.0.0.0/0"), null, null))
379         }
380         val config = initialConfig ?: NetworkAgentConfig.Builder().build()
381         return TestableNetworkAgent(context, mHandlerThread.looper, nc, lp, config).also {
382             agentsToCleanUp.add(it)
383         }
384     }
385 
createConnectedNetworkAgentnull386     private fun createConnectedNetworkAgent(
387         context: Context = realContext,
388         lp: LinkProperties? = null,
389         specifier: String? = UUID.randomUUID().toString(),
390         initialConfig: NetworkAgentConfig? = null,
391         expectedInitSignalStrengthThresholds: IntArray = intArrayOf(),
392         transports: IntArray = intArrayOf()
393     ): Pair<TestableNetworkAgent, TestableNetworkCallback> {
394         val callback = TestableNetworkCallback()
395         // Ensure this NetworkAgent is never unneeded by filing a request with its specifier.
396         requestNetwork(makeTestNetworkRequest(specifier), callback)
397         val nc = makeTestNetworkCapabilities(specifier, transports)
398         val agent = createNetworkAgent(
399             context,
400             initialConfig = initialConfig,
401             initialLp = lp,
402             initialNc = nc
403         )
404         // Connect the agent and verify initial status callbacks.
405         agent.register()
406         agent.setTeardownDelayMillis(0)
407         agent.markConnected()
408         agent.expectCallback<OnNetworkCreated>()
409         agent.expectPostConnectionCallbacks(expectedInitSignalStrengthThresholds)
410         callback.expectAvailableThenValidatedCallbacks(agent.network!!)
411         return agent to callback
412     }
413 
connectNetworknull414     private fun connectNetwork(vararg transports: Int, lp: LinkProperties? = null):
415             Pair<TestableNetworkAgent, Network> {
416         val (agent, callback) = createConnectedNetworkAgent(transports = transports, lp = lp)
417         val network = agent.network!!
418         // createConnectedNetworkAgent internally files a request; release it so that the network
419         // will be torn down if unneeded.
420         mCM.unregisterNetworkCallback(callback)
421         return agent to network
422     }
423 
<lambda>null424     private fun createNetworkAgentWithFakeCS() = createNetworkAgent().also {
425         val binder = it.registerForTest(Network(FAKE_NET_ID), mFakeConnectivityService.registry)
426         mFakeConnectivityService.connect(binder)
427     }
428 
expectPostConnectionCallbacksnull429     private fun TestableNetworkAgent.expectPostConnectionCallbacks(
430         thresholds: IntArray = intArrayOf()
431     ) {
432         expectSignalStrengths(thresholds)
433         expectValidationBypassedStatus()
434         assertNoCallback()
435     }
436 
createTunInterfacenull437     private fun createTunInterface(addrs: Collection<LinkAddress> = emptyList()):
438             TestNetworkInterface = realContext.getSystemService(
439                 TestNetworkManager::class.java
440             )!!.createTunInterface(addrs).also {
441             ifacesToCleanUp.add(it)
442     }
443 
assertLinkPropertiesEventuallynull444     fun assertLinkPropertiesEventually(
445         n: Network,
446         description: String,
447         condition: (LinkProperties?) -> Boolean
448     ): LinkProperties? {
449         val deadline = SystemClock.elapsedRealtime() + DEFAULT_TIMEOUT_MS
450         do {
451             val lp = mCM.getLinkProperties(n)
452             if (condition(lp)) return lp
453             SystemClock.sleep(10 /* ms */)
454         } while (SystemClock.elapsedRealtime() < deadline)
455         fail("Network $n LinkProperties did not $description after $DEFAULT_TIMEOUT_MS ms")
456     }
457 
assertLinkPropertiesEventuallyNotNullnull458     fun assertLinkPropertiesEventuallyNotNull(n: Network) {
459         assertLinkPropertiesEventually(n, "become non-null") { it != null }
460     }
461 
assertLinkPropertiesEventuallyNullnull462     fun assertLinkPropertiesEventuallyNull(n: Network) {
463         assertLinkPropertiesEventually(n, "become null") { it == null }
464     }
465 
466     @Test
testSetSubtypeNameAndExtraInfoByAgentConfignull467     fun testSetSubtypeNameAndExtraInfoByAgentConfig() {
468         val subtypeLTE = TelephonyManager.NETWORK_TYPE_LTE
469         val subtypeNameLTE = "LTE"
470         val legacyExtraInfo = "mylegacyExtraInfo"
471         val config = NetworkAgentConfig.Builder()
472                 .setLegacySubType(subtypeLTE)
473                 .setLegacySubTypeName(subtypeNameLTE)
474                 .setLegacyExtraInfo(legacyExtraInfo).build()
475         val (agent, callback) = createConnectedNetworkAgent(initialConfig = config)
476         val networkInfo = mCM.getNetworkInfo(agent.network)
477         assertEquals(subtypeLTE, networkInfo?.getSubtype())
478         assertEquals(subtypeNameLTE, networkInfo?.getSubtypeName())
479         assertEquals(legacyExtraInfo, config.getLegacyExtraInfo())
480     }
481 
482     @Test
testSetLegacySubtypeInNetworkAgentnull483     fun testSetLegacySubtypeInNetworkAgent() {
484         val subtypeLTE = TelephonyManager.NETWORK_TYPE_LTE
485         val subtypeUMTS = TelephonyManager.NETWORK_TYPE_UMTS
486         val subtypeNameLTE = "LTE"
487         val subtypeNameUMTS = "UMTS"
488         val config = NetworkAgentConfig.Builder()
489                 .setLegacySubType(subtypeLTE)
490                 .setLegacySubTypeName(subtypeNameLTE).build()
491         val (agent, callback) = createConnectedNetworkAgent(initialConfig = config)
492             agent.setLegacySubtype(subtypeUMTS, subtypeNameUMTS)
493 
494             // There is no callback when networkInfo changes,
495             // so use the NetworkCapabilities callback to ensure
496             // that networkInfo is ready for verification.
497             val nc = NetworkCapabilities(agent.nc)
498             nc.addCapability(NET_CAPABILITY_NOT_METERED)
499             agent.sendNetworkCapabilities(nc)
500             callback.expectCaps(agent.network!!) { it.hasCapability(NET_CAPABILITY_NOT_METERED) }
501             val networkInfo = mCM.getNetworkInfo(agent.network!!)!!
502             assertEquals(subtypeUMTS, networkInfo.getSubtype())
503             assertEquals(subtypeNameUMTS, networkInfo.getSubtypeName())
504     }
505 
506     @Test
testConnectAndUnregisternull507     fun testConnectAndUnregister() {
508         val (agent, callback) = createConnectedNetworkAgent()
509         unregister(agent)
510         callback.expect<Lost>(agent.network!!)
511         assertFailsWith<IllegalStateException>("Must not be able to register an agent twice") {
512             agent.register()
513         }
514     }
515 
516     @Test
testOnBandwidthUpdateRequestednull517     fun testOnBandwidthUpdateRequested() {
518         val (agent, _) = createConnectedNetworkAgent()
519         mCM.requestBandwidthUpdate(agent.network!!)
520         agent.expectCallback<OnBandwidthUpdateRequested>()
521         unregister(agent)
522     }
523 
524     @Test
testSignalStrengthThresholdsnull525     fun testSignalStrengthThresholds() {
526         val thresholds = intArrayOf(30, 50, 65)
527         val callbacks = thresholds.map { strength ->
528             val request = NetworkRequest.Builder()
529                     .clearCapabilities()
530                     .addTransportType(TRANSPORT_TEST)
531                     .setSignalStrength(strength)
532                     .build()
533             TestableNetworkCallback(DEFAULT_TIMEOUT_MS).also {
534                 registerNetworkCallback(request, it)
535             }
536         }
537         createConnectedNetworkAgent(expectedInitSignalStrengthThresholds = thresholds).let {
538             (agent, callback) ->
539             // Send signal strength and check that the callbacks are called appropriately.
540             val nc = NetworkCapabilities(agent.nc)
541             val net = agent.network!!
542             nc.setSignalStrength(20)
543             agent.sendNetworkCapabilities(nc)
544             callbacks.forEach { it.assertNoCallback(NO_CALLBACK_TIMEOUT) }
545 
546             nc.setSignalStrength(40)
547             agent.sendNetworkCapabilities(nc)
548             callbacks[0].expectAvailableCallbacks(net)
549             callbacks[1].assertNoCallback(NO_CALLBACK_TIMEOUT)
550             callbacks[2].assertNoCallback(NO_CALLBACK_TIMEOUT)
551 
552             nc.setSignalStrength(80)
553             agent.sendNetworkCapabilities(nc)
554             callbacks[0].expectCaps(net) { it.signalStrength == 80 }
555             callbacks[1].expectAvailableCallbacks(net)
556             callbacks[2].expectAvailableCallbacks(net)
557 
558             nc.setSignalStrength(55)
559             agent.sendNetworkCapabilities(nc)
560             callbacks[0].expectCaps(net) { it.signalStrength == 55 }
561             callbacks[1].expectCaps(net) { it.signalStrength == 55 }
562             callbacks[2].expect<Lost>(net)
563         }
564         callbacks.forEach {
565             mCM.unregisterNetworkCallback(it)
566         }
567     }
568 
569     @Test
agentnull570     fun testSocketKeepalive(): Unit = createNetworkAgentWithFakeCS().let { agent ->
571         val packet = NattKeepalivePacketData(
572             LOCAL_IPV4_ADDRESS /* srcAddress */,
573             1234 /* srcPort */,
574             REMOTE_IPV4_ADDRESS /* dstAddress */,
575             4567 /* dstPort */,
576             ByteArray(100 /* size */)
577         )
578         val slot = 4
579         val interval = 37
580 
581         mFakeConnectivityService.agent.onAddNattKeepalivePacketFilter(slot, packet)
582         mFakeConnectivityService.agent.onStartNattSocketKeepalive(slot, interval, packet)
583 
584         agent.expectCallback<OnAddKeepalivePacketFilter>().let {
585             assertEquals(it.slot, slot)
586             assertEquals(it.packet, packet)
587         }
588         agent.expectCallback<OnStartSocketKeepalive>().let {
589             assertEquals(it.slot, slot)
590             assertEquals(it.interval, interval)
591             assertEquals(it.packet, packet)
592         }
593 
594         agent.assertNoCallback()
595 
596         // Check that when the agent sends a keepalive event, ConnectivityService receives the
597         // expected message.
598         agent.sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED)
599         verify(mFakeConnectivityService.mockRegistry, timeout(DEFAULT_TIMEOUT_MS))
600                 .sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED)
601 
602         mFakeConnectivityService.agent.onStopSocketKeepalive(slot)
603         mFakeConnectivityService.agent.onRemoveKeepalivePacketFilter(slot)
604         agent.expectCallback<OnStopSocketKeepalive>().let {
605             assertEquals(it.slot, slot)
606         }
607         agent.expectCallback<OnRemoveKeepalivePacketFilter>().let {
608             assertEquals(it.slot, slot)
609         }
610     }
611 
612     @Test
agentnull613     fun testSendUpdates(): Unit = createConnectedNetworkAgent().let { (agent, callback) ->
614         val ifaceName = "adhocIface"
615         val lp = LinkProperties(agent.lp)
616         lp.setInterfaceName(ifaceName)
617         agent.sendLinkProperties(lp)
618         callback.expect<LinkPropertiesChanged>(agent.network!!) { it.lp.interfaceName == ifaceName }
619         val nc = NetworkCapabilities(agent.nc)
620         nc.addCapability(NET_CAPABILITY_NOT_METERED)
621         agent.sendNetworkCapabilities(nc)
622         callback.expectCaps(agent.network!!) { it.hasCapability(NET_CAPABILITY_NOT_METERED) }
623     }
624 
ncWithAllowedUidsnull625     private fun ncWithAllowedUids(vararg uids: Int) = NetworkCapabilities.Builder()
626                 .addTransportType(TRANSPORT_TEST)
627                 .setAllowedUids(uids.toSet()).build()
628 
629     /**
630      * Get the single element from this ArraySet, or fail() if doesn't contain exactly 1 element.
631      */
632     fun <T> ArraySet<T>.getSingleElement(): T {
633         if (size != 1) fail("Expected exactly one element, contained $size")
634         return iterator().next()
635     }
636 
doTestAllowedUidsnull637     private fun doTestAllowedUids(
638             transports: IntArray,
639             uid: Int,
640             expectUidsPresent: Boolean,
641             specifier: NetworkSpecifier?,
642             transportInfo: TransportInfo?
643     ) {
644         val callback = TestableNetworkCallback(DEFAULT_TIMEOUT_MS)
645         val agent = createNetworkAgent(initialNc = NetworkCapabilities.Builder().run {
646             addTransportType(TRANSPORT_TEST)
647             transports.forEach { addTransportType(it) }
648             addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
649             addCapability(NET_CAPABILITY_NOT_SUSPENDED)
650             removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
651             setNetworkSpecifier(specifier)
652             setTransportInfo(transportInfo)
653             setAllowedUids(setOf(uid))
654             setOwnerUid(Process.myUid())
655             setAdministratorUids(intArrayOf(Process.myUid()))
656             build()
657         })
658         runWithShellPermissionIdentity {
659             agent.register()
660         }
661         agent.markConnected()
662 
663         registerNetworkCallback(makeTestNetworkRequest(specifier), callback)
664         callback.expect<Available>(agent.network!!)
665         callback.expect<CapabilitiesChanged>(agent.network!!) {
666             if (expectUidsPresent) {
667                 it.caps.allowedUidsNoCopy.getSingleElement() == uid
668             } else {
669                 it.caps.allowedUidsNoCopy.isEmpty()
670             }
671         }
672         agent.unregister()
673         callback.eventuallyExpect<Lost> { it.network == agent.network }
674         // callback will be unregistered in tearDown()
675     }
676 
doTestAllowedUidsnull677     private fun doTestAllowedUids(
678             transport: Int,
679             uid: Int,
680             expectUidsPresent: Boolean
681     ) {
682         doTestAllowedUids(
683             intArrayOf(transport),
684             uid,
685             expectUidsPresent,
686             specifier = null,
687             transportInfo = null
688         )
689     }
690 
doTestAllowedUidsWithSubIdnull691     private fun doTestAllowedUidsWithSubId(
692             subId: Int,
693             transport: Int,
694             uid: Int,
695             expectUidsPresent: Boolean
696     ) {
697         doTestAllowedUidsWithSubId(subId, intArrayOf(transport), uid, expectUidsPresent)
698     }
699 
doTestAllowedUidsWithSubIdnull700     private fun doTestAllowedUidsWithSubId(
701             subId: Int,
702             transports: IntArray,
703             uid: Int,
704             expectUidsPresent: Boolean
705     ) {
706         val specifier = when {
707             transports.size != 1 -> null
708             TRANSPORT_ETHERNET in transports -> EthernetNetworkSpecifier("testInterface")
709             TRANSPORT_CELLULAR in transports -> TelephonyNetworkSpecifier(subId)
710             else -> null
711         }
712         val transportInfo = if (TRANSPORT_WIFI in transports && SdkLevel.isAtLeastV()) {
713             // setSubscriptionId only exists in V+
714             WifiInfo.Builder().setSubscriptionId(subId).build()
715         } else {
716             null
717         }
718         doTestAllowedUids(transports, uid, expectUidsPresent, specifier, transportInfo)
719     }
720 
Stringnull721     private fun String.execute() = runShellCommand(this).trim()
722 
723     @Test
724     @IgnoreUpTo(Build.VERSION_CODES.S)
725     fun testAllowedUids() {
726         doTestAllowedUids(TRANSPORT_CELLULAR, Process.myUid(), expectUidsPresent = false)
727         doTestAllowedUids(TRANSPORT_WIFI, Process.myUid(), expectUidsPresent = false)
728         doTestAllowedUids(TRANSPORT_BLUETOOTH, Process.myUid(), expectUidsPresent = false)
729 
730         // TODO(b/315136340): Allow ownerUid to see allowedUids and add cases that expect uids
731         // present
732     }
733 
734     @Test
735     @IgnoreUpTo(Build.VERSION_CODES.S)
testAllowedUids_WithCarrierServicePackagenull736     fun testAllowedUids_WithCarrierServicePackage() {
737         assumeTrue(realContext.packageManager.hasSystemFeature(FEATURE_TELEPHONY_SUBSCRIPTION))
738 
739         // Use a different package than this one to make sure that a package that doesn't hold
740         // carrier service permission can be set as an allowed UID.
741         val servicePackage = "android.net.cts.carrierservicepackage"
742         val uid = try {
743             realContext.packageManager.getApplicationInfo(servicePackage, 0).uid
744         } catch (e: PackageManager.NameNotFoundException) {
745             fail(
746                 "$servicePackage could not be installed, please check the SuiteApkInstaller" +
747                     " installed CtsCarrierServicePackage.apk",
748                 e
749             )
750         }
751 
752         val tm = realContext.getSystemService(TelephonyManager::class.java)!!
753         val defaultSubId = SubscriptionManager.getDefaultSubscriptionId()
754         assertTrue(
755             defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID,
756             "getDefaultSubscriptionId returns INVALID_SUBSCRIPTION_ID"
757         )
758         tryTest {
759             // This process is not the carrier service UID, so allowedUids should be ignored in all
760             // the following cases.
761             doTestAllowedUidsWithSubId(
762                 defaultSubId,
763                 TRANSPORT_CELLULAR,
764                 uid,
765                     expectUidsPresent = false
766             )
767             doTestAllowedUidsWithSubId(
768                 defaultSubId,
769                 TRANSPORT_WIFI,
770                 uid,
771                     expectUidsPresent = false
772             )
773             doTestAllowedUidsWithSubId(
774                 defaultSubId,
775                 TRANSPORT_BLUETOOTH,
776                 uid,
777                     expectUidsPresent = false
778             )
779 
780             // The tools to set the carrier service package override do not exist before U,
781             // so there is no way to test the rest of this test on < U.
782             if (!SdkLevel.isAtLeastU()) return@tryTest
783             // Acquiring carrier privilege is necessary to override the carrier service package.
784             val defaultSlotIndex = SubscriptionManager.getSlotIndex(defaultSubId)
785             carrierConfigRule.acquireCarrierPrivilege(defaultSubId)
786             carrierConfigRule.setCarrierServicePackageOverride(defaultSubId, servicePackage)
787             val actualServicePackage: String? = runAsShell(READ_PRIVILEGED_PHONE_STATE) {
788                 tm.getCarrierServicePackageNameForLogicalSlot(defaultSlotIndex)
789             }
790             assertEquals(servicePackage, actualServicePackage)
791 
792             // Wait for CarrierServiceAuthenticator to have seen the update of the service package
793             val timeout = SystemClock.elapsedRealtime() + DEFAULT_TIMEOUT_MS
794             while (true) {
795                 if (SystemClock.elapsedRealtime() > timeout) {
796                     fail(
797                         "Couldn't make $servicePackage the service package for $defaultSubId: " +
798                             "dumpsys connectivity".execute().split("\n")
799                                     .filter { it.contains("Logical slot = $defaultSlotIndex.*") }
800                     )
801                 }
802                 if ("dumpsys connectivity"
803                         .execute()
804                         .split("\n")
805                         .filter { it.contains("Logical slot = $defaultSlotIndex : uid = $uid") }
806                         .isNotEmpty()) {
807                     // Found the configuration
808                     break
809                 }
810                 Thread.sleep(500)
811             }
812 
813             // Cell and WiFi are allowed to set UIDs, but not Bluetooth or agents with multiple
814             // transports.
815             // TODO(b/315136340): Allow ownerUid to see allowedUids and enable below test case
816             // doTestAllowedUids(defaultSubId, TRANSPORT_CELLULAR, uid, expectUidsPresent = true)
817             if (SdkLevel.isAtLeastV()) {
818                 // Cannot be tested before V because WifiInfo.Builder#setSubscriptionId doesn't
819                 // exist
820                 // TODO(b/315136340): Allow ownerUid to see allowedUids and enable below test case
821                 // doTestAllowedUids(defaultSubId, TRANSPORT_WIFI, uid, expectUidsPresent = true)
822             }
823             doTestAllowedUidsWithSubId(
824                 defaultSubId,
825                 TRANSPORT_BLUETOOTH,
826                 uid,
827                     expectUidsPresent = false
828             )
829             doTestAllowedUidsWithSubId(
830                 defaultSubId,
831                 intArrayOf(TRANSPORT_CELLULAR, TRANSPORT_WIFI),
832                     uid,
833                 expectUidsPresent = false
834             )
835         }
836     }
837 
838     @Test
testRejectedUpdatesnull839     fun testRejectedUpdates() {
840         val callback = TestableNetworkCallback(DEFAULT_TIMEOUT_MS)
841         // will be cleaned up in tearDown
842         registerNetworkCallback(makeTestNetworkRequest(), callback)
843         val agent = createNetworkAgent(initialNc = ncWithAllowedUids(200))
844         agent.register()
845         agent.markConnected()
846 
847         // Make sure the UIDs have been ignored.
848         callback.expect<Available>(agent.network!!)
849         callback.expectCaps(agent.network!!) {
850             it.allowedUids.isEmpty() && !it.hasCapability(NET_CAPABILITY_VALIDATED)
851         }
852         callback.expect<LinkPropertiesChanged>(agent.network!!)
853         callback.expect<BlockedStatus>(agent.network!!)
854         callback.expectCaps(agent.network!!) {
855             it.allowedUids.isEmpty() && it.hasCapability(NET_CAPABILITY_VALIDATED)
856         }
857         callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
858 
859         // Make sure that the UIDs are also ignored upon update
860         agent.sendNetworkCapabilities(ncWithAllowedUids(200, 300))
861         callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
862     }
863 
864     @Test
testSendScorenull865     fun testSendScore() {
866         // This test will create two networks and check that the one with the stronger
867         // score wins out for a request that matches them both.
868 
869         // File the interesting request
870         val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
871         requestNetwork(makeTestNetworkRequest(), callback)
872 
873         // Connect the first Network, with an unused callback that kept the network up.
874         val (agent1, _) = createConnectedNetworkAgent()
875         callback.expectAvailableThenValidatedCallbacks(agent1.network!!)
876         // If using the int ranking, agent1 must be upgraded to a better score so that there is
877         // no ambiguity when agent2 connects that agent1 is still better. If using policy
878         // ranking, this is not necessary.
879         agent1.sendNetworkScore(
880             NetworkScore.Builder().setLegacyInt(BETTER_NETWORK_SCORE)
881                 .build()
882         )
883 
884         // Connect the second agent.
885         val (agent2, _) = createConnectedNetworkAgent()
886         // The callback should not see anything yet. With int ranking, agent1 was upgraded
887         // to a stronger score beforehand. With policy ranking, agent1 is preferred by
888         // virtue of already satisfying the request.
889         callback.assertNoCallback(NO_CALLBACK_TIMEOUT)
890         // Now downgrade the score and expect the callback now prefers agent2
891         agent1.sendNetworkScore(
892             NetworkScore.Builder()
893                 .setLegacyInt(WORSE_NETWORK_SCORE)
894                 .setExiting(true)
895                 .build()
896         )
897         callback.expect<Available>(agent2.network!!)
898 
899         // tearDown() will unregister the requests and agents
900     }
901 
hasAllTransportsnull902     private fun NetworkCapabilities?.hasAllTransports(transports: IntArray) =
903             this != null && transports.all { hasTransport(it) }
904 
905     @Test
906     @IgnoreUpTo(Build.VERSION_CODES.R)
testSetUnderlyingNetworksAndVpnSpecifiernull907     fun testSetUnderlyingNetworksAndVpnSpecifier() {
908         val mySessionId = "MySession12345"
909         val request = NetworkRequest.Builder()
910                 .addTransportType(TRANSPORT_TEST)
911                 .addTransportType(TRANSPORT_VPN)
912                 .removeCapability(NET_CAPABILITY_NOT_VPN)
913                 .removeCapability(NET_CAPABILITY_TRUSTED) // TODO: add to VPN!
914                 .build()
915         val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
916         registerNetworkCallback(request, callback)
917 
918         val nc = NetworkCapabilities().apply {
919             addTransportType(TRANSPORT_TEST)
920             addTransportType(TRANSPORT_VPN)
921             removeCapability(NET_CAPABILITY_NOT_VPN)
922             setTransportInfo(VpnTransportInfo(VpnManager.TYPE_VPN_SERVICE, mySessionId))
923             if (SdkLevel.isAtLeastS()) {
924                 addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
925             }
926         }
927         val defaultNetwork = mCM.activeNetwork
928         assertNotNull(defaultNetwork)
929         val defaultNetworkCapabilities = mCM.getNetworkCapabilities(defaultNetwork)
930         assertNotNull(defaultNetworkCapabilities)
931         val defaultNetworkTransports = defaultNetworkCapabilities.transportTypes
932 
933         val agent = createNetworkAgent(initialNc = nc)
934         agent.register()
935         agent.markConnected()
936         callback.expectAvailableThenValidatedCallbacks(agent.network!!)
937 
938         // Check that the default network's transport is propagated to the VPN.
939         var vpnNc = mCM.getNetworkCapabilities(agent.network!!)
940         assertNotNull(vpnNc)
941         assertEquals(
942             VpnManager.TYPE_VPN_SERVICE,
943             (vpnNc.transportInfo as VpnTransportInfo).type
944         )
945         assertEquals(mySessionId, (vpnNc.transportInfo as VpnTransportInfo).sessionId)
946 
947         val testAndVpn = intArrayOf(TRANSPORT_TEST, TRANSPORT_VPN)
948         assertTrue(vpnNc.hasAllTransports(testAndVpn))
949         assertFalse(vpnNc.hasCapability(NET_CAPABILITY_NOT_VPN))
950         assertTrue(
951             vpnNc.hasAllTransports(defaultNetworkTransports),
952             "VPN transports ${Arrays.toString(vpnNc.transportTypes)}" +
953                     " lacking transports from ${Arrays.toString(defaultNetworkTransports)}"
954         )
955 
956         // Check that when no underlying networks are announced the underlying transport disappears.
957         agent.setUnderlyingNetworks(listOf<Network>())
958         callback.expectCaps(agent.network!!) {
959             it.transportTypes.size == 2 && it.hasAllTransports(testAndVpn)
960         }
961 
962         // Put the underlying network back and check that the underlying transport reappears.
963         val expectedTransports = (defaultNetworkTransports.toSet() + TRANSPORT_TEST + TRANSPORT_VPN)
964                 .toIntArray()
965         agent.setUnderlyingNetworks(null)
966         callback.expectCaps(agent.network!!) {
967             it.transportTypes.size == expectedTransports.size &&
968                     it.hasAllTransports(expectedTransports)
969         }
970 
971         // Check that some underlying capabilities are propagated.
972         // This is not very accurate because the test does not control the capabilities of the
973         // underlying networks, and because not congested, not roaming, and not suspended are the
974         // default anyway. It's still useful as an extra check though.
975         vpnNc = mCM.getNetworkCapabilities(agent.network!!)!!
976         for (cap in listOf(
977             NET_CAPABILITY_NOT_CONGESTED,
978             NET_CAPABILITY_NOT_ROAMING,
979             NET_CAPABILITY_NOT_SUSPENDED
980         )) {
981             val capStr = valueToString(NetworkCapabilities::class.java, "NET_CAPABILITY_", cap)
982             if (defaultNetworkCapabilities.hasCapability(cap) && !vpnNc.hasCapability(cap)) {
983                 fail("$capStr not propagated from underlying: $defaultNetworkCapabilities")
984             }
985         }
986 
987         unregister(agent)
988         callback.expect<Lost>(agent.network!!)
989     }
990 
doTestOemVpnTypenull991     fun doTestOemVpnType(type: Int) {
992         val mySessionId = "MySession12345"
993         val nc = NetworkCapabilities().apply {
994             addTransportType(TRANSPORT_TEST)
995             addTransportType(TRANSPORT_VPN)
996             addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
997             removeCapability(NET_CAPABILITY_NOT_VPN)
998             setTransportInfo(VpnTransportInfo(type, mySessionId))
999         }
1000 
1001         val agent = createNetworkAgent(initialNc = nc)
1002         agent.register()
1003         agent.markConnected()
1004 
1005         val request = NetworkRequest.Builder()
1006             .clearCapabilities()
1007             .addTransportType(TRANSPORT_VPN)
1008             .removeCapability(NET_CAPABILITY_NOT_VPN)
1009             .build()
1010         val callback = TestableNetworkCallback()
1011         registerNetworkCallback(request, callback)
1012 
1013         callback.expectAvailableThenValidatedCallbacks(agent.network!!)
1014 
1015         var vpnNc = mCM.getNetworkCapabilities(agent.network!!)
1016         assertNotNull(vpnNc)
1017         assertEquals(type, (vpnNc!!.transportInfo as VpnTransportInfo).type)
1018 
1019         agent.unregister()
1020         callback.expect<Lost>(agent.network!!)
1021     }
1022 
1023     @Test
1024     @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
testOemVpnTypesnull1025     fun testOemVpnTypes() {
1026         // TODO: why is this necessary given the @IgnoreUpTo above?
1027         assumeTrue(SdkLevel.isAtLeastB())
1028         doTestOemVpnType(VpnManager.TYPE_VPN_OEM_SERVICE)
1029         doTestOemVpnType(VpnManager.TYPE_VPN_OEM_LEGACY)
1030     }
1031 
unregisternull1032     private fun unregister(agent: TestableNetworkAgent) {
1033         agent.unregister()
1034         agent.eventuallyExpect<OnNetworkUnwanted>()
1035         agent.eventuallyExpect<OnNetworkDestroyed>()
1036     }
1037 
1038     @Test
1039     @IgnoreUpTo(Build.VERSION_CODES.R)
testAgentStartsInConnectingnull1040     fun testAgentStartsInConnecting() {
1041         val mockContext = mock(Context::class.java)
1042         val mockCm = mock(ConnectivityManager::class.java)
1043         val mockedResult = ConnectivityManager.MockHelpers.registerNetworkAgentResult(
1044             mock(Network::class.java),
1045             mock(INetworkAgentRegistry::class.java)
1046         )
1047         doReturn(SHOULD_CREATE_NETWORKS_IMMEDIATELY).`when`(mockCm)
1048             .isFeatureEnabled(
1049                 eq(ConnectivityManager.FEATURE_QUEUE_NETWORK_AGENT_EVENTS_IN_SYSTEM_SERVER)
1050             )
1051         doReturn(Context.CONNECTIVITY_SERVICE).`when`(mockContext)
1052             .getSystemServiceName(ConnectivityManager::class.java)
1053         doReturn(mockCm).`when`(mockContext).getSystemService(Context.CONNECTIVITY_SERVICE)
1054         doReturn(mockedResult).`when`(mockCm).registerNetworkAgent(
1055             any(),
1056             any(),
1057             any(),
1058             any(),
1059             any(),
1060             any(),
1061             anyInt()
1062         )
1063         val agent = createNetworkAgent(mockContext)
1064         agent.register()
1065         verify(mockCm).registerNetworkAgent(
1066             any(),
1067             argThat<NetworkInfo> { it.detailedState == NetworkInfo.DetailedState.CONNECTING },
1068             any(LinkProperties::class.java),
1069             any(NetworkCapabilities::class.java),
1070             any(NetworkScore::class.java),
1071             any(NetworkAgentConfig::class.java),
1072             eq(NetworkProvider.ID_NONE)
1073         )
1074     }
1075 
1076     @Test
testSetAcceptUnvalidatednull1077     fun testSetAcceptUnvalidated() {
1078         createNetworkAgentWithFakeCS().let { agent ->
1079             mFakeConnectivityService.agent.onSaveAcceptUnvalidated(true)
1080             agent.expectCallback<OnSaveAcceptUnvalidated>().let {
1081                 assertTrue(it.accept)
1082             }
1083             agent.assertNoCallback()
1084         }
1085     }
1086 
1087     @Test
testSetAcceptUnvalidatedPreventAutomaticReconnectnull1088     fun testSetAcceptUnvalidatedPreventAutomaticReconnect() {
1089         createNetworkAgentWithFakeCS().let { agent ->
1090             mFakeConnectivityService.agent.onSaveAcceptUnvalidated(false)
1091             mFakeConnectivityService.agent.onPreventAutomaticReconnect()
1092             agent.expectCallback<OnSaveAcceptUnvalidated>().let {
1093                 assertFalse(it.accept)
1094             }
1095             agent.expectCallback<OnAutomaticReconnectDisabled>()
1096             agent.assertNoCallback()
1097             // When automatic reconnect is turned off, the network is torn down and
1098             // ConnectivityService disconnects. As part of the disconnect, ConnectivityService will
1099             // also send itself a message to unregister the NetworkAgent from its internal
1100             // structure.
1101             mFakeConnectivityService.disconnect()
1102             agent.expectCallback<OnNetworkUnwanted>()
1103         }
1104     }
1105 
1106     @Test
testPreventAutomaticReconnectnull1107     fun testPreventAutomaticReconnect() {
1108         createNetworkAgentWithFakeCS().let { agent ->
1109             mFakeConnectivityService.agent.onPreventAutomaticReconnect()
1110             agent.expectCallback<OnAutomaticReconnectDisabled>()
1111             agent.assertNoCallback()
1112             mFakeConnectivityService.disconnect()
1113             agent.expectCallback<OnNetworkUnwanted>()
1114         }
1115     }
1116 
1117     @Test
agentnull1118     fun testValidationStatus() = createNetworkAgentWithFakeCS().let { agent ->
1119         val uri = Uri.parse("http://www.google.com")
1120         mFakeConnectivityService.agent.onValidationStatusChanged(
1121             VALID_NETWORK,
1122             uri.toString()
1123         )
1124         agent.expectCallback<OnValidationStatus>().let {
1125             assertEquals(it.status, VALID_NETWORK)
1126             assertEquals(it.uri, uri)
1127         }
1128 
1129         mFakeConnectivityService.agent.onValidationStatusChanged(INVALID_NETWORK, null)
1130         agent.expectCallback<OnValidationStatus>().let {
1131             assertEquals(it.status, INVALID_NETWORK)
1132             assertNull(it.uri)
1133         }
1134     }
1135 
1136     @Test
testTemporarilyUnmeteredCapabilitynull1137     fun testTemporarilyUnmeteredCapability() {
1138         // This test will create a networks with/without NET_CAPABILITY_TEMPORARILY_NOT_METERED
1139         // and check that the callback reflects the capability changes.
1140 
1141         // Connect the network
1142         val (agent, callback) = createConnectedNetworkAgent()
1143 
1144         // Send TEMP_NOT_METERED and check that the callback is called appropriately.
1145         val nc1 = NetworkCapabilities(agent.nc)
1146                 .addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
1147         agent.sendNetworkCapabilities(nc1)
1148         callback.expectCaps(agent.network!!) {
1149             it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
1150         }
1151 
1152         // Remove TEMP_NOT_METERED and check that the callback is called appropriately.
1153         val nc2 = NetworkCapabilities(agent.nc)
1154                 .removeCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
1155         agent.sendNetworkCapabilities(nc2)
1156         callback.expectCaps(agent.network!!) {
1157             !it.hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
1158         }
1159 
1160         // tearDown() will unregister the requests and agents
1161     }
1162 
1163     @Test
1164     @IgnoreUpTo(Build.VERSION_CODES.R)
testSetLingerDurationnull1165     fun testSetLingerDuration() {
1166         // This test will create two networks and check that the one with the stronger
1167         // score wins out for a request that matches them both. And the weaker agent will
1168         // be disconnected after customized linger duration.
1169 
1170         // Request the first Network, with a request that could moved to agentStronger in order to
1171         // make agentWeaker linger later.
1172         val specifierWeaker = UUID.randomUUID().toString()
1173         val specifierStronger = UUID.randomUUID().toString()
1174         val commonCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
1175         requestNetwork(makeTestNetworkRequest(), commonCallback)
1176         val agentWeaker = createNetworkAgent(specifier = specifierWeaker)
1177         agentWeaker.register()
1178         agentWeaker.markConnected()
1179         commonCallback.expectAvailableThenValidatedCallbacks(agentWeaker.network!!)
1180         // Downgrade agentWeaker to a worse score so that there is no ambiguity when
1181         // agentStronger connects.
1182         agentWeaker.sendNetworkScore(NetworkScore.Builder().setLegacyInt(WORSE_NETWORK_SCORE)
1183                 .setExiting(true).build())
1184 
1185         // Verify invalid linger duration cannot be set.
1186         assertFailsWith<IllegalArgumentException> {
1187             agentWeaker.setLingerDuration(Duration.ofMillis(-1))
1188         }
1189         assertFailsWith<IllegalArgumentException> { agentWeaker.setLingerDuration(Duration.ZERO) }
1190         assertFailsWith<IllegalArgumentException> {
1191             agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MIN_VALUE.toLong()))
1192         }
1193         assertFailsWith<IllegalArgumentException> {
1194             agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong() + 1))
1195         }
1196         assertFailsWith<IllegalArgumentException> {
1197             agentWeaker.setLingerDuration(Duration.ofMillis(
1198                     NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - 1
1199             ))
1200         }
1201         // Verify valid linger timer can be set, but it should not take effect since the network
1202         // is still needed.
1203         agentWeaker.setLingerDuration(Duration.ofMillis(Integer.MAX_VALUE.toLong()))
1204         commonCallback.assertNoCallback(NO_CALLBACK_TIMEOUT)
1205         // Set to the value we want to verify the functionality.
1206         agentWeaker.setLingerDuration(Duration.ofMillis(NetworkAgent.MIN_LINGER_TIMER_MS.toLong()))
1207         // Make a listener which can observe agentWeaker lost later.
1208         val callbackWeaker = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
1209         registerNetworkCallback(
1210             NetworkRequest.Builder()
1211                 .clearCapabilities()
1212                 .addTransportType(TRANSPORT_TEST)
1213                 .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier(specifierWeaker))
1214                 .build(),
1215             callbackWeaker
1216         )
1217         callbackWeaker.expectAvailableCallbacks(agentWeaker.network!!)
1218 
1219         // Connect the agentStronger with a score better than agentWeaker. Verify the callback for
1220         // agentWeaker sees the linger expiry while the callback for both sees the winner.
1221         // Record linger start timestamp prior to send score to prevent possible race, the actual
1222         // timestamp should be slightly late than this since the service handles update
1223         // network score asynchronously.
1224         val lingerStart = SystemClock.elapsedRealtime()
1225         val agentStronger = createNetworkAgent(specifier = specifierStronger)
1226         agentStronger.register()
1227         agentStronger.markConnected()
1228         commonCallback.expectAvailableCallbacks(agentStronger.network!!)
1229         callbackWeaker.expect<Losing>(agentWeaker.network!!)
1230         val expectedRemainingLingerDuration = lingerStart +
1231                 NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - SystemClock.elapsedRealtime()
1232         // If the available callback is too late. The remaining duration will be reduced.
1233         assertTrue(
1234             expectedRemainingLingerDuration > 0,
1235             "expected remaining linger duration is $expectedRemainingLingerDuration"
1236         )
1237         callbackWeaker.assertNoCallback(expectedRemainingLingerDuration)
1238         callbackWeaker.expect<Lost>(agentWeaker.network!!)
1239     }
1240 
1241     @Test
1242     @IgnoreUpTo(Build.VERSION_CODES.R)
testSetSubscriberIdnull1243     fun testSetSubscriberId() {
1244         val imsi = UUID.randomUUID().toString()
1245         val config = NetworkAgentConfig.Builder().setSubscriberId(imsi).build()
1246 
1247         val (agent, _) = createConnectedNetworkAgent(initialConfig = config)
1248         val snapshots = runWithShellPermissionIdentity(ThrowingSupplier {
1249                 mCM!!.allNetworkStateSnapshots }, NETWORK_SETTINGS)
1250         val testNetworkSnapshot = snapshots.findLast { it.network == agent.network }
1251         assertEquals(imsi, testNetworkSnapshot!!.subscriberId)
1252     }
1253 
1254     // TODO: Refactor helper functions to util class and move this test case to
1255     //  {@link android.net.cts.ConnectivityManagerTest}.
1256     @Test
1257     @IgnoreUpTo(Build.VERSION_CODES.R)
testRegisterBestMatchingNetworkCallbacknull1258     fun testRegisterBestMatchingNetworkCallback() {
1259         // Register best matching network callback with additional condition that will be
1260         // exercised later. This assumes the test network agent has NOT_VCN_MANAGED in it and
1261         // does not have NET_CAPABILITY_TEMPORARILY_NOT_METERED.
1262         val bestMatchingCb = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
1263         registerBestMatchingNetworkCallback(
1264             NetworkRequest.Builder()
1265                 .clearCapabilities()
1266                 .addTransportType(TRANSPORT_TEST)
1267                 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
1268                 .build(),
1269             bestMatchingCb,
1270             mHandlerThread.threadHandler
1271         )
1272 
1273         val (agent1, _) = createConnectedNetworkAgent(specifier = "AGENT-1")
1274         bestMatchingCb.expectAvailableThenValidatedCallbacks(agent1.network!!)
1275         // Make agent1 worse so when agent2 shows up, the callback will see that.
1276         agent1.sendNetworkScore(NetworkScore.Builder().setExiting(true).build())
1277         bestMatchingCb.assertNoCallback(NO_CALLBACK_TIMEOUT)
1278 
1279         val (agent2, _) = createConnectedNetworkAgent(specifier = "AGENT-2")
1280         bestMatchingCb.expectAvailableDoubleValidatedCallbacks(agent2.network!!)
1281 
1282         // Change something on agent1 to trigger capabilities changed, since the callback
1283         // only cares about the best network, verify it received nothing from agent1.
1284         val ncAgent1 = agent1.nc
1285         ncAgent1.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
1286         agent1.sendNetworkCapabilities(ncAgent1)
1287         bestMatchingCb.assertNoCallback(NO_CALLBACK_TIMEOUT)
1288 
1289         // Make agent1 the best network again, verify the callback now tracks agent1.
1290         agent1.sendNetworkScore(NetworkScore.Builder()
1291                 .setExiting(false).setTransportPrimary(true).build())
1292         bestMatchingCb.expectAvailableCallbacks(agent1.network!!)
1293 
1294         // Make agent1 temporary vcn managed, which will not satisfying the request.
1295         // Verify the callback switch from/to the other network accordingly.
1296         ncAgent1.removeCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
1297         agent1.sendNetworkCapabilities(ncAgent1)
1298         bestMatchingCb.expectAvailableCallbacks(agent2.network!!)
1299         ncAgent1.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
1300         agent1.sendNetworkCapabilities(ncAgent1)
1301         bestMatchingCb.expectAvailableDoubleValidatedCallbacks(agent1.network!!)
1302 
1303         // Verify the callback doesn't care about agent2 disconnect.
1304         agent2.unregister()
1305         agentsToCleanUp.remove(agent2)
1306         bestMatchingCb.assertNoCallback()
1307         agent1.unregister()
1308         agentsToCleanUp.remove(agent1)
1309         bestMatchingCb.expect<Lost>(agent1.network!!)
1310 
1311         // tearDown() will unregister the requests and agents
1312     }
1313 
1314     private class TestableQosCallback : QosCallback() {
1315         val history = ArrayTrackRecord<CallbackEntry>().newReadHead()
1316 
1317         sealed class CallbackEntry {
1318             data class OnQosSessionAvailable(val sess: QosSession, val attr: QosSessionAttributes) :
1319                 CallbackEntry()
1320             data class OnQosSessionLost(val sess: QosSession) : CallbackEntry()
1321             data class OnError(val ex: QosCallbackException) : CallbackEntry()
1322         }
1323 
onQosSessionAvailablenull1324         override fun onQosSessionAvailable(sess: QosSession, attr: QosSessionAttributes) {
1325             history.add(OnQosSessionAvailable(sess, attr))
1326         }
1327 
onQosSessionLostnull1328         override fun onQosSessionLost(sess: QosSession) {
1329             history.add(OnQosSessionLost(sess))
1330         }
1331 
onErrornull1332         override fun onError(ex: QosCallbackException) {
1333             history.add(OnError(ex))
1334         }
1335 
expectCallbacknull1336         inline fun <reified T : CallbackEntry> expectCallback(): T {
1337             val foundCallback = history.poll(DEFAULT_TIMEOUT_MS)
1338             assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback")
1339             return foundCallback
1340         }
1341 
expectCallbacknull1342         inline fun <reified T : CallbackEntry> expectCallback(valid: (T) -> Boolean) {
1343             val foundCallback = history.poll(DEFAULT_TIMEOUT_MS)
1344             assertTrue(foundCallback is T, "Expected ${T::class} but found $foundCallback")
1345             assertTrue(valid(foundCallback), "Unexpected callback : $foundCallback")
1346         }
1347 
assertNoCallbacknull1348         fun assertNoCallback() {
1349             assertNull(
1350                 history.poll(NO_CALLBACK_TIMEOUT),
1351                 "Callback received"
1352             )
1353         }
1354     }
1355 
setupForQosCallbackTestnull1356     private fun <T : Closeable> setupForQosCallbackTest(creator: (TestableNetworkAgent) -> T) =
1357             createConnectedNetworkAgent().first.let { Pair(it, creator(it)) }
1358 
setupForQosSocketnull1359     private fun setupForQosSocket() = setupForQosCallbackTest {
1360         agent: TestableNetworkAgent -> Socket()
1361             .also { assertNotNull(agent.network?.bindSocket(it))
1362                 it.bind(InetSocketAddress(InetAddress.getLoopbackAddress(), 0)) }
1363     }
1364 
setupForQosDatagramnull1365     private fun setupForQosDatagram() = setupForQosCallbackTest {
1366         agent: TestableNetworkAgent -> DatagramSocket(
1367             InetSocketAddress(InetAddress.getLoopbackAddress(), 0)
1368         )
1369             .also { assertNotNull(agent.network?.bindSocket(it)) }
1370     }
1371 
1372     @Test
testQosCallbackRegisterAndUnregisternull1373     fun testQosCallbackRegisterAndUnregister() {
1374         validateQosCallbackRegisterAndUnregister(IPPROTO_TCP)
1375     }
1376 
1377     @Test
testQosCallbackRegisterAndUnregisterWithDatagramSocketnull1378     fun testQosCallbackRegisterAndUnregisterWithDatagramSocket() {
1379         validateQosCallbackRegisterAndUnregister(IPPROTO_UDP)
1380     }
1381 
validateQosCallbackRegisterAndUnregisternull1382     private fun validateQosCallbackRegisterAndUnregister(proto: Int) {
1383         val (agent, qosTestSocket) = when (proto) {
1384             IPPROTO_TCP -> setupForQosSocket()
1385             IPPROTO_UDP -> setupForQosDatagram()
1386             else -> fail("unsupported protocol")
1387         }
1388         val qosCallback = TestableQosCallback()
1389         var callbackId = -1
1390         Executors.newSingleThreadExecutor().let { executor ->
1391             try {
1392                 val info = QosSocketInfo(agent, qosTestSocket)
1393                 mCM.registerQosCallback(info, executor, qosCallback)
1394                 agent.expectCallback<OnRegisterQosCallback>().let {
1395                     callbackId = it.callbackId
1396                     assertTrue(it.filter.matchesProtocol(proto))
1397                 }
1398 
1399                 assertFailsWith<QosCallbackRegistrationException>(
1400                         "The same callback cannot be " +
1401                         "registered more than once without first being unregistered"
1402                 ) {
1403                     mCM.registerQosCallback(info, executor, qosCallback)
1404                 }
1405             } finally {
1406                 qosTestSocket.close()
1407                 mCM.unregisterQosCallback(qosCallback)
1408                 agent.expectCallback<OnUnregisterQosCallback> { it.callbackId == callbackId }
1409                 executor.shutdown()
1410             }
1411         }
1412     }
1413 
1414     @Test
testQosCallbackOnQosSessionnull1415     fun testQosCallbackOnQosSession() {
1416         validateQosCallbackOnQosSession(IPPROTO_TCP)
1417     }
1418 
1419     @Test
testQosCallbackOnQosSessionWithDatagramSocketnull1420     fun testQosCallbackOnQosSessionWithDatagramSocket() {
1421         validateQosCallbackOnQosSession(IPPROTO_UDP)
1422     }
1423 
QosSocketInfonull1424     fun QosSocketInfo(agent: NetworkAgent, socket: Closeable) = when (socket) {
1425         is Socket -> QosSocketInfo(checkNotNull(agent.network), socket)
1426         is DatagramSocket -> QosSocketInfo(checkNotNull(agent.network), socket)
1427         else -> fail("unexpected socket type")
1428     }
1429 
validateQosCallbackOnQosSessionnull1430     private fun validateQosCallbackOnQosSession(proto: Int) {
1431         val (agent, qosTestSocket) = when (proto) {
1432             IPPROTO_TCP -> setupForQosSocket()
1433             IPPROTO_UDP -> setupForQosDatagram()
1434             else -> fail("unsupported protocol")
1435         }
1436         val qosCallback = TestableQosCallback()
1437         Executors.newSingleThreadExecutor().let { executor ->
1438             try {
1439                 val info = QosSocketInfo(agent, qosTestSocket)
1440                 assertEquals(agent.network, info.getNetwork())
1441                 mCM.registerQosCallback(info, executor, qosCallback)
1442                 val callbackId = agent.expectCallback<OnRegisterQosCallback>().callbackId
1443 
1444                 val uniqueSessionId = 4294967397
1445                 val sessId = 101
1446 
1447                 val attributes = createEpsAttributes(5)
1448                 assertEquals(attributes.qosIdentifier, 5)
1449                 agent.sendQosSessionAvailable(callbackId, sessId, attributes)
1450                 qosCallback.expectCallback<OnQosSessionAvailable> {
1451                             it.sess.sessionId == sessId && it.sess.uniqueId == uniqueSessionId &&
1452                                 it.sess.sessionType == QosSession.TYPE_EPS_BEARER
1453                         }
1454 
1455                 agent.sendQosSessionLost(callbackId, sessId, QosSession.TYPE_EPS_BEARER)
1456                 qosCallback.expectCallback<OnQosSessionLost> {
1457                             it.sess.sessionId == sessId && it.sess.uniqueId == uniqueSessionId &&
1458                                 it.sess.sessionType == QosSession.TYPE_EPS_BEARER
1459                         }
1460 
1461                 // Make sure that we don't get more qos callbacks
1462                 mCM.unregisterQosCallback(qosCallback)
1463                 agent.expectCallback<OnUnregisterQosCallback>()
1464 
1465                 agent.sendQosSessionLost(callbackId, sessId, QosSession.TYPE_EPS_BEARER)
1466                 qosCallback.assertNoCallback()
1467             } finally {
1468                 qosTestSocket.close()
1469                 // safety precaution
1470                 mCM.unregisterQosCallback(qosCallback)
1471 
1472                 executor.shutdown()
1473             }
1474         }
1475     }
1476 
1477     @Test
testQosCallbackOnErrornull1478     fun testQosCallbackOnError() {
1479         val (agent, qosTestSocket) = setupForQosSocket()
1480         val qosCallback = TestableQosCallback()
1481         Executors.newSingleThreadExecutor().let { executor ->
1482             try {
1483                 val info = QosSocketInfo(agent.network!!, qosTestSocket)
1484                 mCM.registerQosCallback(info, executor, qosCallback)
1485                 val callbackId = agent.expectCallback<OnRegisterQosCallback>().callbackId
1486 
1487                 val sessId = 101
1488                 val attributes = createEpsAttributes()
1489 
1490                 // Double check that this is wired up and ready to go
1491                 agent.sendQosSessionAvailable(callbackId, sessId, attributes)
1492                 qosCallback.expectCallback<OnQosSessionAvailable>()
1493 
1494                 // Check that onError is coming through correctly
1495                 agent.sendQosCallbackError(
1496                     callbackId,
1497                     QosCallbackException.EX_TYPE_FILTER_NOT_SUPPORTED
1498                 )
1499                 qosCallback.expectCallback<OnError> {
1500                     it.ex.cause is UnsupportedOperationException
1501                 }
1502 
1503                 // Ensure that when an error occurs the callback was also unregistered
1504                 agent.sendQosSessionLost(callbackId, sessId, QosSession.TYPE_EPS_BEARER)
1505                 qosCallback.assertNoCallback()
1506             } finally {
1507                 qosTestSocket.close()
1508 
1509                 // Make sure that the callback is fully unregistered
1510                 mCM.unregisterQosCallback(qosCallback)
1511 
1512                 executor.shutdown()
1513             }
1514         }
1515     }
1516 
1517     @Test
testQosCallbackIdsAreMappedCorrectlynull1518     fun testQosCallbackIdsAreMappedCorrectly() {
1519         val (agent, qosTestSocket) = setupForQosSocket()
1520         val qosCallback1 = TestableQosCallback()
1521         val qosCallback2 = TestableQosCallback()
1522         Executors.newSingleThreadExecutor().let { executor ->
1523             try {
1524                 val info = QosSocketInfo(agent.network!!, qosTestSocket)
1525                 mCM.registerQosCallback(info, executor, qosCallback1)
1526                 val callbackId1 = agent.expectCallback<OnRegisterQosCallback>().callbackId
1527 
1528                 mCM.registerQosCallback(info, executor, qosCallback2)
1529                 val callbackId2 = agent.expectCallback<OnRegisterQosCallback>().callbackId
1530 
1531                 val sessId1 = 101
1532                 val attributes1 = createEpsAttributes(1)
1533 
1534                 // Check #1
1535                 agent.sendQosSessionAvailable(callbackId1, sessId1, attributes1)
1536                 qosCallback1.expectCallback<OnQosSessionAvailable>()
1537                 qosCallback2.assertNoCallback()
1538 
1539                 // Check #2
1540                 val sessId2 = 102
1541                 val attributes2 = createEpsAttributes(2)
1542                 agent.sendQosSessionAvailable(callbackId2, sessId2, attributes2)
1543                 qosCallback1.assertNoCallback()
1544                 qosCallback2.expectCallback<OnQosSessionAvailable> { sessId2 == it.sess.sessionId }
1545             } finally {
1546                 qosTestSocket.close()
1547 
1548                 // Make sure that the callback is fully unregistered
1549                 mCM.unregisterQosCallback(qosCallback1)
1550                 mCM.unregisterQosCallback(qosCallback2)
1551 
1552                 executor.shutdown()
1553             }
1554         }
1555     }
1556 
1557     @Test
testQosCallbackWhenNetworkReleasednull1558     fun testQosCallbackWhenNetworkReleased() {
1559         val (agent, qosTestSocket) = setupForQosSocket()
1560         Executors.newSingleThreadExecutor().let { executor ->
1561             try {
1562                 val qosCallback1 = TestableQosCallback()
1563                 val qosCallback2 = TestableQosCallback()
1564                 try {
1565                     val info = QosSocketInfo(agent.network!!, qosTestSocket)
1566                     mCM.registerQosCallback(info, executor, qosCallback1)
1567                     mCM.registerQosCallback(info, executor, qosCallback2)
1568                     agent.unregister()
1569 
1570                     qosCallback1.expectCallback<OnError> {
1571                         it.ex.cause is NetworkReleasedException
1572                     }
1573 
1574                     qosCallback2.expectCallback<OnError> {
1575                         it.ex.cause is NetworkReleasedException
1576                     }
1577                 } finally {
1578                     qosTestSocket.close()
1579                     mCM.unregisterQosCallback(qosCallback1)
1580                     mCM.unregisterQosCallback(qosCallback2)
1581                 }
1582             } finally {
1583                 qosTestSocket.close()
1584                 executor.shutdown()
1585             }
1586         }
1587     }
1588 
createEpsAttributesnull1589     private fun createEpsAttributes(qci: Int = 1): EpsBearerQosSessionAttributes {
1590         val remoteAddresses = ArrayList<InetSocketAddress>()
1591         remoteAddresses.add(InetSocketAddress(REMOTE_ADDRESS, 80))
1592         return EpsBearerQosSessionAttributes(
1593             qci,
1594             2,
1595             3,
1596             4,
1597             5,
1598             remoteAddresses
1599         )
1600     }
1601 
sendAndExpectUdpPacketnull1602     fun sendAndExpectUdpPacket(
1603         net: Network,
1604         reader: PollPacketReader,
1605         iface: TestNetworkInterface
1606     ) {
1607         val s = Os.socket(AF_INET6, SOCK_DGRAM, 0)
1608         net.bindSocket(s)
1609         val content = ByteArray(16)
1610         Random.nextBytes(content)
1611         Os.sendto(s, ByteBuffer.wrap(content), 0, REMOTE_ADDRESS, 7 /* port */)
1612         val match = reader.poll(DEFAULT_TIMEOUT_MS) {
1613             val udpStart = IPV6_HEADER_LEN + UDP_HEADER_LEN
1614             it.size == udpStart + content.size &&
1615                     it[0].toInt() and 0xf0 == 0x60 &&
1616                     it[IPV6_PROTOCOL_OFFSET].toInt() == IPPROTO_UDP &&
1617                     Arrays.equals(content, it.copyOfRange(udpStart, udpStart + content.size))
1618         }
1619         assertNotNull(
1620             match,
1621             "Did not receive matching packet on ${iface.interfaceName} " +
1622                 " after ${DEFAULT_TIMEOUT_MS}ms"
1623         )
1624     }
1625 
createInterfaceAndReadernull1626     fun createInterfaceAndReader(): Triple<TestNetworkInterface, PollPacketReader, LinkProperties> {
1627         val iface = createTunInterface(listOf(LINK_ADDRESS))
1628         val handler = Handler(Looper.getMainLooper())
1629         val reader = PollPacketReader(handler, iface.fileDescriptor.fileDescriptor, ETHER_MTU)
1630         reader.startAsyncForTest()
1631         handler.waitForIdle(DEFAULT_TIMEOUT_MS)
1632         val ifName = iface.interfaceName
1633         val lp = makeTestLinkProperties(ifName)
1634         return Triple(iface, reader, lp)
1635     }
1636 
1637     @Test
testRegisterAfterUnregisternull1638     fun testRegisterAfterUnregister() {
1639         val (iface, reader, lp) = createInterfaceAndReader()
1640 
1641         // File a request that matches and keeps up the best-scoring test network.
1642         val testCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
1643         requestNetwork(makeTestNetworkRequest(), testCallback)
1644 
1645         // Register and unregister networkagents in a loop, checking that every time an agent
1646         // connects, the native network is correctly configured and packets can be sent.
1647         // Running 10 iterations takes about 1 second on x86 cuttlefish, and detects the race in
1648         // b/286649301 most of the time.
1649         for (i in 1..10) {
1650             val agent1 = createNetworkAgent(realContext, initialLp = lp)
1651             agent1.register()
1652             agent1.unregister()
1653 
1654             val agent2 = createNetworkAgent(realContext, initialLp = lp)
1655             agent2.register()
1656             agent2.markConnected()
1657             val network2 = agent2.network!!
1658 
1659             testCallback.expectAvailableThenValidatedCallbacks(network2)
1660             sendAndExpectUdpPacket(network2, reader, iface)
1661             agent2.unregister()
1662             testCallback.expect<Lost>(network2)
1663         }
1664     }
1665 
1666     @Test
testUnregisterAfterReplacementnull1667     fun testUnregisterAfterReplacement() {
1668         val (iface, reader, lp) = createInterfaceAndReader()
1669 
1670         // Keeps an eye on all test networks.
1671         val matchAllCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
1672         registerNetworkCallback(makeTestNetworkRequest(), matchAllCallback)
1673 
1674         // File a request that matches and keeps up the best-scoring test network.
1675         val testCallback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
1676         requestNetwork(makeTestNetworkRequest(), testCallback)
1677 
1678         // Connect the first network. This should satisfy the request.
1679         val (agent1, network1) = connectNetwork(lp = lp)
1680         matchAllCallback.expectAvailableThenValidatedCallbacks(network1)
1681         testCallback.expectAvailableThenValidatedCallbacks(network1)
1682         sendAndExpectUdpPacket(network1, reader, iface)
1683 
1684         // Connect a second agent. network1 is preferred because it was already registered, so
1685         // testCallback will not see any events. agent2 is torn down because it has no requests.
1686         val (agent2, network2) = connectNetwork()
1687         matchAllCallback.expectAvailableThenValidatedCallbacks(network2)
1688         matchAllCallback.expect<Lost>(network2)
1689         agent2.expectCallback<OnNetworkUnwanted>()
1690         agent2.expectCallback<OnNetworkDestroyed>()
1691         assertNull(mCM.getLinkProperties(network2))
1692 
1693         // Mark the first network as awaiting replacement. This should destroy the underlying
1694         // native network and send onNetworkDestroyed, but will not send any NetworkCallbacks,
1695         // because for callback and scoring purposes network1 is still connected.
1696         agent1.unregisterAfterReplacement(5_000 /* timeoutMillis */)
1697         agent1.expectCallback<OnNetworkDestroyed>()
1698         assertThrows(IOException::class.java) { network1.bindSocket(DatagramSocket()) }
1699         assertNotNull(mCM.getLinkProperties(network1))
1700 
1701         // Calling unregisterAfterReplacement more than once has no effect.
1702         // If it did, this test would fail because the 1ms timeout means that the network would be
1703         // torn down before the replacement arrives.
1704         agent1.unregisterAfterReplacement(1 /* timeoutMillis */)
1705 
1706         // Connect a third network. Because network1 is awaiting replacement, network3 is preferred
1707         // as soon as it validates (until then, it is outscored by network1).
1708         // The fact that the first event seen by matchAllCallback is the connection of network3
1709         // implicitly ensures that no callbacks are sent since network1 was lost.
1710         val (agent3, network3) = connectNetwork(lp = lp)
1711         if (SHOULD_CREATE_NETWORKS_IMMEDIATELY) {
1712             // This is the correct sequence of events.
1713             matchAllCallback.expectAvailableCallbacks(network3, validated = false)
1714             matchAllCallback.expect<Lost>(network1, 2_000 /* timeoutMs */)
1715             matchAllCallback.expectCaps(network3) { it.hasCapability(NET_CAPABILITY_VALIDATED) }
1716             sendAndExpectUdpPacket(network3, reader, iface)
1717             testCallback.expectAvailableDoubleValidatedCallbacks(network3)
1718         } else {
1719             // This is incorrect and fixed by the "create networks immediately" feature
1720             matchAllCallback.expectAvailableThenValidatedCallbacks(network3)
1721             testCallback.expectAvailableDoubleValidatedCallbacks(network3)
1722             sendAndExpectUdpPacket(network3, reader, iface)
1723             // As soon as the replacement arrives, network1 is disconnected.
1724             // Check that this happens before the replacement timeout (5 seconds) fires.
1725             matchAllCallback.expect<Lost>(network1, 2_000 /* timeoutMs */)
1726         }
1727         agent1.expectCallback<OnNetworkUnwanted>()
1728 
1729         // Test lingering:
1730         // - Connect a higher-scoring network and check that network3 starts lingering.
1731         // - Mark network3 awaiting replacement.
1732         // - Check that network3 is torn down immediately without waiting for the linger timer or
1733         //   the replacement timer to fire. This is a regular teardown, so it results in
1734         //   onNetworkUnwanted before onNetworkDestroyed.
1735         val (agent4, agent4callback) = createConnectedNetworkAgent()
1736         val network4 = agent4.network!!
1737         matchAllCallback.expectAvailableThenValidatedCallbacks(network4)
1738         agent4.sendNetworkScore(NetworkScore.Builder().setTransportPrimary(true).build())
1739         matchAllCallback.expect<Losing>(network3)
1740         testCallback.expectAvailableCallbacks(network4, validated = true)
1741         mCM.unregisterNetworkCallback(agent4callback)
1742         sendAndExpectUdpPacket(network3, reader, iface)
1743         agent3.unregisterAfterReplacement(5_000)
1744         agent3.expectCallback<OnNetworkUnwanted>()
1745         matchAllCallback.expect<Lost>(network3, 1000L)
1746         agent3.expectCallback<OnNetworkDestroyed>()
1747 
1748         // Now mark network4 awaiting replacement with a low timeout, and check that if no
1749         // replacement arrives, it is torn down.
1750         agent4.unregisterAfterReplacement(100 /* timeoutMillis */)
1751         matchAllCallback.expect<Lost>(network4, 1000L /* timeoutMs */)
1752         testCallback.expect<Lost>(network4, 1000L /* timeoutMs */)
1753         agent4.expectCallback<OnNetworkDestroyed>()
1754         agent4.expectCallback<OnNetworkUnwanted>()
1755 
1756         // If a network that is awaiting replacement is unregistered, it disconnects immediately,
1757         // before the replacement timeout fires.
1758         val (agent5, network5) = connectNetwork(lp = lp)
1759         matchAllCallback.expectAvailableThenValidatedCallbacks(network5)
1760         testCallback.expectAvailableThenValidatedCallbacks(network5)
1761         sendAndExpectUdpPacket(network5, reader, iface)
1762         agent5.unregisterAfterReplacement(5_000 /* timeoutMillis */)
1763         agent5.unregister()
1764         matchAllCallback.expect<Lost>(network5, 1000L /* timeoutMs */)
1765         testCallback.expect<Lost>(network5, 1000L /* timeoutMs */)
1766         agent5.expectCallback<OnNetworkDestroyed>()
1767         agent5.expectCallback<OnNetworkUnwanted>()
1768 
1769         // If unregisterAfterReplacement is called before markConnected, the network disconnects.
1770         val specifier6 = UUID.randomUUID().toString()
1771         val callback = TestableNetworkCallback()
1772         requestNetwork(makeTestNetworkRequest(specifier = specifier6), callback)
1773         val agent6 = createNetworkAgent(specifier = specifier6)
1774         agent6.register()
1775         if (SHOULD_CREATE_NETWORKS_IMMEDIATELY) {
1776             agent6.expectCallback<OnNetworkCreated>()
1777         } else {
1778             // No callbacks are sent, so check LinkProperties to wait for the network to be created.
1779             assertLinkPropertiesEventuallyNotNull(agent6.network!!)
1780         }
1781 
1782         // unregisterAfterReplacement tears down the network immediately.
1783         // Approximately check that this is the case by picking an unregister timeout that's longer
1784         // than the timeout of the expectCallback<OnNetworkUnwanted> below.
1785         // TODO: consider adding configurable timeouts to TestableNetworkAgent expectations.
1786         val timeoutMs = agent6.DEFAULT_TIMEOUT_MS.toInt() + 1_000
1787         agent6.unregisterAfterReplacement(timeoutMs)
1788         agent6.expectCallback<OnNetworkUnwanted>()
1789         if (!SdkLevel.isAtLeastT() || SHOULD_CREATE_NETWORKS_IMMEDIATELY) {
1790             // Before T, onNetworkDestroyed is called even if the network was never created.
1791             // If immediate native network creation is supported, the network was created by
1792             // register(). Destroying it sends onNetworkDestroyed.
1793             agent6.expectCallback<OnNetworkDestroyed>()
1794         }
1795         // Poll for LinkProperties becoming null, because when onNetworkUnwanted is called, the
1796         // network has not yet been removed from the CS data structures.
1797         assertLinkPropertiesEventuallyNull(agent6.network!!)
1798         assertFalse(mCM.getAllNetworks().contains(agent6.network!!))
1799 
1800         // After unregisterAfterReplacement is called, the network is no longer usable and
1801         // markConnected has no effect.
1802         agent6.markConnected()
1803         agent6.assertNoCallback()
1804         assertNull(mCM.getLinkProperties(agent6.network!!))
1805         matchAllCallback.assertNoCallback(200 /* timeoutMs */)
1806 
1807         // If wifi is replaced within the timeout, the device does not switch to cellular.
1808         val (cellAgent, cellNetwork) = connectNetwork(TRANSPORT_CELLULAR)
1809         testCallback.expectAvailableThenValidatedCallbacks(cellNetwork)
1810         matchAllCallback.expectAvailableThenValidatedCallbacks(cellNetwork)
1811 
1812         val (wifiAgent, wifiNetwork) = connectNetwork(TRANSPORT_WIFI)
1813         testCallback.expectAvailableCallbacks(wifiNetwork, validated = true)
1814         testCallback.expectCaps(wifiNetwork) { it.hasCapability(NET_CAPABILITY_VALIDATED) }
1815         matchAllCallback.expectAvailableCallbacks(wifiNetwork, validated = false)
1816         matchAllCallback.expect<Losing>(cellNetwork)
1817         matchAllCallback.expectCaps(wifiNetwork) { it.hasCapability(NET_CAPABILITY_VALIDATED) }
1818 
1819         wifiAgent.unregisterAfterReplacement(5_000 /* timeoutMillis */)
1820         wifiAgent.expectCallback<OnNetworkDestroyed>()
1821 
1822         // Once the network is awaiting replacement, changing LinkProperties, NetworkCapabilities or
1823         // score, or calling reportNetworkConnectivity, have no effect.
1824         val wifiSpecifier = mCM.getNetworkCapabilities(wifiNetwork)!!.networkSpecifier
1825         assertNotNull(wifiSpecifier)
1826         assertTrue(wifiSpecifier is EthernetNetworkSpecifier)
1827 
1828         val wifiNc = makeTestNetworkCapabilities(
1829             wifiSpecifier.interfaceName,
1830             intArrayOf(TRANSPORT_WIFI)
1831         )
1832         wifiAgent.sendNetworkCapabilities(wifiNc)
1833         val wifiLp = mCM.getLinkProperties(wifiNetwork)!!
1834         val newRoute = RouteInfo(IpPrefix("192.0.2.42/24"))
1835         assertFalse(wifiLp.getRoutes().contains(newRoute))
1836         wifiLp.addRoute(newRoute)
1837         wifiAgent.sendLinkProperties(wifiLp)
1838         mCM.reportNetworkConnectivity(wifiNetwork, false)
1839         // The test implicitly checks that no callbacks are sent here, because the next events seen
1840         // by the callbacks are for the new network connecting.
1841 
1842         val (newWifiAgent, newWifiNetwork) = connectNetwork(TRANSPORT_WIFI)
1843         testCallback.expectAvailableCallbacks(newWifiNetwork, validated = true)
1844         if (SHOULD_CREATE_NETWORKS_IMMEDIATELY) {
1845             // This is the correct sequence of events
1846             matchAllCallback.expectAvailableCallbacks(newWifiNetwork, validated = false)
1847             matchAllCallback.expect<Lost>(wifiNetwork)
1848             matchAllCallback.expectCaps(newWifiNetwork) {
1849                 it.hasCapability(NET_CAPABILITY_VALIDATED)
1850             }
1851         } else {
1852             // When networks are not created immediately, the sequence is slightly incorrect
1853             // and instead is as follows
1854             matchAllCallback.expectAvailableThenValidatedCallbacks(newWifiNetwork)
1855             matchAllCallback.expect<Lost>(wifiNetwork)
1856         }
1857         wifiAgent.expectCallback<OnNetworkUnwanted>()
1858         testCallback.expect<CapabilitiesChanged>(newWifiNetwork)
1859 
1860         cellAgent.unregister()
1861         matchAllCallback.expect<Lost>(cellNetwork)
1862         newWifiAgent.unregister()
1863         matchAllCallback.expect<Lost>(newWifiNetwork)
1864         testCallback.expect<Lost>(newWifiNetwork)
1865 
1866         // Calling unregisterAfterReplacement several times in quick succession works.
1867         // These networks are all kept up by testCallback.
1868         val agent10 = createNetworkAgent(realContext, initialLp = lp)
1869         agent10.register()
1870         agent10.unregisterAfterReplacement(5_000)
1871 
1872         val agent11 = createNetworkAgent(realContext, initialLp = lp)
1873         agent11.register()
1874         agent11.unregisterAfterReplacement(5_000)
1875 
1876         val agent12 = createNetworkAgent(realContext, initialLp = lp)
1877         agent12.register()
1878         agent12.unregisterAfterReplacement(5_000)
1879 
1880         val agent13 = createNetworkAgent(realContext, initialLp = lp)
1881         agent13.register()
1882         agent13.markConnected()
1883         testCallback.expectAvailableThenValidatedCallbacks(agent13.network!!)
1884         sendAndExpectUdpPacket(agent13.network!!, reader, iface)
1885         agent13.unregister()
1886     }
1887 
1888     @Test
testUnregisterAgentBeforeAgentFullyConnectednull1889     fun testUnregisterAgentBeforeAgentFullyConnected() {
1890         val specifier = UUID.randomUUID().toString()
1891         val callback = TestableNetworkCallback()
1892         val transports = intArrayOf(TRANSPORT_CELLULAR)
1893         // Ensure this NetworkAgent is never unneeded by filing a request with its specifier.
1894         requestNetwork(makeTestNetworkRequest(specifier = specifier), callback)
1895         val nc = makeTestNetworkCapabilities(specifier, transports)
1896         val agent = createNetworkAgent(realContext, initialNc = nc)
1897         // Connect the agent
1898         agent.register()
1899         // Mark agent connected then unregister agent immediately. Verify that both available and
1900         // lost callback should be sent still.
1901         agent.markConnected()
1902         agent.unregister()
1903         callback.expect<Available>(agent.network!!)
1904         callback.eventuallyExpect<Lost> { it.network == agent.network }
1905     }
1906 
doTestNativeNetworkCreationnull1907     fun doTestNativeNetworkCreation(expectCreatedImmediately: Boolean, transports: IntArray) {
1908         val iface = createTunInterface()
1909         val ifName = iface.interfaceName
1910         val nc = makeTestNetworkCapabilities(ifName, transports).also {
1911             if (transports.contains(TRANSPORT_VPN)) {
1912                 val sessionId = "NetworkAgentTest-${Process.myPid()}"
1913                 it.setTransportInfo(VpnTransportInfo(
1914                     VpnManager.TYPE_VPN_PLATFORM,
1915                     sessionId,
1916                     /*bypassable=*/
1917                     false,
1918                     /*longLivedTcpConnectionsExpensive=*/
1919                     false
1920                 ))
1921                 it.underlyingNetworks = listOf()
1922             }
1923         }
1924         val lp = makeTestLinkProperties(ifName)
1925 
1926         // File a request containing the agent's specifier to receive callbacks and to ensure that
1927         // the agent is not torn down due to being unneeded.
1928         val request = makeTestNetworkRequest(specifier = ifName)
1929         val requestCallback = TestableNetworkCallback()
1930         requestNetwork(request, requestCallback)
1931 
1932         val listenCallback = TestableNetworkCallback()
1933         registerNetworkCallback(request, listenCallback)
1934 
1935         // Register the NetworkAgent...
1936         val agent = createNetworkAgent(realContext, initialNc = nc, initialLp = lp)
1937         val network = agent.register()
1938 
1939         // ... and then change the NetworkCapabilities and LinkProperties.
1940         nc.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
1941         agent.sendNetworkCapabilities(nc)
1942         lp.addLinkAddress(LinkAddress("192.0.2.2/25"))
1943         lp.addRoute(RouteInfo(IpPrefix("192.0.2.0/25"), null /* nextHop */, ifName))
1944         agent.sendLinkProperties(lp)
1945 
1946         requestCallback.assertNoCallback()
1947         listenCallback.assertNoCallback()
1948         if (!expectCreatedImmediately) {
1949             agent.assertNoCallback()
1950             agent.markConnected()
1951             agent.expectCallback<OnNetworkCreated>()
1952         } else {
1953             agent.expectCallback<OnNetworkCreated>()
1954             agent.markConnected()
1955         }
1956         agent.expectPostConnectionCallbacks()
1957 
1958         // onAvailable must be called only when the network connects, and no other callbacks may be
1959         // called before that happens. The callbacks report the state of the network as it was when
1960         // it connected, so they reflect the NC and LP changes made after registration.
1961         requestCallback.expect<Available>(network)
1962         listenCallback.expect<Available>(network)
1963 
1964         requestCallback.expect<CapabilitiesChanged>(network) { it.caps.hasCapability(
1965             NET_CAPABILITY_TEMPORARILY_NOT_METERED
1966         ) }
1967         listenCallback.expect<CapabilitiesChanged>(network) { it.caps.hasCapability(
1968             NET_CAPABILITY_TEMPORARILY_NOT_METERED
1969         ) }
1970 
1971         requestCallback.expect<LinkPropertiesChanged>(network) { it.lp.equals(lp) }
1972         listenCallback.expect<LinkPropertiesChanged>(network) { it.lp.equals(lp) }
1973 
1974         requestCallback.expect<BlockedStatus>()
1975         listenCallback.expect<BlockedStatus>()
1976 
1977         // Except for network validation, ensure no more callbacks are sent.
1978         requestCallback.expectCaps(network) {
1979             it.hasCapability(NET_CAPABILITY_VALIDATED)
1980         }
1981         listenCallback.expectCaps(network) {
1982             it.hasCapability(NET_CAPABILITY_VALIDATED)
1983         }
1984         unregister(agent)
1985         // Lost implicitly checks that no further callbacks happened after connect.
1986         requestCallback.expect<Lost>(network)
1987         listenCallback.expect<Lost>(network)
1988         assertNull(mCM.getLinkProperties(network))
1989     }
1990 
1991     @Test
testNativeNetworkCreation_PhysicalNetworknull1992     fun testNativeNetworkCreation_PhysicalNetwork() {
1993         doTestNativeNetworkCreation(
1994                 expectCreatedImmediately = SHOULD_CREATE_NETWORKS_IMMEDIATELY,
1995                 intArrayOf(TRANSPORT_CELLULAR)
1996         )
1997     }
1998 
1999     @Test
testNativeNetworkCreation_Vpnnull2000     fun testNativeNetworkCreation_Vpn() {
2001         // VPN networks are always created as soon as the agent is registered.
2002         doTestNativeNetworkCreation(expectCreatedImmediately = true, intArrayOf(TRANSPORT_VPN))
2003     }
2004 
2005     @Test(expected = IllegalStateException::class)
testRegisterAgainnull2006     fun testRegisterAgain() {
2007         val agent = createNetworkAgent()
2008         agent.register()
2009         agent.unregister()
2010         agent.register()
2011     }
2012 
2013     @Test
testUnregisterBeforeRegisternull2014     fun testUnregisterBeforeRegister() {
2015         // For backward compatibility, this shouldn't crash.
2016         val agent = createNetworkAgent()
2017         agent.unregister()
2018     }
2019 }
2020