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