Merge "Auto-configure wifi on virtual devices" into rvc-dev
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
index aa59959..eedccb6 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
@@ -29,6 +29,7 @@
 
 import android.net.Network;
 import android.net.NetworkCapabilities;
+import android.util.Log;
 
 import org.junit.After;
 import org.junit.Before;
@@ -141,15 +142,16 @@
         }
 
         public void expectBlockedStatusCallback(Network expectedNetwork, boolean expectBlocked) {
-            expectCallback(CallbackState.BLOCKED_STATUS, expectedNetwork,
-                    expectBlocked);
+            expectCallback(CallbackState.BLOCKED_STATUS, expectedNetwork, expectBlocked);
         }
 
-        public void waitBlockedStatusCallback(Network expectedNetwork, boolean expectBlocked) {
+        public void expectBlockedStatusCallbackEventually(Network expectedNetwork,
+                boolean expectBlocked) {
             final long deadline = System.currentTimeMillis() + TEST_CALLBACK_TIMEOUT_MS;
             do {
                 final CallbackInfo cb = nextCallback((int) (deadline - System.currentTimeMillis()));
-                if (cb.state == CallbackState.BLOCKED_STATUS) {
+                if (cb.state == CallbackState.BLOCKED_STATUS
+                        && cb.network.equals(expectedNetwork)) {
                     assertEquals(expectBlocked, cb.arg);
                     return;
                 }
@@ -157,17 +159,23 @@
             fail("Didn't receive onBlockedStatusChanged()");
         }
 
-        public void expectCapabilitiesCallback(Network expectedNetwork, boolean hasCapability,
-                int capability) {
-            final CallbackInfo cb = nextCallback(TEST_CALLBACK_TIMEOUT_MS);
-            final NetworkCapabilities cap = (NetworkCapabilities) cb.arg;
-            assertEquals(expectedNetwork, cb.network);
-            assertEquals(CallbackState.CAPABILITIES, cb.state);
-            if (hasCapability != cap.hasCapability(capability)) {
-                fail("NetworkCapabilities callback "
-                        + (hasCapability ? "missing expected" : "has unexpected")
-                        + " capability. " + cb);
-            }
+        public void expectCapabilitiesCallbackEventually(Network expectedNetwork, boolean hasCap,
+                int cap) {
+            final long deadline = System.currentTimeMillis() + TEST_CALLBACK_TIMEOUT_MS;
+            do {
+                final CallbackInfo cb = nextCallback((int) (deadline - System.currentTimeMillis()));
+                if (cb.state != CallbackState.CAPABILITIES
+                        || !expectedNetwork.equals(cb.network)
+                        || (hasCap != ((NetworkCapabilities) cb.arg).hasCapability(cap))) {
+                    Log.i("NetworkCallbackTest#expectCapabilitiesCallback",
+                            "Ignoring non-matching callback : " + cb);
+                    continue;
+                }
+                // Found a match, return
+                return;
+            } while (System.currentTimeMillis() <= deadline);
+            fail("Didn't receive the expected callback to onCapabilitiesChanged(). Check the "
+                    + "log for a list of received callbacks, if any.");
         }
     }
 
@@ -194,8 +202,8 @@
         // callback to ensure wifi is connected before the test and store the default network.
         mNetwork = mTestNetworkCallback.expectAvailableCallbackAndGetNetwork();
         // Check that the network is metered.
-        mTestNetworkCallback.expectCapabilitiesCallback(mNetwork, false /* hasCapability */,
-                NET_CAPABILITY_NOT_METERED);
+        mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
+                false /* hasCapability */, NET_CAPABILITY_NOT_METERED);
         mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false);
     }
 
@@ -215,28 +223,28 @@
             // Enable restrict background
             setRestrictBackground(true);
             assertBackgroundNetworkAccess(false);
-            mTestNetworkCallback.waitBlockedStatusCallback(mNetwork, true);
+            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
 
             // Add to whitelist
             addRestrictBackgroundWhitelist(mUid);
             assertBackgroundNetworkAccess(true);
-            mTestNetworkCallback.waitBlockedStatusCallback(mNetwork, false);
+            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
 
             // Remove from whitelist
             removeRestrictBackgroundWhitelist(mUid);
             assertBackgroundNetworkAccess(false);
-            mTestNetworkCallback.waitBlockedStatusCallback(mNetwork, true);
+            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
         } finally {
             mMeterednessConfiguration.resetNetworkMeteredness();
         }
 
         // Set to non-metered network
         mMeterednessConfiguration.configureNetworkMeteredness(false);
