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 4a8edee..c62d3cb 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -87,6 +87,7 @@
     private NetworkInfo mNetworkInfo;
     private Object mLock = new Object();
     private UiDevice mUiDevice;
+    private boolean mWasVerboseLoggingEnabled;
 
     // Please refer to WifiManager
     private static final int MIN_RSSI = -100;
@@ -187,6 +188,13 @@
         mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
         mConnectivityManager = getContext().getSystemService(ConnectivityManager.class);
         assertNotNull(mWifiManager);
+
+        // turn on verbose logging for tests
+        mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.isVerboseLoggingEnabled());
+        ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.setVerboseLoggingEnabled(true));
+
         mWifiLock = mWifiManager.createWifiLock(TAG);
         mWifiLock.acquire();
         if (!mWifiManager.isWifiEnabled())
@@ -215,6 +223,8 @@
             setWifiEnabled(true);
         mWifiLock.release();
         mContext.unregisterReceiver(mReceiver);
+        ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
         Thread.sleep(DURATION);
         super.tearDown();
     }
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
new file mode 100644
index 0000000..96cf45f
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
@@ -0,0 +1,509 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.cts;
+
+import static android.net.NetworkCapabilitiesProto.TRANSPORT_WIFI;
+import static android.os.Process.myUid;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.UiAutomation;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
+import android.net.MacAddress;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
+import android.net.wifi.WifiNetworkSpecifier;
+import android.os.PatternMatcher;
+import android.os.WorkSource;
+import android.platform.test.annotations.AppModeFull;
+import android.support.test.uiautomator.UiDevice;
+import android.test.AndroidTestCase;
+import android.text.TextUtils;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.PollingCheck;
+import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.compatibility.common.util.SystemUtil;
+
+import java.util.List;
+import java.util.concurrent.Executors;
+
+/**
+ * Tests the entire connection flow using {@link WifiNetworkSpecifier} embedded in a
+ * {@link NetworkRequest} & passed into {@link ConnectivityManager#requestNetwork(NetworkRequest,
+ * ConnectivityManager.NetworkCallback)}.
+ *
+ * Assumes that all the saved networks is either open/WPA1/WPA2/WPA3 authenticated network.
+ * TODO(b/150716005): Use assumeTrue for wifi support check.
+ */
+@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
+public class WifiNetworkSpecifierTest extends AndroidTestCase {
+    private static final String TAG = "WifiNetworkSpecifierTest";
+
+    private WifiManager mWifiManager;
+    private ConnectivityManager mConnectivityManager;
+    private UiDevice mUiDevice;
+    private final Object mLock = new Object();
+    private final Object mUiLock = new Object();
+    private WifiConfiguration mTestNetwork;
+    private boolean mWasVerboseLoggingEnabled;
+
+    private static final int DURATION = 10_000;
+    private static final int DURATION_UI_INTERACTION = 15_000;
+    private static final int DURATION_NETWORK_CONNECTION = 30_000;
+    private static final int DURATION_SCREEN_TOGGLE = 2000;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+        mConnectivityManager = getContext().getSystemService(ConnectivityManager.class);
+        assertNotNull(mWifiManager);
+
+        // turn on verbose logging for tests
+        mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.isVerboseLoggingEnabled());
+        ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.setVerboseLoggingEnabled(true));
+
+        if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true);
+        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        turnScreenOn();
+        PollingCheck.check("Wifi not enabled", DURATION, () -> mWifiManager.isWifiEnabled());
+
+        List<WifiConfiguration> savedNetworks = ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.getPrivilegedConfiguredNetworks());
+        assertFalse("Need at least one saved network", savedNetworks.isEmpty());
+        // Pick any one of the saved networks on the device (assumes that it is in range)
+        mTestNetwork = savedNetworks.get(0);
+        // Disconnect & disable auto-join on the saved network to prevent auto-connect from
+        // interfering with the test.
+        ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.disableNetwork(mTestNetwork.networkId));
+        // wait for Wifi to be disconnected
+        PollingCheck.check(
+                "Wifi not disconnected",
+                20000,
+                () -> mWifiManager.getConnectionInfo().getNetworkId() == -1);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            super.tearDown();
+            return;
+        }
+        if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true);
+        turnScreenOff();
+        ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.enableNetwork(mTestNetwork.networkId, false));
+        ShellIdentityUtils.invokeWithShellPermissions(
+                () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
+        super.tearDown();
+    }
+
+    private void setWifiEnabled(boolean enable) throws Exception {
+        // now trigger the change using shell commands.
+        SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable"));
+    }
+
+    private void turnScreenOn() throws Exception {
+        mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
+        mUiDevice.executeShellCommand("wm dismiss-keyguard");
+        // Since the screen on/off intent is ordered, they will not be sent right now.
+        Thread.sleep(DURATION_SCREEN_TOGGLE);
+    }
+
+    private void turnScreenOff() throws Exception {
+        mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP");
+        // Since the screen on/off intent is ordered, they will not be sent right now.
+        Thread.sleep(DURATION_SCREEN_TOGGLE);
+    }
+
+    private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
+        private final Object mLock;
+        public boolean onAvailableCalled = false;
+        public boolean onUnavailableCalled = false;
+        public NetworkCapabilities networkCapabilities;
+
+        TestNetworkCallback(Object lock) {
+            mLock = lock;
+        }
+
+        @Override
+        public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
+                LinkProperties linkProperties, boolean blocked) {
+            synchronized (mLock) {
+                onAvailableCalled = true;
+                this.networkCapabilities = networkCapabilities;
+                mLock.notify();
+            }
+        }
+
+        @Override
+        public void onUnavailable() {
+            synchronized (mLock) {
+                onUnavailableCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    private static class TestNetworkRequestMatchCallback implements NetworkRequestMatchCallback {
+        private final Object mLock;
+
+        public boolean onRegistrationCalled = false;
+        public boolean onAbortCalled = false;
+        public boolean onMatchCalled = false;
+        public boolean onConnectSuccessCalled = false;
+        public boolean onConnectFailureCalled = false;
+        public WifiManager.NetworkRequestUserSelectionCallback userSelectionCallback = null;
+        public List<ScanResult> matchedScanResults = null;
+
+        TestNetworkRequestMatchCallback(Object lock) {
+            mLock = lock;
+        }
+
+        @Override
+        public void onUserSelectionCallbackRegistration(
+                WifiManager.NetworkRequestUserSelectionCallback userSelectionCallback) {
+            synchronized (mLock) {
+                onRegistrationCalled = true;
+                this.userSelectionCallback = userSelectionCallback;
+                mLock.notify();
+            }
+        }
+
+        @Override
+        public void onAbort() {
+            synchronized (mLock) {
+                onAbortCalled = true;
+                mLock.notify();
+            }
+        }
+
+        @Override
+        public void onMatch(List<ScanResult> scanResults) {
+            synchronized (mLock) {
+                // This can be invoked multiple times. So, ignore after the first one to avoid
+                // disturbing the rest of the test sequence.
+                if (onMatchCalled) return;
+                onMatchCalled = true;
+                matchedScanResults = scanResults;
+                mLock.notify();
+            }
+        }
+
+        @Override
+        public void onUserSelectionConnectSuccess(WifiConfiguration config) {
+            synchronized (mLock) {
+                onConnectSuccessCalled = true;
+                mLock.notify();
+            }
+        }
+
+        @Override
+        public void onUserSelectionConnectFailure(WifiConfiguration config) {
+            synchronized (mLock) {
+                onConnectFailureCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    private void handleUiInteractions(boolean shouldUserReject) {
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        TestNetworkRequestMatchCallback networkRequestMatchCallback =
+                new TestNetworkRequestMatchCallback(mUiLock);
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+
+            // 1. Wait for registration callback.
+            synchronized (mUiLock) {
+                try {
+                    mWifiManager.registerNetworkRequestMatchCallback(
+                            Executors.newSingleThreadExecutor(), networkRequestMatchCallback);
+                    // now wait for the registration callback first.
+                    mUiLock.wait(DURATION_UI_INTERACTION);
+                } catch (InterruptedException e) {
+                }
+            }
+            assertTrue(networkRequestMatchCallback.onRegistrationCalled);
+            assertNotNull(networkRequestMatchCallback.userSelectionCallback);
+
+            // 2. Wait for matching scan results
+            synchronized (mUiLock) {
+                try {
+                    // now wait for the registration callback first.
+                    mUiLock.wait(DURATION_UI_INTERACTION);
+                } catch (InterruptedException e) {
+                }
+            }
+            assertTrue(networkRequestMatchCallback.onMatchCalled);
+            assertNotNull(networkRequestMatchCallback.matchedScanResults);
+            assertThat(networkRequestMatchCallback.matchedScanResults.size()).isAtLeast(1);
+
+            // 3. Trigger connection to one of the matched networks or reject the request.
+            if (shouldUserReject) {
+                networkRequestMatchCallback.userSelectionCallback.reject();
+            } else {
+                networkRequestMatchCallback.userSelectionCallback.select(mTestNetwork);
+            }
+
+            // 4. Wait for connection success or abort.
+            synchronized (mUiLock) {
+                try {
+                    // now wait for the registration callback first.
+                    mUiLock.wait(DURATION_UI_INTERACTION);
+                } catch (InterruptedException e) {
+                }
+            }
+            if (shouldUserReject) {
+                assertTrue(networkRequestMatchCallback.onAbortCalled);
+            } else {
+                assertTrue(networkRequestMatchCallback.onConnectSuccessCalled);
+            }
+        } finally {
+            mWifiManager.unregisterNetworkRequestMatchCallback(networkRequestMatchCallback);
+            uiAutomation.dropShellPermissionIdentity();
+        }
+    }
+
+    /**
+     * Tests the entire connection flow using the provided specifier.
+     *
+     * @param specifier Specifier to use for network request.
+     * @param shouldUserReject Whether to simulate user rejection or not.
+     */
+    private void testConnectionFlowWithSpecifier(
+            WifiNetworkSpecifier specifier, boolean shouldUserReject) {
+        // Fork a thread to handle the UI interactions.
+        Thread uiThread = new Thread(() -> handleUiInteractions(shouldUserReject));
+
+        // File the network request & wait for the callback.
+        TestNetworkCallback networkCallbackListener = new TestNetworkCallback(mLock);
+        synchronized (mLock) {
+            try {
+                // File a request for wifi network.
+                mConnectivityManager.requestNetwork(
+                        new NetworkRequest.Builder()
+                                .addTransportType(TRANSPORT_WIFI)
+                                .setNetworkSpecifier(specifier)
+                                .build(),
+                        networkCallbackListener);
+                // Wait for the request to reach the wifi stack before kick-starting the UI
+                // interactions.
+                Thread.sleep(100);
+                // Start the UI interactions.
+                uiThread.run();
+                // now wait for callback
+                mLock.wait(DURATION_NETWORK_CONNECTION);
+            } catch (InterruptedException e) {
+            }
+        }
+        if (shouldUserReject) {
+            assertTrue(networkCallbackListener.onUnavailableCalled);
+        } else {
+            assertTrue(networkCallbackListener.onAvailableCalled);
+        }
+
+        try {
+            // Ensure that the UI interaction thread has completed.
+            uiThread.join(DURATION_UI_INTERACTION);
+        } catch (InterruptedException e) {
+            fail("UI interaction interrupted");
+        }
+
+        // Release the request after the test.
+        mConnectivityManager.unregisterNetworkCallback(networkCallbackListener);
+    }
+
+    private void testSuccessfulConnectionWithSpecifier(WifiNetworkSpecifier specifier) {
+        testConnectionFlowWithSpecifier(specifier, false);
+    }
+
+    private void testUserRejectionWithSpecifier(WifiNetworkSpecifier specifier) {
+        testConnectionFlowWithSpecifier(specifier, true);
+    }
+
+    private WifiNetworkSpecifier.Builder createSpecifierBuilderWithCredentialFromSavedNetwork() {
+        WifiNetworkSpecifier.Builder specifierBuilder = new WifiNetworkSpecifier.Builder();
+        if (mTestNetwork.preSharedKey != null) {
+            if (mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
+                specifierBuilder.setWpa2Passphrase(mTestNetwork.preSharedKey);
+            } else if (mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
+                specifierBuilder.setWpa3Passphrase(mTestNetwork.preSharedKey);
+            } else {
+                fail("Unsupported security type found in saved networks");
+            }
+        } else if (!mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.OWE)) {
+            specifierBuilder.setIsEnhancedOpen(false);
+        } else if (!mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) {
+            fail("Unsupported security type found in saved networks");
+        }
+        specifierBuilder.setIsHiddenSsid(mTestNetwork.hiddenSSID);
+        return specifierBuilder;
+    }
+
+    /**
+     * Tests the entire connection flow using a specific SSID in the specifier.
+     */
+    public void testConnectionWithSpecificSsid() {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork()
+                .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+                .build();
+        testSuccessfulConnectionWithSpecifier(specifier);
+    }
+
+    /**
+     * Tests the entire connection flow using a SSID pattern in the specifier.
+     */
+    public void testConnectionWithSsidPattern() {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        // Creates a ssid pattern by dropping the last char in the saved network & pass that
+        // as a prefix match pattern in the request.
+        String ssidUnquoted = WifiInfo.sanitizeSsid(mTestNetwork.SSID);
+        assertThat(ssidUnquoted.length()).isAtLeast(2);
+        String ssidPrefix = ssidUnquoted.substring(0, ssidUnquoted.length() - 1);
+        // Note: The match may return more than 1 network in this case since we use a prefix match,
+        // But, we will still ensure that the UI interactions in the test still selects the
+        // saved network for connection.
+        WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork()
+                .setSsidPattern(new PatternMatcher(ssidPrefix, PatternMatcher.PATTERN_PREFIX))
+                .build();
+        testSuccessfulConnectionWithSpecifier(specifier);
+    }
+
+    private static class TestScanResultsCallback extends WifiManager.ScanResultsCallback {
+        private final Object mLock;
+        public boolean onAvailableCalled = false;
+
+        TestScanResultsCallback(Object lock) {
+            mLock = lock;
+        }
+
+        @Override
+        public void onScanResultsAvailable() {
+            synchronized (mLock) {
+                onAvailableCalled = true;
+                mLock.notify();
+            }
+        }
+    }
+
+    /**
+     * Loops through all available scan results and finds the first match for the saved network.
+     *
+     * Note:
+     * a) If there are more than 2 networks with the same SSID, but different credential type, then
+     * this matching may pick the wrong one.
+     */
+    private ScanResult findScanResultMatchingSavedNetwork() {
+        // Trigger a scan to get fresh scan results.
+        TestScanResultsCallback scanResultsCallback = new TestScanResultsCallback(mLock);
+        synchronized (mLock) {
+            try {
+                mWifiManager.registerScanResultsCallback(
+                        Executors.newSingleThreadExecutor(), scanResultsCallback);
+                mWifiManager.startScan(new WorkSource(myUid()));
+                // now wait for callback
+                mLock.wait(DURATION_NETWORK_CONNECTION);
+            } catch (InterruptedException e) {
+            } finally {
+                mWifiManager.unregisterScanResultsCallback(scanResultsCallback);
+            }
+        }
+        List<ScanResult> scanResults = mWifiManager.getScanResults();
+        if (scanResults == null || scanResults.isEmpty()) fail("No scan results available");
+        for (ScanResult scanResult : scanResults) {
+            if (TextUtils.equals(scanResult.SSID, WifiInfo.sanitizeSsid(mTestNetwork.SSID))) {
+                return scanResult;
+            }
+        }
+        fail("No matching scan results found");
+        return null;
+    }
+
+    /**
+     * Tests the entire connection flow using a specific BSSID in the specifier.
+     */
+    public void testConnectionWithSpecificBssid() {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        ScanResult scanResult = findScanResultMatchingSavedNetwork();
+        WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork()
+                .setBssid(MacAddress.fromString(scanResult.BSSID))
+                .build();
+        testSuccessfulConnectionWithSpecifier(specifier);
+    }
+
+    /**
+     * Tests the entire connection flow using a BSSID pattern in the specifier.
+     */
+    public void testConnectionWithBssidPattern() {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        ScanResult scanResult = findScanResultMatchingSavedNetwork();
+        // Note: The match may return more than 1 network in this case since we use a prefix match,
+        // But, we will still ensure that the UI interactions in the test still selects the
+        // saved network for connection.
+        WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork()
+                .setBssidPattern(MacAddress.fromString(scanResult.BSSID),
+                        MacAddress.fromString("ff:ff:ff:00:00:00"))
+                .build();
+        testSuccessfulConnectionWithSpecifier(specifier);
+    }
+
+    /**
+     * Tests the entire connection flow using a BSSID pattern in the specifier.
+     */
+    public void testUserRejectionWithSpecificSsid() {
+        if (!WifiFeature.isWifiSupported(getContext())) {
+            // skip the test if WiFi is not supported
+            return;
+        }
+        WifiNetworkSpecifier specifier = createSpecifierBuilderWithCredentialFromSavedNetwork()
+                .setSsid(WifiInfo.sanitizeSsid(mTestNetwork.SSID))
+                .build();
+        testUserRejectionWithSpecifier(specifier);
+    }
+}
