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