-        mTestNetworkCallback.expectCapabilitiesCallback(mNetwork, true /* hasCapability */,
-                NET_CAPABILITY_NOT_METERED);
+        mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
+                true /* hasCapability */, NET_CAPABILITY_NOT_METERED);
         try {
             assertBackgroundNetworkAccess(true);
-            mTestNetworkCallback.waitBlockedStatusCallback(mNetwork, false);
+            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
 
             // Disable restrict background, should not trigger callback
             setRestrictBackground(false);
@@ -253,30 +261,30 @@
             // Enable Power Saver
             setBatterySaverMode(true);
             assertBackgroundNetworkAccess(false);
-            mTestNetworkCallback.waitBlockedStatusCallback(mNetwork, true);
+            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
 
             // Disable Power Saver
             setBatterySaverMode(false);
             assertBackgroundNetworkAccess(true);
-            mTestNetworkCallback.waitBlockedStatusCallback(mNetwork, false);
+            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
         } finally {
             mMeterednessConfiguration.resetNetworkMeteredness();
         }
 
         // Set to non-metered network
         mMeterednessConfiguration.configureNetworkMeteredness(false);
-        mTestNetworkCallback.expectCapabilitiesCallback(mNetwork, true /* hasCapability */,
-                NET_CAPABILITY_NOT_METERED);
+        mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
+                true /* hasCapability */, NET_CAPABILITY_NOT_METERED);
         try {
             // Enable Power Saver
             setBatterySaverMode(true);
             assertBackgroundNetworkAccess(false);
-            mTestNetworkCallback.waitBlockedStatusCallback(mNetwork, true);
+            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
 
             // Disable Power Saver
             setBatterySaverMode(false);
             assertBackgroundNetworkAccess(true);
-            mTestNetworkCallback.waitBlockedStatusCallback(mNetwork, false);
+            mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, false);
         } finally {
             mMeterednessConfiguration.resetNetworkMeteredness();
         }
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
index 26397ef..a451ea8 100755
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -1016,7 +1016,8 @@
         final Thread[] threads = new Thread[NUM_THREADS];
         startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
                  new String[] {"0.0.0.0/0", "::/0"},
-                 "", "", null, null /* underlyingNetworks */, false /* isAlwaysMetered */);
+                 "" /* allowedApplications */, "com.android.shell" /* disallowedApplications */,
+                null /* proxyInfo */, null /* underlyingNetworks */, false /* isAlwaysMetered */);
 
         for (int i = 0; i < NUM_THREADS; i++) {
             threads[i] = new Thread(() -> {
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/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 2824db7..c8e1fc3 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -495,8 +495,8 @@
                 .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
                 .setNetworkSpecifier(StringNetworkSpecifier(name2))
                 .build()
-        val callback1 = TestableNetworkCallback()
-        val callback2 = TestableNetworkCallback()
+        val callback1 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
+        val callback2 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
         requestNetwork(request1, callback1)
         requestNetwork(request2, callback2)
 
@@ -505,7 +505,7 @@
                 .clearCapabilities()
                 .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
                 .build()
-        val callback = TestableNetworkCallback()
+        val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
         requestNetwork(request, callback)
 
         // Connect the first Network
@@ -602,7 +602,7 @@
                 .clearCapabilities()
                 .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
                 .build()
-        val callback1 = TestableNetworkCallback(DEFAULT_TIMEOUT_MS).also {
+        val callback1 = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS).also {
             registerNetworkCallback(request1, it)
         }
         requestNetwork(request1, callback1)
@@ -612,7 +612,7 @@
                 .clearCapabilities()
                 .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
                 .build()
-        val callback = TestableNetworkCallback()
+        val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
         requestNetwork(request, callback)
 
         // Connect the network
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 5e2f627..f47f454 100644
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -697,6 +697,7 @@
 
     @Test
     public void testRequestLatestEntitlementResult() throws Exception {
+        assumeTrue(mTM.isTetheringSupported());
         // Verify that requestLatestTetheringEntitlementResult() can get entitlement
         // result(TETHER_ERROR_ENTITLEMENT_UNKNOWN due to invalid downstream type) via listener.
         assertEntitlementResult(listener -> mTM.requestLatestTetheringEntitlementResult(
@@ -715,6 +716,9 @@
                 }, false),
                 TETHER_ERROR_ENTITLEMENT_UNKNOWN);
 
+        // Do not request TETHERING_WIFI entitlement result if TETHERING_WIFI is not available.
+        assumeTrue(mTM.getTetherableWifiRegexs().length > 0);
+
         // Verify that null listener will cause IllegalArgumentException.
         try {
             mTM.requestLatestTetheringEntitlementResult(