Merge "Force the app idle state again after whitelisting it." into rvc-dev
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index 112799b..7eaf133 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -83,7 +83,7 @@
min_sdk_version: "29",
target_sdk_version: "30",
test_suites: [
- "device-tests",
+ "general-tests",
"mts",
],
test_config_template: "AndroidTestTemplate.xml",
diff --git a/tests/cts/net/AndroidTestTemplate.xml b/tests/cts/net/AndroidTestTemplate.xml
index 1f75da1..4e93751 100644
--- a/tests/cts/net/AndroidTestTemplate.xml
+++ b/tests/cts/net/AndroidTestTemplate.xml
@@ -19,6 +19,8 @@
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+
+ <option name="config-descriptor:metadata" key="mainline-param" value="CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk" />
<option name="not-shardable" value="true" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/cts/net/TEST_MAPPING b/tests/cts/net/TEST_MAPPING
index e2a9c75..3162e22 100644
--- a/tests/cts/net/TEST_MAPPING
+++ b/tests/cts/net/TEST_MAPPING
@@ -9,5 +9,15 @@
}
]
}
+ ],
+ "mainline-presubmit": [
+ {
+ "name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk]",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.SkipPresubmit"
+ }
+ ]
+ }
]
}
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 85d2113..f1bc130 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
@@ -21,6 +21,9 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
+import static android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION;
+
+import static com.android.compatibility.common.util.ShellIdentityUtils.invokeWithShellPermissions;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -44,6 +47,7 @@
import android.net.NetworkInfo.State;
import android.net.NetworkRequest;
import android.net.TestNetworkManager;
+import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -58,13 +62,21 @@
import com.android.compatibility.common.util.SystemUtil;
+import junit.framework.AssertionFailedError;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
public final class CtsNetUtils {
private static final String TAG = CtsNetUtils.class.getSimpleName();
@@ -72,7 +84,8 @@
private static final int SOCKET_TIMEOUT_MS = 2000;
private static final int PRIVATE_DNS_PROBE_MS = 1_000;
- public static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 6_000;
+ private static final int PRIVATE_DNS_SETTING_TIMEOUT_MS = 6_000;
+ private static final int CONNECTIVITY_CHANGE_TIMEOUT_SECS = 30;
public static final int HTTP_PORT = 80;
public static final String TEST_HOST = "connectivitycheck.gstatic.com";
public static final String HTTP_REQUEST =
@@ -170,8 +183,8 @@
/**
* 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.
+ * A network is considered connected when a {@link NetworkRequest} with TRANSPORT_WIFI
+ * receives a {@link NetworkCallback#onAvailable(Network)} callback.
*/
public Network ensureWifiConnected() {
return connectToWifi(false /* expectLegacyBroadcast */);
@@ -202,8 +215,18 @@
try {
clearWifiBlacklist();
SystemUtil.runShellCommand("svc wifi enable");
- SystemUtil.runWithShellPermissionIdentity(() -> mWifiManager.reconnect(),
- NETWORK_SETTINGS);
+ final WifiConfiguration config = maybeAddVirtualWifiConfiguration();
+ if (config == null) {
+ // TODO: this may not clear the BSSID blacklist, as opposed to
+ // mWifiManager.connect(config)
+ SystemUtil.runWithShellPermissionIdentity(() -> mWifiManager.reconnect(),
+ NETWORK_SETTINGS);
+ } else {
+ // When running CTS, devices are expected to have wifi networks pre-configured.
+ // This condition is only hit on virtual devices.
+ SystemUtil.runWithShellPermissionIdentity(
+ () -> mWifiManager.connect(config, null /* listener */), NETWORK_SETTINGS);
+ }
// Ensure we get an onAvailable callback and possibly a CONNECTIVITY_ACTION.
wifiNetwork = callback.waitForAvailable();
assertNotNull(err, wifiNetwork);
@@ -219,6 +242,68 @@
return wifiNetwork;
}
+ private WifiConfiguration maybeAddVirtualWifiConfiguration() {
+ final List<WifiConfiguration> configs = invokeWithShellPermissions(
+ mWifiManager::getConfiguredNetworks);
+ // If no network is configured, add a config for virtual access points if applicable
+ if (configs.size() == 0) {
+ final List<ScanResult> scanResults = getWifiScanResults();
+ final WifiConfiguration virtualConfig = maybeConfigureVirtualNetwork(scanResults);
+ assertNotNull("The device has no configured wifi network", virtualConfig);
+
+ return virtualConfig;
+ }
+ // No need to add a configuration: there is already one
+ return null;
+ }
+
+ private List<ScanResult> getWifiScanResults() {
+ final CompletableFuture<List<ScanResult>> scanResultsFuture = new CompletableFuture<>();
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ final BroadcastReceiver receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ scanResultsFuture.complete(mWifiManager.getScanResults());
+ }
+ };
+ mContext.registerReceiver(receiver, new IntentFilter(SCAN_RESULTS_AVAILABLE_ACTION));
+ mWifiManager.startScan();
+ });
+
+ try {
+ return scanResultsFuture.get(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS);
+ } catch (ExecutionException | InterruptedException | TimeoutException e) {
+ throw new AssertionFailedError("Wifi scan results not received within timeout");
+ }
+ }
+
+ /**
+ * If a virtual wifi network is detected, add a configuration for that network.
+ * TODO(b/158150376): have the test infrastructure add virtual wifi networks when appropriate.
+ */
+ private WifiConfiguration maybeConfigureVirtualNetwork(List<ScanResult> scanResults) {
+ // Virtual wifi networks used on the emulator and cloud testing infrastructure
+ final List<String> virtualSsids = Arrays.asList("VirtWifi", "AndroidWifi");
+ Log.d(TAG, "Wifi scan results: " + scanResults);
+ final ScanResult virtualScanResult = scanResults.stream().filter(
+ s -> virtualSsids.contains(s.SSID)).findFirst().orElse(null);
+
+ // Only add the virtual configuration if the virtual AP is detected in scans
+ if (virtualScanResult == null) return null;
+
+ final WifiConfiguration virtualConfig = new WifiConfiguration();
+ // ASCII SSIDs need to be surrounded by double quotes
+ virtualConfig.SSID = "\"" + virtualScanResult.SSID + "\"";
+ virtualConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+
+ SystemUtil.runWithShellPermissionIdentity(() -> {
+ final int networkId = mWifiManager.addNetwork(virtualConfig);
+ assertTrue(networkId >= 0);
+ assertTrue(mWifiManager.enableNetwork(networkId, false /* attemptConnect */));
+ });
+ return virtualConfig;
+ }
+
/**
* Re-enable wifi networks that were blacklisted, typically because no internet connection was
* detected the last time they were connected. This is necessary to make sure wifi can reconnect
@@ -226,8 +311,8 @@
*/
private void clearWifiBlacklist() {
SystemUtil.runWithShellPermissionIdentity(() -> {
- for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) {
- mWifiManager.enableNetwork(config.networkId, false /* attemptConnect */);
+ for (WifiConfiguration cfg : mWifiManager.getConfiguredNetworks()) {
+ assertTrue(mWifiManager.enableNetwork(cfg.networkId, false /* attemptConnect */));
}
});
}
@@ -533,7 +618,7 @@
}
public boolean waitForState() throws InterruptedException {
- return mReceiveLatch.await(30, TimeUnit.SECONDS);
+ return mReceiveLatch.await(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS);
}
}
@@ -550,11 +635,13 @@
public Network lastLostNetwork;
public Network waitForAvailable() throws InterruptedException {
- return mAvailableLatch.await(30, TimeUnit.SECONDS) ? currentNetwork : null;
+ return mAvailableLatch.await(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS)
+ ? currentNetwork : null;
}
public Network waitForLost() throws InterruptedException {
- return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null;
+ return mLostLatch.await(CONNECTIVITY_CHANGE_TIMEOUT_SECS, TimeUnit.SECONDS)
+ ? lastLostNetwork : null;
}
public boolean waitForUnavailable() throws InterruptedException {