• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2022 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.CONNECTIVITY_USE_RESTRICTED_NETWORKS
19 import android.Manifest.permission.MANAGE_TEST_NETWORKS
20 import android.Manifest.permission.NETWORK_SETTINGS
21 import android.content.Context
22 import android.net.ConnectivityManager
23 import android.net.EthernetManager
24 import android.net.EthernetManager.ETHERNET_STATE_DISABLED
25 import android.net.EthernetManager.ETHERNET_STATE_ENABLED
26 import android.net.EthernetManager.InterfaceStateListener
27 import android.net.EthernetManager.ROLE_CLIENT
28 import android.net.EthernetManager.ROLE_NONE
29 import android.net.EthernetManager.ROLE_SERVER
30 import android.net.EthernetManager.STATE_ABSENT
31 import android.net.EthernetManager.STATE_LINK_DOWN
32 import android.net.EthernetManager.STATE_LINK_UP
33 import android.net.EthernetManager.TetheredInterfaceCallback
34 import android.net.EthernetManager.TetheredInterfaceRequest
35 import android.net.EthernetNetworkManagementException
36 import android.net.EthernetNetworkSpecifier
37 import android.net.EthernetNetworkUpdateRequest
38 import android.net.InetAddresses
39 import android.net.IpConfiguration
40 import android.net.LinkAddress
41 import android.net.MacAddress
42 import android.net.Network
43 import android.net.NetworkCapabilities
44 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED
45 import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED
46 import android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED
47 import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
48 import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
49 import android.net.NetworkCapabilities.TRANSPORT_TEST
50 import android.net.NetworkRequest
51 import android.net.StaticIpConfiguration
52 import android.net.TestNetworkInterface
53 import android.net.TestNetworkManager
54 import android.net.TestNetworkManager.TestInterfaceRequest
55 import android.net.cts.EthernetManagerTest.EthernetStateListener.CallbackEntry.EthernetStateChanged
56 import android.net.cts.EthernetManagerTest.EthernetStateListener.CallbackEntry.InterfaceStateChanged
57 import android.os.Build
58 import android.os.Handler
59 import android.os.Looper
60 import android.os.OutcomeReceiver
61 import android.os.Process
62 import android.os.SystemProperties
63 import android.platform.test.annotations.AppModeFull
64 import androidx.test.platform.app.InstrumentationRegistry
65 import com.android.net.module.util.ArrayTrackRecord
66 import com.android.net.module.util.TrackRecord
67 import com.android.testutils.ConnectivityModuleTest
68 import com.android.testutils.DevSdkIgnoreRule
69 import com.android.testutils.DevSdkIgnoreRunner
70 import com.android.testutils.DeviceInfoUtils.isKernelVersionAtLeast
71 import com.android.testutils.RecorderCallback.CallbackEntry.Available
72 import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
73 import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
74 import com.android.testutils.RecorderCallback.CallbackEntry.Lost
75 import com.android.testutils.RouterAdvertisementResponder
76 import com.android.testutils.PollPacketReader
77 import com.android.testutils.TestableNetworkCallback
78 import com.android.testutils.assertThrows
79 import com.android.testutils.runAsShell
80 import com.android.testutils.waitForIdle
81 import com.google.common.truth.Truth.assertThat
82 import java.io.IOException
83 import java.net.Inet6Address
84 import java.net.Socket
85 import java.util.Random
86 import java.util.concurrent.CompletableFuture
87 import java.util.concurrent.ExecutionException
88 import java.util.concurrent.TimeUnit
89 import java.util.concurrent.TimeoutException
90 import java.util.function.IntConsumer
91 import kotlin.test.assertEquals
92 import kotlin.test.assertFailsWith
93 import kotlin.test.assertFalse
94 import kotlin.test.assertNotNull
95 import kotlin.test.assertNull
96 import kotlin.test.assertTrue
97 import org.junit.After
98 import org.junit.Assume.assumeFalse
99 import org.junit.Assume.assumeTrue
100 import org.junit.Before
101 import org.junit.Test
102 import org.junit.runner.RunWith
103 
104 private const val TAG = "EthernetManagerTest"
105 // This timeout does not affect the test duration for passing tests. It needs to be long enough to
106 // account for RS delay (and potentially the first retry interval (4s)). There have been failures
107 // where the interface did not gain provisioning within the allotted timeout.
108 private const val TIMEOUT_MS = 10_000L
109 // Timeout used to confirm no callbacks matching given criteria are received. Must be long enough to
110 // process all callbacks including ip provisioning when using the updateConfiguration API.
111 // Note that increasing this timeout increases the test duration.
112 private const val NO_CALLBACK_TIMEOUT_MS = 500L
113 
114 private val DEFAULT_IP_CONFIGURATION = IpConfiguration(IpConfiguration.IpAssignment.DHCP,
115         IpConfiguration.ProxySettings.NONE, null, null)
116 private val ETH_REQUEST: NetworkRequest = NetworkRequest.Builder()
117         .addTransportType(TRANSPORT_TEST)
118         .addTransportType(TRANSPORT_ETHERNET)
119         .removeCapability(NET_CAPABILITY_TRUSTED)
120         .build()
121 private val TEST_CAPS = NetworkCapabilities.Builder(ETH_REQUEST.networkCapabilities)
122         .addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
123         .addCapability(NET_CAPABILITY_NOT_CONGESTED)
124         .build()
125 private val STATIC_IP_CONFIGURATION = IpConfiguration.Builder()
126         .setStaticIpConfiguration(StaticIpConfiguration.Builder()
127                 .setIpAddress(LinkAddress("192.0.2.1/30")).build())
128         .build()
129 
130 @AppModeFull(reason = "Instant apps can't access EthernetManager")
131 // EthernetManager is not updatable before T, so tests do not need to be backwards compatible.
132 @RunWith(DevSdkIgnoreRunner::class)
133 // This test depends on behavior introduced post-T as part of connectivity module updates
134 @ConnectivityModuleTest
135 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
136 class EthernetManagerTest {
137 
138     private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
139     private val em by lazy { context.getSystemService(EthernetManager::class.java)!! }
140     private val cm by lazy { context.getSystemService(ConnectivityManager::class.java)!! }
141     private val handler by lazy { Handler(Looper.getMainLooper()) }
142 
143     private val ifaceListener = EthernetStateListener()
144     private val createdIfaces = ArrayList<EthernetTestInterface>()
145     private val addedListeners = ArrayList<EthernetStateListener>()
146     private val registeredCallbacks = ArrayList<TestableNetworkCallback>()
147 
148     private var tetheredInterfaceRequest: TetheredInterfaceRequest? = null
149 
150     private var ethernetEnabled = true
151 
152     private class EthernetTestInterface(
153         context: Context,
154         private val handler: Handler,
155         hasCarrier: Boolean
156     ) {
157         private val tapInterface: TestNetworkInterface
158         private val packetReader: PollPacketReader
159         private val raResponder: RouterAdvertisementResponder
160         private val tnm: TestNetworkManager
161         val name get() = tapInterface.interfaceName
162         val onLinkPrefix get() = raResponder.prefix
163 
164         init {
165             tnm = runAsShell(MANAGE_TEST_NETWORKS) {
166                 context.getSystemService(TestNetworkManager::class.java)!!
167             }
168             tapInterface = runAsShell(MANAGE_TEST_NETWORKS) {
169                 // Configuring a tun/tap interface always enables the carrier. If hasCarrier is
170                 // false, it is subsequently disabled. This means that the interface may briefly get
171                 // link. With IPv6 provisioning delays (RS delay and DAD) disabled, this can cause
172                 // tests that expect no network to come up when hasCarrier is false to become flaky.
173                 val req = TestInterfaceRequest.Builder()
174                         .setTap()
175                         .setHasCarrier(hasCarrier)
176                         .setBringUp(false)
177                         .build()
178                 tnm.createTestInterface(req)
179             }
180             val mtu = tapInterface.mtu
181             packetReader = PollPacketReader(
182                     handler,
183                     tapInterface.fileDescriptor.fileDescriptor,
184                     mtu
185             )
186             raResponder = RouterAdvertisementResponder(packetReader)
187             val iidString = "fe80::${Integer.toHexString(Random().nextInt(65536))}"
188             val linklocal = InetAddresses.parseNumericAddress(iidString) as Inet6Address
189             raResponder.addRouterEntry(MacAddress.fromString("01:23:45:67:89:ab"), linklocal)
190 
191             packetReader.startAsyncForTest()
192             raResponder.start()
193         }
194 
195         // WARNING: this function requires kernel support. Call assumeChangingCarrierSupported() at
196         // the top of your test.
197         fun setCarrierEnabled(enabled: Boolean) {
198             runAsShell(MANAGE_TEST_NETWORKS) {
199                 tnm.setCarrierEnabled(tapInterface, enabled)
200             }
201         }
202 
203         fun destroy() {
204             raResponder.stop()
205             handler.post({ packetReader.stop() })
206             handler.waitForIdle(TIMEOUT_MS)
207         }
208     }
209 
210     private open class EthernetStateListener private constructor(
211         private val history: ArrayTrackRecord<CallbackEntry>
212     ) : InterfaceStateListener, IntConsumer,
213                 TrackRecord<EthernetStateListener.CallbackEntry> by history {
214         constructor() : this(ArrayTrackRecord())
215 
216         val events = history.newReadHead()
217 
218         sealed class CallbackEntry {
219             data class InterfaceStateChanged(
220                 val iface: String,
221                 val state: Int,
222                 val role: Int,
223                 val configuration: IpConfiguration?
224             ) : CallbackEntry() {
225                 override fun toString(): String {
226                     val stateString = when (state) {
227                         STATE_ABSENT -> "STATE_ABSENT"
228                         STATE_LINK_UP -> "STATE_LINK_UP"
229                         STATE_LINK_DOWN -> "STATE_LINK_DOWN"
230                         else -> state.toString()
231                     }
232                     val roleString = when (role) {
233                         ROLE_NONE -> "ROLE_NONE"
234                         ROLE_CLIENT -> "ROLE_CLIENT"
235                         ROLE_SERVER -> "ROLE_SERVER"
236                         else -> role.toString()
237                     }
238                     return ("InterfaceStateChanged(iface=$iface, state=$stateString, " +
239                             "role=$roleString, ipConfig=$configuration)")
240                 }
241             }
242 
243             data class EthernetStateChanged(val state: Int) : CallbackEntry() {
244                 override fun toString(): String {
245                     val stateString = when (state) {
246                         ETHERNET_STATE_ENABLED -> "ETHERNET_STATE_ENABLED"
247                         ETHERNET_STATE_DISABLED -> "ETHERNET_STATE_DISABLED"
248                         else -> state.toString()
249                     }
250                     return "EthernetStateChanged(state=$stateString)"
251                 }
252             }
253         }
254 
255         override fun onInterfaceStateChanged(
256             iface: String,
257             state: Int,
258             role: Int,
259             cfg: IpConfiguration?
260         ) {
261             add(InterfaceStateChanged(iface, state, role, cfg))
262         }
263 
264         override fun accept(state: Int) {
265             add(EthernetStateChanged(state))
266         }
267 
268         fun <T : CallbackEntry> expectCallback(expected: T): T {
269             val event = events.poll(TIMEOUT_MS)
270             assertEquals(expected, event)
271             return event as T
272         }
273 
274         fun expectCallback(iface: EthernetTestInterface, state: Int, role: Int) {
275             expectCallback(createChangeEvent(iface.name, state, role))
276         }
277 
278         fun expectCallback(state: Int) {
279             expectCallback(EthernetStateChanged(state))
280         }
281 
282         private fun createChangeEvent(iface: String, state: Int, role: Int) =
283                 InterfaceStateChanged(iface, state, role,
284                         if (state != STATE_ABSENT) DEFAULT_IP_CONFIGURATION else null)
285 
286         fun eventuallyExpect(expected: CallbackEntry) {
287             val cb = events.poll(TIMEOUT_MS) { it == expected }
288             assertNotNull(cb, "Never received expected $expected. Received: ${events.backtrace()}")
289         }
290 
291         fun eventuallyExpect(iface: EthernetTestInterface, state: Int, role: Int) {
292             eventuallyExpect(createChangeEvent(iface.name, state, role))
293         }
294 
295         fun eventuallyExpect(state: Int) {
296             eventuallyExpect(EthernetStateChanged(state))
297         }
298 
299         fun assertNoCallback() {
300             val cb = events.poll(NO_CALLBACK_TIMEOUT_MS)
301             assertNull(cb, "Expected no callback but got $cb")
302         }
303     }
304 
305     private class TetheredInterfaceListener : TetheredInterfaceCallback {
306         private val available = CompletableFuture<String>()
307 
308         override fun onAvailable(iface: String) {
309             available.complete(iface)
310         }
311 
312         override fun onUnavailable() {
313             available.completeExceptionally(IllegalStateException("onUnavailable was called"))
314         }
315 
316         fun expectOnAvailable(timeout: Long = TIMEOUT_MS): String {
317             return available.get(timeout, TimeUnit.MILLISECONDS)
318         }
319     }
320 
321     private class EthernetOutcomeReceiver :
322         OutcomeReceiver<String, EthernetNetworkManagementException> {
323         private val result = CompletableFuture<String>()
324 
325         override fun onResult(iface: String) {
326             assertFalse(result.isDone())
327             result.complete(iface)
328         }
329 
330         override fun onError(e: EthernetNetworkManagementException) {
331             assertFalse(result.isDone())
332             result.completeExceptionally(e)
333         }
334 
335         fun expectResult(expected: String) {
336             assertEquals(expected, result.get(TIMEOUT_MS, TimeUnit.MILLISECONDS))
337         }
338 
339         fun expectError() {
340             // Assert that the future fails with EthernetNetworkManagementException from the
341             // completeExceptionally() call inside onUnavailable.
342             assertFailsWith(EthernetNetworkManagementException::class) {
343                 try {
344                     result.get()
345                 } catch (e: ExecutionException) {
346                     throw e.cause!!
347                 }
348             }
349         }
350     }
351 
352     private fun isEthernetSupported(): Boolean {
353         return context.getSystemService(EthernetManager::class.java) != null
354     }
355 
356     @Before
357     fun setUp() {
358         assumeTrue(isEthernetSupported())
359         setIncludeTestInterfaces(true)
360         addInterfaceStateListener(ifaceListener)
361         // Handler.post() events may get processed after native fd events, so it is possible that
362         // RTM_NEWLINK (from a subsequent createInterface() call) arrives before the interface state
363         // listener is registered. This affects the callbacks and breaks the tests.
364         // setEthernetEnabled() will always wait on a callback, so it is used as a barrier to ensure
365         // proper listener registration before proceeding.
366         setEthernetEnabled(true)
367     }
368 
369     @After
370     fun tearDown() {
371         if (!isEthernetSupported()) return
372         // Reenable ethernet, so ABSENT callbacks are received.
373         setEthernetEnabled(true)
374 
375         for (iface in createdIfaces) {
376             iface.destroy()
377             ifaceListener.eventuallyExpect(iface, STATE_ABSENT, ROLE_NONE)
378         }
379 
380         // After test interfaces are removed, disable tracking.
381         setIncludeTestInterfaces(false)
382 
383         for (listener in addedListeners) {
384             // Even if a given listener was not registered as both an interface and ethernet state
385             // listener, calling remove is safe.
386             em.removeInterfaceStateListener(listener)
387             em.removeEthernetStateListener(listener)
388         }
389         registeredCallbacks.forEach { cm.unregisterNetworkCallback(it) }
390         releaseTetheredInterface()
391         // Force releaseTetheredInterface() to be processed before starting the next test by calling
392         // setEthernetEnabled(true) which always waits on a callback.
393         setEthernetEnabled(true)
394     }
395 
396     // Setting the carrier up / down relies on TUNSETCARRIER which was added in kernel version 5.0.
397     private fun assumeChangingCarrierSupported() {
398         assumeTrue(isKernelVersionAtLeast("5.0.0"))
399     }
400 
401     // Configuring a tap interface without carrier relies on IFF_NO_CARRIER
402     // which was added in kernel version 6.0.
403     private fun assumeCreateInterfaceWithoutCarrierSupported() {
404         assumeTrue(isKernelVersionAtLeast("6.0.0"))
405     }
406 
407     private fun isAdbOverEthernet(): Boolean {
408         // If no ethernet interface is available, adb is not connected over ethernet.
409         if (em.getInterfaceList().isEmpty()) return false
410 
411         // cuttlefish is special and does not connect adb over ethernet.
412         if (SystemProperties.get("ro.product.board", "") == "cutf") return false
413 
414         // Check if adb is connected over the network.
415         return (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1 ||
416                 SystemProperties.getInt("service.adb.tcp.port", -1) > -1)
417     }
418 
419     private fun addInterfaceStateListener(listener: EthernetStateListener) {
420         em.addInterfaceStateListener(handler::post, listener)
421         addedListeners.add(listener)
422     }
423 
424     private fun addEthernetStateListener(listener: EthernetStateListener) {
425         em.addEthernetStateListener(handler::post, listener)
426         addedListeners.add(listener)
427     }
428 
429     // WARNING: setting hasCarrier to false requires kernel support. Call
430     // assumeCreateInterfaceWithoutCarrierSupported() at the top of your test.
431     private fun createInterface(hasCarrier: Boolean = true): EthernetTestInterface {
432         val iface = EthernetTestInterface(
433             context,
434             handler,
435             hasCarrier
436         ).also { createdIfaces.add(it) }
437 
438         // when an interface comes up, we should always see a down cb before an up cb.
439         ifaceListener.eventuallyExpect(iface, STATE_LINK_DOWN, ROLE_CLIENT)
440         if (hasCarrier && ethernetEnabled) {
441             ifaceListener.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
442         }
443         return iface
444     }
445 
446     private fun setIncludeTestInterfaces(value: Boolean) {
447         runAsShell(NETWORK_SETTINGS) {
448             em.setIncludeTestInterfaces(value)
449         }
450     }
451 
452     private fun removeInterface(iface: EthernetTestInterface) {
453         iface.destroy()
454         createdIfaces.remove(iface)
455         ifaceListener.eventuallyExpect(iface, STATE_ABSENT, ROLE_NONE)
456     }
457 
458     private fun requestNetwork(request: NetworkRequest): TestableNetworkCallback {
459         return TestableNetworkCallback(
460                 timeoutMs = TIMEOUT_MS,
461                 noCallbackTimeoutMs = NO_CALLBACK_TIMEOUT_MS).also {
462             cm.requestNetwork(request, it)
463             registeredCallbacks.add(it)
464         }
465     }
466 
467     private fun registerNetworkListener(request: NetworkRequest): TestableNetworkCallback {
468         return TestableNetworkCallback(
469                 timeoutMs = TIMEOUT_MS,
470                 noCallbackTimeoutMs = NO_CALLBACK_TIMEOUT_MS).also {
471             cm.registerNetworkCallback(request, it)
472             registeredCallbacks.add(it)
473         }
474     }
475 
476     private fun requestTetheredInterface() = TetheredInterfaceListener().also {
477         tetheredInterfaceRequest = runAsShell(NETWORK_SETTINGS) {
478             em.requestTetheredInterface(handler::post, it)
479         }
480     }
481 
482     private fun releaseTetheredInterface() {
483         runAsShell(NETWORK_SETTINGS) {
484             tetheredInterfaceRequest?.release()
485             tetheredInterfaceRequest = null
486         }
487     }
488 
489     private fun releaseRequest(cb: TestableNetworkCallback) {
490         cm.unregisterNetworkCallback(cb)
491         registeredCallbacks.remove(cb)
492     }
493 
494     private fun disableInterface(iface: EthernetTestInterface) = EthernetOutcomeReceiver().also {
495         runAsShell(MANAGE_TEST_NETWORKS) {
496             em.disableInterface(iface.name, handler::post, it)
497         }
498     }
499 
500     private fun enableInterface(iface: EthernetTestInterface) = EthernetOutcomeReceiver().also {
501         runAsShell(MANAGE_TEST_NETWORKS) {
502             em.enableInterface(iface.name, handler::post, it)
503         }
504     }
505 
506     private fun updateConfiguration(
507         iface: EthernetTestInterface,
508         ipConfig: IpConfiguration? = null,
509         capabilities: NetworkCapabilities? = null
510     ) = EthernetOutcomeReceiver().also {
511         runAsShell(MANAGE_TEST_NETWORKS) {
512             em.updateConfiguration(
513                 iface.name,
514                 EthernetNetworkUpdateRequest.Builder()
515                     .setIpConfiguration(ipConfig)
516                     .setNetworkCapabilities(capabilities).build(),
517                 handler::post,
518                 it)
519         }
520     }
521 
522     // WARNING: check that isAdbOverEthernet() is false before calling setEthernetEnabled(false).
523     private fun setEthernetEnabled(enabled: Boolean) {
524         runAsShell(NETWORK_SETTINGS) { em.setEthernetEnabled(enabled) }
525 
526         ethernetEnabled = enabled
527         val listener = EthernetStateListener()
528         addEthernetStateListener(listener)
529         listener.eventuallyExpect(if (enabled) ETHERNET_STATE_ENABLED else ETHERNET_STATE_DISABLED)
530     }
531 
532     // NetworkRequest.Builder does not create a copy of the passed NetworkRequest, so in order to
533     // keep ETH_REQUEST as it is, a defensive copy is created here.
534     private fun NetworkRequest.copyWithEthernetSpecifier(ifaceName: String) =
535         NetworkRequest.Builder(NetworkRequest(ETH_REQUEST))
536             .setNetworkSpecifier(EthernetNetworkSpecifier(ifaceName)).build()
537 
538     // b/233534110: eventuallyExpect<Lost>() does not advance ReadHead, use
539     // eventuallyExpect(Lost::class) instead.
540     private fun TestableNetworkCallback.eventuallyExpectLost(n: Network? = null) =
541         eventuallyExpect(Lost::class) { n?.equals(it.network) ?: true }
542 
543     private fun TestableNetworkCallback.assertNeverLost(n: Network? = null) =
544         assertNoCallback { it is Lost && (n?.equals(it.network) ?: true) }
545 
546     private fun TestableNetworkCallback.assertNeverAvailable(n: Network? = null) =
547         assertNoCallback { it is Available && (n?.equals(it.network) ?: true) }
548 
549     private fun TestableNetworkCallback.expectCapabilitiesWithInterfaceName(name: String) =
550         expect<CapabilitiesChanged> { it.caps.networkSpecifier == EthernetNetworkSpecifier(name) }
551 
552     private fun TestableNetworkCallback.eventuallyExpectCapabilities(nc: NetworkCapabilities) {
553         // b/233534110: eventuallyExpect<CapabilitiesChanged>() does not advance ReadHead.
554         eventuallyExpect(CapabilitiesChanged::class) {
555             // CS may mix in additional capabilities, so NetworkCapabilities#equals cannot be used.
556             // Check if all expected capabilities are present instead.
557             it is CapabilitiesChanged && nc.capabilities.all { c -> it.caps.hasCapability(c) }
558         }
559     }
560 
561     private fun TestableNetworkCallback.eventuallyExpectLpForStaticConfig(
562         config: StaticIpConfiguration
563     ) {
564         // b/233534110: eventuallyExpect<LinkPropertiesChanged>() does not advance ReadHead.
565         eventuallyExpect(LinkPropertiesChanged::class) {
566             it is LinkPropertiesChanged && it.lp.linkAddresses.any { la ->
567                 la.isSameAddressAs(config.ipAddress)
568             }
569         }
570     }
571 
572     @Test
573     fun testCallbacks() {
574         // Only run this test when no non-restricted / physical interfaces are present.
575         // This test ensures that interface state listeners function properly, so the assumption
576         // check is explicitly *not* using an interface state listener.
577         // Since restricted interfaces cannot be used for tethering,
578         // assumeNoInterfaceForTetheringAvailable() is an okay proxy.
579         assumeNoInterfaceForTetheringAvailable()
580 
581         // If an interface exists when the callback is registered, it is reported on registration.
582         val iface = createInterface()
583         val listener1 = EthernetStateListener()
584         addInterfaceStateListener(listener1)
585         listener1.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
586 
587         // If an interface appears, existing callbacks see it.
588         val iface2 = createInterface()
589         listener1.expectCallback(iface2, STATE_LINK_DOWN, ROLE_CLIENT)
590         listener1.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
591 
592         // Register a new listener, it should see state of all existing interfaces immediately.
593         val listener2 = EthernetStateListener()
594         addInterfaceStateListener(listener2)
595         listener2.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
596         listener2.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
597 
598         // Removing interfaces first sends link down, then STATE_ABSENT/ROLE_NONE.
599         removeInterface(iface)
600         for (listener in listOf(listener1, listener2)) {
601             listener.expectCallback(iface, STATE_LINK_DOWN, ROLE_CLIENT)
602             listener.expectCallback(iface, STATE_ABSENT, ROLE_NONE)
603         }
604 
605         removeInterface(iface2)
606         for (listener in listOf(listener1, listener2)) {
607             listener.expectCallback(iface2, STATE_LINK_DOWN, ROLE_CLIENT)
608             listener.expectCallback(iface2, STATE_ABSENT, ROLE_NONE)
609             listener.assertNoCallback()
610         }
611     }
612 
613     private fun assumeNoInterfaceForTetheringAvailable() {
614          // Requesting a tethered interface will stop IpClient. Prevent it from doing so
615          // if adb is connected over ethernet.
616          assumeFalse(isAdbOverEthernet())
617         // Interfaces that have configured NetworkCapabilities will never be used for tethering,
618         // see aosp/2123900.
619         try {
620             // assumeException does not exist.
621             requestTetheredInterface().expectOnAvailable(NO_CALLBACK_TIMEOUT_MS)
622             // interface used for tethering is available, throw an assumption error.
623             assumeTrue(false)
624         } catch (e: TimeoutException) {
625             // do nothing -- the TimeoutException indicates that no interface is available for
626             // tethering.
627             releaseTetheredInterface()
628             // Force releaseTetheredInterface() to be processed before proceeding by calling
629             // setEthernetEnabled(true) which always waits on a callback.
630             setEthernetEnabled(true)
631         }
632     }
633 
634     @Test
635     fun testCallbacks_forServerModeInterfaces() {
636         // do not run this test if an interface that can be used for tethering already exists.
637         assumeNoInterfaceForTetheringAvailable()
638 
639         val iface = createInterface()
640         requestTetheredInterface().expectOnAvailable()
641 
642         val listener = EthernetStateListener()
643         addInterfaceStateListener(listener)
644         // TODO(b/295146844): do not report IpConfiguration for server mode interfaces.
645         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_SERVER)
646 
647         releaseTetheredInterface()
648         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_CLIENT)
649 
650         requestTetheredInterface().expectOnAvailable()
651         // This should be changed to expectCallback, once b/236895792 is fixed.
652         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_SERVER)
653 
654         releaseTetheredInterface()
655         listener.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
656     }
657 
658     @Test
659     fun testCallbacks_afterRemovingServerModeInterface() {
660         // do not run this test if an interface that can be used for tethering already exists.
661         assumeNoInterfaceForTetheringAvailable()
662 
663         val iface = createInterface()
664         requestTetheredInterface().expectOnAvailable()
665         removeInterface(iface)
666 
667         val listener = EthernetStateListener()
668         addInterfaceStateListener(listener)
669         listener.assertNoCallback()
670     }
671 
672     @Test
673     fun testGetInterfaceList() {
674         // Create two test interfaces and check the return list contains the interface names.
675         val iface1 = createInterface()
676         val iface2 = createInterface()
677         var ifaces = em.getInterfaceList()
678         assertTrue(ifaces.size > 0)
679         assertTrue(ifaces.contains(iface1.name))
680         assertTrue(ifaces.contains(iface2.name))
681 
682         // Remove one existing test interface and check the return list doesn't contain the
683         // removed interface name.
684         removeInterface(iface1)
685         ifaces = em.getInterfaceList()
686         assertFalse(ifaces.contains(iface1.name))
687         assertTrue(ifaces.contains(iface2.name))
688 
689         removeInterface(iface2)
690     }
691 
692     @Test
693     fun testNetworkRequest_withSingleExistingInterface() {
694         createInterface()
695 
696         // install a listener which will later be used to verify the Lost callback
697         val listenerCb = registerNetworkListener(ETH_REQUEST)
698         // assert the network is only brought up by a request.
699         listenerCb.assertNeverAvailable()
700 
701         val cb = requestNetwork(ETH_REQUEST)
702         val network = cb.expect<Available>().network
703 
704         cb.assertNeverLost()
705         releaseRequest(cb)
706         listenerCb.eventuallyExpectLost(network)
707     }
708 
709     @Test
710     fun testNetworkRequest_beforeSingleInterfaceIsUp() {
711         val cb = requestNetwork(ETH_REQUEST)
712 
713         // bring up interface after network has been requested.
714         // Note: there is no guarantee that the NetworkRequest has been processed before the
715         // interface is actually created. That being said, it takes a few seconds between calling
716         // createInterface and the interface actually being properly registered with the ethernet
717         // module, so it is extremely unlikely that the CS handler thread has not run until then.
718         val iface = createInterface()
719         val network = cb.expect<Available>().network
720 
721         // remove interface before network request has been removed
722         cb.assertNeverLost()
723         removeInterface(iface)
724         cb.eventuallyExpectLost()
725     }
726 
727     @Test
728     fun testNetworkRequest_withMultipleInterfaces() {
729         val iface1 = createInterface()
730         val iface2 = createInterface()
731 
732         val cb = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface2.name))
733 
734         cb.expect<Available>()
735         cb.expectCapabilitiesWithInterfaceName(iface2.name)
736 
737         removeInterface(iface1)
738         cb.assertNeverLost()
739         removeInterface(iface2)
740         cb.eventuallyExpectLost()
741     }
742 
743     @Test
744     fun testNetworkRequest_withInterfaceBeingReplaced() {
745         val iface1 = createInterface()
746 
747         val cb = requestNetwork(ETH_REQUEST)
748         val network = cb.expect<Available>().network
749 
750         // create another network and verify the request sticks to the current network
751         val iface2 = createInterface()
752         cb.assertNeverLost()
753 
754         // remove iface1 and verify the request brings up iface2
755         removeInterface(iface1)
756         cb.eventuallyExpectLost(network)
757         cb.expect<Available>()
758     }
759 
760     @Test
761     fun testNetworkRequest_withMultipleInterfacesAndRequests() {
762         val iface1 = createInterface()
763         val iface2 = createInterface()
764 
765         val cb1 = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface1.name))
766         val cb2 = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface2.name))
767         val cb3 = requestNetwork(ETH_REQUEST)
768 
769         cb1.expect<Available>()
770         cb1.expectCapabilitiesWithInterfaceName(iface1.name)
771         cb2.expect<Available>()
772         cb2.expectCapabilitiesWithInterfaceName(iface2.name)
773         // this request can be matched by either network.
774         cb3.expect<Available>()
775 
776         cb1.assertNeverLost()
777         cb2.assertNeverLost()
778         cb3.assertNeverLost()
779     }
780 
781     @Test
782     fun testNetworkRequest_ensureProperRefcounting() {
783         // create first request before interface is up / exists; create another request after it has
784         // been created; release one of them and check that the network stays up.
785         val listener = registerNetworkListener(ETH_REQUEST)
786         val cb1 = requestNetwork(ETH_REQUEST)
787 
788         val iface = createInterface()
789         val network = cb1.expect<Available>().network
790 
791         val cb2 = requestNetwork(ETH_REQUEST)
792         cb2.expect<Available>()
793 
794         // release the first request; this used to trigger b/197548738
795         releaseRequest(cb1)
796 
797         cb2.assertNeverLost()
798         releaseRequest(cb2)
799         listener.eventuallyExpectLost(network)
800     }
801 
802     @Test
803     fun testNetworkRequest_forInterfaceWhileTogglingCarrier() {
804         assumeCreateInterfaceWithoutCarrierSupported()
805         assumeChangingCarrierSupported()
806 
807         val iface = createInterface(false /* hasCarrier */)
808 
809         val cb = requestNetwork(ETH_REQUEST)
810         cb.assertNeverAvailable()
811 
812         iface.setCarrierEnabled(true)
813         cb.expect<Available>()
814 
815         iface.setCarrierEnabled(false)
816         cb.eventuallyExpectLost()
817     }
818 
819     // TODO: move to MTS
820     @Test
821     fun testNetworkRequest_linkPropertiesUpdate() {
822         val iface = createInterface()
823         val cb = requestNetwork(ETH_REQUEST)
824         // b/233534110: eventuallyExpect<LinkPropertiesChanged>() does not advance ReadHead
825         cb.eventuallyExpect(LinkPropertiesChanged::class) {
826             it is LinkPropertiesChanged && it.lp.addresses.any {
827                 address -> iface.onLinkPrefix.contains(address)
828             }
829         }
830     }
831 
832     @Test
833     fun testRemoveInterface_whileInServerMode() {
834         assumeNoInterfaceForTetheringAvailable()
835 
836         val listener = EthernetStateListener()
837         addInterfaceStateListener(listener)
838 
839         val iface = createInterface()
840         val ifaceName = requestTetheredInterface().expectOnAvailable()
841 
842         assertEquals(iface.name, ifaceName)
843         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_SERVER)
844 
845         removeInterface(iface)
846 
847         // Note: removeInterface already verifies that a STATE_ABSENT, ROLE_NONE callback is
848         // received, but it can't hurt to explicitly check for it.
849         listener.expectCallback(iface, STATE_ABSENT, ROLE_NONE)
850         releaseTetheredInterface()
851         listener.assertNoCallback()
852     }
853 
854     @Test
855     fun testEnableDisableInterface_withActiveRequest() {
856         val iface = createInterface()
857         val cb = requestNetwork(ETH_REQUEST)
858         cb.expect<Available>()
859         cb.assertNeverLost()
860 
861         disableInterface(iface).expectResult(iface.name)
862         cb.eventuallyExpectLost()
863 
864         enableInterface(iface).expectResult(iface.name)
865         cb.expect<Available>()
866     }
867 
868     @Test
869     fun testEnableDisableInterface_withoutStateChange() {
870         val iface = createInterface()
871         // Interface is already enabled, so enableInterface() should return success
872         enableInterface(iface).expectResult(iface.name)
873 
874         disableInterface(iface).expectResult(iface.name)
875         // Interface is already disabled, so disableInterface() should return success.
876         disableInterface(iface).expectResult(iface.name)
877     }
878 
879     @Test
880     fun testEnableDisableInterface_withMissingInterface() {
881         val iface = createInterface()
882         removeInterface(iface)
883         // Interface does not exist, enable/disableInterface() should both return an error.
884         enableInterface(iface).expectError()
885         disableInterface(iface).expectError()
886     }
887 
888     @Test
889     fun testEnableDisableInterface_callbacks() {
890         val iface = createInterface()
891         val listener = EthernetStateListener()
892         addInterfaceStateListener(listener)
893         // Uses eventuallyExpect to account for interfaces that could already exist on device
894         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_CLIENT)
895 
896         disableInterface(iface).expectResult(iface.name)
897         listener.eventuallyExpect(iface, STATE_LINK_DOWN, ROLE_CLIENT)
898 
899         enableInterface(iface).expectResult(iface.name)
900         listener.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
901 
902         disableInterface(iface).expectResult(iface.name)
903         listener.expectCallback(iface, STATE_LINK_DOWN, ROLE_CLIENT)
904     }
905 
906     @Test
907     fun testEnableDisableInterface_disableEnableEthernet() {
908         val iface = createInterface()
909         val listener = EthernetStateListener()
910         addInterfaceStateListener(listener)
911         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_CLIENT)
912 
913         // When ethernet is disabled, interface should be down and enable/disableInterface()
914         // should not bring the interfaces up.
915         setEthernetEnabled(false)
916         listener.eventuallyExpect(iface, STATE_LINK_DOWN, ROLE_CLIENT)
917         enableInterface(iface).expectError()
918         disableInterface(iface).expectError()
919         listener.assertNoCallback()
920 
921         // When ethernet is enabled, enable/disableInterface() should succeed.
922         setEthernetEnabled(true)
923         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_CLIENT)
924         disableInterface(iface).expectResult(iface.name)
925         listener.eventuallyExpect(iface, STATE_LINK_DOWN, ROLE_CLIENT)
926         enableInterface(iface).expectResult(iface.name)
927         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_CLIENT)
928     }
929 
930     @Test
931     fun testUpdateConfiguration_forBothIpConfigAndCapabilities() {
932         val iface = createInterface()
933         val cb = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface.name))
934         cb.expect<Available>()
935 
936         updateConfiguration(iface, STATIC_IP_CONFIGURATION, TEST_CAPS).expectResult(iface.name)
937         cb.eventuallyExpectCapabilities(TEST_CAPS)
938         cb.eventuallyExpectLpForStaticConfig(STATIC_IP_CONFIGURATION.staticIpConfiguration)
939     }
940 
941     @Test
942     fun testUpdateConfiguration_forOnlyIpConfig() {
943         val iface = createInterface()
944         val cb = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface.name))
945         cb.expect<Available>()
946 
947         updateConfiguration(iface, STATIC_IP_CONFIGURATION).expectResult(iface.name)
948         cb.eventuallyExpectLpForStaticConfig(STATIC_IP_CONFIGURATION.staticIpConfiguration)
949     }
950 
951     @Test
952     fun testUpdateConfiguration_forOnlyCapabilities() {
953         val iface = createInterface()
954         val cb = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface.name))
955         cb.expect<Available>()
956 
957         updateConfiguration(iface, capabilities = TEST_CAPS).expectResult(iface.name)
958         cb.eventuallyExpectCapabilities(TEST_CAPS)
959     }
960 
961     @Test
962     fun testUpdateConfiguration_forAllowedUids() {
963         // Configure a restricted network.
964         val iface = createInterface()
965         val request = NetworkRequest.Builder(ETH_REQUEST.copyWithEthernetSpecifier(iface.name))
966                 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED).build()
967         updateConfiguration(iface, capabilities = request.networkCapabilities)
968                 .expectResult(iface.name)
969 
970         // Request the restricted network as the shell with CONNECTIVITY_USE_RESTRICTED_NETWORKS.
971         val cb = runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS) { requestNetwork(request) }
972         val network = cb.expect<Available>().network
973         cb.assertNeverLost(network)
974 
975         // The network is restricted therefore binding to it when available will fail.
976         Socket().use { socket ->
977             assertThrows(IOException::class.java, { network.bindSocket(socket) })
978         }
979 
980         // Add the test process UID to the allowed UIDs for the network and ultimately bind again.
981         val allowedUids = setOf(Process.myUid())
982         val nc = NetworkCapabilities.Builder(request.networkCapabilities)
983                 .setAllowedUids(allowedUids).build()
984         updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
985 
986         // UpdateConfiguration() currently does a restart on the ethernet interface therefore lost
987         // will be expected first before available, as part of the restart.
988         cb.expect<Lost>(network)
989         val updatedNetwork = cb.expect<Available>().network
990         // With the test process UID allowed, binding to a restricted network should be successful.
991         Socket().use { socket -> updatedNetwork.bindSocket(socket) }
992 
993         // Reset capabilities to not-restricted, otherwise tearDown won't see the interface callback
994         // as ifaceListener does not have the restricted permission.
995         // TODO: Find a better way to do this when there are more tests around restricted
996         // interfaces.
997         updateConfiguration(iface, capabilities = TEST_CAPS).expectResult(iface.name)
998     }
999 
1000     // TODO: consider only having this test in MTS as it makes use of the fact that
1001     // setEthernetEnabled(false) untracks all interfaces. This behavior is an implementation detail
1002     // and may change in the future.
1003     @Test
1004     fun testUpdateConfiguration_onUntrackedInterface() {
1005         assumeFalse(isAdbOverEthernet())
1006         val iface = createInterface()
1007         setEthernetEnabled(false)
1008 
1009         // Updating the IpConfiguration and NetworkCapabilities on absent interfaces is a supported
1010         // use case.
1011         updateConfiguration(iface, STATIC_IP_CONFIGURATION, TEST_CAPS).expectResult(iface.name)
1012 
1013         setEthernetEnabled(true)
1014         val cb = requestNetwork(ETH_REQUEST)
1015         cb.expect<Available>()
1016         cb.eventuallyExpectCapabilities(TEST_CAPS)
1017         cb.eventuallyExpectLpForStaticConfig(STATIC_IP_CONFIGURATION.staticIpConfiguration)
1018     }
1019 
1020     @Test
1021     fun testUpdateConfiguration_withLinkDown() {
1022         assumeChangingCarrierSupported()
1023         // createInterface without carrier is racy, so create it and then remove carrier.
1024         val iface = createInterface()
1025         val cb = requestNetwork(ETH_REQUEST)
1026         cb.expect<Available>()
1027 
1028         iface.setCarrierEnabled(false)
1029         cb.eventuallyExpectLost()
1030 
1031         updateConfiguration(iface, STATIC_IP_CONFIGURATION, TEST_CAPS).expectResult(iface.name)
1032         cb.assertNoCallback()
1033 
1034         iface.setCarrierEnabled(true)
1035         cb.eventuallyExpectCapabilities(TEST_CAPS)
1036         cb.eventuallyExpectLpForStaticConfig(STATIC_IP_CONFIGURATION.staticIpConfiguration)
1037     }
1038 
1039     @Test
1040     fun testAddInterface_disableEnableEthernet() {
1041         val listener = EthernetStateListener()
1042         addInterfaceStateListener(listener)
1043 
1044         // When ethernet is disabled, newly added interfaces should not be brought up.
1045         setEthernetEnabled(false)
1046         val iface = createInterface(/* hasCarrier */ true)
1047         listener.eventuallyExpect(iface, STATE_LINK_DOWN, ROLE_CLIENT)
1048 
1049         // When ethernet is re-enabled after interface is added, it will be brought up.
1050         setEthernetEnabled(true)
1051         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_CLIENT)
1052     }
1053 
1054 
1055     @Test
1056     fun testRemoveInterface_disableEnableEthernet() {
1057         // Set up 2 interfaces for testing
1058         val iface1 = createInterface()
1059         val listener = EthernetStateListener()
1060         addInterfaceStateListener(listener)
1061         listener.eventuallyExpect(iface1, STATE_LINK_UP, ROLE_CLIENT)
1062         val iface2 = createInterface()
1063         listener.eventuallyExpect(iface2, STATE_LINK_UP, ROLE_CLIENT)
1064 
1065         // Removing interfaces when ethernet is enabled will first send link down, then
1066         // STATE_ABSENT/ROLE_NONE.
1067         removeInterface(iface1)
1068         listener.expectCallback(iface1, STATE_LINK_DOWN, ROLE_CLIENT)
1069         listener.expectCallback(iface1, STATE_ABSENT, ROLE_NONE)
1070 
1071         // Removing interfaces after ethernet is disabled will first send link down when ethernet is
1072         // disabled, then STATE_ABSENT/ROLE_NONE when interface is removed.
1073         setEthernetEnabled(false)
1074         listener.expectCallback(iface2, STATE_LINK_DOWN, ROLE_CLIENT)
1075         removeInterface(iface2)
1076         listener.expectCallback(iface2, STATE_ABSENT, ROLE_NONE)
1077     }
1078 
1079     @Test
1080     fun testSetTetheringInterfaceMode_disableEnableEthernet() {
1081         // do not run this test if an interface that can be used for tethering already exists.
1082         assumeNoInterfaceForTetheringAvailable()
1083 
1084         val listener = EthernetStateListener()
1085         addInterfaceStateListener(listener)
1086 
1087         val iface = createInterface()
1088         requestTetheredInterface().expectOnAvailable()
1089         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_SERVER)
1090 
1091         // (b/234743836): Currently the state of server mode interfaces always returns true due to
1092         // that interface state for server mode interfaces is not tracked properly.
1093         // So we do not get any state change when disabling ethernet.
1094         setEthernetEnabled(false)
1095         listener.assertNoCallback()
1096 
1097         // When ethernet is disabled, change interface mode will not bring the interface up.
1098         releaseTetheredInterface()
1099         listener.eventuallyExpect(iface, STATE_LINK_DOWN, ROLE_CLIENT)
1100 
1101         // When ethernet is re-enabled, interface will be brought up.
1102         setEthernetEnabled(true)
1103         listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_CLIENT)
1104     }
1105 
1106     @Test
1107     fun testGetInterfaceList_disableEnableEthernet() {
1108         // Test that interface list can be obtained when ethernet is disabled.
1109         setEthernetEnabled(false)
1110         // Create two test interfaces and check the return list contains the interface names.
1111         val iface1 = createInterface()
1112         val iface2 = createInterface()
1113         var ifaces = em.getInterfaceList()
1114         assertThat(ifaces).containsAtLeast(iface1.name, iface2.name)
1115 
1116         // Remove one existing test interface and check the return list doesn't contain the
1117         // removed interface name.
1118         removeInterface(iface1)
1119         ifaces = em.getInterfaceList()
1120         assertThat(ifaces).doesNotContain(iface1.name)
1121         assertThat(ifaces).contains(iface2.name)
1122 
1123         removeInterface(iface2)
1124     }
1125 }
1126