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