Merge "WifiMigrationTest: Add test for WifiMigration.loadFromSettings" into rvc-dev
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
index 51a4f32..fc4f2ea 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -81,9 +81,11 @@
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Executor;
@@ -1212,8 +1214,12 @@
         Thread.sleep(DURATION_SCREEN_TOGGLE);
     }
 
-    private void turnScreenOff() throws Exception {
+    private void turnScreenOffNoDelay() throws Exception {
         mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP");
+    }
+
+    private void turnScreenOff() throws Exception {
+        turnScreenOffNoDelay();
         // Since the screen on/off intent is ordered, they will not be sent right now.
         Thread.sleep(DURATION_SCREEN_TOGGLE);
     }
@@ -1799,6 +1805,59 @@
         mWifiManager.isPreferredNetworkOffloadSupported();
     }
 
+    /** Test that PNO scans reconnects us when the device is disconnected and the screen is off. */
+    public void testPnoScan() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        if (!mWifiManager.isPreferredNetworkOffloadSupported()) {
+            // skip the test if PNO scanning is not supported
+            return;
+        }
+
+        // make sure we're connected
+        waitForConnection();
+
+        WifiInfo currentNetwork = ShellIdentityUtils.invokeWithShellPermissions(
+                mWifiManager::getConnectionInfo);
+
+        // disable all networks that aren't already disabled
+        List<WifiConfiguration> savedNetworks = ShellIdentityUtils.invokeWithShellPermissions(
+                mWifiManager::getConfiguredNetworks);
+        Set<Integer> disabledNetworkIds = new HashSet<>();
+        for (WifiConfiguration config : savedNetworks) {
+            if (config.getNetworkSelectionStatus().getNetworkSelectionDisableReason()
+                    == WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE) {
+                ShellIdentityUtils.invokeWithShellPermissions(
+                        () -> mWifiManager.disableNetwork(config.networkId));
+                disabledNetworkIds.add(config.networkId);
+            }
+        }
+
+        try {
+            // wait for disconnection from current network
+            waitForDisconnection();
+
+            // turn screen off
+            turnScreenOffNoDelay();
+
+            // re-enable the current network - this will trigger PNO
+            ShellIdentityUtils.invokeWithShellPermissions(
+                    () -> mWifiManager.enableNetwork(currentNetwork.getNetworkId(), false));
+            disabledNetworkIds.remove(currentNetwork.getNetworkId());
+
+            // PNO should reconnect us back to the network we disconnected from
+            waitForConnection();
+        } finally {
+            // re-enable disabled networks
+            for (int disabledNetworkId : disabledNetworkIds) {
+                ShellIdentityUtils.invokeWithShellPermissions(
+                        () -> mWifiManager.enableNetwork(disabledNetworkId, false));
+            }
+        }
+    }
+
     /**
      * Tests {@link WifiManager#isTdlsSupported()} does not crash.
      */
diff --git a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
index 98dbe52..4d72eae 100644
--- a/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/cts/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -180,15 +180,15 @@
         }
     }
 
-    private class StartTetheringCallback extends TetheringManager.StartTetheringCallback {
+    private class StartTetheringCallback implements TetheringManager.StartTetheringCallback {
         @Override
         public void onTetheringStarted() {
             // Do nothing, TetherChangeReceiver will wait until it receives the broadcast.
         }
 
         @Override
-        public void onTetheringFailed(final int resultCode) {
-            fail("startTethering fail: " + resultCode);
+        public void onTetheringFailed(final int error) {
+            fail("startTethering fail: " + error);
         }
     }