From fa761d59174072b7bdf07a83ead15226d6509220 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Mon, 15 Jun 2020 12:19:58 +0900 Subject: [PATCH] Toggle wifi when running CaptivePortalTest Instead of reconnecting without disabling/re-enabling wifi in CaptivePortalTest, actually do the toggle during the test and on teardown to ensure that the BSSID blacklist is cleared. CaptivePortalTest intentionally makes the network not validate, which causes it to be added to the BSSID blacklist. Toggling wifi is necessary to make sure the test does not affect other tests. Also check development SDK instead of the exact SDK_INT number so that the test can pass on current AOSP builds. Bug: 158924461 Test: atest CtsNetTestCasesLatestSdk:CaptivePortalTest \ CtsNetTestCasesLatestSdk:ConnectivityManagerTest Change-Id: I31f9f4a9678e11042005c29535af840246358764 --- .../src/android/net/cts/CaptivePortalTest.kt | 15 ++-- .../android/net/cts/util/CtsNetUtils.java | 83 +++++++++++++++++-- 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt index 0816aba750..4a7d38a172 100644 --- a/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt +++ b/tests/cts/net/src/android/net/cts/CaptivePortalTest.kt @@ -41,6 +41,7 @@ import android.text.TextUtils import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import androidx.test.runner.AndroidJUnit4 import com.android.compatibility.common.util.SystemUtil +import com.android.testutils.isDevSdkInRange import fi.iki.elonen.NanoHTTPD import fi.iki.elonen.NanoHTTPD.Response.IStatus import fi.iki.elonen.NanoHTTPD.Response.Status @@ -105,6 +106,9 @@ class CaptivePortalTest { @After fun tearDown() { clearTestUrls() + if (pm.hasSystemFeature(FEATURE_WIFI)) { + reconnectWifi() + } server.stop() } @@ -167,7 +171,7 @@ class CaptivePortalTest { assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage) val startPortalAppPermission = - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) CONNECTIVITY_INTERNAL + if (isDevSdkInRange(0, Build.VERSION_CODES.Q)) CONNECTIVITY_INTERNAL else NETWORK_SETTINGS doAsShell(startPortalAppPermission) { cm.startCaptivePortalApp(network) } assertTrue(portalContentRequestCv.block(TEST_TIMEOUT_MS), "The captive portal login " + @@ -180,9 +184,6 @@ class CaptivePortalTest { // disconnectFromCell should be called after connectToCell utils.disconnectFromCell() } - - clearTestUrls() - reconnectWifi() } private fun setHttpsUrl(url: String?) = setConfig(TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING, url) @@ -203,10 +204,8 @@ class CaptivePortalTest { } private fun reconnectWifi() { - doAsShell(NETWORK_SETTINGS) { - assertTrue(wm.disconnect()) - assertTrue(wm.reconnect()) - } + utils.ensureWifiDisconnected(null /* wifiNetworkToCheck */) + utils.ensureWifiConnected() } /** diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java index b1f3602950..85d2113d89 100644 --- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java +++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java @@ -157,8 +157,36 @@ public final class CtsNetUtils { } } - /** Enable WiFi and wait for it to become connected to a network. */ + /** + * Enable WiFi and wait for it to become connected to a network. + * + * This method expects to receive a legacy broadcast on connect, which may not be sent if the + * network does not become default or if it is not the first network. + */ public Network connectToWifi() { + return connectToWifi(true /* expectLegacyBroadcast */); + } + + /** + * Enable WiFi and wait for it to become connected to a network. + * + * A network is considered connected when a {@link NetworkCallback#onAvailable(Network)} + * callback is received. + */ + public Network ensureWifiConnected() { + return connectToWifi(false /* expectLegacyBroadcast */); + } + + /** + * Enable WiFi and wait for it to become connected to a network. + * + * @param expectLegacyBroadcast Whether to check for a legacy CONNECTIVITY_ACTION connected + * broadcast. The broadcast is typically not sent if the network + * does not become the default network, and is not the first + * network to appear. + * @return The network that was newly connected. + */ + private Network connectToWifi(boolean expectLegacyBroadcast) { final TestNetworkCallback callback = new TestNetworkCallback(); mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); Network wifiNetwork = null; @@ -170,15 +198,16 @@ public final class CtsNetUtils { mContext.registerReceiver(receiver, filter); boolean connected = false; + final String err = "Wifi must be configured to connect to an access point for this test."; try { clearWifiBlacklist(); SystemUtil.runShellCommand("svc wifi enable"); SystemUtil.runWithShellPermissionIdentity(() -> mWifiManager.reconnect(), NETWORK_SETTINGS); - // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION. + // Ensure we get an onAvailable callback and possibly a CONNECTIVITY_ACTION. wifiNetwork = callback.waitForAvailable(); - assertNotNull(wifiNetwork); - connected = receiver.waitForState(); + assertNotNull(err, wifiNetwork); + connected = !expectLegacyBroadcast || receiver.waitForState(); } catch (InterruptedException ex) { fail("connectToWifi was interrupted"); } finally { @@ -186,8 +215,7 @@ public final class CtsNetUtils { mContext.unregisterReceiver(receiver); } - assertTrue("Wifi must be configured to connect to an access point for this test.", - connected); + assertTrue(err, connected); return wifiNetwork; } @@ -204,8 +232,47 @@ public final class CtsNetUtils { }); } - /** Disable WiFi and wait for it to become disconnected from the network. */ + /** + * Disable WiFi and wait for it to become disconnected from the network. + * + * This method expects to receive a legacy broadcast on disconnect, which may not be sent if the + * network was not default, or was not the first network. + * + * @param wifiNetworkToCheck If non-null, a network that should be disconnected. This network + * is expected to be able to establish a TCP connection to a remote + * server before disconnecting, and to have that connection closed in + * the process. + */ public void disconnectFromWifi(Network wifiNetworkToCheck) { + disconnectFromWifi(wifiNetworkToCheck, true /* expectLegacyBroadcast */); + } + + /** + * Disable WiFi and wait for it to become disconnected from the network. + * + * @param wifiNetworkToCheck If non-null, a network that should be disconnected. This network + * is expected to be able to establish a TCP connection to a remote + * server before disconnecting, and to have that connection closed in + * the process. + */ + public void ensureWifiDisconnected(Network wifiNetworkToCheck) { + disconnectFromWifi(wifiNetworkToCheck, false /* expectLegacyBroadcast */); + } + + /** + * Disable WiFi and wait for it to become disconnected from the network. + * + * @param wifiNetworkToCheck If non-null, a network that should be disconnected. This network + * is expected to be able to establish a TCP connection to a remote + * server before disconnecting, and to have that connection closed in + * the process. + * @param expectLegacyBroadcast Whether to check for a legacy CONNECTIVITY_ACTION disconnected + * broadcast. The broadcast is typically not sent if the network + * was not the default network and not the first network to appear. + * The check will always be skipped if the device was not connected + * to wifi in the first place. + */ + private void disconnectFromWifi(Network wifiNetworkToCheck, boolean expectLegacyBroadcast) { final TestNetworkCallback callback = new TestNetworkCallback(); mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback); @@ -238,6 +305,8 @@ public final class CtsNetUtils { // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION. assertNotNull("Did not receive onLost callback after disabling wifi", callback.waitForLost()); + } + if (wasWifiConnected && expectLegacyBroadcast) { assertTrue("Wifi failed to reach DISCONNECTED state.", receiver.waitForState()); } } catch (InterruptedException ex) {