diff --git a/tests/cts/net/src/android/net/wifi/OWNERS b/tests/cts/net/src/android/net/wifi/OWNERS
deleted file mode 100644
index 4a6001b..0000000
--- a/tests/cts/net/src/android/net/wifi/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-etancohen@google.com
-lorenzo@google.com
-mplass@google.com
-rpius@google.com
-satk@google.com
diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
deleted file mode 100644
index 8f23324..0000000
--- a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * Copyright (C) 2017 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.aware.cts;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.mockito.Mockito.mock;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.location.LocationManager;
-import android.net.ConnectivityManager;
-import android.net.MacAddress;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.wifi.WifiManager;
-import android.net.wifi.aware.AttachCallback;
-import android.net.wifi.aware.Characteristics;
-import android.net.wifi.aware.DiscoverySession;
-import android.net.wifi.aware.DiscoverySessionCallback;
-import android.net.wifi.aware.IdentityChangedListener;
-import android.net.wifi.aware.ParcelablePeerHandle;
-import android.net.wifi.aware.PeerHandle;
-import android.net.wifi.aware.PublishConfig;
-import android.net.wifi.aware.PublishDiscoverySession;
-import android.net.wifi.aware.SubscribeConfig;
-import android.net.wifi.aware.SubscribeDiscoverySession;
-import android.net.wifi.aware.WifiAwareManager;
-import android.net.wifi.aware.WifiAwareNetworkSpecifier;
-import android.net.wifi.aware.WifiAwareSession;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Parcel;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-import com.android.compatibility.common.util.SystemUtil;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single
- * device to validate Wi-Fi Aware.
- */
-@AppModeFull(reason = "Cannot get WifiAwareManager in instant app mode")
-public class SingleDeviceTest extends AndroidTestCase {
-    private static final String TAG = "WifiAwareCtsTests";
-
-    // wait for Wi-Fi Aware state changes & network requests callbacks
-    static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10; // 10 seconds
-    private static final int MIN_DISTANCE_MM = 1 * 1000;
-    private static final int MAX_DISTANCE_MM = 3 * 1000;
-    private static final byte[] PMK_VALID = "01234567890123456789012345678901".getBytes();
-
-    private final Object mLock = new Object();
-    private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest");
-    private final Handler mHandler;
-    {
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-    }
-
-    private WifiAwareManager mWifiAwareManager;
-    private WifiManager mWifiManager;
-    private WifiManager.WifiLock mWifiLock;
-    private ConnectivityManager mConnectivityManager;
-
-    // used to store any WifiAwareSession allocated during tests - will clean-up after tests
-    private List<WifiAwareSession> mSessions = new ArrayList<>();
-
-    private class WifiAwareBroadcastReceiver extends BroadcastReceiver {
-        private CountDownLatch mBlocker = new CountDownLatch(1);
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED.equals(intent.getAction())) {
-                mBlocker.countDown();
-            }
-        }
-
-        boolean waitForStateChange() throws InterruptedException {
-            return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
-        }
-    }
-
-    private class AttachCallbackTest extends AttachCallback {
-        static final int ATTACHED = 0;
-        static final int ATTACH_FAILED = 1;
-        static final int ERROR = 2; // no callback: timeout, interruption
-
-        private CountDownLatch mBlocker = new CountDownLatch(1);
-        private int mCallbackCalled = ERROR; // garbage init
-        private WifiAwareSession mSession = null;
-
-        @Override
-        public void onAttached(WifiAwareSession session) {
-            mCallbackCalled = ATTACHED;
-            mSession = session;
-            synchronized (mLock) {
-                mSessions.add(session);
-            }
-            mBlocker.countDown();
-        }
-
-        @Override
-        public void onAttachFailed() {
-            mCallbackCalled = ATTACH_FAILED;
-            mBlocker.countDown();
-        }
-
-        /**
-         * Waits for any of the callbacks to be called - or an error (timeout, interruption).
-         * Returns one of the ATTACHED, ATTACH_FAILED, or ERROR values.
-         */
-        int waitForAnyCallback() {
-            try {
-                boolean noTimeout = mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
-                if (noTimeout) {
-                    return mCallbackCalled;
-                } else {
-                    return ERROR;
-                }
-            } catch (InterruptedException e) {
-                return ERROR;
-            }
-        }
-
-        /**
-         * Access the session created by a callback. Only useful to be called after calling
-         * waitForAnyCallback() and getting the ATTACHED code back.
-         */
-        WifiAwareSession getSession() {
-            return mSession;
-        }
-    }
-
-    private class IdentityChangedListenerTest extends IdentityChangedListener {
-        private CountDownLatch mBlocker = new CountDownLatch(1);
-        private byte[] mMac = null;
-
-        @Override
-        public void onIdentityChanged(byte[] mac) {
-            mMac = mac;
-            mBlocker.countDown();
-        }
-
-        /**
-         * Waits for the listener callback to be called - or an error (timeout, interruption).
-         * Returns true on callback called, false on error (timeout, interruption).
-         */
-        boolean waitForListener() {
-            try {
-                return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                return false;
-            }
-        }
-
-        /**
-         * Returns the MAC address of the discovery interface supplied to the triggered callback.
-         */
-        byte[] getMac() {
-            return mMac;
-        }
-    }
-
-    private class DiscoverySessionCallbackTest extends DiscoverySessionCallback {
-        static final int ON_PUBLISH_STARTED = 0;
-        static final int ON_SUBSCRIBE_STARTED = 1;
-        static final int ON_SESSION_CONFIG_UPDATED = 2;
-        static final int ON_SESSION_CONFIG_FAILED = 3;
-        static final int ON_SESSION_TERMINATED = 4;
-        static final int ON_SERVICE_DISCOVERED = 5;
-        static final int ON_MESSAGE_SEND_SUCCEEDED = 6;
-        static final int ON_MESSAGE_SEND_FAILED = 7;
-        static final int ON_MESSAGE_RECEIVED = 8;
-
-        private final Object mLocalLock = new Object();
-
-        private CountDownLatch mBlocker;
-        private int mCurrentWaitForCallback;
-        private ArrayDeque<Integer> mCallbackQueue = new ArrayDeque<>();
-
-        private PublishDiscoverySession mPublishDiscoverySession;
-        private SubscribeDiscoverySession mSubscribeDiscoverySession;
-
-        private void processCallback(int callback) {
-            synchronized (mLocalLock) {
-                if (mBlocker != null && mCurrentWaitForCallback == callback) {
-                    mBlocker.countDown();
-                } else {
-                    mCallbackQueue.addLast(callback);
-                }
-            }
-        }
-
-        @Override
-        public void onPublishStarted(PublishDiscoverySession session) {
-            mPublishDiscoverySession = session;
-            processCallback(ON_PUBLISH_STARTED);
-        }
-
-        @Override
-        public void onSubscribeStarted(SubscribeDiscoverySession session) {
-            mSubscribeDiscoverySession = session;
-            processCallback(ON_SUBSCRIBE_STARTED);
-        }
-
-        @Override
-        public void onSessionConfigUpdated() {
-            processCallback(ON_SESSION_CONFIG_UPDATED);
-        }
-
-        @Override
-        public void onSessionConfigFailed() {
-            processCallback(ON_SESSION_CONFIG_FAILED);
-        }
-
-        @Override
-        public void onSessionTerminated() {
-            processCallback(ON_SESSION_TERMINATED);
-        }
-
-        @Override
-        public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo,
-                List<byte[]> matchFilter) {
-            processCallback(ON_SERVICE_DISCOVERED);
-        }
-
-        @Override
-        public void onMessageSendSucceeded(int messageId) {
-            processCallback(ON_MESSAGE_SEND_SUCCEEDED);
-        }
-
-        @Override
-        public void onMessageSendFailed(int messageId) {
-            processCallback(ON_MESSAGE_SEND_FAILED);
-        }
-
-        @Override
-        public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
-            processCallback(ON_MESSAGE_RECEIVED);
-        }
-
-        /**
-         * Wait for the specified callback - any of the ON_* constants. Returns a true
-         * on success (specified callback triggered) or false on failure (timed-out or
-         * interrupted while waiting for the requested callback).
-         *
-         * Note: other callbacks happening while while waiting for the specified callback will
-         * be queued.
-         */
-        boolean waitForCallback(int callback) {
-            return waitForCallback(callback, WAIT_FOR_AWARE_CHANGE_SECS);
-        }
-
-        /**
-         * Wait for the specified callback - any of the ON_* constants. Returns a true
-         * on success (specified callback triggered) or false on failure (timed-out or
-         * interrupted while waiting for the requested callback).
-         *
-         * Same as waitForCallback(int callback) execpt that allows specifying a custom timeout.
-         * The default timeout is a short value expected to be sufficient for all behaviors which
-         * should happen relatively quickly. Specifying a custom timeout should only be done for
-         * those cases which are known to take a specific longer period of time.
-         *
-         * Note: other callbacks happening while while waiting for the specified callback will
-         * be queued.
-         */
-        boolean waitForCallback(int callback, int timeoutSec) {
-            synchronized (mLocalLock) {
-                boolean found = mCallbackQueue.remove(callback);
-                if (found) {
-                    return true;
-                }
-
-                mCurrentWaitForCallback = callback;
-                mBlocker = new CountDownLatch(1);
-            }
-
-            try {
-                return mBlocker.await(timeoutSec, TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                return false;
-            }
-        }
-
-        /**
-         * Indicates whether the specified callback (any of the ON_* constants) has already
-         * happened and in the queue. Useful when the order of events is important.
-         */
-        boolean hasCallbackAlreadyHappened(int callback) {
-            synchronized (mLocalLock) {
-                return mCallbackQueue.contains(callback);
-            }
-        }
-
-        /**
-         * Returns the last created publish discovery session.
-         */
-        PublishDiscoverySession getPublishDiscoverySession() {
-            PublishDiscoverySession session = mPublishDiscoverySession;
-            mPublishDiscoverySession = null;
-            return session;
-        }
-
-        /**
-         * Returns the last created subscribe discovery session.
-         */
-        SubscribeDiscoverySession getSubscribeDiscoverySession() {
-            SubscribeDiscoverySession session = mSubscribeDiscoverySession;
-            mSubscribeDiscoverySession = null;
-            return session;
-        }
-    }
-
-    private class NetworkCallbackTest extends ConnectivityManager.NetworkCallback {
-        private CountDownLatch mBlocker = new CountDownLatch(1);
-
-        @Override
-        public void onUnavailable() {
-            mBlocker.countDown();
-        }
-
-        /**
-         * Wait for the onUnavailable() callback to be triggered. Returns true if triggered,
-         * otherwise (timed-out, interrupted) returns false.
-         */
-        boolean waitForOnUnavailable() {
-            try {
-                return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
-            } catch (InterruptedException e) {
-                return false;
-            }
-        }
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        assertTrue("Wi-Fi Aware requires Location to be Enabled",
-                ((LocationManager) getContext().getSystemService(
-                        Context.LOCATION_SERVICE)).isLocationEnabled());
-
-        mWifiAwareManager = (WifiAwareManager) getContext().getSystemService(
-                Context.WIFI_AWARE_SERVICE);
-        assertNotNull("Wi-Fi Aware Manager", mWifiAwareManager);
-
-        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        assertNotNull("Wi-Fi Manager", mWifiManager);
-        mWifiLock = mWifiManager.createWifiLock(TAG);
-        mWifiLock.acquire();
-        if (!mWifiManager.isWifiEnabled()) {
-            SystemUtil.runShellCommand("svc wifi enable");
-        }
-
-        mConnectivityManager = (ConnectivityManager) getContext().getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        assertNotNull("Connectivity Manager", mConnectivityManager);
-
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED);
-        WifiAwareBroadcastReceiver receiver = new WifiAwareBroadcastReceiver();
-        mContext.registerReceiver(receiver, intentFilter);
-        if (!mWifiAwareManager.isAvailable()) {
-            assertTrue("Timeout waiting for Wi-Fi Aware to change status",
-                    receiver.waitForStateChange());
-            assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable());
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            super.tearDown();
-            return;
-        }
-
-        synchronized (mLock) {
-            for (WifiAwareSession session : mSessions) {
-                // no damage from destroying twice (i.e. ok if test cleaned up after itself already)
-                session.close();
-            }
-            mSessions.clear();
-        }
-
-        super.tearDown();
-    }
-
-    /**
-     * Validate:
-     * - Characteristics are available
-     * - Characteristics values are legitimate. Not in the CDD. However, the tested values are
-     *   based on the Wi-Fi Aware protocol.
-     */
-    public void testCharacteristics() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        Characteristics characteristics = mWifiAwareManager.getCharacteristics();
-        assertNotNull("Wi-Fi Aware characteristics are null", characteristics);
-        assertEquals("Service Name Length", characteristics.getMaxServiceNameLength(), 255);
-        assertEquals("Service Specific Information Length",
-                characteristics.getMaxServiceSpecificInfoLength(), 255);
-        assertEquals("Match Filter Length", characteristics.getMaxMatchFilterLength(), 255);
-        assertNotEquals("Cipher suites", characteristics.getSupportedCipherSuites(), 0);
-    }
-
-    /**
-     * Validate that on Wi-Fi Aware availability change we get a broadcast + the API returns
-     * correct status.
-     */
-    public void testAvailabilityStatusChange() throws Exception {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED);
-
-        // 1. Disable Wi-Fi
-        WifiAwareBroadcastReceiver receiver1 = new WifiAwareBroadcastReceiver();
-        mContext.registerReceiver(receiver1, intentFilter);
-        SystemUtil.runShellCommand("svc wifi disable");
-
-        assertTrue("Timeout waiting for Wi-Fi Aware to change status",
-                receiver1.waitForStateChange());
-        assertFalse("Wi-Fi Aware is available (should not be)", mWifiAwareManager.isAvailable());
-
-        // 2. Enable Wi-Fi
-        WifiAwareBroadcastReceiver receiver2 = new WifiAwareBroadcastReceiver();
-        mContext.registerReceiver(receiver2, intentFilter);
-        SystemUtil.runShellCommand("svc wifi enable");
-
-        assertTrue("Timeout waiting for Wi-Fi Aware to change status",
-                receiver2.waitForStateChange());
-        assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable());
-    }
-
-    /**
-     * Validate that can attach to Wi-Fi Aware.
-     */
-    public void testAttachNoIdentity() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        WifiAwareSession session = attachAndGetSession();
-        session.close();
-    }
-
-    /**
-     * Validate that can attach to Wi-Fi Aware and get identity information. Use the identity
-     * information to validate that MAC address changes on every attach.
-     *
-     * Note: relies on no other entity using Wi-Fi Aware during the CTS test. Since if it is used
-     * then the attach/destroy will not correspond to enable/disable and will not result in a new
-     * MAC address being generated.
-     */
-    public void testAttachDiscoveryAddressChanges() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        final int numIterations = 10;
-        Set<TestUtils.MacWrapper> macs = new HashSet<>();
-
-        for (int i = 0; i < numIterations; ++i) {
-            AttachCallbackTest attachCb = new AttachCallbackTest();
-            IdentityChangedListenerTest identityL = new IdentityChangedListenerTest();
-            mWifiAwareManager.attach(attachCb, identityL, mHandler);
-            assertEquals("Wi-Fi Aware attach: iteration " + i, AttachCallbackTest.ATTACHED,
-                    attachCb.waitForAnyCallback());
-            assertTrue("Wi-Fi Aware attach: iteration " + i, identityL.waitForListener());
-
-            WifiAwareSession session = attachCb.getSession();
-            assertNotNull("Wi-Fi Aware session: iteration " + i, session);
-
-            byte[] mac = identityL.getMac();
-            assertNotNull("Wi-Fi Aware discovery MAC: iteration " + i, mac);
-
-            session.close();
-
-            macs.add(new TestUtils.MacWrapper(mac));
-        }
-
-        assertEquals("", numIterations, macs.size());
-    }
-
-    /**
-     * Validate a successful publish discovery session lifetime: publish, update publish, destroy.
-     */
-    public void testPublishDiscoverySuccess() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        final String serviceName = "ValidName";
-
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                serviceName).build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-
-        // 1. publish
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-        PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
-        assertNotNull("Publish session", discoverySession);
-
-        // 2. update-publish
-        publishConfig = new PublishConfig.Builder().setServiceName(
-                serviceName).setServiceSpecificInfo("extras".getBytes()).build();
-        discoverySession.updatePublish(publishConfig);
-        assertTrue("Publish update", discoveryCb.waitForCallback(
-                DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
-
-        // 3. destroy
-        assertFalse("Publish not terminated", discoveryCb.hasCallbackAlreadyHappened(
-                DiscoverySessionCallbackTest.ON_SESSION_TERMINATED));
-        discoverySession.close();
-
-        // 4. try update post-destroy: should time-out waiting for cb
-        discoverySession.updatePublish(publishConfig);
-        assertFalse("Publish update post destroy", discoveryCb.waitForCallback(
-                DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
-
-        session.close();
-    }
-
-    /**
-     * Validate that publish with a Time To Live (TTL) setting expires within the specified
-     * time (and validates that the terminate callback is triggered).
-     */
-    public void testPublishLimitedTtlSuccess() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        final String serviceName = "ValidName";
-        final int ttlSec = 5;
-
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-
-        // 1. publish
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-        PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
-        assertNotNull("Publish session", discoverySession);
-
-        // 2. wait for terminate within 'ttlSec'.
-        assertTrue("Publish terminated",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED,
-                        ttlSec + 5));
-
-        // 3. try update post-termination: should time-out waiting for cb
-        publishConfig = new PublishConfig.Builder().setServiceName(
-                serviceName).setServiceSpecificInfo("extras".getBytes()).build();
-        discoverySession.updatePublish(publishConfig);
-        assertFalse("Publish update post terminate", discoveryCb.waitForCallback(
-                DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
-
-        session.close();
-    }
-
-    /**
-     * Validate a successful subscribe discovery session lifetime: subscribe, update subscribe,
-     * destroy.
-     */
-    public void testSubscribeDiscoverySuccess() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        final String serviceName = "ValidName";
-
-        WifiAwareSession session = attachAndGetSession();
-
-        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(
-                serviceName).build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-
-        // 1. subscribe
-        session.subscribe(subscribeConfig, discoveryCb, mHandler);
-        assertTrue("Subscribe started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED));
-        SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession();
-        assertNotNull("Subscribe session", discoverySession);
-
-        // 2. update-subscribe
-        subscribeConfig = new SubscribeConfig.Builder().setServiceName(
-                serviceName).setServiceSpecificInfo("extras".getBytes())
-                .setMinDistanceMm(MIN_DISTANCE_MM).build();
-        discoverySession.updateSubscribe(subscribeConfig);
-        assertTrue("Subscribe update", discoveryCb.waitForCallback(
-                DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
-
-        // 3. destroy
-        assertFalse("Subscribe not terminated", discoveryCb.hasCallbackAlreadyHappened(
-                DiscoverySessionCallbackTest.ON_SESSION_TERMINATED));
-        discoverySession.close();
-
-        // 4. try update post-destroy: should time-out waiting for cb
-        discoverySession.updateSubscribe(subscribeConfig);
-        assertFalse("Subscribe update post destroy", discoveryCb.waitForCallback(
-                DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
-
-        session.close();
-    }
-
-    /**
-     * Validate that subscribe with a Time To Live (TTL) setting expires within the specified
-     * time (and validates that the terminate callback is triggered).
-     */
-    public void testSubscribeLimitedTtlSuccess() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        final String serviceName = "ValidName";
-        final int ttlSec = 5;
-
-        WifiAwareSession session = attachAndGetSession();
-
-        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(
-                serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-
-        // 1. subscribe
-        session.subscribe(subscribeConfig, discoveryCb, mHandler);
-        assertTrue("Subscribe started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED));
-        SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession();
-        assertNotNull("Subscribe session", discoverySession);
-
-        // 2. wait for terminate within 'ttlSec'.
-        assertTrue("Subscribe terminated",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED,
-                        ttlSec + 5));
-
-        // 3. try update post-termination: should time-out waiting for cb
-        subscribeConfig = new SubscribeConfig.Builder().setServiceName(
-                serviceName).setServiceSpecificInfo("extras".getBytes()).build();
-        discoverySession.updateSubscribe(subscribeConfig);
-        assertFalse("Subscribe update post terminate", discoveryCb.waitForCallback(
-                DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
-
-        session.close();
-    }
-
-    /**
-     * Test the send message flow. Since testing single device cannot send to a real peer -
-     * validate that sending to a bogus peer fails.
-     */
-    public void testSendMessageFail() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                "ValidName").build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-
-        // 1. publish
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-        PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
-        assertNotNull("Publish session", discoverySession);
-
-        // 2. send a message with a null peer-handle - expect exception
-        try {
-            discoverySession.sendMessage(null, -1290, "some message".getBytes());
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException e) {
-            // empty
-        }
-
-        discoverySession.close();
-        session.close();
-    }
-
-    /**
-     * Request an Aware data-path (open) as a Responder with an arbitrary peer MAC address. Validate
-     * that receive an onUnavailable() callback.
-     */
-    public void testDataPathOpenOutOfBandFail() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-        MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
-
-        // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                "ValidName").build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-
-        // 2. request an AWARE network
-        NetworkCallbackTest networkCb = new NetworkCallbackTest();
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
-                session.createNetworkSpecifierOpen(
-                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR,
-                        mac.toByteArray())).build();
-        mConnectivityManager.requestNetwork(nr, networkCb);
-        assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable());
-
-        session.close();
-    }
-
-    /**
-     * Request an Aware data-path (encrypted with Passphrase) as a Responder with an arbitrary peer
-     * MAC address.
-     * Validate that receive an onUnavailable() callback.
-     */
-    public void testDataPathPassphraseOutOfBandFail() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-        MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
-
-        // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                "ValidName").build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-
-        // 2. request an AWARE network
-        NetworkCallbackTest networkCb = new NetworkCallbackTest();
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
-                session.createNetworkSpecifierPassphrase(
-                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, mac.toByteArray(),
-                        "abcdefghihk")).build();
-        mConnectivityManager.requestNetwork(nr, networkCb);
-        assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable());
-
-        session.close();
-    }
-
-    /**
-     * Request an Aware data-path (encrypted with PMK) as a Responder with an arbitrary peer MAC
-     * address.
-     * Validate that receive an onUnavailable() callback.
-     */
-    public void testDataPathPmkOutOfBandFail() {
-        if (!TestUtils.shouldTestWifiAware(getContext())) {
-            return;
-        }
-        MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
-
-        // 1. initialize Aware: only purpose is to make sure it is available for OOB data-path
-        WifiAwareSession session = attachAndGetSession();
-
-        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
-                "ValidName").build();
-        DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
-        session.publish(publishConfig, discoveryCb, mHandler);
-        assertTrue("Publish started",
-                discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
-
-        // 2. request an AWARE network
-        NetworkCallbackTest networkCb = new NetworkCallbackTest();
-        NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
-                NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
-                session.createNetworkSpecifierPmk(
-                        WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, mac.toByteArray(),
-                        PMK_VALID)).build();
-        mConnectivityManager.requestNetwork(nr, networkCb);
-        assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable());
-
-        session.close();
-    }
-
-    /**
-     * Test WifiAwareNetworkSpecifier.
-     */
-    public void testWifiAwareNetworkSpecifier() {
-        DiscoverySession session = mock(DiscoverySession.class);
-        PeerHandle handle = mock(PeerHandle.class);
-        WifiAwareNetworkSpecifier networkSpecifier =
-                new WifiAwareNetworkSpecifier.Builder(session, handle).build();
-        assertFalse(networkSpecifier.satisfiedBy(null));
-        assertTrue(networkSpecifier.satisfiedBy(networkSpecifier));
-
-        WifiAwareNetworkSpecifier anotherNetworkSpecifier =
-                new WifiAwareNetworkSpecifier.Builder(session, handle).setPmk(PMK_VALID).build();
-        assertFalse(networkSpecifier.satisfiedBy(anotherNetworkSpecifier));
-    }
-
-    /**
-     * Test ParcelablePeerHandle parcel.
-     */
-    public void testParcelablePeerHandle() {
-        PeerHandle peerHandle = mock(PeerHandle.class);
-        ParcelablePeerHandle parcelablePeerHandle = new ParcelablePeerHandle(peerHandle);
-        Parcel parcelW = Parcel.obtain();
-        parcelablePeerHandle.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        ParcelablePeerHandle rereadParcelablePeerHandle =
-                ParcelablePeerHandle.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(parcelablePeerHandle, rereadParcelablePeerHandle);
-        assertEquals(parcelablePeerHandle.hashCode(), rereadParcelablePeerHandle.hashCode());
-    }
-
-    // local utilities
-
-    private WifiAwareSession attachAndGetSession() {
-        AttachCallbackTest attachCb = new AttachCallbackTest();
-        mWifiAwareManager.attach(attachCb, mHandler);
-        int cbCalled = attachCb.waitForAnyCallback();
-        assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled);
-
-        WifiAwareSession session = attachCb.getSession();
-        assertNotNull("Wi-Fi Aware session", session);
-
-        return session;
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java b/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java
deleted file mode 100644
index a12c8bb..0000000
--- a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2017 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.aware.cts;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-
-import java.util.Arrays;
-
-/**
- * Test utilities for Wi-Fi Aware CTS test suite.
- */
-class TestUtils {
-    static final String TAG = "WifiAwareCtsTests";
-
-    /**
-     * Returns a flag indicating whether or not Wi-Fi Aware should be tested. Wi-Fi Aware
-     * should be tested if the feature is supported on the current device.
-     */
-    static boolean shouldTestWifiAware(Context context) {
-        final PackageManager pm = context.getPackageManager();
-        return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);
-    }
-
-    /**
-     * Wraps a byte[] (MAC address representation). Intended to provide hash and equality operators
-     * so that the MAC address can be used in containers.
-     */
-    static class MacWrapper {
-        private byte[] mMac;
-
-        MacWrapper(byte[] mac) {
-            mMac = mac;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-
-            if (!(o instanceof MacWrapper)) {
-                return false;
-            }
-
-            MacWrapper lhs = (MacWrapper) o;
-            return Arrays.equals(mMac, lhs.mMac);
-        }
-
-        @Override
-        public int hashCode() {
-            return Arrays.hashCode(mMac);
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
deleted file mode 100644
index d91bce8..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Copyright (C) 2012 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 org.junit.Assert.assertNotEquals;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.ConnectivityManager.NetworkCallback;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkRequest;
-import android.net.wifi.WifiManager;
-import android.net.wifi.p2p.WifiP2pDevice;
-import android.net.wifi.p2p.WifiP2pGroup;
-import android.net.wifi.p2p.WifiP2pGroupList;
-import android.net.wifi.p2p.WifiP2pInfo;
-import android.net.wifi.p2p.WifiP2pManager;
-import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
-import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
-import android.provider.Settings;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.compatibility.common.util.ShellIdentityUtils;
-import com.android.compatibility.common.util.SystemUtil;
-
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class ConcurrencyTest extends AndroidTestCase {
-    private class MySync {
-        static final int WIFI_STATE = 0;
-        static final int P2P_STATE = 1;
-        static final int DISCOVERY_STATE = 2;
-        static final int NETWORK_INFO = 3;
-
-        public BitSet pendingSync = new BitSet();
-
-        public int expectedWifiState;
-        public int expectedP2pState;
-        public int expectedDiscoveryState;
-        public NetworkInfo expectedNetworkInfo;
-    }
-
-    private class MyResponse {
-        public boolean valid = false;
-
-        public boolean success;
-        public int p2pState;
-        public int discoveryState;
-        public NetworkInfo networkInfo;
-        public WifiP2pInfo p2pInfo;
-        public String deviceName;
-        public WifiP2pGroupList persistentGroups;
-        public WifiP2pGroup group = new WifiP2pGroup();
-    }
-
-    private WifiManager mWifiManager;
-    private WifiP2pManager mWifiP2pManager;
-    private WifiP2pManager.Channel mWifiP2pChannel;
-    private MySync mMySync = new MySync();
-    private MyResponse mMyResponse = new MyResponse();
-    private boolean mWasVerboseLoggingEnabled;
-
-    private static final String TAG = "ConcurrencyTest";
-    private static final int TIMEOUT_MSEC = 6000;
-    private static final int WAIT_MSEC = 60;
-    private static final int DURATION = 10000;
-    private IntentFilter mIntentFilter;
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-                synchronized (mMySync) {
-                    mMySync.pendingSync.set(MySync.WIFI_STATE);
-                    mMySync.expectedWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                            WifiManager.WIFI_STATE_DISABLED);
-                    mMySync.notify();
-                }
-            } else if(action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) {
-                synchronized (mMySync) {
-                    mMySync.pendingSync.set(MySync.P2P_STATE);
-                    mMySync.expectedP2pState = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,
-                            WifiP2pManager.WIFI_P2P_STATE_DISABLED);
-                    mMySync.notify();
-                }
-            } else if (action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)) {
-                synchronized (mMySync) {
-                    mMySync.pendingSync.set(MySync.DISCOVERY_STATE);
-                    mMySync.expectedDiscoveryState = intent.getIntExtra(
-                            WifiP2pManager.EXTRA_DISCOVERY_STATE,
-                            WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
-                    mMySync.notify();
-                }
-            } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
-                synchronized (mMySync) {
-                    mMySync.pendingSync.set(MySync.NETWORK_INFO);
-                    mMySync.expectedNetworkInfo = (NetworkInfo) intent.getExtra(
-                            WifiP2pManager.EXTRA_NETWORK_INFO, null);
-                    mMySync.notify();
-                }
-            }
-        }
-    };
-
-    private WifiP2pManager.ActionListener mActionListener = new WifiP2pManager.ActionListener() {
-        @Override
-        public void onSuccess() {
-            synchronized (mMyResponse) {
-                mMyResponse.valid = true;
-                mMyResponse.success = true;
-                mMyResponse.notify();
-            }
-        }
-
-        @Override
-        public void onFailure(int reason) {
-            synchronized (mMyResponse) {
-                Log.d(TAG, "failure reason: " + reason);
-                mMyResponse.valid = true;
-                mMyResponse.success = false;
-                mMyResponse.notify();
-            }
-        }
-    };
-
-    @Override
-    protected void setUp() throws Exception {
-       super.setUp();
-       if (!WifiFeature.isWifiSupported(getContext()) &&
-                !WifiFeature.isP2pSupported(getContext())) {
-            // skip the test if WiFi && p2p are not supported
-            return;
-        }
-
-        mIntentFilter = new IntentFilter();
-        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
-
-        mContext.registerReceiver(mReceiver, mIntentFilter);
-        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        assertNotNull(mWifiManager);
-        if (mWifiManager.isWifiEnabled()) {
-            SystemUtil.runShellCommand("svc wifi disable");
-            Thread.sleep(DURATION);
-        }
-
-        // turn on verbose logging for tests
-        mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.isVerboseLoggingEnabled());
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setVerboseLoggingEnabled(true));
-
-        assertTrue(!mWifiManager.isWifiEnabled());
-        mMySync.expectedWifiState = WifiManager.WIFI_STATE_DISABLED;
-        mMySync.expectedP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED;
-        mMySync.expectedDiscoveryState = WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED;
-        mMySync.expectedNetworkInfo = null;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext()) &&
-                !WifiFeature.isP2pSupported(getContext())) {
-            // skip the test if WiFi and p2p are not supported
-            super.tearDown();
-            return;
-        }
-        mContext.unregisterReceiver(mReceiver);
-
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
-
-        enableWifi();
-        super.tearDown();
-    }
-
-    private boolean waitForBroadcasts(List<Integer> waitSyncList) {
-        synchronized (mMySync) {
-            long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-            while (System.currentTimeMillis() < timeout) {
-                List<Integer> handledSyncList = waitSyncList.stream()
-                        .filter(w -> mMySync.pendingSync.get(w))
-                        .collect(Collectors.toList());
-                handledSyncList.forEach(w -> mMySync.pendingSync.clear(w));
-                waitSyncList.removeAll(handledSyncList);
-                if (waitSyncList.isEmpty()) {
-                    break;
-                }
-                try {
-                    mMySync.wait(WAIT_MSEC);
-                } catch (InterruptedException e) { }
-            }
-            if (!waitSyncList.isEmpty()) {
-                Log.i(TAG, "Missing broadcast: " + waitSyncList);
-            }
-            return waitSyncList.isEmpty();
-        }
-    }
-
-    private boolean waitForBroadcasts(int waitSingleSync) {
-        return waitForBroadcasts(
-                new LinkedList<Integer>(Arrays.asList(waitSingleSync)));
-    }
-
-    private boolean waitForServiceResponse(MyResponse waitResponse) {
-        synchronized (waitResponse) {
-            long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-            while (System.currentTimeMillis() < timeout) {
-                try {
-                    waitResponse.wait(WAIT_MSEC);
-                } catch (InterruptedException e) { }
-
-                if (waitResponse.valid) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-
-    // Return true if location is enabled.
-    private boolean isLocationEnabled() {
-        return Settings.Secure.getInt(getContext().getContentResolver(),
-                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF)
-                != Settings.Secure.LOCATION_MODE_OFF;
-    }
-
-    // Returns true if the device has location feature.
-    private boolean hasLocationFeature() {
-        return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION);
-    }
-
-    private void resetResponse(MyResponse responseObj) {
-        synchronized (responseObj) {
-            responseObj.valid = false;
-            responseObj.networkInfo = null;
-            responseObj.p2pInfo = null;
-            responseObj.deviceName = null;
-            responseObj.persistentGroups = null;
-            responseObj.group = null;
-        }
-    }
-
-    /*
-     * Enables Wifi and block until connection is established.
-     */
-    private void enableWifi() throws InterruptedException {
-        if (!mWifiManager.isWifiEnabled()) {
-            SystemUtil.runShellCommand("svc wifi enable");
-        }
-
-        ConnectivityManager cm =
-            (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
-        NetworkRequest request =
-            new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-                                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                                        .build();
-        final CountDownLatch latch = new CountDownLatch(1);
-        NetworkCallback networkCallback = new NetworkCallback() {
-            @Override
-            public void onAvailable(Network network) {
-                latch.countDown();
-            }
-        };
-        cm.registerNetworkCallback(request, networkCallback);
-        latch.await(DURATION, TimeUnit.MILLISECONDS);
-
-        cm.unregisterNetworkCallback(networkCallback);
-    }
-
-    private boolean setupWifiP2p() {
-        // Cannot support p2p alone
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            assertTrue(!WifiFeature.isP2pSupported(getContext()));
-            return false;
-        }
-
-        if (!WifiFeature.isP2pSupported(getContext())) {
-            // skip the test if p2p is not supported
-            return false;
-        }
-
-        if (!hasLocationFeature()) {
-            Log.d(TAG, "Skipping test as location is not supported");
-            return false;
-        }
-        if (!isLocationEnabled()) {
-            fail("Please enable location for this test - since P-release WiFi Direct"
-                    + " needs Location enabled.");
-        }
-
-        mWifiP2pManager =
-                (WifiP2pManager) getContext().getSystemService(Context.WIFI_P2P_SERVICE);
-        mWifiP2pChannel = mWifiP2pManager.initialize(
-                getContext(), getContext().getMainLooper(), null);
-
-        assertNotNull(mWifiP2pManager);
-        assertNotNull(mWifiP2pChannel);
-
-        long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-        while (!mWifiManager.isWifiEnabled() && System.currentTimeMillis() < timeout) {
-            try {
-                enableWifi();
-            } catch (InterruptedException e) { }
-        }
-
-        assertTrue(mWifiManager.isWifiEnabled());
-
-        assertTrue(waitForBroadcasts(
-                new LinkedList<Integer>(
-                Arrays.asList(MySync.WIFI_STATE, MySync.P2P_STATE))));
-
-        assertEquals(WifiManager.WIFI_STATE_ENABLED, mMySync.expectedWifiState);
-        assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMySync.expectedP2pState);
-
-        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
-        // wait for changing to EnabledState
-        assertNotNull(mMySync.expectedNetworkInfo);
-
-        return true;
-    }
-
-    public void testConcurrency() {
-        if (!setupWifiP2p()) {
-            return;
-        }
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.requestP2pState(mWifiP2pChannel, new WifiP2pManager.P2pStateListener() {
-            @Override
-            public void onP2pStateAvailable(int state) {
-                synchronized (mMyResponse) {
-                    mMyResponse.valid = true;
-                    mMyResponse.p2pState = state;
-                    mMyResponse.notify();
-                }
-            }
-        });
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMyResponse.p2pState);
-    }
-
-    public void testRequestDiscoveryState() {
-        if (!setupWifiP2p()) {
-            return;
-        }
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.requestDiscoveryState(
-                mWifiP2pChannel, new WifiP2pManager.DiscoveryStateListener() {
-                    @Override
-                    public void onDiscoveryStateAvailable(int state) {
-                        synchronized (mMyResponse) {
-                            mMyResponse.valid = true;
-                            mMyResponse.discoveryState = state;
-                            mMyResponse.notify();
-                        }
-                    }
-                });
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED, mMyResponse.discoveryState);
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.discoverPeers(mWifiP2pChannel, mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-        assertTrue(waitForBroadcasts(MySync.DISCOVERY_STATE));
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.requestDiscoveryState(mWifiP2pChannel,
-                new WifiP2pManager.DiscoveryStateListener() {
-                    @Override
-                    public void onDiscoveryStateAvailable(int state) {
-                        synchronized (mMyResponse) {
-                            mMyResponse.valid = true;
-                            mMyResponse.discoveryState = state;
-                            mMyResponse.notify();
-                        }
-                    }
-                });
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED, mMyResponse.discoveryState);
-
-        mWifiP2pManager.stopPeerDiscovery(mWifiP2pChannel, null);
-    }
-
-    public void testRequestNetworkInfo() {
-        if (!setupWifiP2p()) {
-            return;
-        }
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel,
-                new WifiP2pManager.NetworkInfoListener() {
-                    @Override
-                    public void onNetworkInfoAvailable(NetworkInfo info) {
-                        synchronized (mMyResponse) {
-                            mMyResponse.valid = true;
-                            mMyResponse.networkInfo = info;
-                            mMyResponse.notify();
-                        }
-                    }
-                });
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertNotNull(mMyResponse.networkInfo);
-        // The state might be IDLE, DISCONNECTED, FAILED before a connection establishment.
-        // Just ensure the state is NOT CONNECTED.
-        assertNotEquals(NetworkInfo.DetailedState.CONNECTED,
-                mMySync.expectedNetworkInfo.getDetailedState());
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
-        assertNotNull(mMySync.expectedNetworkInfo);
-        assertEquals(NetworkInfo.DetailedState.CONNECTED,
-                mMySync.expectedNetworkInfo.getDetailedState());
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel,
-                new WifiP2pManager.NetworkInfoListener() {
-                    @Override
-                    public void onNetworkInfoAvailable(NetworkInfo info) {
-                        synchronized (mMyResponse) {
-                            mMyResponse.valid = true;
-                            mMyResponse.networkInfo = info;
-                            mMyResponse.notify();
-                        }
-                    }
-                });
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertNotNull(mMyResponse.networkInfo);
-        assertEquals(NetworkInfo.DetailedState.CONNECTED,
-                mMyResponse.networkInfo.getDetailedState());
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.requestConnectionInfo(mWifiP2pChannel,
-                new WifiP2pManager.ConnectionInfoListener() {
-                    @Override
-                    public void onConnectionInfoAvailable(WifiP2pInfo info) {
-                        synchronized (mMyResponse) {
-                            mMyResponse.valid = true;
-                            mMyResponse.p2pInfo = new WifiP2pInfo(info);
-                            mMyResponse.notify();
-                        }
-                    }
-                });
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertNotNull(mMyResponse.p2pInfo);
-        assertTrue(mMyResponse.p2pInfo.groupFormed);
-        assertTrue(mMyResponse.p2pInfo.isGroupOwner);
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.requestGroupInfo(mWifiP2pChannel,
-                new WifiP2pManager.GroupInfoListener() {
-                    @Override
-                    public void onGroupInfoAvailable(WifiP2pGroup group) {
-                        synchronized (mMyResponse) {
-                            mMyResponse.group = new WifiP2pGroup(group);
-                            mMyResponse.valid = true;
-                            mMyResponse.notify();
-                        }
-                    }
-                });
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertNotNull(mMyResponse.group);
-        assertNotEquals(0, mMyResponse.group.getFrequency());
-        assertTrue(mMyResponse.group.getNetworkId() >= 0);
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-    }
-
-    private String getDeviceName() {
-        resetResponse(mMyResponse);
-        mWifiP2pManager.requestDeviceInfo(mWifiP2pChannel,
-                new WifiP2pManager.DeviceInfoListener() {
-                    @Override
-                    public void onDeviceInfoAvailable(WifiP2pDevice wifiP2pDevice) {
-                        synchronized (mMyResponse) {
-                            mMyResponse.deviceName = wifiP2pDevice.deviceName;
-                            mMyResponse.valid = true;
-                            mMyResponse.notify();
-                        }
-                    }
-                });
-        assertTrue(waitForServiceResponse(mMyResponse));
-        return mMyResponse.deviceName;
-    }
-
-    public void testSetDeviceName() {
-        if (!setupWifiP2p()) {
-            return;
-        }
-
-        String testDeviceName = "test";
-        String originalDeviceName = getDeviceName();
-        assertNotNull(originalDeviceName);
-
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            mWifiP2pManager.setDeviceName(
-                    mWifiP2pChannel, testDeviceName, mActionListener);
-            assertTrue(waitForServiceResponse(mMyResponse));
-            assertTrue(mMyResponse.success);
-        });
-
-        String currentDeviceName = getDeviceName();
-        assertEquals(testDeviceName, currentDeviceName);
-
-        // restore the device name at the end
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            mWifiP2pManager.setDeviceName(
-                    mWifiP2pChannel, originalDeviceName, mActionListener);
-            assertTrue(waitForServiceResponse(mMyResponse));
-            assertTrue(mMyResponse.success);
-        });
-    }
-
-    private WifiP2pGroupList getPersistentGroups() {
-        resetResponse(mMyResponse);
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            mWifiP2pManager.requestPersistentGroupInfo(mWifiP2pChannel,
-                    new WifiP2pManager.PersistentGroupInfoListener() {
-                        @Override
-                        public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups) {
-                            synchronized (mMyResponse) {
-                                mMyResponse.persistentGroups = groups;
-                                mMyResponse.valid = true;
-                                mMyResponse.notify();
-                            }
-                        }
-                    });
-            assertTrue(waitForServiceResponse(mMyResponse));
-        });
-        return mMyResponse.persistentGroups;
-    }
-
-    public void testPersistentGroupOperation() {
-        if (!setupWifiP2p()) {
-            return;
-        }
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
-        assertNotNull(mMySync.expectedNetworkInfo);
-        assertEquals(NetworkInfo.DetailedState.CONNECTED,
-                mMySync.expectedNetworkInfo.getDetailedState());
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-
-        WifiP2pGroupList persistentGroups = getPersistentGroups();
-        assertNotNull(persistentGroups);
-        assertEquals(1, persistentGroups.getGroupList().size());
-
-        resetResponse(mMyResponse);
-        final int firstNetworkId = persistentGroups.getGroupList().get(0).getNetworkId();
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            mWifiP2pManager.deletePersistentGroup(mWifiP2pChannel,
-                    firstNetworkId,
-                    mActionListener);
-            assertTrue(waitForServiceResponse(mMyResponse));
-            assertTrue(mMyResponse.success);
-        });
-
-        persistentGroups = getPersistentGroups();
-        assertNotNull(persistentGroups);
-        assertEquals(0, persistentGroups.getGroupList().size());
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
-        assertNotNull(mMySync.expectedNetworkInfo);
-        assertEquals(NetworkInfo.DetailedState.CONNECTED,
-                mMySync.expectedNetworkInfo.getDetailedState());
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-
-        resetResponse(mMyResponse);
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            mWifiP2pManager.factoryReset(mWifiP2pChannel, mActionListener);
-            assertTrue(waitForServiceResponse(mMyResponse));
-            assertTrue(mMyResponse.success);
-        });
-
-        persistentGroups = getPersistentGroups();
-        assertNotNull(persistentGroups);
-        assertEquals(0, persistentGroups.getGroupList().size());
-    }
-
-    public void testP2pListening() {
-        if (!setupWifiP2p()) {
-            return;
-        }
-
-        resetResponse(mMyResponse);
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            mWifiP2pManager.setWifiP2pChannels(mWifiP2pChannel, 6, 11, mActionListener);
-            assertTrue(waitForServiceResponse(mMyResponse));
-            assertTrue(mMyResponse.success);
-        });
-
-        resetResponse(mMyResponse);
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            mWifiP2pManager.startListening(mWifiP2pChannel, mActionListener);
-            assertTrue(waitForServiceResponse(mMyResponse));
-            assertTrue(mMyResponse.success);
-        });
-
-        resetResponse(mMyResponse);
-        ShellIdentityUtils.invokeWithShellPermissions(() -> {
-            mWifiP2pManager.stopListening(mWifiP2pChannel, mActionListener);
-            assertTrue(waitForServiceResponse(mMyResponse));
-            assertTrue(mMyResponse.success);
-        });
-    }
-
-    public void testP2pService() {
-        if (!setupWifiP2p()) {
-            return;
-        }
-
-        // This only store the listener to the WifiP2pManager internal variable, nothing to fail.
-        mWifiP2pManager.setServiceResponseListener(mWifiP2pChannel,
-                new WifiP2pManager.ServiceResponseListener() {
-                    @Override
-                    public void onServiceAvailable(
-                            int protocolType, byte[] responseData, WifiP2pDevice srcDevice) {
-                    }
-                });
-
-        resetResponse(mMyResponse);
-        List<String> services = new ArrayList<String>();
-        services.add("urn:schemas-upnp-org:service:AVTransport:1");
-        services.add("urn:schemas-upnp-org:service:ConnectionManager:1");
-        WifiP2pServiceInfo rendererService = WifiP2pUpnpServiceInfo.newInstance(
-                "6859dede-8574-59ab-9332-123456789011",
-                "urn:schemas-upnp-org:device:MediaRenderer:1",
-                services);
-        mWifiP2pManager.addLocalService(mWifiP2pChannel,
-                rendererService,
-                mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.removeLocalService(mWifiP2pChannel,
-                rendererService,
-                mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-
-        resetResponse(mMyResponse);
-        mWifiP2pManager.clearLocalServices(mWifiP2pChannel,
-                mActionListener);
-        assertTrue(waitForServiceResponse(mMyResponse));
-        assertTrue(mMyResponse.success);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java b/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java
deleted file mode 100644
index 52ed2a6..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.net.wifi.hotspot2.ConfigParser;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.test.AndroidTestCase;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Arrays;
-
-/**
- * CTS tests for Hotspot 2.0 Release 1 installation file parsing API.
- */
-public class ConfigParserTest extends AndroidTestCase {
-    /**
-     * Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a
-     * CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}.
-     */
-    private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT =
-            "assets/HSR1ProfileWithCACert.base64";
-
-    /**
-     * Read the content of the given resource file into a String.
-     *
-     * @param filename String name of the file
-     * @return String
-     * @throws IOException
-     */
-    private String loadResourceFile(String filename) throws IOException {
-        InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-        StringBuilder builder = new StringBuilder();
-        String line;
-        while ((line = reader.readLine()) != null) {
-            builder.append(line).append("\n");
-        }
-
-        return builder.toString();
-    }
-
-    /**
-     * Generate a {@link PasspointConfiguration} that matches the configuration specified in the
-     * XML file {@link #PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT}.
-     *
-     * @return {@link PasspointConfiguration}
-     */
-    private PasspointConfiguration generateConfigurationFromProfile() {
-        PasspointConfiguration config = new PasspointConfiguration();
-
-        // HomeSP configuration.
-        HomeSp homeSp = new HomeSp();
-        homeSp.setFriendlyName("Century House");
-        homeSp.setFqdn("mi6.co.uk");
-        homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
-        config.setHomeSp(homeSp);
-
-        // Credential configuration.
-        Credential credential = new Credential();
-        credential.setRealm("shaken.stirred.com");
-        Credential.UserCredential userCredential = new Credential.UserCredential();
-        userCredential.setUsername("james");
-        userCredential.setPassword("Ym9uZDAwNw==");
-        userCredential.setEapType(21);
-        userCredential.setNonEapInnerMethod("MS-CHAP-V2");
-        credential.setUserCredential(userCredential);
-        Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
-        certCredential.setCertType("x509v3");
-        byte[] certSha256Fingerprint = new byte[32];
-        Arrays.fill(certSha256Fingerprint, (byte)0x1f);
-        certCredential.setCertSha256Fingerprint(certSha256Fingerprint);
-        credential.setCertCredential(certCredential);
-        Credential.SimCredential simCredential = new Credential.SimCredential();
-        simCredential.setImsi("imsi");
-        simCredential.setEapType(24);
-        credential.setSimCredential(simCredential);
-        credential.setCaCertificate(FakeKeys.CA_CERT0);
-        config.setCredential(credential);
-        return config;
-    }
-
-    /**
-     * Verify a valid installation file is parsed successfully with the matching contents.
-     *
-     * @throws Exception
-     */
-    public void testParseConfigFile() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
-        PasspointConfiguration expectedConfig = generateConfigurationFromProfile();
-        PasspointConfiguration actualConfig =
-                ConfigParser.parsePasspointConfig(
-                        "application/x-wifi-config", configStr.getBytes());
-        assertTrue(actualConfig.equals(expectedConfig));
-    }
-}
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java b/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
deleted file mode 100644
index 9624dd7..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/ConnectedNetworkScorerTest.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * 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.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE;
-import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE;
-import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS;
-import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.UiAutomation;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiUsabilityStatsEntry;
-import android.support.test.uiautomator.UiDevice;
-import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
-
-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.CountDownLatch;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-public class ConnectedNetworkScorerTest extends AndroidTestCase {
-    private WifiManager mWifiManager;
-    private UiDevice mUiDevice;
-    private boolean mWasVerboseLoggingEnabled;
-
-    private static final int DURATION = 10_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 = getContext().getSystemService(WifiManager.class);
-        assertThat(mWifiManager).isNotNull();
-
-        // 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.getConfiguredNetworks());
-        assertFalse("Need at least one saved network", savedNetworks.isEmpty());
-        // Wait for wifi is to be connected
-        PollingCheck.check(
-                "Wifi not connected",
-                DURATION,
-                () -> mWifiManager.getConnectionInfo().getNetworkId() != -1);
-        assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isNotEqualTo(-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.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");
-    }
-
-    private static class TestUsabilityStatsListener implements
-            WifiManager.OnWifiUsabilityStatsListener {
-        private final CountDownLatch mCountDownLatch;
-        public int seqNum;
-        public boolean isSameBssidAndFre;
-        public WifiUsabilityStatsEntry statsEntry;
-
-        TestUsabilityStatsListener(CountDownLatch countDownLatch) {
-            mCountDownLatch = countDownLatch;
-        }
-
-        @Override
-        public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
-                WifiUsabilityStatsEntry statsEntry) {
-            this.seqNum = seqNum;
-            this.isSameBssidAndFre = isSameBssidAndFreq;
-            this.statsEntry = statsEntry;
-            mCountDownLatch.countDown();
-        }
-    }
-
-    /**
-     * Tests the {@link android.net.wifi.WifiUsabilityStatsEntry} retrieved from
-     * {@link WifiManager.OnWifiUsabilityStatsListener}.
-     */
-    public void testWifiUsabilityStatsEntry() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        CountDownLatch countDownLatch = new CountDownLatch(1);
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        TestUsabilityStatsListener usabilityStatsListener =
-                new TestUsabilityStatsListener(countDownLatch);
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            mWifiManager.addOnWifiUsabilityStatsListener(
-                    Executors.newSingleThreadExecutor(), usabilityStatsListener);
-            // Wait for new usability stats (while connected & screen on this is triggered
-            // by platform periodically).
-            assertThat(countDownLatch.await(DURATION, TimeUnit.MILLISECONDS)).isTrue();
-
-            assertThat(usabilityStatsListener.statsEntry).isNotNull();
-            WifiUsabilityStatsEntry statsEntry = usabilityStatsListener.statsEntry;
-
-            assertThat(statsEntry.getTimeStampMillis()).isGreaterThan(0L);
-            assertThat(statsEntry.getRssi()).isLessThan(0);
-            assertThat(statsEntry.getLinkSpeedMbps()).isGreaterThan(0);
-            assertThat(statsEntry.getTotalTxSuccess()).isGreaterThan(0L);
-            assertThat(statsEntry.getTotalTxRetries()).isAtLeast(0L);
-            assertThat(statsEntry.getTotalTxBad()).isAtLeast(0L);
-            assertThat(statsEntry.getTotalRxSuccess()).isAtLeast(0L);
-            assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L);
-            assertThat(statsEntry.getTotalRadioTxTimeMillis()).isGreaterThan(0L);
-            assertThat(statsEntry.getTotalRadioRxTimeMillis()).isGreaterThan(0L);
-            assertThat(statsEntry.getTotalScanTimeMillis()).isGreaterThan(0L);
-            assertThat(statsEntry.getTotalNanScanTimeMillis()).isAtLeast(0L);
-            assertThat(statsEntry.getTotalBackgroundScanTimeMillis()).isAtLeast(0L);
-            assertThat(statsEntry.getTotalRoamScanTimeMillis()).isAtLeast(0L);
-            assertThat(statsEntry.getTotalPnoScanTimeMillis()).isAtLeast(0L);
-            assertThat(statsEntry.getTotalHotspot2ScanTimeMillis()).isAtLeast(0L);
-            assertThat(statsEntry.getTotalCcaBusyFreqTimeMillis()).isAtLeast(0L);
-            assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L);
-            assertThat(statsEntry.getTotalRadioOnFreqTimeMillis()).isGreaterThan(0L);
-            assertThat(statsEntry.getTotalBeaconRx()).isGreaterThan(0L);
-            assertThat(statsEntry.getProbeStatusSinceLastUpdate())
-                    .isAnyOf(PROBE_STATUS_SUCCESS,
-                            PROBE_STATUS_FAILURE,
-                            PROBE_STATUS_NO_PROBE,
-                            PROBE_STATUS_UNKNOWN);
-            // -1 is default value for some of these fields if they're not available.
-            assertThat(statsEntry.getProbeElapsedTimeSinceLastUpdateMillis()).isAtLeast(-1);
-            assertThat(statsEntry.getProbeMcsRateSinceLastUpdate()).isAtLeast(-1);
-            assertThat(statsEntry.getRxLinkSpeedMbps()).isAtLeast(-1);
-            // no longer populated, return default value.
-            assertThat(statsEntry.getCellularDataNetworkType())
-                    .isAnyOf(TelephonyManager.NETWORK_TYPE_UNKNOWN,
-                            TelephonyManager.NETWORK_TYPE_GPRS,
-                            TelephonyManager.NETWORK_TYPE_EDGE,
-                            TelephonyManager.NETWORK_TYPE_UMTS,
-                            TelephonyManager.NETWORK_TYPE_CDMA,
-                            TelephonyManager.NETWORK_TYPE_EVDO_0,
-                            TelephonyManager.NETWORK_TYPE_EVDO_A,
-                            TelephonyManager.NETWORK_TYPE_1xRTT,
-                            TelephonyManager.NETWORK_TYPE_HSDPA,
-                            TelephonyManager.NETWORK_TYPE_HSUPA,
-                            TelephonyManager.NETWORK_TYPE_HSPA,
-                            TelephonyManager.NETWORK_TYPE_IDEN,
-                            TelephonyManager.NETWORK_TYPE_EVDO_B,
-                            TelephonyManager.NETWORK_TYPE_LTE,
-                            TelephonyManager.NETWORK_TYPE_EHRPD,
-                            TelephonyManager.NETWORK_TYPE_HSPAP,
-                            TelephonyManager.NETWORK_TYPE_GSM,
-                            TelephonyManager.NETWORK_TYPE_TD_SCDMA,
-                            TelephonyManager.NETWORK_TYPE_IWLAN,
-                            TelephonyManager.NETWORK_TYPE_NR);
-            assertThat(statsEntry.getCellularSignalStrengthDbm()).isAtMost(0);
-            assertThat(statsEntry.getCellularSignalStrengthDb()).isAtMost(0);
-            assertThat(statsEntry.isSameRegisteredCell()).isFalse();
-        } finally {
-            mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener);
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests the {@link android.net.wifi.WifiManager#updateWifiUsabilityScore(int, int, int)}
-     */
-    public void testUpdateWifiUsabilityScore() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            // update scoring with dummy values.
-            mWifiManager.updateWifiUsabilityScore(0, 50, 50);
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    private static class TestConnectedNetworkScorer implements
-            WifiManager.WifiConnectedNetworkScorer {
-        private CountDownLatch mCountDownLatch;
-        public int startSessionId;
-        public int stopSessionId;
-        public WifiManager.ScoreUpdateObserver scoreUpdateObserver;
-
-        TestConnectedNetworkScorer(CountDownLatch countDownLatch) {
-            mCountDownLatch = countDownLatch;
-        }
-
-        @Override
-        public void onStart(int sessionId) {
-            synchronized (mCountDownLatch) {
-                this.startSessionId = sessionId;
-                mCountDownLatch.countDown();
-            }
-        }
-
-        @Override
-        public void onStop(int sessionId) {
-            synchronized (mCountDownLatch) {
-                this.stopSessionId = sessionId;
-                mCountDownLatch.countDown();
-            }
-        }
-
-        @Override
-        public void onSetScoreUpdateObserver(WifiManager.ScoreUpdateObserver observerImpl) {
-            this.scoreUpdateObserver = observerImpl;
-        }
-
-        public void resetCountDownLatch(CountDownLatch countDownLatch) {
-            synchronized (mCountDownLatch) {
-                mCountDownLatch = countDownLatch;
-            }
-        }
-    }
-
-    /**
-     * Tests the {@link android.net.wifi.WifiConnectedNetworkScorer} interface.
-     *
-     * Note: We could write more interesting test cases (if the device has a mobile connection), but
-     * that would make the test flaky. The default network/route selection on the device is not just
-     * controlled by the wifi scorer input, but also based on params which are controlled by
-     * other parts of the platform (likely in connectivity service) and hence will behave
-     * differently on OEM devices.
-     */
-    public void testSetWifiConnectedNetworkScorer() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        CountDownLatch countDownLatchScorer = new CountDownLatch(1);
-        CountDownLatch countDownLatchUsabilityStats = new CountDownLatch(1);
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        TestConnectedNetworkScorer connectedNetworkScorer =
-                new TestConnectedNetworkScorer(countDownLatchScorer);
-        TestUsabilityStatsListener usabilityStatsListener =
-                new TestUsabilityStatsListener(countDownLatchUsabilityStats);
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            mWifiManager.setWifiConnectedNetworkScorer(
-                    Executors.newSingleThreadExecutor(), connectedNetworkScorer);
-            // Since we're already connected, wait for onStart to be invoked.
-            assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue();
-
-            assertThat(connectedNetworkScorer.startSessionId).isAtLeast(0);
-            assertThat(connectedNetworkScorer.scoreUpdateObserver).isNotNull();
-            WifiManager.ScoreUpdateObserver scoreUpdateObserver =
-                    connectedNetworkScorer.scoreUpdateObserver;
-
-            // Now trigger a dummy score update.
-            scoreUpdateObserver.notifyScoreUpdate(connectedNetworkScorer.startSessionId, 50);
-
-            // Register the usability listener
-            mWifiManager.addOnWifiUsabilityStatsListener(
-                    Executors.newSingleThreadExecutor(), usabilityStatsListener);
-            // Trigger a usability stats update.
-            scoreUpdateObserver.triggerUpdateOfWifiUsabilityStats(
-                    connectedNetworkScorer.startSessionId);
-            // Ensure that we got the stats update callback.
-            assertThat(countDownLatchUsabilityStats.await(DURATION, TimeUnit.MILLISECONDS))
-                    .isTrue();
-            assertThat(usabilityStatsListener.seqNum).isAtLeast(0);
-
-            // Reset the scorer countdown latch for onStop
-            countDownLatchScorer = new CountDownLatch(1);
-            connectedNetworkScorer.resetCountDownLatch(countDownLatchScorer);
-            // Now disconnect from the network.
-            mWifiManager.disconnect();
-            // Wait for it to be disconnected.
-            PollingCheck.check(
-                    "Wifi not disconnected",
-                    DURATION,
-                    () -> mWifiManager.getConnectionInfo().getNetworkId() == -1);
-            assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isEqualTo(-1);
-
-            // Wait for stop to be invoked and ensure that the session id matches.
-            assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue();
-            assertThat(connectedNetworkScorer.stopSessionId)
-                    .isEqualTo(connectedNetworkScorer.startSessionId);
-        } finally {
-            mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener);
-            mWifiManager.clearWifiConnectedNetworkScorer();
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java b/tests/cts/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java
deleted file mode 100644
index eef50a0..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/EasyConnectStatusCallbackTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.wifi.EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT;
-import static android.net.wifi.WifiConfiguration.SECURITY_TYPE_PSK;
-import static android.net.wifi.WifiManager.EASY_CONNECT_NETWORK_ROLE_STA;
-
-import android.app.UiAutomation;
-import android.content.Context;
-import android.net.wifi.EasyConnectStatusCallback;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.HandlerThread;
-import android.test.AndroidTestCase;
-import android.util.SparseArray;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import java.util.concurrent.Executor;
-
-public class EasyConnectStatusCallbackTest extends AndroidTestCase {
-    private static final String TEST_SSID = "\"testSsid\"";
-    private static final String TEST_PASSPHRASE = "\"testPassword\"";
-    private static final int TEST_WAIT_DURATION_MS = 12_000; // Long delay is necessary, see below
-    private WifiManager mWifiManager;
-    private static final String TEST_DPP_URI =
-            "DPP:C:81/1;I:Easy_Connect_Demo;M:000102030405;"
-                    + "K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgACDmtXD1Sz6/5B4YRdmTkbkkFLDwk8f0yRnfm1Go"
-                    + "kpx/0=;;";
-    private final HandlerThread mHandlerThread = new HandlerThread("EasyConnectTest");
-    protected final Executor mExecutor;
-    {
-        mHandlerThread.start();
-        mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper()));
-    }
-    private final Object mLock = new Object();
-    private boolean mOnFailureCallback = false;
-    private int mErrorCode;
-
-    @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);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() {
-        @Override
-        public void onEnrolleeSuccess(int newNetworkId) {
-
-        }
-
-        @Override
-        public void onConfiguratorSuccess(int code) {
-
-        }
-
-        @Override
-        public void onProgress(int code) {
-
-        }
-
-        @Override
-        public void onFailure(int code) {
-            synchronized (mLock) {
-                mOnFailureCallback = true;
-                mErrorCode = code;
-                mLock.notify();
-            }
-        }
-
-        public void onFailure(int code, String ssid, SparseArray<int[]> channelListArray,
-                int[] operatingClassArray) {
-            synchronized (mLock) {
-                mOnFailureCallback = true;
-                mErrorCode = code;
-                mLock.notify();
-            }
-        }
-    };
-
-    /**
-     * Tests {@link android.net.wifi.EasyConnectStatusCallback} class.
-     *
-     * Since Easy Connect requires 2 devices, start Easy Connect session and expect an error.
-     */
-    public void testConfiguratorInitiatorOnFailure() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            WifiConfiguration config;
-            config = new WifiConfiguration();
-            config.SSID = TEST_SSID;
-            config.preSharedKey = TEST_PASSPHRASE;
-            config.setSecurityParams(SECURITY_TYPE_PSK);
-            int networkId = mWifiManager.addNetwork(config);
-            assertFalse(networkId == -1);
-            synchronized (mLock) {
-                mWifiManager.startEasyConnectAsConfiguratorInitiator(TEST_DPP_URI, networkId,
-                        EASY_CONNECT_NETWORK_ROLE_STA, mExecutor, mEasyConnectStatusCallback);
-                // Note: A long delay is necessary because there is no enrollee, and the system
-                // tries to discover it. We will wait for a timeout error to occur.
-                mLock.wait(TEST_WAIT_DURATION_MS);
-            }
-            mWifiManager.removeNetwork(networkId);
-            assertTrue(mOnFailureCallback);
-            assertEquals(EASY_CONNECT_EVENT_FAILURE_TIMEOUT, mErrorCode);
-            mWifiManager.stopEasyConnectSession();
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link android.net.wifi.EasyConnectStatusCallback} class.
-     *
-     * Since Easy Connect requires 2 devices, start Easy Connect session and expect an error.
-     */
-    public void testEnrolleeInitiatorOnFailure() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            synchronized (mLock) {
-                mWifiManager.startEasyConnectAsEnrolleeInitiator(TEST_DPP_URI, mExecutor,
-                        mEasyConnectStatusCallback);
-                // Note: A long delay is necessary because there is no configurator, and the system
-                // tries to discover it. We will wait for a timeout error to occur.
-                mLock.wait(TEST_WAIT_DURATION_MS);
-            }
-            assertTrue(mOnFailureCallback);
-            assertEquals(EASY_CONNECT_EVENT_FAILURE_TIMEOUT, mErrorCode);
-            mWifiManager.stopEasyConnectSession();
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java b/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java
deleted file mode 100644
index f875301..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2016 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 java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-
-/**
- * A class containing test certificates and private keys.
- */
-public class FakeKeys {
-    private static final String CA_CERT0_STRING = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIDKDCCAhCgAwIBAgIJAILlFdwzLVurMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
-            "BAMTB0VBUCBDQTEwHhcNMTYwMTEyMTE1MDE1WhcNMjYwMTA5MTE1MDE1WjASMRAw\n" +
-            "DgYDVQQDEwdFQVAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
-            "znAPUz26Msae4ws43czR41/J2QtrSIZUKmVUsVumDbYHrPNvTXKSMXAcewORDQYX\n" +
-            "RqvHvpn8CscB1+oGXZvHwxj4zV0WKoK2zeXkau3vcyl3HIKupJfq2TEACefVjj0t\n" +
-            "JW+X35PGWp9/H5zIUNVNVjS7Ums84IvKhRB8512PB9UyHagXYVX5GWpAcVpyfrlR\n" +
-            "FI9Qdhh+Pbk0uyktdbf/CdfgHOoebrTtwRljM0oDtX+2Cv6j0wBK7hD8pPvf1+uy\n" +
-            "GzczigAU/4Kw7eZqydf9B+5RupR+IZipX41xEiIrKRwqi517WWzXcjaG2cNbf451\n" +
-            "xpH5PnV3i1tq04jMGQUzFwIDAQABo4GAMH4wHQYDVR0OBBYEFIwX4vs8BiBcScod\n" +
-            "5noZHRM8E4+iMEIGA1UdIwQ7MDmAFIwX4vs8BiBcScod5noZHRM8E4+ioRakFDAS\n" +
-            "MRAwDgYDVQQDEwdFQVAgQ0ExggkAguUV3DMtW6swDAYDVR0TBAUwAwEB/zALBgNV\n" +
-            "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFfQqOTA7Rv7K+luQ7pnas4BYwHE\n" +
-            "9GEP/uohv6KOy0TGQFbrRTjFoLVNB9BZ1ymMDZ0/TIwIUc7wi7a8t5mEqYH153wW\n" +
-            "aWooiSjyLLhuI4sNrNCOtisdBq2r2MFXt6h0mAQYOPv8R8K7/fgSxGFqzhyNmmVL\n" +
-            "1qBJldx34SpwsTALQVPb4hGwJzZfr1PcpEQx6xMnTl8xEWZE3Ms99uaUxbQqIwRu\n" +
-            "LgAOkNCmY2m89VhzaHJ1uV85AdM/tD+Ysmlnnjt9LRCejbBipjIGjOXrg1JP+lxV\n" +
-            "muM4vH+P/mlmxsPPz0d65b+EGmJZpoLkO/tdNNvCYzjJpTEWpEsO6NMhKYo=\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_CERT0 = loadCertificate(CA_CERT0_STRING);
-
-    private static final String CA_CERT1_STRING = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIDKDCCAhCgAwIBAgIJAOM5SzKO2pzCMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
-            "BAMTB0VBUCBDQTAwHhcNMTYwMTEyMDAxMDQ3WhcNMjYwMTA5MDAxMDQ3WjASMRAw\n" +
-            "DgYDVQQDEwdFQVAgQ0EwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
-            "89ug+IEKVQXnJGKg5g4uVHg6J/8iRUxR5k2eH5o03hrJNMfN2D+cBe/wCiZcnWbI\n" +
-            "GbGZACWm2nQth2wy9Zgm2LOd3b4ocrHYls3XLq6Qb5Dd7a0JKU7pdGufiNVEkrmF\n" +
-            "EB+N64wgwH4COTvCiN4erp5kyJwkfqAl2xLkZo0C464c9XoyQOXbmYD9A8v10wZu\n" +
-            "jyNsEo7Nr2USyw+qhjWSbFbEirP77Tvx+7pJQJwdtk1V9Tn73T2dGF2WHYejei9S\n" +
-            "mcWpdIUqsu9etYH+zDmtu7I1xlkwiaVsNr2+D+qaCJyOYqrDTKVNK5nmbBPXDWZc\n" +
-            "NoDbTOoqquX7xONpq9M6jQIDAQABo4GAMH4wHQYDVR0OBBYEFAZ3A2S4qJZZwuNY\n" +
-            "wkJ6mAdc0gVdMEIGA1UdIwQ7MDmAFAZ3A2S4qJZZwuNYwkJ6mAdc0gVdoRakFDAS\n" +
-            "MRAwDgYDVQQDEwdFQVAgQ0EwggkA4zlLMo7anMIwDAYDVR0TBAUwAwEB/zALBgNV\n" +
-            "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHmdMwEhtys4d0E+t7owBmoVR+lU\n" +
-            "hMCcRtWs8YKX5WIM2kTweT0h/O1xwE1mWmRv/IbDAEb8od4BjAQLhIcolStr2JaO\n" +
-            "9ZzyxjOnNzqeErh/1DHDbb/moPpqfeJ8YiEz7nH/YU56Q8iCPO7TsgS0sNNE7PfN\n" +
-            "IUsBW0yHRgpQ4OxWmiZG2YZWiECRzAC0ecPzo59N5iH4vLQIMTMYquiDeMPQnn1e\n" +
-            "NDGxG8gCtDKIaS6tMg3a28MvWB094pr2ETou8O1C8Ji0Y4hE8QJmSdT7I4+GZjgW\n" +
-            "g94DZ5RiL7sdp3vC48CXOmeT61YBIvhGUsE1rPhXqkpqQ3Z3C4TFF0jXZZc=\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_CERT1 = loadCertificate(CA_CERT1_STRING);
-
-    private static final String CA_PUBLIC_CERT_STRING = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx\n" +
-            "GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds\n" +
-            "b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV\n" +
-            "BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD\n" +
-            "VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa\n" +
-            "DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc\n" +
-            "THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb\n" +
-            "Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP\n" +
-            "c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX\n" +
-            "gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n" +
-            "HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF\n" +
-            "AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj\n" +
-            "Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG\n" +
-            "j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH\n" +
-            "hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC\n" +
-            "X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CA_PUBLIC_CERT = loadCertificate(CA_PUBLIC_CERT_STRING);
-
-    private static final String CLIENT_CERT_STR = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIE/DCCAuQCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxCzAJBgNV\n" +
-            "BAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdUZXN0aW5n\n" +
-            "MB4XDTE2MDkzMDIwNTQyOFoXDTE3MDkzMDIwNTQyOFowRDELMAkGA1UEBhMCVVMx\n" +
-            "CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdU\n" +
-            "ZXN0aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpmcbuaeHfnJ\n" +
-            "k+2QNvxmdVFTawyFMNk0USCq5sexscwmxbewG/Rb8YnixwJWS44v2XkSujB67z5C\n" +
-            "s2qudFEhRXKdEuC6idbAuA97KjipHh0AAniWMsyv61fvbgsUC0b0canx3LiDq81p\n" +
-            "y28NNGmAvoazLZUZ4AhBRiwYZY6FKk723gmZoGbEIeG7J1dlXPusc1662rIjz4eU\n" +
-            "zlmmlvqyHfNqnNk8L14Vug6Xh+lOEGN85xhu1YHAEKGrS89kZxs5rum/cZU8KH2V\n" +
-            "v6eKnY03kxjiVLQtnLpm/7VUEoCMGHyruRj+p3my4+DgqMsmsH52RZCBsjyGlpbU\n" +
-            "NOwOTIX6xh+Rqloduz4AnrMYYIiIw2s8g+2zJM7VbcVKx0fGS26BKdrxgrXWfmNE\n" +
-            "nR0/REQ5AxDGw0jfTUvtdTkXAf+K4MDjcNLEZ+MA4rHfAfQWZtUR5BkHCQYxNpJk\n" +
-            "pA0gyk+BpKdC4WdzI14NSWsu5sRCmBCFqH6BTOSEq/V1cNorBxNwLSSTwFFqUDqx\n" +
-            "Y5nQLXygkJf9WHZWtSKeSjtOYgilz7UKzC2s3CsjmIyGFe+SwpuHJnuE4Uc8Z5Cb\n" +
-            "bjNGHPzqL6XnmzZHJp7RF8kBdKdjGC7dCUltzOfICZeKlzOOq+Kw42T/nXjuXvpb\n" +
-            "nkXNxg741Nwd6RecykXJbseFwm3EYxkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA\n" +
-            "Ga1mGwI9aXkL2fTPXO9YkAPzoGeX8aeuVYSQaSkNq+5vnogYCyAt3YDHjRG+ewTT\n" +
-            "WbnPA991xRAPac+biJeXWmwvgGj0YuT7e79phAiGkTTnbAjFHGfYnBy/tI/v7btO\n" +
-            "hRNElA5yTJ1m2fVbBEKXzMR83jrT9iyI+YLRN86zUZIaC86xxSbqnrdWN2jOK6MX\n" +
-            "dS8Arp9tPQjC/4gW+2Ilxv68jiYh+5auWHQZVjppWVY//iu4mAbkq1pTwQEhZ8F8\n" +
-            "Zrmh9DHh60hLFcfSuhIAwf/NMzppwdkjy1ruKVrpijhGKGp4OWu8nvOUgHSzxc7F\n" +
-            "PwpVZ5N2Ku4L8MLO6BG2VasRJK7l17TzDXlfLZHJjkuryOFxVaQKt8ZNFgTOaCXS\n" +
-            "E+gpTLksKU7riYckoiP4+H1sn9qcis0e8s4o/uf1UVc8GSdDw61ReGM5oZEDm1u8\n" +
-            "H9x20QU6igLqzyBpqvCKv7JNgU1uB2PAODHH78zJiUfnKd1y+o+J1iWzaGj3EFji\n" +
-            "T8AXksbTP733FeFXfggXju2dyBH+Z1S5BBTEOd1brWgXlHSAZGm97MKZ94r6/tkX\n" +
-            "qfv3fCos0DKz0oV7qBxYS8wiYhzrRVxG6ITAoH8uuUVVQaZF+G4nJ2jEqNbfuKyX\n" +
-            "ATQsVNjNNlDA0J33GobPMjT326wa4YAWMx8PI5PJZ3g=\n" +
-            "-----END CERTIFICATE-----\n";
-    public static final X509Certificate CLIENT_CERT = loadCertificate(CLIENT_CERT_STR);
-
-    private static final byte[] FAKE_RSA_KEY_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
-            (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
-            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
-            (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
-            (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
-            (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
-            (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
-            (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
-            (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
-            (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
-            (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
-            (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
-            (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
-            (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
-            (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
-            (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
-            (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
-            (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
-            (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
-            (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
-            (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
-            (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
-            (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
-            (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
-            (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
-            (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
-            (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
-            (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
-            (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
-            (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
-            (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
-            (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
-            (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
-            (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
-            (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
-            (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
-            (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
-            (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
-            (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
-            (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
-            (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
-            (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
-            (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
-            (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
-            (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
-            (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
-            (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
-            (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
-            (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
-            (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
-            (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
-            (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
-            (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
-            (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
-            (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
-            (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
-            (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
-            (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
-            (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
-            (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
-            (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
-            (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
-            (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
-            (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
-            (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
-            (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
-            (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
-            (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
-            (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
-            (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
-            (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
-            (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
-            (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
-            (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
-            (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
-            (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
-            (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
-            (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
-            (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
-            (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
-            (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
-            (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
-            (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
-            (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
-            (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
-            (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
-            (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
-            (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
-            (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
-            (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
-            (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
-            (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
-            (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
-            (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
-            (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
-            (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
-            (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
-            (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
-            (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
-            (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
-            (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
-            (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
-    };
-    public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1);
-
-    private static X509Certificate loadCertificate(String blob) {
-        try {
-            final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
-            InputStream stream = new ByteArrayInputStream(blob.getBytes(StandardCharsets.UTF_8));
-
-            return (X509Certificate) certFactory.generateCertificate(stream);
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) {
-        try {
-            KeyFactory kf = KeyFactory.getInstance("RSA");
-            return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey));
-        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
-            return null;
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java b/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java
deleted file mode 100644
index 71f04a3..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/MulticastLockTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2019 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 android.content.Context;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.MulticastLock;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class MulticastLockTest extends AndroidTestCase {
-
-    private static final String WIFI_TAG = "MulticastLockTest";
-
-    /**
-     * Verify acquire and release of Multicast locks
-     */
-    public void testMulticastLock() {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        MulticastLock mcl = wm.createMulticastLock(WIFI_TAG);
-
-        mcl.setReferenceCounted(true);
-        assertFalse(mcl.isHeld());
-        mcl.acquire();
-        assertTrue(mcl.isHeld());
-        mcl.release();
-        assertFalse(mcl.isHeld());
-        mcl.acquire();
-        mcl.acquire();
-        assertTrue(mcl.isHeld());
-        mcl.release();
-        assertTrue(mcl.isHeld());
-        mcl.release();
-        assertFalse(mcl.isHeld());
-        assertNotNull(mcl.toString());
-        try {
-            mcl.release();
-            fail("should throw out exception because release is called"
-                    +" a greater number of times than acquire");
-        } catch (RuntimeException e) {
-            // expected
-        }
-
-        mcl = wm.createMulticastLock(WIFI_TAG);
-        mcl.setReferenceCounted(false);
-        assertFalse(mcl.isHeld());
-        mcl.acquire();
-        assertTrue(mcl.isHeld());
-        mcl.release();
-        assertFalse(mcl.isHeld());
-        mcl.acquire();
-        mcl.acquire();
-        assertTrue(mcl.isHeld());
-        mcl.release();
-        assertFalse(mcl.isHeld());
-        assertNotNull(mcl.toString());
-        // releasing again after release: but ignored for non-referenced locks
-        mcl.release();
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java
deleted file mode 100644
index f2a2b48..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/NsdManagerTest.java
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (C) 2012 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 android.content.Context;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.util.Arrays;
-import java.util.Random;
-import java.util.List;
-import java.util.ArrayList;
-
-@AppModeFull(reason = "Socket cannot bind in instant app mode")
-public class NsdManagerTest extends AndroidTestCase {
-
-    private static final String TAG = "NsdManagerTest";
-    private static final String SERVICE_TYPE = "_nmt._tcp";
-    private static final int TIMEOUT = 2000;
-
-    private static final boolean DBG = false;
-
-    NsdManager mNsdManager;
-
-    NsdManager.RegistrationListener mRegistrationListener;
-    NsdManager.DiscoveryListener mDiscoveryListener;
-    NsdManager.ResolveListener mResolveListener;
-    private NsdServiceInfo mResolvedService;
-
-    public NsdManagerTest() {
-        initRegistrationListener();
-        initDiscoveryListener();
-        initResolveListener();
-    }
-
-    private void initRegistrationListener() {
-        mRegistrationListener = new NsdManager.RegistrationListener() {
-            @Override
-            public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
-                setEvent("onRegistrationFailed", errorCode);
-            }
-
-            @Override
-            public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
-                setEvent("onUnregistrationFailed", errorCode);
-            }
-
-            @Override
-            public void onServiceRegistered(NsdServiceInfo serviceInfo) {
-                setEvent("onServiceRegistered", serviceInfo);
-            }
-
-            @Override
-            public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
-                setEvent("onServiceUnregistered", serviceInfo);
-            }
-        };
-    }
-
-    private void initDiscoveryListener() {
-        mDiscoveryListener = new NsdManager.DiscoveryListener() {
-            @Override
-            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
-                setEvent("onStartDiscoveryFailed", errorCode);
-            }
-
-            @Override
-            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
-                setEvent("onStopDiscoveryFailed", errorCode);
-            }
-
-            @Override
-            public void onDiscoveryStarted(String serviceType) {
-                NsdServiceInfo info = new NsdServiceInfo();
-                info.setServiceType(serviceType);
-                setEvent("onDiscoveryStarted", info);
-            }
-
-            @Override
-            public void onDiscoveryStopped(String serviceType) {
-                NsdServiceInfo info = new NsdServiceInfo();
-                info.setServiceType(serviceType);
-                setEvent("onDiscoveryStopped", info);
-            }
-
-            @Override
-            public void onServiceFound(NsdServiceInfo serviceInfo) {
-                setEvent("onServiceFound", serviceInfo);
-            }
-
-            @Override
-            public void onServiceLost(NsdServiceInfo serviceInfo) {
-                setEvent("onServiceLost", serviceInfo);
-            }
-        };
-    }
-
-    private void initResolveListener() {
-        mResolveListener = new NsdManager.ResolveListener() {
-            @Override
-            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
-                setEvent("onResolveFailed", errorCode);
-            }
-
-            @Override
-            public void onServiceResolved(NsdServiceInfo serviceInfo) {
-                mResolvedService = serviceInfo;
-                setEvent("onServiceResolved", serviceInfo);
-            }
-        };
-    }
-
-
-
-    private final class EventData {
-        EventData(String callbackName, NsdServiceInfo info) {
-            mCallbackName = callbackName;
-            mSucceeded = true;
-            mErrorCode = 0;
-            mInfo = info;
-        }
-        EventData(String callbackName, int errorCode) {
-            mCallbackName = callbackName;
-            mSucceeded = false;
-            mErrorCode = errorCode;
-            mInfo = null;
-        }
-        private final String mCallbackName;
-        private final boolean mSucceeded;
-        private final int mErrorCode;
-        private final NsdServiceInfo mInfo;
-    }
-
-    private final List<EventData> mEventCache = new ArrayList<EventData>();
-
-    private void setEvent(String callbackName, int errorCode) {
-        if (DBG) Log.d(TAG, callbackName + " failed with " + String.valueOf(errorCode));
-        EventData eventData = new EventData(callbackName, errorCode);
-        synchronized (mEventCache) {
-            mEventCache.add(eventData);
-            mEventCache.notify();
-        }
-    }
-
-    private void setEvent(String callbackName, NsdServiceInfo info) {
-        if (DBG) Log.d(TAG, "Received event " + callbackName + " for " + info.getServiceName());
-        EventData eventData = new EventData(callbackName, info);
-        synchronized (mEventCache) {
-            mEventCache.add(eventData);
-            mEventCache.notify();
-        }
-    }
-
-    void clearEventCache() {
-        synchronized(mEventCache) {
-            mEventCache.clear();
-        }
-    }
-
-    int eventCacheSize() {
-        synchronized(mEventCache) {
-            return mEventCache.size();
-        }
-    }
-
-    private int mWaitId = 0;
-    private EventData waitForCallback(String callbackName) {
-
-        synchronized(mEventCache) {
-
-            mWaitId ++;
-            if (DBG) Log.d(TAG, "Waiting for " + callbackName + ", id=" + String.valueOf(mWaitId));
-
-            try {
-                long startTime = android.os.SystemClock.uptimeMillis();
-                long elapsedTime = 0;
-                int index = 0;
-                while (elapsedTime < TIMEOUT ) {
-                    // first check if we've received that event
-                    for (; index < mEventCache.size(); index++) {
-                        EventData e = mEventCache.get(index);
-                        if (e.mCallbackName.equals(callbackName)) {
-                            if (DBG) Log.d(TAG, "exiting wait id=" + String.valueOf(mWaitId));
-                            return e;
-                        }
-                    }
-
-                    // Not yet received, just wait
-                    mEventCache.wait(TIMEOUT - elapsedTime);
-                    elapsedTime = android.os.SystemClock.uptimeMillis() - startTime;
-                }
-                // we exited the loop because of TIMEOUT; fail the call
-                if (DBG) Log.d(TAG, "timed out waiting id=" + String.valueOf(mWaitId));
-                return null;
-            } catch (InterruptedException e) {
-                return null;                       // wait timed out!
-            }
-        }
-    }
-
-    private EventData waitForNewEvents() throws InterruptedException {
-        if (DBG) Log.d(TAG, "Waiting for a bit, id=" + String.valueOf(mWaitId));
-
-        long startTime = android.os.SystemClock.uptimeMillis();
-        long elapsedTime = 0;
-        synchronized (mEventCache) {
-            int index = mEventCache.size();
-            while (elapsedTime < TIMEOUT ) {
-                // first check if we've received that event
-                for (; index < mEventCache.size(); index++) {
-                    EventData e = mEventCache.get(index);
-                    return e;
-                }
-
-                // Not yet received, just wait
-                mEventCache.wait(TIMEOUT - elapsedTime);
-                elapsedTime = android.os.SystemClock.uptimeMillis() - startTime;
-            }
-        }
-
-        return null;
-    }
-
-    private String mServiceName;
-
-    @Override
-    public void setUp() {
-        if (DBG) Log.d(TAG, "Setup test ...");
-        mNsdManager = (NsdManager) getContext().getSystemService(Context.NSD_SERVICE);
-
-        Random rand = new Random();
-        mServiceName = new String("NsdTest");
-        for (int i = 0; i < 4; i++) {
-            mServiceName = mServiceName + String.valueOf(rand.nextInt(10));
-        }
-    }
-
-    @Override
-    public void tearDown() {
-        if (DBG) Log.d(TAG, "Tear down test ...");
-    }
-
-    public void testNDSManager() throws Exception {
-        EventData lastEvent = null;
-
-        if (DBG) Log.d(TAG, "Starting test ...");
-
-        NsdServiceInfo si = new NsdServiceInfo();
-        si.setServiceType(SERVICE_TYPE);
-        si.setServiceName(mServiceName);
-
-        byte testByteArray[] = new byte[] {-128, 127, 2, 1, 0, 1, 2};
-        String String256 = "1_________2_________3_________4_________5_________6_________" +
-                 "7_________8_________9_________10________11________12________13________" +
-                 "14________15________16________17________18________19________20________" +
-                 "21________22________23________24________25________123456";
-
-        // Illegal attributes
-        try {
-            si.setAttribute(null, (String) null);
-            fail("Could set null key");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute("", (String) null);
-            fail("Could set empty key");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute(String256, (String) null);
-            fail("Could set key with 255 characters");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute("key", String256.substring(3));
-            fail("Could set key+value combination with more than 255 characters");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute("key", String256.substring(4));
-            fail("Could set key+value combination with 255 characters");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute(new String(new byte[]{0x19}), (String) null);
-            fail("Could set key with invalid character");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute("=", (String) null);
-            fail("Could set key with invalid character");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            si.setAttribute(new String(new byte[]{0x7F}), (String) null);
-            fail("Could set key with invalid character");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        // Allowed attributes
-        si.setAttribute("booleanAttr", (String) null);
-        si.setAttribute("keyValueAttr", "value");
-        si.setAttribute("keyEqualsAttr", "=");
-        si.setAttribute(" whiteSpaceKeyValueAttr ", " value ");
-        si.setAttribute("binaryDataAttr", testByteArray);
-        si.setAttribute("nullBinaryDataAttr", (byte[]) null);
-        si.setAttribute("emptyBinaryDataAttr", new byte[]{});
-        si.setAttribute("longkey", String256.substring(9));
-
-        ServerSocket socket;
-        int localPort;
-
-        try {
-            socket = new ServerSocket(0);
-            localPort = socket.getLocalPort();
-            si.setPort(localPort);
-        } catch (IOException e) {
-            if (DBG) Log.d(TAG, "Could not open a local socket");
-            assertTrue(false);
-            return;
-        }
-
-        if (DBG) Log.d(TAG, "Port = " + String.valueOf(localPort));
-
-        clearEventCache();
-
-        mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
-        lastEvent = waitForCallback("onServiceRegistered");                 // id = 1
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-        assertTrue(eventCacheSize() == 1);
-
-        // We may not always get the name that we tried to register;
-        // This events tells us the name that was registered.
-        String registeredName = lastEvent.mInfo.getServiceName();
-        si.setServiceName(registeredName);
-
-        clearEventCache();
-
-        mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
-                mDiscoveryListener);
-
-        // Expect discovery started
-        lastEvent = waitForCallback("onDiscoveryStarted");                  // id = 2
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        // Remove this event, so accounting becomes easier later
-        synchronized (mEventCache) {
-            mEventCache.remove(lastEvent);
-        }
-
-        // Expect a service record to be discovered (and filter the ones
-        // that are unrelated to this test)
-        boolean found = false;
-        for (int i = 0; i < 32; i++) {
-
-            lastEvent = waitForCallback("onServiceFound");                  // id = 3
-            if (lastEvent == null) {
-                // no more onServiceFound events are being reported!
-                break;
-            }
-
-            assertTrue(lastEvent.mSucceeded);
-
-            if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
-                    lastEvent.mInfo.getServiceName());
-
-            if (lastEvent.mInfo.getServiceName().equals(registeredName)) {
-                // Save it, as it will get overwritten with new serviceFound events
-                si = lastEvent.mInfo;
-                found = true;
-            }
-
-            // Remove this event from the event cache, so it won't be found by subsequent
-            // calls to waitForCallback
-            synchronized (mEventCache) {
-                mEventCache.remove(lastEvent);
-            }
-        }
-
-        assertTrue(found);
-
-        // We've removed all serviceFound events, and we've removed the discoveryStarted
-        // event as well, so now the event cache should be empty!
-        assertTrue(eventCacheSize() == 0);
-
-        // Resolve the service
-        clearEventCache();
-        mNsdManager.resolveService(si, mResolveListener);
-        lastEvent = waitForCallback("onServiceResolved");                   // id = 4
-
-        assertNotNull(mResolvedService);
-
-        // Check Txt attributes
-        assertEquals(8, mResolvedService.getAttributes().size());
-        assertTrue(mResolvedService.getAttributes().containsKey("booleanAttr"));
-        assertNull(mResolvedService.getAttributes().get("booleanAttr"));
-        assertEquals("value", new String(mResolvedService.getAttributes().get("keyValueAttr")));
-        assertEquals("=", new String(mResolvedService.getAttributes().get("keyEqualsAttr")));
-        assertEquals(" value ", new String(mResolvedService.getAttributes()
-                .get(" whiteSpaceKeyValueAttr ")));
-        assertEquals(String256.substring(9), new String(mResolvedService.getAttributes()
-                .get("longkey")));
-        assertTrue(Arrays.equals(testByteArray,
-                mResolvedService.getAttributes().get("binaryDataAttr")));
-        assertTrue(mResolvedService.getAttributes().containsKey("nullBinaryDataAttr"));
-        assertNull(mResolvedService.getAttributes().get("nullBinaryDataAttr"));
-        assertTrue(mResolvedService.getAttributes().containsKey("emptyBinaryDataAttr"));
-        assertNull(mResolvedService.getAttributes().get("emptyBinaryDataAttr"));
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": Port = " +
-                String.valueOf(lastEvent.mInfo.getPort()));
-
-        assertTrue(lastEvent.mInfo.getPort() == localPort);
-        assertTrue(eventCacheSize() == 1);
-
-        checkForAdditionalEvents();
-        clearEventCache();
-
-        // Unregister the service
-        mNsdManager.unregisterService(mRegistrationListener);
-        lastEvent = waitForCallback("onServiceUnregistered");               // id = 5
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        // Expect a callback for service lost
-        lastEvent = waitForCallback("onServiceLost");                       // id = 6
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName));
-
-        // Register service again to see if we discover it
-        checkForAdditionalEvents();
-        clearEventCache();
-
-        si = new NsdServiceInfo();
-        si.setServiceType(SERVICE_TYPE);
-        si.setServiceName(mServiceName);
-        si.setPort(localPort);
-
-        // Create a new registration listener and register same service again
-        initRegistrationListener();
-
-        mNsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
-
-        lastEvent = waitForCallback("onServiceRegistered");                 // id = 7
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        registeredName = lastEvent.mInfo.getServiceName();
-
-        // Expect a record to be discovered
-        // Expect a service record to be discovered (and filter the ones
-        // that are unrelated to this test)
-        found = false;
-        for (int i = 0; i < 32; i++) {
-
-            lastEvent = waitForCallback("onServiceFound");                  // id = 8
-            if (lastEvent == null) {
-                // no more onServiceFound events are being reported!
-                break;
-            }
-
-            assertTrue(lastEvent.mSucceeded);
-
-            if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
-                    lastEvent.mInfo.getServiceName());
-
-            if (lastEvent.mInfo.getServiceName().equals(registeredName)) {
-                // Save it, as it will get overwritten with new serviceFound events
-                si = lastEvent.mInfo;
-                found = true;
-            }
-
-            // Remove this event from the event cache, so it won't be found by subsequent
-            // calls to waitForCallback
-            synchronized (mEventCache) {
-                mEventCache.remove(lastEvent);
-            }
-        }
-
-        assertTrue(found);
-
-        // Resolve the service
-        clearEventCache();
-        mNsdManager.resolveService(si, mResolveListener);
-        lastEvent = waitForCallback("onServiceResolved");                   // id = 9
-
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-
-        if (DBG) Log.d(TAG, "id = " + String.valueOf(mWaitId) + ": ServiceName = " +
-                lastEvent.mInfo.getServiceName());
-
-        assertTrue(lastEvent.mInfo.getServiceName().equals(registeredName));
-
-        assertNotNull(mResolvedService);
-
-        // Check that we don't have any TXT records
-        assertEquals(0, mResolvedService.getAttributes().size());
-
-        checkForAdditionalEvents();
-        clearEventCache();
-
-        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
-        lastEvent = waitForCallback("onDiscoveryStopped");                  // id = 10
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-        assertTrue(checkCacheSize(1));
-
-        checkForAdditionalEvents();
-        clearEventCache();
-
-        mNsdManager.unregisterService(mRegistrationListener);
-
-        lastEvent =  waitForCallback("onServiceUnregistered");              // id = 11
-        assertTrue(lastEvent != null);
-        assertTrue(lastEvent.mSucceeded);
-        assertTrue(checkCacheSize(1));
-    }
-
-    boolean checkCacheSize(int size) {
-        synchronized (mEventCache) {
-            int cacheSize = mEventCache.size();
-            if (cacheSize != size) {
-                Log.d(TAG, "id = " + mWaitId + ": event cache size = " + cacheSize);
-                for (int i = 0; i < cacheSize; i++) {
-                    EventData e = mEventCache.get(i);
-                    String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : "";
-                    Log.d(TAG, "eventName is " + e.mCallbackName + sname);
-                }
-            }
-            return (cacheSize == size);
-        }
-    }
-
-    boolean checkForAdditionalEvents() {
-        try {
-            EventData e = waitForNewEvents();
-            if (e != null) {
-                String sname = (e.mInfo != null) ? "(" + e.mInfo.getServiceName() + ")" : "";
-                Log.d(TAG, "ignoring unexpected event " + e.mCallbackName + sname);
-            }
-            return (e == null);
-        }
-        catch (InterruptedException ex) {
-            return false;
-        }
-    }
-}
-
diff --git a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java b/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java
deleted file mode 100644
index feafd43..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.omadm.PpsMoParser;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.test.AndroidTestCase;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * CTS tests for PPS MO (PerProviderSubscription Management Object) XML string parsing API.
- */
-public class PpsMoParserTest extends AndroidTestCase {
-    private static final String PPS_MO_XML_FILE = "assets/PerProviderSubscription.xml";
-
-    /**
-     * Read the content of the given resource file into a String.
-     *
-     * @param filename String name of the file
-     * @return String
-     * @throws IOException
-     */
-    private String loadResourceFile(String filename) throws IOException {
-        InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-        StringBuilder builder = new StringBuilder();
-        String line;
-        while ((line = reader.readLine()) != null) {
-            builder.append(line).append("\n");
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Generate a {@link PasspointConfiguration} that matches the configuration specified in the
-     * XML file {@link #PPS_MO_XML_FILE}.
-     *
-     * @return {@link PasspointConfiguration}
-     */
-    private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception {
-        DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
-        byte[] certFingerprint = new byte[32];
-        Arrays.fill(certFingerprint, (byte) 0x1f);
-
-        PasspointConfiguration config = new PasspointConfiguration();
-
-        // HomeSP configuration.
-        HomeSp homeSp = new HomeSp();
-        homeSp.setFriendlyName("Century House");
-        assertEquals("Century House", homeSp.getFriendlyName());
-        homeSp.setFqdn("mi6.co.uk");
-        assertEquals("mi6.co.uk", homeSp.getFqdn());
-        homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
-        assertTrue(Arrays.equals(new long[] {0x112233L, 0x445566L},
-                homeSp.getRoamingConsortiumOis()));
-        config.setHomeSp(homeSp);
-        assertEquals(homeSp, config.getHomeSp());
-
-        // Credential configuration.
-        Credential credential = new Credential();
-        credential.setRealm("shaken.stirred.com");
-        assertEquals("shaken.stirred.com", credential.getRealm());
-        Credential.UserCredential userCredential = new Credential.UserCredential();
-        userCredential.setUsername("james");
-        assertEquals("james", userCredential.getUsername());
-        userCredential.setPassword("Ym9uZDAwNw==");
-        assertEquals("Ym9uZDAwNw==", userCredential.getPassword());
-        userCredential.setEapType(21);
-        assertEquals(21, userCredential.getEapType());
-        userCredential.setNonEapInnerMethod("MS-CHAP-V2");
-        assertEquals("MS-CHAP-V2", userCredential.getNonEapInnerMethod());
-        credential.setUserCredential(userCredential);
-        assertEquals(userCredential, credential.getUserCredential());
-        Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
-        certCredential.setCertType("x509v3");
-        assertEquals("x509v3", certCredential.getCertType());
-        certCredential.setCertSha256Fingerprint(certFingerprint);
-        assertTrue(Arrays.equals(certFingerprint, certCredential.getCertSha256Fingerprint()));
-        credential.setCertCredential(certCredential);
-        assertEquals(certCredential, credential.getCertCredential());
-        Credential.SimCredential simCredential = new Credential.SimCredential();
-        simCredential.setImsi("imsi");
-        assertEquals("imsi", simCredential.getImsi());
-        simCredential.setEapType(24);
-        assertEquals(24, simCredential.getEapType());
-        credential.setSimCredential(simCredential);
-        assertEquals(simCredential, credential.getSimCredential());
-        config.setCredential(credential);
-        assertEquals(credential, config.getCredential());
-        return config;
-    }
-
-    /**
-     * Parse and verify all supported fields under PPS MO tree.
-     *
-     * @throws Exception
-     */
-    public void testParsePPSMOTree() throws Exception {
-        String ppsMoTree = loadResourceFile(PPS_MO_XML_FILE);
-        PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree();
-        PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree);
-        assertTrue(actualConfig.equals(expectedConfig));
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java b/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java
deleted file mode 100644
index 1977378..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/ScanResultTest.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.wifi.ScanResult;
-import android.net.wifi.ScanResult.InformationElement;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.WifiLock;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-import com.android.compatibility.common.util.ShellIdentityUtils;
-import com.android.compatibility.common.util.SystemUtil;
-
-@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class ScanResultTest extends AndroidTestCase {
-    private static class MySync {
-        int expectedState = STATE_NULL;
-    }
-
-    private WifiManager mWifiManager;
-    private WifiLock mWifiLock;
-    private static MySync mMySync;
-    private boolean mWasVerboseLoggingEnabled;
-    private boolean mWasScanThrottleEnabled;
-
-    private static final int STATE_NULL = 0;
-    private static final int STATE_WIFI_CHANGING = 1;
-    private static final int STATE_WIFI_CHANGED = 2;
-    private static final int STATE_START_SCAN = 3;
-    private static final int STATE_SCAN_RESULTS_AVAILABLE = 4;
-    private static final int STATE_SCAN_FAILURE = 5;
-
-    private static final String TAG = "WifiInfoTest";
-    private static final int TIMEOUT_MSEC = 6000;
-    private static final int WAIT_MSEC = 60;
-    private static final int ENABLE_WAIT_MSEC = 10000;
-    private static final int SCAN_WAIT_MSEC = 10000;
-    private static final int SCAN_MAX_RETRY_COUNT = 6;
-    private static final int SCAN_FIND_BSSID_MAX_RETRY_COUNT = 5;
-    private static final long SCAN_FIND_BSSID_WAIT_MSEC = 5_000L;
-
-    private static final String TEST_SSID = "TEST_SSID";
-    public static final String TEST_BSSID = "04:ac:fe:45:34:10";
-    public static final String TEST_CAPS = "CCMP";
-    public static final int TEST_LEVEL = -56;
-    public static final int TEST_FREQUENCY = 2412;
-    public static final long TEST_TIMESTAMP = 4660L;
-
-    private IntentFilter mIntentFilter;
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
-                synchronized (mMySync) {
-                    mMySync.expectedState = STATE_WIFI_CHANGED;
-                    mMySync.notify();
-                }
-            } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
-                synchronized (mMySync) {
-                    if (intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) {
-                        mMySync.expectedState = STATE_SCAN_RESULTS_AVAILABLE;
-                    } else {
-                        mMySync.expectedState = STATE_SCAN_FAILURE;
-                    }
-                    mMySync.notify();
-                }
-            }
-        }
-    };
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        mMySync = new MySync();
-        mIntentFilter = new IntentFilter();
-        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
-        mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK);
-
-        mContext.registerReceiver(mReceiver, mIntentFilter);
-        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        assertThat(mWifiManager).isNotNull();
-
-        // turn on verbose logging for tests
-        mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.isVerboseLoggingEnabled());
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setVerboseLoggingEnabled(true));
-        // Disable scan throttling for tests.
-        mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.isScanThrottleEnabled());
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setScanThrottleEnabled(false));
-
-        mWifiLock = mWifiManager.createWifiLock(TAG);
-        mWifiLock.acquire();
-        if (!mWifiManager.isWifiEnabled())
-            setWifiEnabled(true);
-        Thread.sleep(ENABLE_WAIT_MSEC);
-        assertThat(mWifiManager.isWifiEnabled()).isTrue();
-        mMySync.expectedState = STATE_NULL;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            super.tearDown();
-            return;
-        }
-        mWifiLock.release();
-        mContext.unregisterReceiver(mReceiver);
-        if (!mWifiManager.isWifiEnabled())
-            setWifiEnabled(true);
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled));
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
-        Thread.sleep(ENABLE_WAIT_MSEC);
-        super.tearDown();
-    }
-
-    private void setWifiEnabled(boolean enable) throws Exception {
-        synchronized (mMySync) {
-            mMySync.expectedState = STATE_WIFI_CHANGING;
-            if (enable) {
-                SystemUtil.runShellCommand("svc wifi enable");
-            } else {
-                SystemUtil.runShellCommand("svc wifi disable");
-            }
-            waitForBroadcast(TIMEOUT_MSEC, STATE_WIFI_CHANGED);
-       }
-    }
-
-    private boolean waitForBroadcast(long timeout, int expectedState) throws Exception {
-        long waitTime = System.currentTimeMillis() + timeout;
-        while (System.currentTimeMillis() < waitTime
-                && mMySync.expectedState != expectedState)
-            mMySync.wait(WAIT_MSEC);
-        return mMySync.expectedState == expectedState;
-    }
-
-    public void testScanResultProperties() {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        // this test case should in Wifi environment
-        for (ScanResult scanResult : mWifiManager.getScanResults()) {
-            assertThat(scanResult.toString()).isNotNull();
-
-            for (InformationElement ie : scanResult.getInformationElements()) {
-                testInformationElementCopyConstructor(ie);
-                testInformationElementFields(ie);
-            }
-
-            assertThat(scanResult.getWifiStandard()).isAnyOf(
-                    ScanResult.WIFI_STANDARD_UNKNOWN,
-                    ScanResult.WIFI_STANDARD_LEGACY,
-                    ScanResult.WIFI_STANDARD_11N,
-                    ScanResult.WIFI_STANDARD_11AC,
-                    ScanResult.WIFI_STANDARD_11AX
-            );
-
-            scanResult.isPasspointNetwork();
-        }
-    }
-
-    private void testInformationElementCopyConstructor(InformationElement ie) {
-        InformationElement copy = new InformationElement(ie);
-
-        assertThat(copy.getId()).isEqualTo(ie.getId());
-        assertThat(copy.getIdExt()).isEqualTo(ie.getIdExt());
-        assertThat(copy.getBytes()).isEqualTo(ie.getBytes());
-    }
-
-    private void testInformationElementFields(InformationElement ie) {
-        // id is 1 octet
-        int id = ie.getId();
-        assertThat(id).isAtLeast(0);
-        assertThat(id).isAtMost(255);
-
-        // idExt is 0 or 1 octet
-        int idExt = ie.getIdExt();
-        assertThat(idExt).isAtLeast(0);
-        assertThat(idExt).isAtMost(255);
-
-        ByteBuffer bytes = ie.getBytes();
-        assertThat(bytes).isNotNull();
-    }
-
-    /* Multiple scans to ensure bssid is updated */
-    private void scanAndWait() throws Exception {
-        synchronized (mMySync) {
-            for (int retry  = 0; retry < SCAN_MAX_RETRY_COUNT; retry++) {
-                mMySync.expectedState = STATE_START_SCAN;
-                mWifiManager.startScan();
-                if (waitForBroadcast(SCAN_WAIT_MSEC, STATE_SCAN_RESULTS_AVAILABLE)) {
-                    break;
-                }
-            }
-        }
-   }
-
-    public void testScanResultTimeStamp() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        long timestamp = 0;
-        String BSSID = null;
-
-        scanAndWait();
-
-        List<ScanResult> scanResults = mWifiManager.getScanResults();
-        for (ScanResult result : scanResults) {
-            BSSID = result.BSSID;
-            timestamp = result.timestamp;
-            assertThat(timestamp).isNotEqualTo(0);
-            break;
-        }
-
-        scanAndWait();
-
-        scanResults = mWifiManager.getScanResults();
-        for (ScanResult result : scanResults) {
-            if (result.BSSID.equals(BSSID)) {
-                long timeDiff = (result.timestamp - timestamp) / 1000;
-                assertThat(timeDiff).isGreaterThan(0L);
-                assertThat(timeDiff).isLessThan(6L * SCAN_WAIT_MSEC);
-            }
-        }
-    }
-
-    /** Test that the copy constructor copies fields correctly. */
-    public void testScanResultConstructors() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        ScanResult scanResult = new ScanResult();
-        scanResult.SSID = TEST_SSID;
-        scanResult.BSSID = TEST_BSSID;
-        scanResult.capabilities = TEST_CAPS;
-        scanResult.level = TEST_LEVEL;
-        scanResult.frequency = TEST_FREQUENCY;
-        scanResult.timestamp = TEST_TIMESTAMP;
-
-        ScanResult scanResult2 = new ScanResult(scanResult);
-        assertThat(scanResult2.SSID).isEqualTo(TEST_SSID);
-        assertThat(scanResult2.BSSID).isEqualTo(TEST_BSSID);
-        assertThat(scanResult2.capabilities).isEqualTo(TEST_CAPS);
-        assertThat(scanResult2.level).isEqualTo(TEST_LEVEL);
-        assertThat(scanResult2.frequency).isEqualTo(TEST_FREQUENCY);
-        assertThat(scanResult2.timestamp).isEqualTo(TEST_TIMESTAMP);
-    }
-
-    public void testScanResultMatchesWifiInfo() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // This test case should run while connected to Wifi
-        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-        assertThat(wifiInfo).isNotNull();
-
-        ScanResult currentNetwork = null;
-        for (int i = 0; i < SCAN_FIND_BSSID_MAX_RETRY_COUNT; i++) {
-            scanAndWait();
-            final List<ScanResult> scanResults = mWifiManager.getScanResults();
-            currentNetwork = scanResults.stream().filter(r -> r.BSSID.equals(wifiInfo.getBSSID()))
-                    .findAny().orElse(null);
-
-            if (currentNetwork != null) {
-                break;
-            }
-            Thread.sleep(SCAN_FIND_BSSID_WAIT_MSEC);
-        }
-        assertWithMessage("Current network not found in scan results")
-                .that(currentNetwork).isNotNull();
-
-        String wifiInfoSsidQuoted = wifiInfo.getSSID();
-        String scanResultSsidUnquoted = currentNetwork.SSID;
-
-        assertWithMessage(
-                "SSID mismatch: make sure this isn't a hidden network or an SSID containing "
-                        + "non-UTF-8 characters - neither is supported by this CTS test.")
-                .that("\"" + scanResultSsidUnquoted + "\"")
-                .isEqualTo(wifiInfoSsidQuoted);
-        assertThat(currentNetwork.frequency).isEqualTo(wifiInfo.getFrequency());
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java b/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java
deleted file mode 100644
index 11edf73..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/SupplicantStateTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net.wifi.SupplicantState;
-import android.test.AndroidTestCase;
-
-public class SupplicantStateTest extends AndroidTestCase {
-
-    public void testIsValidState() {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        assertTrue(SupplicantState.isValidState(SupplicantState.DISCONNECTED));
-        assertTrue(SupplicantState.isValidState(SupplicantState.INACTIVE));
-        assertTrue(SupplicantState.isValidState(SupplicantState.SCANNING));
-        assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATING));
-        assertTrue(SupplicantState.isValidState(SupplicantState.ASSOCIATED));
-        assertTrue(SupplicantState.isValidState(SupplicantState.FOUR_WAY_HANDSHAKE));
-        assertTrue(SupplicantState.isValidState(SupplicantState.GROUP_HANDSHAKE));
-        assertTrue(SupplicantState.isValidState(SupplicantState.COMPLETED));
-        assertTrue(SupplicantState.isValidState(SupplicantState.DORMANT));
-        assertFalse(SupplicantState.isValidState(SupplicantState.UNINITIALIZED));
-        assertFalse(SupplicantState.isValidState(SupplicantState.INVALID));
-    }
-
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java
deleted file mode 100644
index a59c85e..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiConfigurationTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2008 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 java.util.List;
-
-import android.content.Context;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class WifiConfigurationTest extends AndroidTestCase {
-    private  WifiManager mWifiManager;
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mWifiManager = (WifiManager) mContext
-                .getSystemService(Context.WIFI_SERVICE);
-    }
-
-    public void testWifiConfiguration() {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        List<WifiConfiguration> wifiConfigurations = mWifiManager.getConfiguredNetworks();
-        if (wifiConfigurations != null) {
-            for (int i = 0; i < wifiConfigurations.size(); i++) {
-                WifiConfiguration wifiConfiguration = wifiConfigurations.get(i);
-                assertNotNull(wifiConfiguration);
-                assertNotNull(wifiConfiguration.toString());
-            }
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
deleted file mode 100644
index 45b9d97..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
+++ /dev/null
@@ -1,899 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.google.common.truth.Truth.assertThat;
-
-import android.content.pm.PackageManager;
-import android.net.wifi.WifiEnterpriseConfig;
-import android.net.wifi.WifiEnterpriseConfig.Eap;
-import android.net.wifi.WifiEnterpriseConfig.Phase2;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-import java.io.ByteArrayInputStream;
-import java.security.KeyFactory;
-import java.security.PrivateKey;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.PKCS8EncodedKeySpec;
-
-@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class WifiEnterpriseConfigTest extends AndroidTestCase {
-
-    private static final String IDENTITY = "identity";
-    private static final String PASSWORD = "password";
-    private static final String SUBJECT_MATCH = "subjectmatch";
-    private static final String ALT_SUBJECT_MATCH = "altsubjectmatch";
-    private static final String DOM_SUBJECT_MATCH = "domsubjectmatch";
-    private static final String PLMN = "plmn";
-    private static final String REALM = "realm";
-    private static final String ANON_IDENTITY = "anonidentity";
-    private static final String CERTIFICATE_ALIAS1 = "certificatealias1";
-    private static final String CERTIFICATE_ALIAS2 = "certificatealias2";
-    private static final String CA_PATH = "capath";
-    private static final String CLIENT_CERTIFICATE_ALIAS = "clientcertificatealias";
-    private static final String WAPI_CERT_SUITE = "wapicertsuite";
-
-    /*
-     * The keys and certificates below are generated with:
-     *
-     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
-     * openssl ecparam -name prime256v1 -out ecparam.pem
-     * openssl req -newkey ec:ecparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
-     * mkdir -p demoCA/newcerts
-     * touch demoCA/index.txt
-     * echo "01" > demoCA/serial
-     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
-     */
-
-    /**
-     * Generated from above and converted with:
-     *
-     * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-
-    private static final byte[] FAKE_EC_1 = {
-        (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x2f, (byte) 0x30, (byte) 0x82,
-        (byte) 0x03, (byte) 0x17, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-        (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xa7, (byte) 0xe4,
-        (byte) 0x70, (byte) 0x50, (byte) 0x9b, (byte) 0xd2, (byte) 0x68, (byte) 0x68,
-        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-        (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-        (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xad,
-        (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
-        (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
-        (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a,
-        (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
-        (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12,
-        (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-        (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
-        (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79,
-        (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53,
-        (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f,
-        (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31,
-        (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-        (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65,
-        (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31,
-        (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-        (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69,
-        (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
-        (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65,
-        (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67,
-        (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29,
-        (byte) 0x30, (byte) 0x27, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-        (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09,
-        (byte) 0x01, (byte) 0x16, (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d,
-        (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d,
-        (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73,
-        (byte) 0x40, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69,
-        (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
-        (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30,
-        (byte) 0x31, (byte) 0x31, (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x31,
-        (byte) 0x38, (byte) 0x35, (byte) 0x31, (byte) 0x5a, (byte) 0x17, (byte) 0x0d,
-        (byte) 0x32, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32,
-        (byte) 0x31, (byte) 0x31, (byte) 0x31, (byte) 0x38, (byte) 0x35, (byte) 0x31,
-        (byte) 0x5a, (byte) 0x30, (byte) 0x81, (byte) 0xad, (byte) 0x31, (byte) 0x0b,
-        (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-        (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31,
-        (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-        (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f,
-        (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61,
-        (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10,
-        (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c,
-        (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
-        (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x15,
-        (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-        (byte) 0x0a, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
-        (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70,
-        (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31, (byte) 0x10, (byte) 0x30,
-        (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b,
-        (byte) 0x0c, (byte) 0x07, (byte) 0x53, (byte) 0x65, (byte) 0x63, (byte) 0x74,
-        (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21, (byte) 0x30,
-        (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03,
-        (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66, (byte) 0x69,
-        (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x70,
-        (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43, (byte) 0x6f,
-        (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54, (byte) 0x65,
-        (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x29, (byte) 0x30, (byte) 0x27,
-        (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01, (byte) 0x16,
-        (byte) 0x1a, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65, (byte) 0x6d,
-        (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61, (byte) 0x64,
-        (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40, (byte) 0x64,
-        (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e,
-        (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x82, (byte) 0x01,
-        (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-        (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-        (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82,
-        (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01,
-        (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00,
-        (byte) 0xb4, (byte) 0x6e, (byte) 0x66, (byte) 0x24, (byte) 0xe7, (byte) 0x5c,
-        (byte) 0xd8, (byte) 0x6f, (byte) 0x08, (byte) 0xd3, (byte) 0x80, (byte) 0xa3,
-        (byte) 0xb9, (byte) 0xaf, (byte) 0x90, (byte) 0xef, (byte) 0x1c, (byte) 0x2a,
-        (byte) 0x5f, (byte) 0x39, (byte) 0x0b, (byte) 0xbd, (byte) 0x75, (byte) 0x0d,
-        (byte) 0x3e, (byte) 0x19, (byte) 0x2e, (byte) 0x47, (byte) 0x1e, (byte) 0x14,
-        (byte) 0xc2, (byte) 0x1a, (byte) 0x59, (byte) 0xcc, (byte) 0x1b, (byte) 0xb6,
-        (byte) 0x9b, (byte) 0x46, (byte) 0x1f, (byte) 0x7f, (byte) 0x71, (byte) 0xdd,
-        (byte) 0x38, (byte) 0xbe, (byte) 0x89, (byte) 0x30, (byte) 0xba, (byte) 0x88,
-        (byte) 0xfb, (byte) 0x3f, (byte) 0x57, (byte) 0x35, (byte) 0xe7, (byte) 0xa7,
-        (byte) 0x2f, (byte) 0x2c, (byte) 0x8d, (byte) 0x7c, (byte) 0xe2, (byte) 0xd8,
-        (byte) 0x0c, (byte) 0x0a, (byte) 0xe6, (byte) 0x62, (byte) 0x46, (byte) 0x8c,
-        (byte) 0xf4, (byte) 0x51, (byte) 0xfc, (byte) 0x6a, (byte) 0x79, (byte) 0xdd,
-        (byte) 0x0a, (byte) 0x41, (byte) 0x23, (byte) 0xd3, (byte) 0xe9, (byte) 0x5e,
-        (byte) 0x91, (byte) 0xcd, (byte) 0xbd, (byte) 0x55, (byte) 0x28, (byte) 0x71,
-        (byte) 0xec, (byte) 0x52, (byte) 0x19, (byte) 0x85, (byte) 0x0c, (byte) 0x1b,
-        (byte) 0xfa, (byte) 0xbf, (byte) 0xfe, (byte) 0xae, (byte) 0x5c, (byte) 0x3b,
-        (byte) 0x99, (byte) 0x42, (byte) 0xd4, (byte) 0xe7, (byte) 0x17, (byte) 0xec,
-        (byte) 0x41, (byte) 0x22, (byte) 0x2c, (byte) 0x1e, (byte) 0x7b, (byte) 0x53,
-        (byte) 0xad, (byte) 0x02, (byte) 0xfd, (byte) 0xf6, (byte) 0x4a, (byte) 0xb1,
-        (byte) 0x6e, (byte) 0x6c, (byte) 0x87, (byte) 0xf5, (byte) 0x7d, (byte) 0x9b,
-        (byte) 0x34, (byte) 0x0e, (byte) 0x3b, (byte) 0x0e, (byte) 0xaa, (byte) 0xc5,
-        (byte) 0xc4, (byte) 0xef, (byte) 0xf2, (byte) 0x5a, (byte) 0xa9, (byte) 0xac,
-        (byte) 0x19, (byte) 0xce, (byte) 0x5f, (byte) 0xc5, (byte) 0xcc, (byte) 0x0d,
-        (byte) 0xee, (byte) 0x7f, (byte) 0x32, (byte) 0xb4, (byte) 0xfe, (byte) 0xc1,
-        (byte) 0xca, (byte) 0x9b, (byte) 0x3f, (byte) 0xad, (byte) 0x2c, (byte) 0x7a,
-        (byte) 0xc5, (byte) 0x8d, (byte) 0x48, (byte) 0xa1, (byte) 0xc9, (byte) 0x74,
-        (byte) 0xfe, (byte) 0x8a, (byte) 0xe3, (byte) 0xb0, (byte) 0x92, (byte) 0xee,
-        (byte) 0x73, (byte) 0x09, (byte) 0x0a, (byte) 0xbc, (byte) 0xc8, (byte) 0x63,
-        (byte) 0xba, (byte) 0x0e, (byte) 0x26, (byte) 0xab, (byte) 0x1e, (byte) 0xff,
-        (byte) 0xbc, (byte) 0x24, (byte) 0x12, (byte) 0x26, (byte) 0x11, (byte) 0xe0,
-        (byte) 0x04, (byte) 0xcb, (byte) 0x96, (byte) 0x7d, (byte) 0x41, (byte) 0xf7,
-        (byte) 0x79, (byte) 0x32, (byte) 0x05, (byte) 0x33, (byte) 0x19, (byte) 0x6e,
-        (byte) 0xb9, (byte) 0x75, (byte) 0xf3, (byte) 0x50, (byte) 0xa4, (byte) 0xc3,
-        (byte) 0x55, (byte) 0x9d, (byte) 0x8f, (byte) 0xb6, (byte) 0xab, (byte) 0x97,
-        (byte) 0xe7, (byte) 0xe2, (byte) 0xe8, (byte) 0x15, (byte) 0xfc, (byte) 0x35,
-        (byte) 0xbd, (byte) 0xce, (byte) 0x17, (byte) 0xbe, (byte) 0xe3, (byte) 0x73,
-        (byte) 0xd4, (byte) 0x88, (byte) 0x39, (byte) 0x27, (byte) 0x7e, (byte) 0x6d,
-        (byte) 0xa2, (byte) 0x27, (byte) 0xfa, (byte) 0x96, (byte) 0xe3, (byte) 0x38,
-        (byte) 0xc0, (byte) 0xa1, (byte) 0x55, (byte) 0xc6, (byte) 0xf3, (byte) 0x20,
-        (byte) 0xea, (byte) 0x50, (byte) 0x8d, (byte) 0x6c, (byte) 0x94, (byte) 0x9a,
-        (byte) 0x43, (byte) 0x74, (byte) 0xc0, (byte) 0xfa, (byte) 0xef, (byte) 0xe0,
-        (byte) 0xb1, (byte) 0x1c, (byte) 0x6d, (byte) 0x5e, (byte) 0x44, (byte) 0x08,
-        (byte) 0xef, (byte) 0xd5, (byte) 0x80, (byte) 0xad, (byte) 0x02, (byte) 0x03,
-        (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x50, (byte) 0x30,
-        (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-        (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14,
-        (byte) 0xe9, (byte) 0xd0, (byte) 0x9e, (byte) 0x0e, (byte) 0x62, (byte) 0x31,
-        (byte) 0x02, (byte) 0x9a, (byte) 0x33, (byte) 0xd7, (byte) 0x4a, (byte) 0x93,
-        (byte) 0x0d, (byte) 0xf3, (byte) 0xd6, (byte) 0x74, (byte) 0xce, (byte) 0x69,
-        (byte) 0xe1, (byte) 0xef, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
-        (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xe9, (byte) 0xd0, (byte) 0x9e,
-        (byte) 0x0e, (byte) 0x62, (byte) 0x31, (byte) 0x02, (byte) 0x9a, (byte) 0x33,
-        (byte) 0xd7, (byte) 0x4a, (byte) 0x93, (byte) 0x0d, (byte) 0xf3, (byte) 0xd6,
-        (byte) 0x74, (byte) 0xce, (byte) 0x69, (byte) 0xe1, (byte) 0xef, (byte) 0x30,
-        (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
-        (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01,
-        (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-        (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-        (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82,
-        (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x52, (byte) 0x70, (byte) 0xb6,
-        (byte) 0x10, (byte) 0x7f, (byte) 0xaa, (byte) 0x86, (byte) 0x8f, (byte) 0x02,
-        (byte) 0xb0, (byte) 0x97, (byte) 0x89, (byte) 0xb9, (byte) 0x04, (byte) 0x1d,
-        (byte) 0x79, (byte) 0xa3, (byte) 0x74, (byte) 0x7c, (byte) 0xdf, (byte) 0xad,
-        (byte) 0x87, (byte) 0xe4, (byte) 0x00, (byte) 0xd3, (byte) 0x3a, (byte) 0x5c,
-        (byte) 0x48, (byte) 0x3b, (byte) 0xfe, (byte) 0x77, (byte) 0xfd, (byte) 0xbe,
-        (byte) 0xce, (byte) 0x5b, (byte) 0xd2, (byte) 0xea, (byte) 0x3e, (byte) 0x7f,
-        (byte) 0xef, (byte) 0x20, (byte) 0x0d, (byte) 0x0b, (byte) 0xc7, (byte) 0xc4,
-        (byte) 0x25, (byte) 0x20, (byte) 0xe1, (byte) 0x8f, (byte) 0xc5, (byte) 0x19,
-        (byte) 0x37, (byte) 0x9c, (byte) 0xa0, (byte) 0x9d, (byte) 0x02, (byte) 0x30,
-        (byte) 0x5f, (byte) 0x49, (byte) 0x4e, (byte) 0x56, (byte) 0xc4, (byte) 0xab,
-        (byte) 0xcb, (byte) 0x5c, (byte) 0xe6, (byte) 0x40, (byte) 0x93, (byte) 0x92,
-        (byte) 0xee, (byte) 0xa1, (byte) 0x69, (byte) 0x7d, (byte) 0x10, (byte) 0x6b,
-        (byte) 0xd4, (byte) 0xf7, (byte) 0xec, (byte) 0xd9, (byte) 0xa5, (byte) 0x29,
-        (byte) 0x63, (byte) 0x29, (byte) 0xd9, (byte) 0x27, (byte) 0x2d, (byte) 0x5e,
-        (byte) 0x34, (byte) 0x37, (byte) 0xa9, (byte) 0xba, (byte) 0x0a, (byte) 0x7b,
-        (byte) 0x99, (byte) 0x1a, (byte) 0x7d, (byte) 0xa7, (byte) 0xa7, (byte) 0xf0,
-        (byte) 0xbf, (byte) 0x40, (byte) 0x29, (byte) 0x5d, (byte) 0x2f, (byte) 0x2e,
-        (byte) 0x0f, (byte) 0x35, (byte) 0x90, (byte) 0xb5, (byte) 0xc3, (byte) 0xfd,
-        (byte) 0x1e, (byte) 0xe2, (byte) 0xb3, (byte) 0xae, (byte) 0xf9, (byte) 0xde,
-        (byte) 0x9d, (byte) 0x76, (byte) 0xe1, (byte) 0x20, (byte) 0xf5, (byte) 0x1c,
-        (byte) 0x30, (byte) 0x42, (byte) 0x80, (byte) 0x2a, (byte) 0x4f, (byte) 0x85,
-        (byte) 0x5c, (byte) 0xb4, (byte) 0x49, (byte) 0x68, (byte) 0x6c, (byte) 0x7c,
-        (byte) 0x2a, (byte) 0xc8, (byte) 0xbc, (byte) 0x15, (byte) 0xed, (byte) 0x88,
-        (byte) 0xfd, (byte) 0x8a, (byte) 0x63, (byte) 0xe0, (byte) 0x93, (byte) 0xfd,
-        (byte) 0x86, (byte) 0xab, (byte) 0xa9, (byte) 0xf6, (byte) 0x63, (byte) 0xa5,
-        (byte) 0x29, (byte) 0xaf, (byte) 0xdc, (byte) 0x8f, (byte) 0xca, (byte) 0xc2,
-        (byte) 0x28, (byte) 0xe7, (byte) 0x26, (byte) 0x89, (byte) 0x75, (byte) 0xf1,
-        (byte) 0x3e, (byte) 0x2e, (byte) 0x86, (byte) 0x11, (byte) 0x8b, (byte) 0xfa,
-        (byte) 0xf5, (byte) 0xb4, (byte) 0xb4, (byte) 0x04, (byte) 0x02, (byte) 0xa3,
-        (byte) 0x85, (byte) 0x81, (byte) 0xad, (byte) 0xb3, (byte) 0xec, (byte) 0x2d,
-        (byte) 0x4b, (byte) 0x40, (byte) 0x59, (byte) 0x61, (byte) 0x0d, (byte) 0x59,
-        (byte) 0x09, (byte) 0x09, (byte) 0xee, (byte) 0xc7, (byte) 0x51, (byte) 0xef,
-        (byte) 0x6f, (byte) 0xd6, (byte) 0x9a, (byte) 0xa5, (byte) 0x45, (byte) 0xa2,
-        (byte) 0x89, (byte) 0xc2, (byte) 0x97, (byte) 0x93, (byte) 0xbc, (byte) 0x5b,
-        (byte) 0x37, (byte) 0x55, (byte) 0x73, (byte) 0x55, (byte) 0x0c, (byte) 0x9c,
-        (byte) 0xcb, (byte) 0x10, (byte) 0xec, (byte) 0x76, (byte) 0xfe, (byte) 0xa7,
-        (byte) 0x70, (byte) 0x4e, (byte) 0x9a, (byte) 0xa2, (byte) 0xf9, (byte) 0x40,
-        (byte) 0xdd, (byte) 0x96, (byte) 0x7d, (byte) 0x67, (byte) 0x5c, (byte) 0x8e,
-        (byte) 0x43, (byte) 0x1a, (byte) 0x26, (byte) 0xaa, (byte) 0xee, (byte) 0x38,
-        (byte) 0x11, (byte) 0x26, (byte) 0x3d, (byte) 0x69, (byte) 0xc7, (byte) 0x6a,
-        (byte) 0xe7, (byte) 0xbd, (byte) 0x67, (byte) 0x70, (byte) 0x35, (byte) 0xff,
-        (byte) 0x72, (byte) 0x2c, (byte) 0x87, (byte) 0x82, (byte) 0x68, (byte) 0x3f,
-        (byte) 0x8d
-    };
-
-    private static final byte[] FAKE_EC_2 = {
-        (byte) 0x30, (byte) 0x82, (byte) 0x04, (byte) 0x4f, (byte) 0x30, (byte) 0x82,
-        (byte) 0x03, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-        (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xd9, (byte) 0xc4,
-        (byte) 0xe1, (byte) 0xfc, (byte) 0x3d, (byte) 0x02, (byte) 0x21, (byte) 0x1f,
-        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-        (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-        (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0xbd,
-        (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41,
-        (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06,
-        (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a,
-        (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
-        (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x12,
-        (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-        (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53, (byte) 0x6f, (byte) 0x6d,
-        (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69, (byte) 0x74, (byte) 0x79,
-        (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x12, (byte) 0x53,
-        (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x4f, (byte) 0x74,
-        (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d, (byte) 0x43, (byte) 0x6f,
-        (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e, (byte) 0x79, (byte) 0x31,
-        (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-        (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c, (byte) 0x53, (byte) 0x6f,
-        (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x65, (byte) 0x63,
-        (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e, (byte) 0x31, (byte) 0x21,
-        (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-        (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57, (byte) 0x69, (byte) 0x66,
-        (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72,
-        (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73, (byte) 0x65, (byte) 0x43,
-        (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69, (byte) 0x67, (byte) 0x54,
-        (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31, (byte) 0x2e, (byte) 0x30,
-        (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
-        (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x09, (byte) 0x01,
-        (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e, (byte) 0x2d, (byte) 0x65,
-        (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c, (byte) 0x2d, (byte) 0x61,
-        (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73, (byte) 0x73, (byte) 0x40,
-        (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x64,
-        (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6e, (byte) 0x2e,
-        (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17,
-        (byte) 0x0d, (byte) 0x31, (byte) 0x36, (byte) 0x30, (byte) 0x31, (byte) 0x31,
-        (byte) 0x35, (byte) 0x31, (byte) 0x31, (byte) 0x33, (byte) 0x32, (byte) 0x34,
-        (byte) 0x36, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x36,
-        (byte) 0x30, (byte) 0x31, (byte) 0x31, (byte) 0x32, (byte) 0x31, (byte) 0x31,
-        (byte) 0x33, (byte) 0x32, (byte) 0x34, (byte) 0x36, (byte) 0x5a, (byte) 0x30,
-        (byte) 0x81, (byte) 0xbd, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
-        (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13,
-        (byte) 0x02, (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30,
-        (byte) 0x11, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08,
-        (byte) 0x0c, (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65,
-        (byte) 0x2d, (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65,
-        (byte) 0x31, (byte) 0x12, (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x09, (byte) 0x53,
-        (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x43, (byte) 0x69,
-        (byte) 0x74, (byte) 0x79, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19,
-        (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c,
-        (byte) 0x12, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
-        (byte) 0x4f, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x72, (byte) 0x2d,
-        (byte) 0x43, (byte) 0x6f, (byte) 0x6d, (byte) 0x70, (byte) 0x61, (byte) 0x6e,
-        (byte) 0x79, (byte) 0x31, (byte) 0x15, (byte) 0x30, (byte) 0x13, (byte) 0x06,
-        (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x0c,
-        (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53,
-        (byte) 0x65, (byte) 0x63, (byte) 0x74, (byte) 0x69, (byte) 0x6f, (byte) 0x6e,
-        (byte) 0x31, (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x18, (byte) 0x57,
-        (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x45, (byte) 0x6e, (byte) 0x74,
-        (byte) 0x65, (byte) 0x72, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x73,
-        (byte) 0x65, (byte) 0x43, (byte) 0x6f, (byte) 0x6e, (byte) 0x66, (byte) 0x69,
-        (byte) 0x67, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x31,
-        (byte) 0x2e, (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-        (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-        (byte) 0x09, (byte) 0x01, (byte) 0x16, (byte) 0x1f, (byte) 0x61, (byte) 0x6e,
-        (byte) 0x2d, (byte) 0x65, (byte) 0x6d, (byte) 0x61, (byte) 0x69, (byte) 0x6c,
-        (byte) 0x2d, (byte) 0x61, (byte) 0x64, (byte) 0x72, (byte) 0x65, (byte) 0x73,
-        (byte) 0x73, (byte) 0x40, (byte) 0x73, (byte) 0x6f, (byte) 0x6d, (byte) 0x65,
-        (byte) 0x2d, (byte) 0x64, (byte) 0x6f, (byte) 0x6d, (byte) 0x61, (byte) 0x69,
-        (byte) 0x6e, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
-        (byte) 0x82, (byte) 0x01, (byte) 0x22, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
-        (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
-        (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00,
-        (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x0f, (byte) 0x00, (byte) 0x30,
-        (byte) 0x82, (byte) 0x01, (byte) 0x0a, (byte) 0x02, (byte) 0x82, (byte) 0x01,
-        (byte) 0x01, (byte) 0x00, (byte) 0xa9, (byte) 0xa3, (byte) 0x21, (byte) 0xfd,
-        (byte) 0xa6, (byte) 0xc1, (byte) 0x04, (byte) 0x48, (byte) 0xc2, (byte) 0xc8,
-        (byte) 0x44, (byte) 0x50, (byte) 0xc4, (byte) 0x6d, (byte) 0x35, (byte) 0x24,
-        (byte) 0xf0, (byte) 0x6d, (byte) 0x69, (byte) 0xfb, (byte) 0xd1, (byte) 0xfc,
-        (byte) 0xde, (byte) 0xe9, (byte) 0xdb, (byte) 0xca, (byte) 0xee, (byte) 0x24,
-        (byte) 0x3d, (byte) 0x85, (byte) 0x8d, (byte) 0x84, (byte) 0xb4, (byte) 0x73,
-        (byte) 0xd1, (byte) 0x09, (byte) 0x37, (byte) 0x16, (byte) 0x80, (byte) 0x70,
-        (byte) 0x6b, (byte) 0x61, (byte) 0xcc, (byte) 0xf2, (byte) 0x98, (byte) 0xbd,
-        (byte) 0x53, (byte) 0x3a, (byte) 0x68, (byte) 0x60, (byte) 0x02, (byte) 0xba,
-        (byte) 0x0c, (byte) 0x53, (byte) 0x96, (byte) 0xfb, (byte) 0x80, (byte) 0xd1,
-        (byte) 0x5b, (byte) 0xc3, (byte) 0xcb, (byte) 0x7a, (byte) 0x81, (byte) 0x00,
-        (byte) 0x5d, (byte) 0x20, (byte) 0x72, (byte) 0xc0, (byte) 0xe4, (byte) 0x48,
-        (byte) 0x0e, (byte) 0xa2, (byte) 0xcd, (byte) 0xa2, (byte) 0x63, (byte) 0x8c,
-        (byte) 0x05, (byte) 0x7c, (byte) 0x63, (byte) 0x5b, (byte) 0xda, (byte) 0x0e,
-        (byte) 0xa7, (byte) 0x05, (byte) 0x09, (byte) 0x6d, (byte) 0xd5, (byte) 0xe4,
-        (byte) 0x3a, (byte) 0x4e, (byte) 0xa1, (byte) 0xf5, (byte) 0xfd, (byte) 0x47,
-        (byte) 0xee, (byte) 0x7b, (byte) 0xa3, (byte) 0x4c, (byte) 0x8c, (byte) 0xd3,
-        (byte) 0xbb, (byte) 0x58, (byte) 0x0f, (byte) 0x1c, (byte) 0x56, (byte) 0x80,
-        (byte) 0x80, (byte) 0xb5, (byte) 0xf9, (byte) 0x80, (byte) 0xc2, (byte) 0xd1,
-        (byte) 0x1d, (byte) 0x3f, (byte) 0xe8, (byte) 0x2a, (byte) 0x63, (byte) 0x0b,
-        (byte) 0x54, (byte) 0x5f, (byte) 0xd4, (byte) 0xcb, (byte) 0xb7, (byte) 0x94,
-        (byte) 0xe2, (byte) 0x35, (byte) 0x65, (byte) 0x59, (byte) 0xd1, (byte) 0x72,
-        (byte) 0xa4, (byte) 0xb8, (byte) 0xee, (byte) 0x82, (byte) 0x11, (byte) 0x7a,
-        (byte) 0x4c, (byte) 0x26, (byte) 0x66, (byte) 0x9b, (byte) 0x27, (byte) 0x3d,
-        (byte) 0x14, (byte) 0x4b, (byte) 0x4b, (byte) 0xc8, (byte) 0xf0, (byte) 0x6e,
-        (byte) 0x43, (byte) 0x8f, (byte) 0xee, (byte) 0x1f, (byte) 0xeb, (byte) 0x20,
-        (byte) 0xe2, (byte) 0x4c, (byte) 0x79, (byte) 0xbf, (byte) 0x21, (byte) 0x0d,
-        (byte) 0x36, (byte) 0xed, (byte) 0x5f, (byte) 0xcc, (byte) 0x70, (byte) 0x68,
-        (byte) 0x8a, (byte) 0x05, (byte) 0x7c, (byte) 0x2f, (byte) 0x1b, (byte) 0xe9,
-        (byte) 0xec, (byte) 0x83, (byte) 0x6e, (byte) 0x9a, (byte) 0x78, (byte) 0x31,
-        (byte) 0x3d, (byte) 0xf4, (byte) 0xde, (byte) 0x1b, (byte) 0xd2, (byte) 0x76,
-        (byte) 0x32, (byte) 0x6c, (byte) 0x1e, (byte) 0xc9, (byte) 0x90, (byte) 0x7f,
-        (byte) 0xc4, (byte) 0x30, (byte) 0xc0, (byte) 0xae, (byte) 0xab, (byte) 0x70,
-        (byte) 0x08, (byte) 0x78, (byte) 0xbf, (byte) 0x2e, (byte) 0x8b, (byte) 0x07,
-        (byte) 0xab, (byte) 0x8f, (byte) 0x03, (byte) 0xc5, (byte) 0xd3, (byte) 0xeb,
-        (byte) 0x98, (byte) 0x19, (byte) 0x50, (byte) 0x83, (byte) 0x52, (byte) 0xf7,
-        (byte) 0xff, (byte) 0xf5, (byte) 0x89, (byte) 0xe6, (byte) 0xe7, (byte) 0xa7,
-        (byte) 0xcb, (byte) 0xdf, (byte) 0x96, (byte) 0x9d, (byte) 0x14, (byte) 0x04,
-        (byte) 0x5e, (byte) 0x45, (byte) 0x82, (byte) 0xf7, (byte) 0x23, (byte) 0x1a,
-        (byte) 0xb6, (byte) 0x64, (byte) 0x57, (byte) 0xe8, (byte) 0x7e, (byte) 0xa1,
-        (byte) 0xaf, (byte) 0x58, (byte) 0x68, (byte) 0x70, (byte) 0xc5, (byte) 0x0f,
-        (byte) 0x8d, (byte) 0x54, (byte) 0xf3, (byte) 0x49, (byte) 0xa3, (byte) 0x97,
-        (byte) 0x32, (byte) 0xa7, (byte) 0x2a, (byte) 0x79, (byte) 0xbe, (byte) 0xcd,
-        (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
-        (byte) 0x50, (byte) 0x30, (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06,
-        (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16,
-        (byte) 0x04, (byte) 0x14, (byte) 0xac, (byte) 0xf3, (byte) 0x73, (byte) 0x9a,
-        (byte) 0x25, (byte) 0x08, (byte) 0x01, (byte) 0x07, (byte) 0x86, (byte) 0x8b,
-        (byte) 0xc4, (byte) 0xed, (byte) 0xb1, (byte) 0x6b, (byte) 0x53, (byte) 0xa3,
-        (byte) 0x21, (byte) 0xb4, (byte) 0xb4, (byte) 0x46, (byte) 0x30, (byte) 0x1f,
-        (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04,
-        (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0xac,
-        (byte) 0xf3, (byte) 0x73, (byte) 0x9a, (byte) 0x25, (byte) 0x08, (byte) 0x01,
-        (byte) 0x07, (byte) 0x86, (byte) 0x8b, (byte) 0xc4, (byte) 0xed, (byte) 0xb1,
-        (byte) 0x6b, (byte) 0x53, (byte) 0xa3, (byte) 0x21, (byte) 0xb4, (byte) 0xb4,
-        (byte) 0x46, (byte) 0x30, (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-        (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03,
-        (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
-        (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
-        (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00,
-        (byte) 0x03, (byte) 0x82, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x16,
-        (byte) 0xf6, (byte) 0xd0, (byte) 0xe1, (byte) 0x14, (byte) 0x2d, (byte) 0x52,
-        (byte) 0x47, (byte) 0xa2, (byte) 0x89, (byte) 0xe6, (byte) 0x7f, (byte) 0xac,
-        (byte) 0x88, (byte) 0x04, (byte) 0x15, (byte) 0x21, (byte) 0x00, (byte) 0x72,
-        (byte) 0xf9, (byte) 0xee, (byte) 0xb2, (byte) 0x1b, (byte) 0x8e, (byte) 0x46,
-        (byte) 0x8b, (byte) 0x90, (byte) 0x20, (byte) 0x4f, (byte) 0xa7, (byte) 0xae,
-        (byte) 0x30, (byte) 0xb6, (byte) 0x24, (byte) 0xc5, (byte) 0x54, (byte) 0xaf,
-        (byte) 0x6c, (byte) 0x1e, (byte) 0xd6, (byte) 0x73, (byte) 0x22, (byte) 0x48,
-        (byte) 0x07, (byte) 0xb5, (byte) 0x13, (byte) 0x35, (byte) 0xbb, (byte) 0x9e,
-        (byte) 0xd9, (byte) 0x19, (byte) 0x79, (byte) 0xda, (byte) 0x76, (byte) 0x7f,
-        (byte) 0xf7, (byte) 0x87, (byte) 0xc9, (byte) 0xc3, (byte) 0x0b, (byte) 0x38,
-        (byte) 0x20, (byte) 0x26, (byte) 0xfc, (byte) 0x7f, (byte) 0x32, (byte) 0x2a,
-        (byte) 0xd5, (byte) 0x09, (byte) 0x87, (byte) 0xda, (byte) 0x23, (byte) 0x1f,
-        (byte) 0x71, (byte) 0x83, (byte) 0x00, (byte) 0x17, (byte) 0xf6, (byte) 0xb9,
-        (byte) 0x57, (byte) 0x21, (byte) 0xdf, (byte) 0x29, (byte) 0xcc, (byte) 0xdb,
-        (byte) 0xe9, (byte) 0x2c, (byte) 0xba, (byte) 0x86, (byte) 0x34, (byte) 0x53,
-        (byte) 0x29, (byte) 0x09, (byte) 0xc7, (byte) 0x3c, (byte) 0x8e, (byte) 0xa3,
-        (byte) 0x86, (byte) 0x81, (byte) 0x26, (byte) 0x7b, (byte) 0xa1, (byte) 0xbe,
-        (byte) 0xbc, (byte) 0xc9, (byte) 0x83, (byte) 0xb5, (byte) 0x36, (byte) 0x65,
-        (byte) 0x51, (byte) 0xb4, (byte) 0x41, (byte) 0xf0, (byte) 0x05, (byte) 0x78,
-        (byte) 0x3a, (byte) 0xa6, (byte) 0xad, (byte) 0x4b, (byte) 0x08, (byte) 0xd1,
-        (byte) 0xe4, (byte) 0xf1, (byte) 0x2e, (byte) 0xc7, (byte) 0x23, (byte) 0x6d,
-        (byte) 0xf0, (byte) 0x9d, (byte) 0x60, (byte) 0x6d, (byte) 0xe7, (byte) 0x11,
-        (byte) 0xaf, (byte) 0x41, (byte) 0x68, (byte) 0xee, (byte) 0x06, (byte) 0x76,
-        (byte) 0x82, (byte) 0x48, (byte) 0xee, (byte) 0x41, (byte) 0xc4, (byte) 0xf8,
-        (byte) 0xe1, (byte) 0x83, (byte) 0xbc, (byte) 0xa8, (byte) 0xbd, (byte) 0x9c,
-        (byte) 0x17, (byte) 0x45, (byte) 0xf4, (byte) 0x36, (byte) 0x67, (byte) 0x47,
-        (byte) 0x0e, (byte) 0x32, (byte) 0x13, (byte) 0x6e, (byte) 0xc1, (byte) 0x1e,
-        (byte) 0x08, (byte) 0xef, (byte) 0x10, (byte) 0xdf, (byte) 0x45, (byte) 0xbf,
-        (byte) 0x5a, (byte) 0xc4, (byte) 0x44, (byte) 0x4c, (byte) 0xd0, (byte) 0xd5,
-        (byte) 0x23, (byte) 0xde, (byte) 0xd7, (byte) 0x83, (byte) 0x1e, (byte) 0xb0,
-        (byte) 0x27, (byte) 0x4d, (byte) 0x57, (byte) 0xa3, (byte) 0xe8, (byte) 0x36,
-        (byte) 0x52, (byte) 0x1c, (byte) 0x48, (byte) 0x0a, (byte) 0xc4, (byte) 0xd8,
-        (byte) 0x32, (byte) 0xfc, (byte) 0xd0, (byte) 0x26, (byte) 0x6f, (byte) 0xa4,
-        (byte) 0x61, (byte) 0x2c, (byte) 0x3a, (byte) 0xa9, (byte) 0xfe, (byte) 0xa4,
-        (byte) 0x7a, (byte) 0x58, (byte) 0x54, (byte) 0x58, (byte) 0x96, (byte) 0x2b,
-        (byte) 0x6e, (byte) 0x9c, (byte) 0xc9, (byte) 0x00, (byte) 0xda, (byte) 0xc6,
-        (byte) 0xbb, (byte) 0x97, (byte) 0xc4, (byte) 0x95, (byte) 0x32, (byte) 0x6b,
-        (byte) 0x03, (byte) 0x6f, (byte) 0x33, (byte) 0x59, (byte) 0xd4, (byte) 0xa4,
-        (byte) 0x4a, (byte) 0x29, (byte) 0x29, (byte) 0x9a, (byte) 0xf4, (byte) 0x87,
-        (byte) 0x26, (byte) 0xe6, (byte) 0xee, (byte) 0x5c, (byte) 0x0b, (byte) 0xe9,
-        (byte) 0x98, (byte) 0x5d, (byte) 0xab, (byte) 0x31, (byte) 0xa1, (byte) 0x63,
-        (byte) 0xaa, (byte) 0x1a, (byte) 0xea, (byte) 0x61, (byte) 0x27, (byte) 0x5e,
-        (byte) 0x9e, (byte) 0x34, (byte) 0x73
-    };
-
-    /**
-     * Client certificate generated from above and converted with:
-     *
-     * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_EC_3 = {
-        (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xdf, (byte) 0x30, (byte) 0x82,
-        (byte) 0x01, (byte) 0xc7, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-        (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
-        (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05,
-        (byte) 0x00, (byte) 0x30, (byte) 0x64, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
-        (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
-        (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
-        (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-        (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
-        (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-        (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
-        (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
-        (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
-        (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-        (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, (byte) 0x47, (byte) 0x6f,
-        (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x31, (byte) 0x10,
-        (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-        (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64,
-        (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x0d,
-        (byte) 0x30, (byte) 0x0b, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-        (byte) 0x03, (byte) 0x0c, (byte) 0x04, (byte) 0x54, (byte) 0x45, (byte) 0x53,
-        (byte) 0x54, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31,
-        (byte) 0x37, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x37, (byte) 0x31,
-        (byte) 0x37, (byte) 0x35, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x5a,
-        (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x37, (byte) 0x30, (byte) 0x31,
-        (byte) 0x32, (byte) 0x35, (byte) 0x31, (byte) 0x37, (byte) 0x35, (byte) 0x38,
-        (byte) 0x31, (byte) 0x32, (byte) 0x5a, (byte) 0x30, (byte) 0x50, (byte) 0x31,
-        (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-        (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53,
-        (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43,
-        (byte) 0x41, (byte) 0x31, (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
-        (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06,
-        (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65,
-        (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41,
-        (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64,
-        (byte) 0x31, (byte) 0x11, (byte) 0x30, (byte) 0x0f, (byte) 0x06, (byte) 0x03,
-        (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x08, (byte) 0x54,
-        (byte) 0x45, (byte) 0x53, (byte) 0x54, (byte) 0x2d, (byte) 0x55, (byte) 0x53,
-        (byte) 0x52, (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06,
-        (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d,
-        (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86,
-        (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07,
-        (byte) 0x03, (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0x4a, (byte) 0xb8,
-        (byte) 0x60, (byte) 0x17, (byte) 0x40, (byte) 0x91, (byte) 0x30, (byte) 0xf7,
-        (byte) 0xdf, (byte) 0x36, (byte) 0x83, (byte) 0x31, (byte) 0xb5, (byte) 0x3a,
-        (byte) 0xf4, (byte) 0xd4, (byte) 0xa1, (byte) 0xce, (byte) 0xd5, (byte) 0x54,
-        (byte) 0x97, (byte) 0x93, (byte) 0x7e, (byte) 0x7b, (byte) 0x08, (byte) 0x63,
-        (byte) 0x37, (byte) 0x62, (byte) 0xf1, (byte) 0x4e, (byte) 0x6a, (byte) 0x2e,
-        (byte) 0x35, (byte) 0x4e, (byte) 0x9f, (byte) 0x48, (byte) 0xcd, (byte) 0x09,
-        (byte) 0x17, (byte) 0xb3, (byte) 0xc1, (byte) 0x58, (byte) 0x02, (byte) 0x49,
-        (byte) 0x7b, (byte) 0x4c, (byte) 0xf7, (byte) 0x9b, (byte) 0xbb, (byte) 0x1b,
-        (byte) 0x2b, (byte) 0x9c, (byte) 0xe9, (byte) 0x36, (byte) 0xc4, (byte) 0x00,
-        (byte) 0x81, (byte) 0x2c, (byte) 0x28, (byte) 0xd9, (byte) 0x6b, (byte) 0xad,
-        (byte) 0xe3, (byte) 0xe8, (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79,
-        (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
-        (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30,
-        (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48,
-        (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d,
-        (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70,
-        (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20,
-        (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61,
-        (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65,
-        (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63,
-        (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06,
-        (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16,
-        (byte) 0x04, (byte) 0x14, (byte) 0xef, (byte) 0xf0, (byte) 0x15, (byte) 0xd7,
-        (byte) 0xc9, (byte) 0x3e, (byte) 0x9a, (byte) 0x73, (byte) 0xfa, (byte) 0x38,
-        (byte) 0xc5, (byte) 0x81, (byte) 0x84, (byte) 0x74, (byte) 0xd3, (byte) 0x83,
-        (byte) 0x74, (byte) 0x26, (byte) 0xf1, (byte) 0x0b, (byte) 0x30, (byte) 0x1f,
-        (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04,
-        (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x38,
-        (byte) 0x6a, (byte) 0x9b, (byte) 0xf8, (byte) 0x3c, (byte) 0x0d, (byte) 0x54,
-        (byte) 0x9f, (byte) 0xdf, (byte) 0xf8, (byte) 0x53, (byte) 0x32, (byte) 0xa8,
-        (byte) 0xf7, (byte) 0x09, (byte) 0x15, (byte) 0x08, (byte) 0x76, (byte) 0xab,
-        (byte) 0x8d, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-        (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-        (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82,
-        (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0xa6, (byte) 0x6c, (byte) 0x18,
-        (byte) 0xa9, (byte) 0x67, (byte) 0x16, (byte) 0x6a, (byte) 0x9e, (byte) 0x23,
-        (byte) 0xb3, (byte) 0x2a, (byte) 0xb8, (byte) 0x16, (byte) 0x7b, (byte) 0xb4,
-        (byte) 0xc8, (byte) 0xbc, (byte) 0x51, (byte) 0xe0, (byte) 0x6f, (byte) 0x05,
-        (byte) 0x66, (byte) 0xa1, (byte) 0x6f, (byte) 0x96, (byte) 0xde, (byte) 0x5b,
-        (byte) 0x41, (byte) 0x60, (byte) 0xe5, (byte) 0x29, (byte) 0x99, (byte) 0x12,
-        (byte) 0xfc, (byte) 0xa9, (byte) 0x91, (byte) 0x23, (byte) 0xb7, (byte) 0x9e,
-        (byte) 0x00, (byte) 0x5f, (byte) 0x93, (byte) 0xd4, (byte) 0xf7, (byte) 0x27,
-        (byte) 0x29, (byte) 0x77, (byte) 0xfb, (byte) 0x53, (byte) 0x09, (byte) 0xdc,
-        (byte) 0xe9, (byte) 0xd0, (byte) 0x5c, (byte) 0x92, (byte) 0x6d, (byte) 0xb7,
-        (byte) 0xcf, (byte) 0x04, (byte) 0xab, (byte) 0xf1, (byte) 0x39, (byte) 0xb9,
-        (byte) 0x49, (byte) 0x23, (byte) 0x7c, (byte) 0x0f, (byte) 0x15, (byte) 0x27,
-        (byte) 0xcd, (byte) 0x65, (byte) 0x3c, (byte) 0x6b, (byte) 0x91, (byte) 0x42,
-        (byte) 0x5a, (byte) 0xfe, (byte) 0xbe, (byte) 0xb8, (byte) 0xa2, (byte) 0xfd,
-        (byte) 0x67, (byte) 0x43, (byte) 0x4b, (byte) 0xc9, (byte) 0x28, (byte) 0x65,
-        (byte) 0x1b, (byte) 0x82, (byte) 0x5b, (byte) 0x25, (byte) 0x20, (byte) 0x9b,
-        (byte) 0xea, (byte) 0x99, (byte) 0xbb, (byte) 0x66, (byte) 0xc1, (byte) 0x8e,
-        (byte) 0x46, (byte) 0x0b, (byte) 0x4e, (byte) 0x06, (byte) 0xdd, (byte) 0x50,
-        (byte) 0x51, (byte) 0x64, (byte) 0xe8, (byte) 0x83, (byte) 0x99, (byte) 0x8e,
-        (byte) 0x53, (byte) 0xe9, (byte) 0x48, (byte) 0x47, (byte) 0x0e, (byte) 0x08,
-        (byte) 0x5e, (byte) 0x0d, (byte) 0x4a, (byte) 0x54, (byte) 0x17, (byte) 0xc1,
-        (byte) 0xf8, (byte) 0xcf, (byte) 0xba, (byte) 0x5c, (byte) 0x38, (byte) 0x70,
-        (byte) 0x33, (byte) 0x31, (byte) 0x22, (byte) 0x03, (byte) 0x6f, (byte) 0x54,
-        (byte) 0x3c, (byte) 0x41, (byte) 0xf0, (byte) 0x89, (byte) 0x85, (byte) 0xbc,
-        (byte) 0x77, (byte) 0x3c, (byte) 0xe8, (byte) 0xec, (byte) 0xb4, (byte) 0x35,
-        (byte) 0x7a, (byte) 0xcc, (byte) 0x8c, (byte) 0x5f, (byte) 0xa1, (byte) 0xed,
-        (byte) 0xa6, (byte) 0x28, (byte) 0x14, (byte) 0xc7, (byte) 0x8a, (byte) 0xef,
-        (byte) 0x56, (byte) 0x26, (byte) 0x35, (byte) 0x46, (byte) 0xab, (byte) 0xb0,
-        (byte) 0x97, (byte) 0xd2, (byte) 0xbd, (byte) 0xa9, (byte) 0x6a, (byte) 0xe4,
-        (byte) 0x3e, (byte) 0x87, (byte) 0xfb, (byte) 0xe1, (byte) 0x09, (byte) 0x8d,
-        (byte) 0x33, (byte) 0x12, (byte) 0xcf, (byte) 0xf0, (byte) 0xc0, (byte) 0xb8,
-        (byte) 0x9b, (byte) 0x9f, (byte) 0xb1, (byte) 0xcb, (byte) 0xac, (byte) 0x76,
-        (byte) 0xa8, (byte) 0x05, (byte) 0x6b, (byte) 0xcc, (byte) 0x41, (byte) 0xd2,
-        (byte) 0x26, (byte) 0x73, (byte) 0xfa, (byte) 0x69, (byte) 0xd3, (byte) 0x1f,
-        (byte) 0xa9, (byte) 0x0c, (byte) 0x6a, (byte) 0xd6, (byte) 0xc9, (byte) 0x35,
-        (byte) 0xc5, (byte) 0xad, (byte) 0xa1, (byte) 0x98, (byte) 0xc9, (byte) 0x78,
-        (byte) 0xa0, (byte) 0xe8, (byte) 0x02, (byte) 0x69, (byte) 0x80, (byte) 0x44,
-        (byte) 0xd9, (byte) 0xe6, (byte) 0xe5, (byte) 0x26, (byte) 0x4f, (byte) 0xcf,
-        (byte) 0x38, (byte) 0xcb, (byte) 0x55, (byte) 0x8c, (byte) 0x7d, (byte) 0x3c,
-        (byte) 0xa8, (byte) 0x82, (byte) 0x69, (byte) 0xa3, (byte) 0xdf, (byte) 0x0a,
-        (byte) 0x79, (byte) 0x7b, (byte) 0xdd, (byte) 0x24, (byte) 0x6a, (byte) 0x21,
-        (byte) 0x7b, (byte) 0x20, (byte) 0x94, (byte) 0xcd, (byte) 0x15, (byte) 0x92,
-        (byte) 0xad, (byte) 0x4a, (byte) 0x72, (byte) 0x0b, (byte) 0x0e, (byte) 0xb2,
-        (byte) 0xc9
-    };
-
-    private static final byte[] FAKE_KEY_3 = {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
-            (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
-            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
-            (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
-            (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
-            (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
-            (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
-            (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
-            (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
-            (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
-            (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
-            (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
-            (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
-            (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
-            (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
-            (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
-            (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
-            (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
-            (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
-            (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
-            (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
-            (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
-            (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
-            (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
-            (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
-            (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
-            (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
-            (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
-            (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
-            (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
-            (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
-            (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
-            (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
-            (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
-            (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
-            (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
-            (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
-            (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
-            (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
-            (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
-            (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
-            (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
-            (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
-            (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
-            (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
-            (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
-            (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
-            (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
-            (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
-            (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
-            (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
-            (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
-            (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
-            (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
-            (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
-            (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
-            (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
-            (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
-            (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
-            (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
-            (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
-            (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
-            (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
-            (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
-            (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
-            (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
-            (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
-            (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
-            (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
-            (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
-            (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
-            (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
-            (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
-            (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
-            (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
-            (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
-            (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
-            (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
-            (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
-            (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
-            (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
-            (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
-            (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
-            (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
-            (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
-            (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
-            (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
-            (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
-            (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
-            (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
-            (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
-            (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
-            (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
-            (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
-            (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
-            (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
-            (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
-            (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
-            (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
-            (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
-            (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
-            (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
-    };
-
-    private boolean hasWifi() {
-        return getContext().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_WIFI);
-    }
-
-    public void testSettersAndGetters() throws Exception {
-        if (!hasWifi()) {
-            return;
-        }
-
-        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
-        assertTrue(config.getEapMethod() == Eap.NONE);
-        config.setEapMethod(Eap.PEAP);
-        assertTrue(config.getEapMethod() == Eap.PEAP);
-        config.setEapMethod(Eap.PWD);
-        assertTrue(config.getEapMethod() == Eap.PWD);
-        config.setEapMethod(Eap.TLS);
-        assertTrue(config.getEapMethod() == Eap.TLS);
-        config.setEapMethod(Eap.TTLS);
-        assertTrue(config.getEapMethod() == Eap.TTLS);
-        assertTrue(config.getPhase2Method() == Phase2.NONE);
-        config.setPhase2Method(Phase2.PAP);
-        assertTrue(config.getPhase2Method() == Phase2.PAP);
-        config.setPhase2Method(Phase2.MSCHAP);
-        assertTrue(config.getPhase2Method() == Phase2.MSCHAP);
-        config.setPhase2Method(Phase2.MSCHAPV2);
-        assertTrue(config.getPhase2Method() == Phase2.MSCHAPV2);
-        config.setPhase2Method(Phase2.GTC);
-        assertTrue(config.getPhase2Method() == Phase2.GTC);
-        config.setIdentity(IDENTITY);
-        assertTrue(config.getIdentity().equals(IDENTITY));
-        config.setAnonymousIdentity(ANON_IDENTITY);
-        assertTrue(config.getAnonymousIdentity().equals(ANON_IDENTITY));
-        config.setPassword(PASSWORD);
-        assertTrue(config.getPassword().equals(PASSWORD));
-        CertificateFactory factory = CertificateFactory.getInstance("X.509");
-        X509Certificate cert1 = (X509Certificate) factory.generateCertificate(
-                new ByteArrayInputStream(FAKE_EC_1));
-        X509Certificate cert2 = (X509Certificate) factory.generateCertificate(
-                new ByteArrayInputStream(FAKE_EC_2));
-        config.setCaCertificate(cert1);
-        assertTrue(config.getCaCertificate().getSerialNumber().equals(cert1.getSerialNumber()));
-        config.setCaCertificates(new X509Certificate[]{cert1, cert2});
-        X509Certificate[] certs = config.getCaCertificates();
-        assertTrue(cert1.getSerialNumber().equals(certs[0].getSerialNumber()));
-        assertTrue(cert2.getSerialNumber().equals(certs[1].getSerialNumber()));
-
-        X509Certificate clientCert = (X509Certificate) factory.generateCertificate(
-                new ByteArrayInputStream(FAKE_EC_3));
-        KeyFactory kf = KeyFactory.getInstance("RSA");
-        PrivateKey clientKey = kf.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_3));
-
-        config.setClientKeyEntry(clientKey, clientCert);
-        X509Certificate testClientCert = config.getClientCertificate();
-        X509Certificate[] testClientCertChain = config.getClientCertificateChain();
-        assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber()));
-        assertTrue(testClientCertChain.length == 1);
-        assertTrue(testClientCertChain[0] == testClientCert);
-
-        config.setClientKeyEntry(null, null);
-        assertTrue(config.getClientCertificate() == null);
-        assertTrue(config.getClientCertificateChain() == null);
-
-        config.setClientKeyEntryWithCertificateChain(clientKey,
-                new X509Certificate[]{clientCert, cert1});
-        testClientCert = config.getClientCertificate();
-        testClientCertChain = config.getClientCertificateChain();
-        assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber()));
-        assertTrue(testClientCertChain.length == 2);
-        assertTrue(testClientCertChain[0] == testClientCert);
-        assertTrue(testClientCertChain[1] == cert1);
-        assertSame(clientKey, config.getClientPrivateKey());
-
-        config.setSubjectMatch(SUBJECT_MATCH);
-        assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH));
-        // Hotspot 2.0 related attributes
-        config.setPlmn(PLMN);
-        assertTrue(config.getPlmn().equals(PLMN));
-        config.setRealm(REALM);
-        assertTrue(config.getRealm().equals(REALM));
-        config.setAltSubjectMatch(ALT_SUBJECT_MATCH);
-        assertTrue(config.getAltSubjectMatch().equals(ALT_SUBJECT_MATCH));
-        config.setDomainSuffixMatch(DOM_SUBJECT_MATCH);
-        assertTrue(config.getDomainSuffixMatch().equals(DOM_SUBJECT_MATCH));
-    }
-
-    public void testEnterpriseConfigDoesNotPrintPassword() {
-        if(!hasWifi()) {
-            return;
-        }
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        final String identity = "IdentityIsOkayToBeDisplayedHere";
-        final String password = "PasswordIsNotOkayToBeDisplayedHere";
-        enterpriseConfig.setIdentity(identity);
-        enterpriseConfig.setPassword(password);
-        final String stringRepresentation = enterpriseConfig.toString();
-        assertTrue(stringRepresentation.contains(identity));
-        assertFalse(stringRepresentation.contains(password));
-    }
-
-    public void testGetSetCaCertificateAliases() {
-        if (!hasWifi()) {
-            return;
-        }
-        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
-
-        config.setCaCertificateAliases(null);
-        assertThat(config.getCaCertificateAliases()).isNull();
-
-        config.setCaCertificateAliases(new String[]{CERTIFICATE_ALIAS1});
-        assertThat(config.getCaCertificateAliases()).isEqualTo(new String[]{CERTIFICATE_ALIAS1});
-
-        config.setCaCertificateAliases(new String[]{CERTIFICATE_ALIAS1, CERTIFICATE_ALIAS2});
-        assertThat(config.getCaCertificateAliases())
-                .isEqualTo(new String[]{CERTIFICATE_ALIAS1, CERTIFICATE_ALIAS2});
-    }
-
-    public void testGetSetCaPath() {
-        if (!hasWifi()) {
-            return;
-        }
-        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
-
-        config.setCaPath("");
-        assertThat(config.getCaPath()).isEmpty();
-
-        config.setCaPath(CA_PATH);
-        assertThat(config.getCaPath()).isEqualTo(CA_PATH);
-    }
-
-    public void testGetSetClientCertificateAlias() {
-        if (!hasWifi()) {
-            return;
-        }
-        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
-
-        config.setClientCertificateAlias("");
-        assertThat(config.getClientCertificateAlias()).isEmpty();
-
-        config.setClientCertificateAlias(CLIENT_CERTIFICATE_ALIAS);
-        assertThat(config.getClientCertificateAlias()).isEqualTo(CLIENT_CERTIFICATE_ALIAS);
-    }
-
-    public void testGetSetOcsp() {
-        if (!hasWifi()) {
-            return;
-        }
-        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
-
-        config.setOcsp(WifiEnterpriseConfig.OCSP_NONE);
-        assertThat(config.getOcsp()).isEqualTo(WifiEnterpriseConfig.OCSP_NONE);
-
-        config.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
-        assertThat(config.getOcsp())
-                .isEqualTo(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
-
-        try {
-            config.setOcsp(-1);
-            fail("WifiEnterpriseConfig.setOcsp(-1) did not throw an IllegalArgumentException!");
-        } catch (IllegalArgumentException expected) {}
-    }
-
-    public void testGetSetWapiCertSuite() {
-        if (!hasWifi()) {
-            return;
-        }
-        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
-
-        config.setWapiCertSuite("");
-        assertThat(config.getWapiCertSuite()).isEmpty();
-
-        config.setWapiCertSuite(WAPI_CERT_SUITE);
-        assertThat(config.getWapiCertSuite()).isEqualTo(WAPI_CERT_SUITE);
-    }
-
-    public void testIsAuthenticationSimBased() {
-        if (!hasWifi()) {
-            return;
-        }
-        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
-
-        config.setEapMethod(Eap.AKA);
-        assertThat(config.isAuthenticationSimBased()).isTrue();
-
-        config.setEapMethod(Eap.PWD);
-        assertThat(config.isAuthenticationSimBased()).isFalse();
-
-        config.setEapMethod(Eap.PEAP);
-        config.setPhase2Method(Phase2.SIM);
-        assertThat(config.isAuthenticationSimBased()).isTrue();
-
-        config.setEapMethod(Eap.PEAP);
-        config.setPhase2Method(Phase2.NONE);
-        assertThat(config.isAuthenticationSimBased()).isFalse();
-    }
-
-    public void testCopyConstructor() {
-        if (!hasWifi()) {
-            return;
-        }
-        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
-        config.setEapMethod(Eap.WAPI_CERT);
-        config.setWapiCertSuite(WAPI_CERT_SUITE);
-        config.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
-        config.setCaPath(CA_PATH);
-        config.setPassword(PASSWORD);
-        config.setRealm(REALM);
-
-        WifiEnterpriseConfig copy = new WifiEnterpriseConfig(config);
-        assertThat(copy.getEapMethod()).isEqualTo(Eap.WAPI_CERT);
-        assertThat(copy.getWapiCertSuite()).isEqualTo(WAPI_CERT_SUITE);
-        assertThat(copy.getOcsp())
-                .isEqualTo(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
-        assertThat(copy.getCaPath()).isEqualTo(CA_PATH);
-        assertThat(copy.getPassword()).isEqualTo(PASSWORD);
-        assertThat(copy.getRealm()).isEqualTo(REALM);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java b/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java
deleted file mode 100644
index 3e9fef4..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiFeature.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 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 android.content.Context;
-import android.content.pm.PackageManager;
-
-public class WifiFeature {
-    public static boolean isWifiSupported(Context context) {
-        PackageManager packageManager = context.getPackageManager();
-        return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
-    }
-
-    public static boolean isP2pSupported(Context context) {
-        PackageManager packageManager = context.getPackageManager();
-        return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiFrameworkInitializerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiFrameworkInitializerTest.java
deleted file mode 100644
index d714ed6..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiFrameworkInitializerTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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 android.net.wifi.WifiFrameworkInitializer;
-import android.test.AndroidTestCase;
-
-public class WifiFrameworkInitializerTest extends AndroidTestCase {
-    /**
-     * WifiFrameworkInitializer.registerServiceWrappers() should only be called by
-     * SystemServiceRegistry during boot up when Wifi is first initialized. Calling this API at
-     * any other time should throw an exception.
-     */
-    public void testRegisterServiceWrappers_failsWhenCalledOutsideOfSystemServiceRegistry() {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        try {
-            WifiFrameworkInitializer.registerServiceWrappers();
-            fail("Expected exception when calling "
-                    + "WifiFrameworkInitializer.registerServiceWrappers() outside of "
-                    + "SystemServiceRegistry!");
-        } catch (IllegalStateException expected) {}
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java b/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java
deleted file mode 100644
index a05b81b..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiHotspot2Test.java
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * 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.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
-
-import android.net.Uri;
-import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.test.AndroidTestCase;
-import android.text.TextUtils;
-
-import java.lang.reflect.Constructor;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-public class WifiHotspot2Test extends AndroidTestCase {
-    static final int SIM_CREDENTIAL = 0;
-    static final int USER_CREDENTIAL = 1;
-    static final int CERT_CREDENTIAL = 2;
-    private static final String TEST_SSID = "TEST SSID";
-    private static final String TEST_FRIENDLY_NAME = "Friendly Name";
-    private static final Map<String, String> TEST_FRIENDLY_NAMES =
-            new HashMap<String, String>() {
-                {
-                    put("en", TEST_FRIENDLY_NAME);
-                    put("kr", TEST_FRIENDLY_NAME + 2);
-                    put("jp", TEST_FRIENDLY_NAME + 3);
-                }
-            };
-    private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
-    private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
-    private static final String TEST_NAI = "test.access.com";
-    private static final List<Integer> TEST_METHOD_LIST =
-            Arrays.asList(1 /* METHOD_SOAP_XML_SPP */);
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * Tests {@link PasspointConfiguration#getMeteredOverride()} method.
-     * <p>
-     * Test default value
-     */
-    public void testGetMeteredOverride() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
-        assertEquals(METERED_OVERRIDE_NONE, passpointConfiguration.getMeteredOverride());
-    }
-
-    /**
-     * Tests {@link PasspointConfiguration#getSubscriptionExpirationTimeMillis()} method.
-     * <p>
-     * Test default value
-     */
-    public void testGetSubscriptionExpirationTimeMillis() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
-        assertEquals(Long.MIN_VALUE,
-                passpointConfiguration.getSubscriptionExpirationTimeMillis());
-    }
-
-    /**
-     * Tests {@link PasspointConfiguration#getUniqueId()} method.
-     * <p>
-     * Test unique identifier is not null
-     */
-    public void testGetUniqueId() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // Create a configuration and make sure the unique ID is not null
-        PasspointConfiguration passpointConfiguration1 = createConfig(SIM_CREDENTIAL, "123456*",
-                18 /* EAP_SIM */);
-        String uniqueId1 = passpointConfiguration1.getUniqueId();
-        assertNotNull(uniqueId1);
-
-        // Create another configuration and make sure the unique ID is not null
-        PasspointConfiguration passpointConfiguration2 = createConfig(SIM_CREDENTIAL, "567890*",
-                23 /* EAP_AKA */);
-        String uniqueId2 = passpointConfiguration2.getUniqueId();
-        assertNotNull(uniqueId2);
-
-        // Make sure the IDs are not equal
-        assertFalse(uniqueId1.equals(uniqueId2));
-
-        passpointConfiguration2 = createConfig(USER_CREDENTIAL);
-        assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId()));
-
-        passpointConfiguration2 = createConfig(CERT_CREDENTIAL);
-        assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId()));
-    }
-
-    /**
-     * Tests {@link PasspointConfiguration#isAutojoinEnabled()} method.
-     * <p>
-     * Test default value
-     */
-    public void testIsAutojoinEnabled() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
-        assertTrue(passpointConfiguration.isAutojoinEnabled());
-    }
-
-    /**
-     * Tests {@link PasspointConfiguration#isMacRandomizationEnabled()} method.
-     * <p>
-     * Test default value
-     */
-    public void testIsMacRandomizationEnabled() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
-        assertTrue(passpointConfiguration.isMacRandomizationEnabled());
-    }
-
-    /**
-     * Tests {@link PasspointConfiguration#isOsuProvisioned()} method.
-     * <p>
-     * Test default value
-     */
-    public void testIsOsuProvisioned() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL);
-        assertFalse(passpointConfiguration.isOsuProvisioned());
-    }
-
-    /**
-     * Tests {@link PasspointConfiguration#PasspointConfiguration(PasspointConfiguration)} method.
-     * <p>
-     * Test the PasspointConfiguration copy constructor
-     */
-    public void testPasspointConfigurationCopyConstructor() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL);
-        PasspointConfiguration copyOfPasspointConfiguration =
-                new PasspointConfiguration(passpointConfiguration);
-        assertEquals(passpointConfiguration, copyOfPasspointConfiguration);
-    }
-
-    /**
-     * Tests {@link HomeSp#HomeSp(HomeSp)} method.
-     * <p>
-     * Test the HomeSp copy constructor
-     */
-    public void testHomeSpCopyConstructor() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        HomeSp homeSp = createHomeSp();
-        HomeSp copyOfHomeSp = new HomeSp(homeSp);
-        assertEquals(copyOfHomeSp, homeSp);
-    }
-
-    /**
-     * Tests {@link Credential#Credential(Credential)} method.
-     * <p>
-     * Test the Credential copy constructor
-     */
-    public void testCredentialCopyConstructor() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        Credential credential = createCredentialWithSimCredential("123456*", 18 /* EAP_SIM */);
-        Credential copyOfCredential = new Credential(credential);
-        assertEquals(copyOfCredential, credential);
-    }
-
-    /**
-     * Tests {@link Credential.UserCredential#UserCredential(Credential.UserCredential)} method.
-     * <p>
-     * Test the Credential.UserCredential copy constructor
-     */
-    public void testUserCredentialCopyConstructor() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        Credential.UserCredential userCredential = new Credential.UserCredential();
-        userCredential.setUsername("username");
-        userCredential.setPassword("password");
-        userCredential.setEapType(21 /* EAP_TTLS */);
-        userCredential.setNonEapInnerMethod("MS-CHAP");
-
-        Credential.UserCredential copyOfUserCredential =
-                new Credential.UserCredential(userCredential);
-        assertEquals(copyOfUserCredential, userCredential);
-    }
-
-    /**
-     * Tests
-     * {@link Credential.CertificateCredential#CertificateCredential(Credential.CertificateCredential)}
-     * method.
-     * <p>
-     * Test the Credential.CertificateCredential copy constructor
-     */
-    public void testCertCredentialCopyConstructor() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
-        certCredential.setCertType("x509v3");
-
-        Credential.CertificateCredential copyOfCertificateCredential =
-                new Credential.CertificateCredential(certCredential);
-        assertEquals(copyOfCertificateCredential, certCredential);
-    }
-
-    /**
-     * Tests {@link Credential.SimCredential#SimCredential(Credential.SimCredential)} method.
-     * <p>
-     * Test the Credential.SimCredential copy constructor
-     */
-    public void testSimCredentialCopyConstructor() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        Credential.SimCredential simCredential = new Credential.SimCredential();
-        simCredential.setImsi("1234*");
-        simCredential.setEapType(18/* EAP_SIM */);
-
-        Credential.SimCredential copyOfSimCredential = new Credential.SimCredential(simCredential);
-        assertEquals(copyOfSimCredential, simCredential);
-    }
-
-    /**
-     * Tests {@link Credential#getCaCertificate()}  method.
-     * <p>
-     * Test that getting a set certificate produces the same value
-     */
-    public void testCredentialGetCertificate() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        Credential credential = new Credential();
-        credential.setCaCertificate(FakeKeys.CA_CERT0);
-
-        assertEquals(FakeKeys.CA_CERT0, credential.getCaCertificate());
-    }
-
-    /**
-     * Tests {@link Credential#getClientCertificateChain()} and {@link
-     * Credential#setCaCertificates(X509Certificate[])} methods.
-     * <p>
-     * Test that getting a set client certificate chain produces the same value
-     */
-    public void testCredentialClientCertificateChain() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        Credential credential = new Credential();
-        X509Certificate[] certificates = new X509Certificate[]{FakeKeys.CLIENT_CERT};
-        credential.setClientCertificateChain(certificates);
-
-        assertTrue(Arrays.equals(certificates, credential.getClientCertificateChain()));
-    }
-
-    /**
-     * Tests {@link Credential#getClientPrivateKey()} and
-     * {@link Credential#setClientPrivateKey(PrivateKey)}
-     * methods.
-     * <p>
-     * Test that getting a set client private key produces the same value
-     */
-    public void testCredentialSetGetClientPrivateKey() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        Credential credential = new Credential();
-        credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
-
-        assertEquals(FakeKeys.RSA_KEY1, credential.getClientPrivateKey());
-    }
-
-    /**
-     * Tests {@link Credential#getClientPrivateKey()} and
-     * {@link Credential#setClientPrivateKey(PrivateKey)}
-     * methods.
-     * <p>
-     * Test that getting a set client private key produces the same value
-     */
-    public void testCredentialGetClientPrivateKey() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        Credential credential = new Credential();
-        credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
-
-        assertEquals(FakeKeys.RSA_KEY1, credential.getClientPrivateKey());
-    }
-
-    private static PasspointConfiguration createConfig(int type) throws Exception {
-        return createConfig(type, "123456*", 18 /* EAP_SIM */);
-    }
-
-    private static PasspointConfiguration createConfig(int type, String imsi, int eapType)
-            throws Exception {
-        PasspointConfiguration config = new PasspointConfiguration();
-        config.setHomeSp(createHomeSp());
-        switch (type) {
-            default:
-            case SIM_CREDENTIAL:
-                config.setCredential(
-                        createCredentialWithSimCredential(imsi, eapType));
-                break;
-            case USER_CREDENTIAL:
-                config.setCredential(createCredentialWithUserCredential());
-                break;
-            case CERT_CREDENTIAL:
-                config.setCredential(createCredentialWithCertificateCredential());
-                break;
-        }
-
-        return config;
-    }
-
-    /**
-     * Helper function for generating HomeSp for testing.
-     *
-     * @return {@link HomeSp}
-     */
-    private static HomeSp createHomeSp() {
-        HomeSp homeSp = new HomeSp();
-        homeSp.setFqdn("test.com");
-        homeSp.setFriendlyName("friendly name");
-        homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66});
-        return homeSp;
-    }
-
-    /**
-     * Helper function for generating Credential for testing.
-     *
-     * @param userCred               Instance of UserCredential
-     * @param certCred               Instance of CertificateCredential
-     * @param simCred                Instance of SimCredential
-     * @param clientCertificateChain Chain of client certificates
-     * @param clientPrivateKey       Client private key
-     * @param caCerts                CA certificates
-     * @return {@link Credential}
-     */
-    private static Credential createCredential(Credential.UserCredential userCred,
-            Credential.CertificateCredential certCred,
-            Credential.SimCredential simCred,
-            X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey,
-            X509Certificate... caCerts) {
-        Credential cred = new Credential();
-        cred.setRealm("realm");
-        cred.setUserCredential(userCred);
-        cred.setCertCredential(certCred);
-        cred.setSimCredential(simCred);
-        return cred;
-    }
-
-    /**
-     * Helper function for generating certificate credential for testing.
-     *
-     * @return {@link Credential}
-     */
-    private static Credential createCredentialWithCertificateCredential()
-            throws NoSuchAlgorithmException, CertificateEncodingException {
-        Credential.CertificateCredential certCred = new Credential.CertificateCredential();
-        certCred.setCertType("x509v3");
-        certCred.setCertSha256Fingerprint(
-                MessageDigest.getInstance("SHA-256").digest(
-                        FakeKeys.CLIENT_CERT.getEncoded()));
-        return createCredential(null, certCred, null, new X509Certificate[]{
-                        FakeKeys.CLIENT_CERT},
-                FakeKeys.RSA_KEY1, FakeKeys.CA_CERT0,
-                FakeKeys.CA_CERT1);
-    }
-
-    /**
-     * Helper function for generating SIM credential for testing.
-     *
-     * @return {@link Credential}
-     */
-    private static Credential createCredentialWithSimCredential(String imsi, int eapType) {
-        Credential.SimCredential simCred = new Credential.SimCredential();
-        simCred.setImsi(imsi);
-        simCred.setEapType(eapType);
-        return createCredential(null, null, simCred, null, null, (X509Certificate[]) null);
-    }
-
-    /**
-     * Helper function for generating user credential for testing.
-     *
-     * @return {@link Credential}
-     */
-    private static Credential createCredentialWithUserCredential() {
-        Credential.UserCredential userCred = new Credential.UserCredential();
-        userCred.setUsername("username");
-        userCred.setPassword("password");
-        userCred.setEapType(21 /* EAP_TTLS */);
-        userCred.setNonEapInnerMethod("MS-CHAP");
-        return createCredential(userCred, null, null, null, null,
-                FakeKeys.CA_CERT0);
-    }
-
-    /**
-     * Tests {@link OsuProvider#getFriendlyName()} and {@link OsuProvider#getServerUri()} methods.
-     * <p>
-     * Test that getting a set friendly name and server URI produces the same value
-     */
-    public void testOsuProviderGetters() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // Using Java reflection to construct an OsuProvider instance because its constructor is
-        // hidden and not available to apps.
-        Class<?> osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider");
-        Constructor<?> osuProviderClassConstructor = osuProviderClass.getConstructor(String.class,
-                Map.class, String.class, Uri.class, String.class, List.class);
-
-        OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID,
-                TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI,
-                TEST_METHOD_LIST);
-        String lang = Locale.getDefault().getLanguage();
-        String friendlyName = TEST_FRIENDLY_NAMES.get(lang);
-        if (TextUtils.isEmpty(friendlyName)) {
-            friendlyName = TEST_FRIENDLY_NAMES.get("en");
-        }
-        assertEquals(friendlyName, osuProvider.getFriendlyName());
-        assertEquals(TEST_SERVER_URI, osuProvider.getServerUri());
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
deleted file mode 100644
index 557710d..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.google.common.truth.Truth.assertThat;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.wifi.ScanResult;
-import android.net.wifi.SupplicantState;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.WifiLock;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-import com.android.compatibility.common.util.PollingCheck;
-import com.android.compatibility.common.util.SystemUtil;
-
-import java.nio.charset.StandardCharsets;
-import java.util.concurrent.Callable;
-
-@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class WifiInfoTest extends AndroidTestCase {
-    private static class MySync {
-        int expectedState = STATE_NULL;
-    }
-
-    private WifiManager mWifiManager;
-    private WifiLock mWifiLock;
-    private static MySync mMySync;
-
-    private static final int STATE_NULL = 0;
-    private static final int STATE_WIFI_CHANGING = 1;
-    private static final int STATE_WIFI_CHANGED = 2;
-
-    private static final String TEST_SSID = "Test123";
-    private static final String TEST_BSSID = "12:12:12:12:12:12";
-    private static final int TEST_RSSI = -60;
-    private static final int TEST_NETWORK_ID = 5;
-    private static final int TEST_NETWORK_ID2 = 6;
-
-    private static final String TAG = "WifiInfoTest";
-    private static final int TIMEOUT_MSEC = 6000;
-    private static final int WAIT_MSEC = 60;
-    private static final int DURATION = 10000;
-    private IntentFilter mIntentFilter;
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-                synchronized (mMySync) {
-                    mMySync.expectedState = STATE_WIFI_CHANGED;
-                    mMySync.notify();
-                }
-            }
-        }
-    };
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        mMySync = new MySync();
-        mIntentFilter = new IntentFilter();
-        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-
-        mContext.registerReceiver(mReceiver, mIntentFilter);
-        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        assertThat(mWifiManager).isNotNull();
-        mWifiLock = mWifiManager.createWifiLock(TAG);
-        mWifiLock.acquire();
-        if (!mWifiManager.isWifiEnabled())
-            setWifiEnabled(true);
-        Thread.sleep(DURATION);
-        assertThat(mWifiManager.isWifiEnabled()).isTrue();
-        mMySync.expectedState = STATE_NULL;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            super.tearDown();
-            return;
-        }
-        mWifiLock.release();
-        mContext.unregisterReceiver(mReceiver);
-        if (!mWifiManager.isWifiEnabled())
-            setWifiEnabled(true);
-        Thread.sleep(DURATION);
-        super.tearDown();
-    }
-
-    private void setWifiEnabled(boolean enable) throws Exception {
-        synchronized (mMySync) {
-            mMySync.expectedState = STATE_WIFI_CHANGING;
-            if (enable) {
-                SystemUtil.runShellCommand("svc wifi enable");
-            } else {
-                SystemUtil.runShellCommand("svc wifi disable");
-            }
-            long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-            while (System.currentTimeMillis() < timeout
-                    && mMySync.expectedState == STATE_WIFI_CHANGING)
-                mMySync.wait(WAIT_MSEC);
-        }
-    }
-
-    public void testWifiInfoProperties() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // wait for Wifi to be connected
-        PollingCheck.check(
-                "Wifi not connected - Please ensure there is a saved network in range of this "
-                        + "device",
-                20000,
-                () -> mWifiManager.getConnectionInfo().getNetworkId() != -1);
-
-        // this test case should in Wifi environment
-        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-
-        testWifiInfoPropertiesWhileConnected(wifiInfo);
-
-        setWifiEnabled(false);
-
-        PollingCheck.check("getNetworkId not -1", 20000, new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
-                return wifiInfo.getNetworkId() == -1;
-            }
-        });
-
-        PollingCheck.check("getWifiState not disabled", 20000, new Callable<Boolean>() {
-           @Override
-            public Boolean call() throws Exception {
-               return mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED;
-            }
-        });
-    }
-
-    private void testWifiInfoPropertiesWhileConnected(WifiInfo wifiInfo) {
-        assertThat(wifiInfo).isNotNull();
-        assertThat(wifiInfo.toString()).isNotNull();
-        SupplicantState.isValidState(wifiInfo.getSupplicantState());
-        WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED);
-        String ssid = wifiInfo.getSSID();
-        if (!ssid.startsWith("0x") && !ssid.equals(WifiManager.UNKNOWN_SSID)) {
-            // Non-hex string should be quoted
-            assertThat(ssid).startsWith("\"");
-            assertThat(ssid).endsWith("\"");
-        }
-
-        assertThat(wifiInfo.getBSSID()).isNotNull();
-        assertThat(wifiInfo.getFrequency()).isGreaterThan(0);
-        assertThat(wifiInfo.getMacAddress()).isNotNull();
-
-        wifiInfo.getRssi();
-        wifiInfo.getIpAddress();
-        wifiInfo.getHiddenSSID();
-        wifiInfo.getScore();
-
-        // null for saved networks
-        assertThat(wifiInfo.getRequestingPackageName()).isNull();
-        assertThat(wifiInfo.getPasspointFqdn()).isNull();
-        assertThat(wifiInfo.getPasspointProviderFriendlyName()).isNull();
-
-        // false for saved networks
-        assertThat(wifiInfo.isEphemeral()).isFalse();
-        assertThat(wifiInfo.isOsuAp()).isFalse();
-        assertThat(wifiInfo.isPasspointAp()).isFalse();
-
-        assertThat(wifiInfo.getWifiStandard()).isAnyOf(
-                ScanResult.WIFI_STANDARD_UNKNOWN,
-                ScanResult.WIFI_STANDARD_LEGACY,
-                ScanResult.WIFI_STANDARD_11N,
-                ScanResult.WIFI_STANDARD_11AC,
-                ScanResult.WIFI_STANDARD_11AX
-        );
-
-        assertThat(wifiInfo.getLostTxPacketsPerSecond()).isAtLeast(0.0);
-        assertThat(wifiInfo.getRetriedTxPacketsPerSecond()).isAtLeast(0.0);
-        assertThat(wifiInfo.getSuccessfulRxPacketsPerSecond()).isAtLeast(0.0);
-        assertThat(wifiInfo.getSuccessfulTxPacketsPerSecond()).isAtLeast(0.0);
-
-        // Can be -1 if link speed is unknown
-        assertThat(wifiInfo.getLinkSpeed()).isAtLeast(-1);
-        assertThat(wifiInfo.getTxLinkSpeedMbps()).isAtLeast(-1);
-        assertThat(wifiInfo.getRxLinkSpeedMbps()).isAtLeast(-1);
-        assertThat(wifiInfo.getMaxSupportedTxLinkSpeedMbps()).isAtLeast(-1);
-        assertThat(wifiInfo.getMaxSupportedRxLinkSpeedMbps()).isAtLeast(-1);
-    }
-
-    /**
-     * Test that the WifiInfo Builder returns the same values that was set, and that
-     * calling build multiple times returns different instances.
-     */
-    public void testWifiInfoBuilder() throws Exception {
-        WifiInfo.Builder builder = new WifiInfo.Builder()
-                .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
-                .setBssid(TEST_BSSID)
-                .setRssi(TEST_RSSI)
-                .setNetworkId(TEST_NETWORK_ID);
-
-        WifiInfo info1 = builder.build();
-
-        assertThat(info1.getSSID()).isEqualTo("\"" + TEST_SSID + "\"");
-        assertThat(info1.getBSSID()).isEqualTo(TEST_BSSID);
-        assertThat(info1.getRssi()).isEqualTo(TEST_RSSI);
-        assertThat(info1.getNetworkId()).isEqualTo(TEST_NETWORK_ID);
-
-        WifiInfo info2 = builder
-                .setNetworkId(TEST_NETWORK_ID2)
-                .build();
-
-        // different instances
-        assertThat(info1).isNotSameAs(info2);
-
-        // assert that info1 didn't change
-        assertThat(info1.getSSID()).isEqualTo("\"" + TEST_SSID + "\"");
-        assertThat(info1.getBSSID()).isEqualTo(TEST_BSSID);
-        assertThat(info1.getRssi()).isEqualTo(TEST_RSSI);
-        assertThat(info1.getNetworkId()).isEqualTo(TEST_NETWORK_ID);
-
-        // assert that info2 changed
-        assertThat(info2.getSSID()).isEqualTo("\"" + TEST_SSID + "\"");
-        assertThat(info2.getBSSID()).isEqualTo(TEST_BSSID);
-        assertThat(info2.getRssi()).isEqualTo(TEST_RSSI);
-        assertThat(info2.getNetworkId()).isEqualTo(TEST_NETWORK_ID2);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java
deleted file mode 100644
index fee9ef0..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiLockTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.content.Context;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.WifiLock;
-import android.os.WorkSource;
-import android.platform.test.annotations.AppModeFull;
-import android.test.AndroidTestCase;
-
-@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class WifiLockTest extends AndroidTestCase {
-
-    private static final String WIFI_TAG = "WifiLockTest";
-
-    /**
-     * Verify acquire and release of High Performance wifi locks
-     */
-    public void testHiPerfWifiLock() {
-        testWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF);
-    }
-
-    /**
-     * Verify acquire and release of Low latency wifi locks
-     */
-    public void testLowLatencyWifiLock() {
-        testWifiLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY);
-    }
-
-    private void testWifiLock(int lockType) {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiManager wm = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        WifiLock wl = wm.createWifiLock(lockType, WIFI_TAG);
-
-        wl.setReferenceCounted(true);
-        wl.setWorkSource(new WorkSource());
-        assertFalse(wl.isHeld());
-        wl.acquire();
-        assertTrue(wl.isHeld());
-        wl.release();
-        assertFalse(wl.isHeld());
-        wl.acquire();
-        wl.acquire();
-        assertTrue(wl.isHeld());
-        wl.release();
-        assertTrue(wl.isHeld());
-        wl.release();
-        assertFalse(wl.isHeld());
-        assertNotNull(wl.toString());
-        try {
-            wl.release();
-            fail("should throw out exception because release is called"
-                    +" a greater number of times than acquire");
-        } catch (RuntimeException e) {
-            // expected
-        }
-
-        wl = wm.createWifiLock(lockType, WIFI_TAG);
-        wl.setReferenceCounted(false);
-        assertFalse(wl.isHeld());
-        wl.acquire();
-        assertTrue(wl.isHeld());
-        wl.release();
-        assertFalse(wl.isHeld());
-        wl.acquire();
-        wl.acquire();
-        assertTrue(wl.isHeld());
-        wl.release();
-        assertFalse(wl.isHeld());
-        assertNotNull(wl.toString());
-        // releasing again after release: but ignored for non-referenced locks
-        wl.release();
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
deleted file mode 100644
index 0cf984c..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ /dev/null
@@ -1,2532 +0,0 @@
-/*
- * Copyright (C) 2009 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.NetworkCapabilities.TRANSPORT_WIFI;
-import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
-import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.junit.Assert.assertNotEquals;
-
-import android.app.UiAutomation;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.MacAddress;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkRequest;
-import android.net.TetheringManager;
-import android.net.Uri;
-import android.net.util.MacAddressUtils;
-import android.net.wifi.ScanResult;
-import android.net.wifi.SoftApCapability;
-import android.net.wifi.SoftApConfiguration;
-import android.net.wifi.SoftApInfo;
-import android.net.wifi.WifiClient;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiManager.WifiLock;
-import android.net.wifi.WifiNetworkConnectionStatistics;
-import android.net.wifi.hotspot2.ConfigParser;
-import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.ProvisioningCallback;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.HandlerThread;
-import android.os.Process;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.platform.test.annotations.AppModeFull;
-import android.provider.Settings;
-import android.support.test.uiautomator.UiDevice;
-import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-
-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 com.android.compatibility.common.util.ThrowingRunnable;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.reflect.Constructor;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class WifiManagerTest extends AndroidTestCase {
-    private static class MySync {
-        int expectedState = STATE_NULL;
-    }
-
-    private WifiManager mWifiManager;
-    private ConnectivityManager mConnectivityManager;
-    private TetheringManager mTetheringManager;
-    private WifiLock mWifiLock;
-    private static MySync mMySync;
-    private List<ScanResult> mScanResults = null;
-    private NetworkInfo mNetworkInfo;
-    private final Object mLock = new Object();
-    private UiDevice mUiDevice;
-    private boolean mWasVerboseLoggingEnabled;
-    private boolean mWasScanThrottleEnabled;
-    private SoftApConfiguration mOriginalSoftApConfig = null;
-
-    // Please refer to WifiManager
-    private static final int MIN_RSSI = -100;
-    private static final int MAX_RSSI = -55;
-
-    private static final int STATE_NULL = 0;
-    private static final int STATE_WIFI_CHANGING = 1;
-    private static final int STATE_WIFI_ENABLED = 2;
-    private static final int STATE_WIFI_DISABLED = 3;
-    private static final int STATE_SCANNING = 4;
-    private static final int STATE_SCAN_DONE = 5;
-
-    private static final String TAG = "WifiManagerTest";
-    private static final String SSID1 = "\"WifiManagerTest\"";
-    // A full single scan duration is about 6-7 seconds if country code is set
-    // to US. If country code is set to world mode (00), we would expect a scan
-    // duration of roughly 8 seconds. So we set scan timeout as 9 seconds here.
-    private static final int SCAN_TIMEOUT_MSEC = 9000;
-    private static final int TIMEOUT_MSEC = 6000;
-    private static final int WAIT_MSEC = 60;
-    private static final int TEST_WAIT_DURATION_MS = 10_000;
-    private static final int DURATION_SCREEN_TOGGLE = 2000;
-    private static final int DURATION_SETTINGS_TOGGLE = 1_000;
-    private static final int WIFI_SCAN_TEST_INTERVAL_MILLIS = 60 * 1000;
-    private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000;
-    private static final int WIFI_SCAN_TEST_ITERATIONS = 5;
-
-    private static final int ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP = 50;
-
-    private static final String TEST_PAC_URL = "http://www.example.com/proxy.pac";
-    private static final String MANAGED_PROVISIONING_PACKAGE_NAME
-            = "com.android.managedprovisioning";
-
-    private static final String TEST_SSID_UNQUOTED = "testSsid1";
-    private static final MacAddress TEST_MAC = MacAddress.fromString("aa:bb:cc:dd:ee:ff");
-    private static final String TEST_PASSPHRASE = "passphrase";
-    private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT =
-            "assets/ValidPasspointProfile.base64";
-    private static final String TYPE_WIFI_CONFIG = "application/x-wifi-config";
-
-    private IntentFilter mIntentFilter;
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
-
-                synchronized (mMySync) {
-                    if (intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) {
-                        mScanResults = mWifiManager.getScanResults();
-                    } else {
-                        mScanResults = null;
-                    }
-                    mMySync.expectedState = STATE_SCAN_DONE;
-                    mMySync.notifyAll();
-                }
-            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-                int newState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                        WifiManager.WIFI_STATE_UNKNOWN);
-                synchronized (mMySync) {
-                    if (newState == WifiManager.WIFI_STATE_ENABLED) {
-                        Log.d(TAG, "*** New WiFi state is ENABLED ***");
-                        mMySync.expectedState = STATE_WIFI_ENABLED;
-                        mMySync.notifyAll();
-                    } else if (newState == WifiManager.WIFI_STATE_DISABLED) {
-                        Log.d(TAG, "*** New WiFi state is DISABLED ***");
-                        mMySync.expectedState = STATE_WIFI_DISABLED;
-                        mMySync.notifyAll();
-                    }
-                }
-            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-                synchronized (mMySync) {
-                    mNetworkInfo =
-                            (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
-                    if (mNetworkInfo.getState() == NetworkInfo.State.CONNECTED)
-                        mMySync.notifyAll();
-                }
-            }
-        }
-    };
-    // Initialize with an invalid status value (0)
-    private int mProvisioningStatus = 0;
-    // Initialize with an invalid status value (0)
-    private int mProvisioningFailureStatus = 0;
-    private boolean mProvisioningComplete = false;
-    private ProvisioningCallback mProvisioningCallback = new ProvisioningCallback() {
-        @Override
-        public void onProvisioningFailure(int status) {
-            synchronized (mLock) {
-                mProvisioningFailureStatus = status;
-                mLock.notify();
-            }
-        }
-
-        @Override
-        public void onProvisioningStatus(int status) {
-            synchronized (mLock) {
-                mProvisioningStatus = status;
-                mLock.notify();
-            }
-        }
-
-        @Override
-        public void onProvisioningComplete() {
-            mProvisioningComplete = true;
-        }
-    };
-    private static final String TEST_SSID = "TEST SSID";
-    private static final String TEST_FRIENDLY_NAME = "Friendly Name";
-    private static final Map<String, String> TEST_FRIENDLY_NAMES =
-            new HashMap<String, String>() {
-                {
-                    put("en", TEST_FRIENDLY_NAME);
-                    put("kr", TEST_FRIENDLY_NAME + 2);
-                    put("jp", TEST_FRIENDLY_NAME + 3);
-                }
-            };
-    private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
-    private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
-    private static final String TEST_NAI = "test.access.com";
-    private static final List<Integer> TEST_METHOD_LIST =
-            Arrays.asList(1 /* METHOD_SOAP_XML_SPP */);
-    private final HandlerThread mHandlerThread = new HandlerThread("WifiManagerTest");
-    protected final Executor mExecutor;
-    {
-        mHandlerThread.start();
-        mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper()));
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        mMySync = new MySync();
-        mIntentFilter = new IntentFilter();
-        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
-        mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.ACTION_PICK_WIFI_NETWORK);
-
-        mContext.registerReceiver(mReceiver, mIntentFilter);
-        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        mConnectivityManager = getContext().getSystemService(ConnectivityManager.class);
-        mTetheringManager = getContext().getSystemService(TetheringManager.class);
-        assertNotNull(mWifiManager);
-        assertNotNull(mTetheringManager);
-
-        // turn on verbose logging for tests
-        mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.isVerboseLoggingEnabled());
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setVerboseLoggingEnabled(true));
-        // Disable scan throttling for tests.
-        mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.isScanThrottleEnabled());
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setScanThrottleEnabled(false));
-
-        mWifiLock = mWifiManager.createWifiLock(TAG);
-        mWifiLock.acquire();
-        if (!mWifiManager.isWifiEnabled())
-            setWifiEnabled(true);
-        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        turnScreenOnNoDelay();
-        Thread.sleep(TEST_WAIT_DURATION_MS);
-        assertTrue(mWifiManager.isWifiEnabled());
-        synchronized (mMySync) {
-            mMySync.expectedState = STATE_NULL;
-        }
-
-        List<WifiConfiguration> savedNetworks = ShellIdentityUtils.invokeWithShellPermissions(
-                mWifiManager::getConfiguredNetworks);
-        assertFalse("Need at least one saved network", savedNetworks.isEmpty());
-
-        // Get original config for restore
-        mOriginalSoftApConfig = ShellIdentityUtils.invokeWithShellPermissions(
-                mWifiManager::getSoftApConfiguration);
-    }
-
-    @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);
-        mWifiLock.release();
-        mContext.unregisterReceiver(mReceiver);
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setScanThrottleEnabled(mWasScanThrottleEnabled));
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
-        // restore original softap config
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setSoftApConfiguration(mOriginalSoftApConfig));
-        Thread.sleep(TEST_WAIT_DURATION_MS);
-        super.tearDown();
-    }
-
-    private void setWifiEnabled(boolean enable) throws Exception {
-        synchronized (mMySync) {
-            if (mWifiManager.isWifiEnabled() != enable) {
-                // the new state is different, we expect it to change
-                mMySync.expectedState = STATE_WIFI_CHANGING;
-            } else {
-                mMySync.expectedState = (enable ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED);
-            }
-            // now trigger the change using shell commands.
-            SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable"));
-            waitForExpectedWifiState(enable);
-        }
-    }
-
-    private void waitForExpectedWifiState(boolean enabled) throws InterruptedException {
-        synchronized (mMySync) {
-            long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-            int expected = (enabled ? STATE_WIFI_ENABLED : STATE_WIFI_DISABLED);
-            while (System.currentTimeMillis() < timeout
-                    && mMySync.expectedState != expected) {
-                mMySync.wait(WAIT_MSEC);
-            }
-        }
-    }
-
-    // Get the current scan status from sticky broadcast.
-    private boolean isScanCurrentlyAvailable() {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED);
-        Intent intent = mContext.registerReceiver(null, intentFilter);
-        assertNotNull(intent);
-        if (intent.getAction().equals(WifiManager.ACTION_WIFI_SCAN_AVAILABILITY_CHANGED)) {
-            return intent.getBooleanExtra(WifiManager.EXTRA_SCAN_AVAILABLE, false);
-        }
-        return false;
-    }
-
-    private void startScan() throws Exception {
-        synchronized (mMySync) {
-            mMySync.expectedState = STATE_SCANNING;
-            mScanResults = null;
-            assertTrue(mWifiManager.startScan());
-            long timeout = System.currentTimeMillis() + SCAN_TIMEOUT_MSEC;
-            while (System.currentTimeMillis() < timeout && mMySync.expectedState == STATE_SCANNING)
-                mMySync.wait(WAIT_MSEC);
-        }
-    }
-
-    private void waitForNetworkInfoState(NetworkInfo.State state) throws Exception {
-        synchronized (mMySync) {
-            if (mNetworkInfo.getState() == state) return;
-            long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
-            while (System.currentTimeMillis() < timeout
-                    && mNetworkInfo.getState() != state)
-                mMySync.wait(WAIT_MSEC);
-            assertTrue(mNetworkInfo.getState() == state);
-        }
-
-    }
-
-    private void waitForConnection() throws Exception {
-        waitForNetworkInfoState(NetworkInfo.State.CONNECTED);
-    }
-
-    private void waitForDisconnection() throws Exception {
-        waitForNetworkInfoState(NetworkInfo.State.DISCONNECTED);
-    }
-
-    private boolean existSSID(String ssid) {
-        for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) {
-            if (w.SSID.equals(ssid))
-                return true;
-        }
-        return false;
-    }
-
-    private int findConfiguredNetworks(String SSID, List<WifiConfiguration> networks) {
-        for (final WifiConfiguration w : networks) {
-            if (w.SSID.equals(SSID))
-                return networks.indexOf(w);
-        }
-        return -1;
-    }
-
-    /**
-     * Test creation of WifiManager Lock.
-     */
-    public void testWifiManagerLock() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        final String TAG = "Test";
-        assertNotNull(mWifiManager.createWifiLock(TAG));
-        assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG));
-    }
-
-    /**
-     * Test wifi scanning when location scan is turned off.
-     */
-    public void testWifiManagerScanWhenWifiOffLocationTurnedOn() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        if (!hasLocationFeature()) {
-            Log.d(TAG, "Skipping test as location is not supported");
-            return;
-        }
-        if (!isLocationEnabled()) {
-            fail("Please enable location for this test - since Marshmallow WiFi scan results are"
-                    + " empty when location is disabled!");
-        }
-        setWifiEnabled(false);
-        Thread.sleep(TEST_WAIT_DURATION_MS);
-        startScan();
-        if (mWifiManager.isScanAlwaysAvailable() && isScanCurrentlyAvailable()) {
-            // Make sure at least one AP is found.
-            assertNotNull("mScanResult should not be null!", mScanResults);
-            assertFalse("empty scan results!", mScanResults.isEmpty());
-        } else {
-            // Make sure no scan results are available.
-            assertNull("mScanResult should be null!", mScanResults);
-        }
-        final String TAG = "Test";
-        assertNotNull(mWifiManager.createWifiLock(TAG));
-        assertNotNull(mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG));
-    }
-
-    /**
-     * test point of wifiManager properties:
-     * 1.enable properties
-     * 2.DhcpInfo properties
-     * 3.wifi state
-     * 4.ConnectionInfo
-     */
-    public void testWifiManagerProperties() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        setWifiEnabled(true);
-        assertTrue(mWifiManager.isWifiEnabled());
-        assertNotNull(mWifiManager.getDhcpInfo());
-        assertEquals(WifiManager.WIFI_STATE_ENABLED, mWifiManager.getWifiState());
-        mWifiManager.getConnectionInfo();
-        setWifiEnabled(false);
-        assertFalse(mWifiManager.isWifiEnabled());
-    }
-
-    /**
-     * Test WiFi scan timestamp - fails when WiFi scan timestamps are inconsistent with
-     * {@link SystemClock#elapsedRealtime()} on device.<p>
-     * To run this test in cts-tradefed:
-     * run cts --class android.net.wifi.cts.WifiManagerTest --method testWifiScanTimestamp
-     */
-    public void testWifiScanTimestamp() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            Log.d(TAG, "Skipping test as WiFi is not supported");
-            return;
-        }
-        if (!hasLocationFeature()) {
-            Log.d(TAG, "Skipping test as location is not supported");
-            return;
-        }
-        if (!isLocationEnabled()) {
-            fail("Please enable location for this test - since Marshmallow WiFi scan results are"
-                    + " empty when location is disabled!");
-        }
-        if (!mWifiManager.isWifiEnabled()) {
-            setWifiEnabled(true);
-        }
-        // Scan multiple times to make sure scan timestamps increase with device timestamp.
-        for (int i = 0; i < WIFI_SCAN_TEST_ITERATIONS; ++i) {
-            startScan();
-            // Make sure at least one AP is found.
-            assertTrue("mScanResult should not be null. This may be due to a scan timeout",
-                       mScanResults != null);
-            assertFalse("empty scan results!", mScanResults.isEmpty());
-            long nowMillis = SystemClock.elapsedRealtime();
-            // Keep track of how many APs are fresh in one scan.
-            int numFreshAps = 0;
-            for (ScanResult result : mScanResults) {
-                long scanTimeMillis = TimeUnit.MICROSECONDS.toMillis(result.timestamp);
-                if (Math.abs(nowMillis - scanTimeMillis)  < WIFI_SCAN_TEST_CACHE_DELAY_MILLIS) {
-                    numFreshAps++;
-                }
-            }
-            // At least half of the APs in the scan should be fresh.
-            int numTotalAps = mScanResults.size();
-            String msg = "Stale AP count: " + (numTotalAps - numFreshAps) + ", fresh AP count: "
-                    + numFreshAps;
-            assertTrue(msg, numFreshAps * 2 >= mScanResults.size());
-            if (i < WIFI_SCAN_TEST_ITERATIONS - 1) {
-                // Wait before running next iteration.
-                Thread.sleep(WIFI_SCAN_TEST_INTERVAL_MILLIS);
-            }
-        }
-    }
-
-    // Return true if location is enabled.
-    private boolean isLocationEnabled() {
-        return Settings.Secure.getInt(getContext().getContentResolver(),
-                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) !=
-                Settings.Secure.LOCATION_MODE_OFF;
-    }
-
-    // Returns true if the device has location feature.
-    private boolean hasLocationFeature() {
-        return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION);
-    }
-
-    private boolean hasAutomotiveFeature() {
-        return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
-    }
-
-    public void testSignal() {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        final int numLevels = 9;
-        int expectLevel = 0;
-        assertEquals(expectLevel, WifiManager.calculateSignalLevel(MIN_RSSI, numLevels));
-        assertEquals(numLevels - 1, WifiManager.calculateSignalLevel(MAX_RSSI, numLevels));
-        expectLevel = 4;
-        assertEquals(expectLevel, WifiManager.calculateSignalLevel((MIN_RSSI + MAX_RSSI) / 2,
-                numLevels));
-        int rssiA = 4;
-        int rssiB = 5;
-        assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) < 0);
-        rssiB = 4;
-        assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) == 0);
-        rssiA = 5;
-        rssiB = 4;
-        assertTrue(WifiManager.compareSignalLevel(rssiA, rssiB) > 0);
-    }
-
-    /**
-     * Test that {@link WifiManager#calculateSignalLevel(int)} returns a value in the range
-     * [0, {@link WifiManager#getMaxSignalLevel()}], and its value is monotonically increasing as
-     * the RSSI increases.
-     */
-    public void testCalculateSignalLevel() {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        int maxSignalLevel = mWifiManager.getMaxSignalLevel();
-
-        int prevSignalLevel = 0;
-        for (int rssi = -150; rssi <= 50; rssi++) {
-            int signalLevel = mWifiManager.calculateSignalLevel(rssi);
-
-            // between [0, maxSignalLevel]
-            assertWithMessage("For RSSI=%s", rssi).that(signalLevel).isAtLeast(0);
-            assertWithMessage("For RSSI=%s", rssi).that(signalLevel).isAtMost(maxSignalLevel);
-
-            // calculateSignalLevel(rssi) <= calculateSignalLevel(rssi + 1)
-            assertWithMessage("For RSSI=%s", rssi).that(signalLevel).isAtLeast(prevSignalLevel);
-            prevSignalLevel = signalLevel;
-        }
-    }
-
-    public class TestSoftApCallback implements WifiManager.SoftApCallback {
-        Object softApLock;
-        int currentState;
-        int currentFailureReason;
-        List<WifiClient> currentClientList;
-        SoftApInfo currentSoftApInfo;
-        SoftApCapability currentSoftApCapability;
-        MacAddress lastBlockedClientMacAddress;
-        int lastBlockedClientReason;
-        boolean onStateChangedCalled = false;
-        boolean onSoftapInfoChangedCalled = false;
-        boolean onSoftApCapabilityChangedCalled = false;
-        boolean onConnectedClientCalled = false;
-        boolean onBlockedClientConnectingCalled = false;
-
-        TestSoftApCallback(Object lock) {
-            softApLock = lock;
-        }
-
-        public boolean getOnStateChangedCalled() {
-            synchronized(softApLock) {
-                return onStateChangedCalled;
-            }
-        }
-
-        public boolean getOnSoftapInfoChangedCalled() {
-            synchronized(softApLock) {
-                return onSoftapInfoChangedCalled;
-            }
-        }
-
-        public boolean getOnSoftApCapabilityChangedCalled() {
-            synchronized(softApLock) {
-                return onSoftApCapabilityChangedCalled;
-            }
-        }
-
-        public boolean getOnConnectedClientCalled() {
-            synchronized(softApLock) {
-                return onConnectedClientCalled;
-            }
-        }
-
-        public boolean getOnBlockedClientConnectingCalled() {
-            synchronized(softApLock) {
-                return onBlockedClientConnectingCalled;
-            }
-        }
-
-        public int getCurrentState() {
-            synchronized(softApLock) {
-                return currentState;
-            }
-        }
-
-        public int getCurrentStateFailureReason() {
-            synchronized(softApLock) {
-                return currentFailureReason;
-            }
-        }
-
-        public List<WifiClient> getCurrentClientList() {
-            synchronized(softApLock) {
-                return currentClientList;
-            }
-        }
-
-        public SoftApInfo getCurrentSoftApInfo() {
-            synchronized(softApLock) {
-                return currentSoftApInfo;
-            }
-        }
-
-        public SoftApCapability getCurrentSoftApCapability() {
-            synchronized(softApLock) {
-                return currentSoftApCapability;
-            }
-        }
-
-        public MacAddress getLastBlockedClientMacAddress() {
-            synchronized(softApLock) {
-                return lastBlockedClientMacAddress;
-            }
-        }
-
-        public int getLastBlockedClientReason() {
-            synchronized(softApLock) {
-                return lastBlockedClientReason;
-            }
-        }
-
-        @Override
-        public void onStateChanged(int state, int failureReason) {
-            synchronized(softApLock) {
-                currentState = state;
-                currentFailureReason = failureReason;
-                onStateChangedCalled = true;
-            }
-        }
-
-        @Override
-        public void onConnectedClientsChanged(List<WifiClient> clients) {
-            synchronized(softApLock) {
-                currentClientList = new ArrayList<>(clients);
-                onConnectedClientCalled = true;
-            }
-        }
-
-        @Override
-        public void onInfoChanged(SoftApInfo softApInfo) {
-            synchronized(softApLock) {
-                currentSoftApInfo = softApInfo;
-                onSoftapInfoChangedCalled = true;
-            }
-        }
-
-        @Override
-        public void onCapabilityChanged(SoftApCapability softApCapability) {
-            synchronized(softApLock) {
-                currentSoftApCapability = softApCapability;
-                onSoftApCapabilityChangedCalled = true;
-            }
-        }
-
-        @Override
-        public void onBlockedClientConnecting(WifiClient client, int blockedReason) {
-            synchronized(softApLock) {
-                lastBlockedClientMacAddress = client.getMacAddress();
-                lastBlockedClientReason = blockedReason;
-                onBlockedClientConnectingCalled = true;
-            }
-        }
-    }
-
-    private static class TestLocalOnlyHotspotCallback extends WifiManager.LocalOnlyHotspotCallback {
-        Object hotspotLock;
-        WifiManager.LocalOnlyHotspotReservation reservation = null;
-        boolean onStartedCalled = false;
-        boolean onStoppedCalled = false;
-        boolean onFailedCalled = false;
-        int failureReason = -1;
-
-        TestLocalOnlyHotspotCallback(Object lock) {
-            hotspotLock = lock;
-        }
-
-        @Override
-        public void onStarted(WifiManager.LocalOnlyHotspotReservation r) {
-            synchronized (hotspotLock) {
-                reservation = r;
-                onStartedCalled = true;
-                hotspotLock.notify();
-            }
-        }
-
-        @Override
-        public void onStopped() {
-            synchronized (hotspotLock) {
-                onStoppedCalled = true;
-                hotspotLock.notify();
-            }
-        }
-
-        @Override
-        public void onFailed(int reason) {
-            synchronized (hotspotLock) {
-                onFailedCalled = true;
-                failureReason = reason;
-                hotspotLock.notify();
-            }
-        }
-    }
-
-    private TestLocalOnlyHotspotCallback startLocalOnlyHotspot() {
-        // Location mode must be enabled for this test
-        if (!isLocationEnabled()) {
-            fail("Please enable location for this test");
-        }
-
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(mLock);
-        synchronized (mLock) {
-            try {
-                mWifiManager.startLocalOnlyHotspot(callback, null);
-                // now wait for callback
-                mLock.wait(TEST_WAIT_DURATION_MS);
-            } catch (InterruptedException e) {
-            }
-            // check if we got the callback
-            assertTrue(callback.onStartedCalled);
-
-            SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration();
-            assertNotNull(softApConfig);
-            assertNotNull(softApConfig.toWifiConfiguration());
-            if (!hasAutomotiveFeature()) {
-                assertEquals(
-                        SoftApConfiguration.BAND_2GHZ,
-                        callback.reservation.getSoftApConfiguration().getBand());
-            }
-            assertFalse(callback.onFailedCalled);
-            assertFalse(callback.onStoppedCalled);
-        }
-        return callback;
-    }
-
-    private void stopLocalOnlyHotspot(TestLocalOnlyHotspotCallback callback, boolean wifiEnabled) {
-       synchronized (mMySync) {
-           // we are expecting a new state
-           mMySync.expectedState = STATE_WIFI_CHANGING;
-
-           // now shut down LocalOnlyHotspot
-           callback.reservation.close();
-
-           try {
-               waitForExpectedWifiState(wifiEnabled);
-           } catch (InterruptedException e) {}
-        }
-    }
-
-    /**
-     * Verify that calls to startLocalOnlyHotspot succeed with proper permissions.
-     *
-     * Note: Location mode must be enabled for this test.
-     */
-    public void testStartLocalOnlyHotspotSuccess() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        // check that softap mode is supported by the device
-        if (!mWifiManager.isPortableHotspotSupported()) {
-            return;
-        }
-
-        boolean wifiEnabled = mWifiManager.isWifiEnabled();
-
-        TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
-
-        // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization.
-        // TODO: remove this sleep as soon as b/124330089 is fixed.
-        Log.d(TAG, "Sleeping for 2 seconds");
-        Thread.sleep(2000);
-
-        stopLocalOnlyHotspot(callback, wifiEnabled);
-
-        // wifi should either stay on, or come back on
-        assertEquals(wifiEnabled, mWifiManager.isWifiEnabled());
-    }
-
-    /**
-     * Verify calls to deprecated API's all fail for non-settings apps targeting >= Q SDK.
-     */
-    public void testDeprecatedApis() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        setWifiEnabled(true);
-        waitForConnection(); // ensures that there is at-least 1 saved network on the device.
-
-        WifiConfiguration wifiConfiguration = new WifiConfiguration();
-        wifiConfiguration.SSID = SSID1;
-        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-
-        assertEquals(INVALID_NETWORK_ID,
-                mWifiManager.addNetwork(wifiConfiguration));
-        assertEquals(INVALID_NETWORK_ID,
-                mWifiManager.updateNetwork(wifiConfiguration));
-        assertFalse(mWifiManager.enableNetwork(0, true));
-        assertFalse(mWifiManager.disableNetwork(0));
-        assertFalse(mWifiManager.removeNetwork(0));
-        assertFalse(mWifiManager.disconnect());
-        assertFalse(mWifiManager.reconnect());
-        assertFalse(mWifiManager.reassociate());
-        assertTrue(mWifiManager.getConfiguredNetworks().isEmpty());
-
-        boolean wifiEnabled = mWifiManager.isWifiEnabled();
-        // now we should fail to toggle wifi state.
-        assertFalse(mWifiManager.setWifiEnabled(!wifiEnabled));
-        Thread.sleep(TEST_WAIT_DURATION_MS);
-        assertEquals(wifiEnabled, mWifiManager.isWifiEnabled());
-    }
-
-    /**
-     * Verify that applications can only have one registered LocalOnlyHotspot request at a time.
-     *
-     * Note: Location mode must be enabled for this test.
-     */
-    public void testStartLocalOnlyHotspotSingleRequestByApps() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        // check that softap mode is supported by the device
-        if (!mWifiManager.isPortableHotspotSupported()) {
-            return;
-        }
-
-        boolean caughtException = false;
-
-        boolean wifiEnabled = mWifiManager.isWifiEnabled();
-
-        TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
-
-        // now make a second request - this should fail.
-        TestLocalOnlyHotspotCallback callback2 = new TestLocalOnlyHotspotCallback(mLock);
-        try {
-            mWifiManager.startLocalOnlyHotspot(callback2, null);
-        } catch (IllegalStateException e) {
-            Log.d(TAG, "Caught the IllegalStateException we expected: called startLOHS twice");
-            caughtException = true;
-        }
-        if (!caughtException) {
-            // second start did not fail, should clean up the hotspot.
-
-            // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization.
-            // TODO: remove this sleep as soon as b/124330089 is fixed.
-            Log.d(TAG, "Sleeping for 2 seconds");
-            Thread.sleep(2000);
-
-            stopLocalOnlyHotspot(callback2, wifiEnabled);
-        }
-        assertTrue(caughtException);
-
-        // add sleep to avoid calling stopLocalOnlyHotspot before TetherController initialization.
-        // TODO: remove this sleep as soon as b/124330089 is fixed.
-        Log.d(TAG, "Sleeping for 2 seconds");
-        Thread.sleep(2000);
-
-        stopLocalOnlyHotspot(callback, wifiEnabled);
-    }
-
-    private static class TestExecutor implements Executor {
-        private ConcurrentLinkedQueue<Runnable> tasks = new ConcurrentLinkedQueue<>();
-
-        @Override
-        public void execute(Runnable task) {
-            tasks.add(task);
-        }
-
-        private void runAll() {
-            Runnable task = tasks.poll();
-            while (task != null) {
-                task.run();
-                task = tasks.poll();
-            }
-        }
-    }
-
-    public void testStartLocalOnlyHotspotWithConfig() throws Exception {
-        SoftApConfiguration customConfig = new SoftApConfiguration.Builder()
-                .setBssid(TEST_MAC)
-                .setSsid(TEST_SSID_UNQUOTED)
-                .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                .build();
-        TestExecutor executor = new TestExecutor();
-        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback(mLock);
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-
-            boolean wifiEnabled = mWifiManager.isWifiEnabled();
-            mWifiManager.startLocalOnlyHotspot(customConfig, executor, callback);
-            Log.d(TAG, "Sleeping for 2 seconds");
-            Thread.sleep(2000);
-
-            // Verify callback is run on the supplied executor
-            assertFalse(callback.onStartedCalled);
-            executor.runAll();
-            assertTrue(callback.onStartedCalled);
-
-            assertNotNull(callback.reservation);
-            SoftApConfiguration softApConfig = callback.reservation.getSoftApConfiguration();
-            assertNotNull(softApConfig);
-            assertEquals(TEST_MAC, softApConfig.getBssid());
-            assertEquals(TEST_SSID_UNQUOTED, softApConfig.getSsid());
-            assertEquals(TEST_PASSPHRASE, softApConfig.getPassphrase());
-
-            // clean up
-            stopLocalOnlyHotspot(callback, wifiEnabled);
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Read the content of the given resource file into a String.
-     *
-     * @param filename String name of the file
-     * @return String
-     * @throws IOException
-     */
-    private String loadResourceFile(String filename) throws IOException {
-        InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-        StringBuilder builder = new StringBuilder();
-        String line;
-        while ((line = reader.readLine()) != null) {
-            builder.append(line).append("\n");
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Verify that changing the mac randomization setting of a Passpoint configuration.
-     */
-    public void testMacRandomizationSettingPasspoint() throws Exception {
-        String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
-        PasspointConfiguration config =
-                ConfigParser.parsePasspointConfig(TYPE_WIFI_CONFIG, configStr.getBytes());
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-
-            mWifiManager.addOrUpdatePasspointConfiguration(config);
-            List<PasspointConfiguration> passpointConfigs =
-                    mWifiManager.getPasspointConfigurations();
-            PasspointConfiguration passpointConfig = passpointConfigs.get(0);
-            assertEquals(1, passpointConfigs.size());
-            assertTrue("Mac randomization should be enabled for passpoint networks by default.",
-                    passpointConfig.isMacRandomizationEnabled());
-
-            String fqdn = passpointConfig.getHomeSp().getFqdn();
-            mWifiManager.setMacRandomizationSettingPasspointEnabled(fqdn, false);
-            assertFalse("Mac randomization should be disabled by the API call.",
-                    mWifiManager.getPasspointConfigurations().get(0).isMacRandomizationEnabled());
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-    /**
-     * Verify that the {@link android.Manifest.permission#NETWORK_STACK} permission is never held by
-     * any package.
-     * <p>
-     * No apps should <em>ever</em> attempt to acquire this permission, since it would give those
-     * apps extremely broad access to connectivity functionality.
-     */
-    public void testNetworkStackPermission() {
-        final PackageManager pm = getContext().getPackageManager();
-
-        final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
-                android.Manifest.permission.NETWORK_STACK
-        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-        for (PackageInfo pi : holding) {
-            fail("The NETWORK_STACK permission must not be held by " + pi.packageName
-                    + " and must be revoked for security reasons");
-        }
-    }
-
-    /**
-     * Verify that the {@link android.Manifest.permission#NETWORK_SETTINGS} permission is
-     * never held by any package.
-     * <p>
-     * Only Settings, SysUi, NetworkStack and shell apps should <em>ever</em> attempt to acquire
-     * this permission, since it would give those apps extremely broad access to connectivity
-     * functionality.  The permission is intended to be granted to only those apps with direct user
-     * access and no others.
-     */
-    public void testNetworkSettingsPermission() {
-        final PackageManager pm = getContext().getPackageManager();
-
-        final ArraySet<String> allowedPackages = new ArraySet();
-        final ArraySet<Integer> allowedUIDs = new ArraySet();
-        // explicitly add allowed UIDs
-        allowedUIDs.add(Process.SYSTEM_UID);
-        allowedUIDs.add(Process.SHELL_UID);
-        allowedUIDs.add(Process.PHONE_UID);
-        allowedUIDs.add(Process.NETWORK_STACK_UID);
-        allowedUIDs.add(Process.NFC_UID);
-
-        // only quick settings is allowed to bind to the BIND_QUICK_SETTINGS_TILE permission, using
-        // this fact to determined allowed package name for sysui. This is a signature permission,
-        // so allow any package with this permission.
-        final List<PackageInfo> sysuiPackages = pm.getPackagesHoldingPermissions(new String[] {
-                android.Manifest.permission.BIND_QUICK_SETTINGS_TILE
-        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-        for (PackageInfo info : sysuiPackages) {
-            allowedPackages.add(info.packageName);
-        }
-
-        // the captive portal flow also currently holds the NETWORK_SETTINGS permission
-        final Intent intent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
-        final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS);
-        if (ri != null) {
-            allowedPackages.add(ri.activityInfo.packageName);
-        }
-
-        final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
-                android.Manifest.permission.NETWORK_SETTINGS
-        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-        StringBuilder stringBuilder = new StringBuilder();
-        for (PackageInfo pi : holding) {
-            String packageName = pi.packageName;
-
-            // this is an explicitly allowed package
-            if (allowedPackages.contains(packageName)) continue;
-
-            // now check if the packages are from allowed UIDs
-            int uid = -1;
-            try {
-                uid = pm.getPackageUidAsUser(packageName, UserHandle.USER_SYSTEM);
-            } catch (PackageManager.NameNotFoundException e) {
-                continue;
-            }
-            if (!allowedUIDs.contains(uid)) {
-                stringBuilder.append("The NETWORK_SETTINGS permission must not be held by "
-                    + packageName + ":" + uid + " and must be revoked for security reasons\n");
-            }
-        }
-        if (stringBuilder.length() > 0) {
-            fail(stringBuilder.toString());
-        }
-    }
-
-    /**
-     * Verify that the {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} permission is
-     * only held by the device setup wizard application.
-     * <p>
-     * Only the SetupWizard app should <em>ever</em> attempt to acquire this
-     * permission, since it would give those apps extremely broad access to connectivity
-     * functionality.  The permission is intended to be granted to only the device setup wizard.
-     */
-    public void testNetworkSetupWizardPermission() {
-        final ArraySet<String> allowedPackages = new ArraySet();
-
-        final PackageManager pm = getContext().getPackageManager();
-
-        final Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
-        final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS);
-        String validPkg = "";
-        if (ri != null) {
-            allowedPackages.add(ri.activityInfo.packageName);
-            validPkg = ri.activityInfo.packageName;
-        }
-
-        final Intent preIntent = new Intent("com.android.setupwizard.OEM_PRE_SETUP");
-        preIntent.addCategory(Intent.CATEGORY_DEFAULT);
-        final ResolveInfo preRi = pm
-            .resolveActivity(preIntent, PackageManager.MATCH_DISABLED_COMPONENTS);
-        String prePackageName = "";
-        if (null != preRi) {
-            prePackageName = preRi.activityInfo.packageName;
-        }
-
-        final Intent postIntent = new Intent("com.android.setupwizard.OEM_POST_SETUP");
-        postIntent.addCategory(Intent.CATEGORY_DEFAULT);
-        final ResolveInfo postRi = pm
-            .resolveActivity(postIntent, PackageManager.MATCH_DISABLED_COMPONENTS);
-        String postPackageName = "";
-        if (null != postRi) {
-            postPackageName = postRi.activityInfo.packageName;
-        }
-        if (!TextUtils.isEmpty(prePackageName) && !TextUtils.isEmpty(postPackageName)
-            && prePackageName.equals(postPackageName)) {
-            allowedPackages.add(prePackageName);
-        }
-
-        final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[]{
-            android.Manifest.permission.NETWORK_SETUP_WIZARD
-        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-        for (PackageInfo pi : holding) {
-            if (!allowedPackages.contains(pi.packageName)) {
-                fail("The NETWORK_SETUP_WIZARD permission must not be held by " + pi.packageName
-                    + " and must be revoked for security reasons [" + validPkg + "]");
-            }
-        }
-    }
-
-    /**
-     * Verify that the {@link android.Manifest.permission#NETWORK_MANAGED_PROVISIONING} permission
-     * is only held by the device managed provisioning application.
-     * <p>
-     * Only the ManagedProvisioning app should <em>ever</em> attempt to acquire this
-     * permission, since it would give those apps extremely broad access to connectivity
-     * functionality.  The permission is intended to be granted to only the device managed
-     * provisioning.
-     */
-    public void testNetworkManagedProvisioningPermission() {
-        final PackageManager pm = getContext().getPackageManager();
-
-        // TODO(b/115980767): Using hardcoded package name. Need a better mechanism to find the
-        // managed provisioning app.
-        // Ensure that the package exists.
-        final Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setPackage(MANAGED_PROVISIONING_PACKAGE_NAME);
-        final ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DISABLED_COMPONENTS);
-        String validPkg = "";
-        if (ri != null) {
-            validPkg = ri.activityInfo.packageName;
-        }
-
-        final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
-                android.Manifest.permission.NETWORK_MANAGED_PROVISIONING
-        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-        for (PackageInfo pi : holding) {
-            if (!Objects.equals(pi.packageName, validPkg)) {
-                fail("The NETWORK_MANAGED_PROVISIONING permission must not be held by "
-                        + pi.packageName + " and must be revoked for security reasons ["
-                        + validPkg +"]");
-            }
-        }
-    }
-
-    /**
-     * Verify that the {@link android.Manifest.permission#WIFI_SET_DEVICE_MOBILITY_STATE} permission
-     * is held by at most one application.
-     */
-    public void testWifiSetDeviceMobilityStatePermission() {
-        final PackageManager pm = getContext().getPackageManager();
-
-        final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
-                android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE
-        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-
-        List<String> uniquePackageNames = holding
-                .stream()
-                .map(pi -> pi.packageName)
-                .distinct()
-                .collect(Collectors.toList());
-
-        if (uniquePackageNames.size() > 1) {
-            fail("The WIFI_SET_DEVICE_MOBILITY_STATE permission must not be held by more than one "
-                    + "application, but is held by " + uniquePackageNames.size() + " applications: "
-                    + String.join(", ", uniquePackageNames));
-        }
-    }
-
-    /**
-     * Verify that the {@link android.Manifest.permission#NETWORK_CARRIER_PROVISIONING} permission
-     * is held by at most one application.
-     */
-    public void testNetworkCarrierProvisioningPermission() {
-        final PackageManager pm = getContext().getPackageManager();
-
-        final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
-                android.Manifest.permission.NETWORK_CARRIER_PROVISIONING
-        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-
-        List<String> uniquePackageNames = holding
-                .stream()
-                .map(pi -> pi.packageName)
-                .distinct()
-                .collect(Collectors.toList());
-
-        if (uniquePackageNames.size() > 2) {
-            fail("The NETWORK_CARRIER_PROVISIONING permission must not be held by more than two "
-                    + "applications, but is held by " + uniquePackageNames.size() + " applications: "
-                    + String.join(", ", uniquePackageNames));
-        }
-    }
-
-    /**
-     * Verify that the {@link android.Manifest.permission#WIFI_UPDATE_USABILITY_STATS_SCORE}
-     * permission is held by at most one application.
-     */
-    public void testUpdateWifiUsabilityStatsScorePermission() {
-        final PackageManager pm = getContext().getPackageManager();
-
-        final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
-                android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE
-        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-
-        List<String> uniquePackageNames = holding
-                .stream()
-                .map(pi -> pi.packageName)
-                .distinct()
-                .collect(Collectors.toList());
-
-        if (uniquePackageNames.size() > 1) {
-            fail("The WIFI_UPDATE_USABILITY_STATS_SCORE permission must not be held by more than "
-                + "one application, but is held by " + uniquePackageNames.size() + " applications: "
-                + String.join(", ", uniquePackageNames));
-        }
-    }
-
-    private void turnScreenOnNoDelay() throws Exception {
-        mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
-        mUiDevice.executeShellCommand("wm dismiss-keyguard");
-    }
-
-    private void turnScreenOn() throws Exception {
-        turnScreenOnNoDelay();
-        // Since the screen on/off intent is ordered, they will not be sent right now.
-        Thread.sleep(DURATION_SCREEN_TOGGLE);
-    }
-
-    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);
-    }
-
-    private void assertWifiScanningIsOn() {
-        if (!mWifiManager.isScanAlwaysAvailable()) {
-            fail("Wi-Fi scanning should be on.");
-        }
-    }
-
-    private void runWithScanningEnabled(ThrowingRunnable r) throws Exception {
-        boolean wasScanEnabledForTest = false;
-        if (!mWifiManager.isScanAlwaysAvailable()) {
-            ShellIdentityUtils.invokeWithShellPermissions(
-                    () -> mWifiManager.setScanAlwaysAvailable(true));
-            wasScanEnabledForTest = true;
-        }
-        try {
-            r.run();
-        } finally {
-            if (wasScanEnabledForTest) {
-                ShellIdentityUtils.invokeWithShellPermissions(
-                        () -> mWifiManager.setScanAlwaysAvailable(false));
-            }
-        }
-    }
-
-    /**
-     * Verify that Wi-Fi scanning is not turned off when the screen turns off while wifi is disabled
-     * but location is on.
-     * @throws Exception
-     */
-    public void testScreenOffDoesNotTurnOffWifiScanningWhenWifiDisabled() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        if (!hasLocationFeature()) {
-            // skip the test if location is not supported
-            return;
-        }
-        if (!isLocationEnabled()) {
-            fail("Please enable location for this test - since Marshmallow WiFi scan results are"
-                    + " empty when location is disabled!");
-        }
-        runWithScanningEnabled(() -> {
-            setWifiEnabled(false);
-            turnScreenOn();
-            assertWifiScanningIsOn();
-            // Toggle screen and verify Wi-Fi scanning is still on.
-            turnScreenOff();
-            assertWifiScanningIsOn();
-            turnScreenOn();
-            assertWifiScanningIsOn();
-        });
-    }
-
-    /**
-     * Verify that Wi-Fi scanning is not turned off when the screen turns off while wifi is enabled.
-     * @throws Exception
-     */
-    public void testScreenOffDoesNotTurnOffWifiScanningWhenWifiEnabled() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        if (!hasLocationFeature()) {
-            // skip the test if location is not supported
-            return;
-        }
-        if (!isLocationEnabled()) {
-            fail("Please enable location for this test - since Marshmallow WiFi scan results are"
-                    + " empty when location is disabled!");
-        }
-        runWithScanningEnabled(() -> {
-            setWifiEnabled(true);
-            turnScreenOn();
-            assertWifiScanningIsOn();
-            // Toggle screen and verify Wi-Fi scanning is still on.
-            turnScreenOff();
-            assertWifiScanningIsOn();
-            turnScreenOn();
-            assertWifiScanningIsOn();
-        });
-    }
-
-    /**
-     * Verify that the platform supports a reasonable number of suggestions per app.
-     * @throws Exception
-     */
-    public void testMaxNumberOfNetworkSuggestionsPerApp() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        assertTrue(mWifiManager.getMaxNumberOfNetworkSuggestionsPerApp()
-                > ENFORCED_NUM_NETWORK_SUGGESTIONS_PER_APP);
-    }
-
-    private void verifyRegisterSoftApCallback(TestExecutor executor, TestSoftApCallback callback)
-            throws Exception{
-        // Register callback to get SoftApCapability
-        mWifiManager.registerSoftApCallback(executor, callback);
-        PollingCheck.check(
-                "SoftAp register failed!", 1_000,
-                () -> { executor.runAll();
-                // Verify callback is run on the supplied executor and called
-                return callback.getOnStateChangedCalled() &&
-                callback.getOnSoftapInfoChangedCalled() &&
-                callback.getOnSoftApCapabilityChangedCalled() &&
-                callback.getOnConnectedClientCalled();
-                });
-    }
-
-    private void verifySetGetSoftApConfig(SoftApConfiguration targetConfig) {
-        mWifiManager.setSoftApConfiguration(targetConfig);
-        // Bssid set dodesn't support for tethered hotspot
-        SoftApConfiguration currentConfig = mWifiManager.getSoftApConfiguration();
-        compareSoftApConfiguration(targetConfig, currentConfig);
-    }
-
-    private void compareSoftApConfiguration(SoftApConfiguration currentConfig,
-        SoftApConfiguration testSoftApConfig) {
-        assertEquals(currentConfig.getSsid(), testSoftApConfig.getSsid());
-        assertEquals(currentConfig.getBssid(), testSoftApConfig.getBssid());
-        assertEquals(currentConfig.getSecurityType(), testSoftApConfig.getSecurityType());
-        assertEquals(currentConfig.getPassphrase(), testSoftApConfig.getPassphrase());
-        assertEquals(currentConfig.isHiddenSsid(), testSoftApConfig.isHiddenSsid());
-        assertEquals(currentConfig.getBand(), testSoftApConfig.getBand());
-        assertEquals(currentConfig.getChannel(), testSoftApConfig.getChannel());
-        assertEquals(currentConfig.getMaxNumberOfClients(),
-                testSoftApConfig.getMaxNumberOfClients());
-        assertEquals(currentConfig.isAutoShutdownEnabled(),
-                testSoftApConfig.isAutoShutdownEnabled());
-        assertEquals(currentConfig.getShutdownTimeoutMillis(),
-                testSoftApConfig.getShutdownTimeoutMillis());
-        assertEquals(currentConfig.isClientControlByUserEnabled(),
-                testSoftApConfig.isClientControlByUserEnabled());
-        assertEquals(currentConfig.getAllowedClientList(),
-                testSoftApConfig.getAllowedClientList());
-        assertEquals(currentConfig.getBlockedClientList(),
-                testSoftApConfig.getBlockedClientList());
-    }
-
-    private void turnOffWifiAndTetheredHotspotIfEnabled() throws Exception {
-        if (mWifiManager.isWifiEnabled()) {
-            Log.d(TAG, "Turn off WiFi");
-            mWifiManager.setWifiEnabled(false);
-            PollingCheck.check(
-                "Wifi turn off failed!", 2_000,
-                () -> mWifiManager.isWifiEnabled() == false);
-        }
-        if (mWifiManager.isWifiApEnabled()) {
-            mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
-            Log.d(TAG, "Turn off tethered Hotspot");
-            PollingCheck.check(
-                "SoftAp turn off failed!", 2_000,
-                () -> mWifiManager.isWifiApEnabled() == false);
-            mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
-        }
-    }
-
-    /**
-     * Verify that the configuration from getSoftApConfiguration is same as the configuration which
-     * set by setSoftApConfiguration. And depends softap capability callback to test different
-     * configuration.
-     * @throws Exception
-     */
-    public void testSetGetSoftApConfigurationAndSoftApCapabilityCallback() throws Exception {
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        TestExecutor executor = new TestExecutor();
-        TestSoftApCallback callback = new TestSoftApCallback(mLock);
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            turnOffWifiAndTetheredHotspotIfEnabled();
-            verifyRegisterSoftApCallback(executor, callback);
-
-            SoftApConfiguration.Builder softApConfigBuilder = new SoftApConfiguration.Builder()
-                    .setSsid(TEST_SSID_UNQUOTED)
-                    .setBssid(TEST_MAC)
-                    .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                    .setAutoShutdownEnabled(true)
-                    .setShutdownTimeoutMillis(100000)
-                    .setBand(SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ)
-                    .setHiddenSsid(false);
-
-            // Test SoftApConfiguration set and get
-            verifySetGetSoftApConfig(softApConfigBuilder.build());
-
-            // Test CLIENT_FORCE_DISCONNECT supported config.
-            if (callback.getCurrentSoftApCapability()
-                    .areFeaturesSupported(
-                    SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT)) {
-                softApConfigBuilder.setMaxNumberOfClients(10);
-                softApConfigBuilder.setClientControlByUserEnabled(true);
-                softApConfigBuilder.setBlockedClientList(new ArrayList<>());
-                softApConfigBuilder.setAllowedClientList(new ArrayList<>());
-                verifySetGetSoftApConfig(softApConfigBuilder.build());
-            }
-
-            // Test SAE config
-            if (callback.getCurrentSoftApCapability()
-                    .areFeaturesSupported(SoftApCapability.SOFTAP_FEATURE_WPA3_SAE)) {
-                softApConfigBuilder
-                        .setPassphrase(TEST_PASSPHRASE,
-                          SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION);
-                verifySetGetSoftApConfig(softApConfigBuilder.build());
-                softApConfigBuilder
-                        .setPassphrase(TEST_PASSPHRASE,
-                        SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
-                verifySetGetSoftApConfig(softApConfigBuilder.build());
-            }
-        } finally {
-            mWifiManager.unregisterSoftApCallback(callback);
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Verify that startTetheredHotspot with specific channel config.
-     * @throws Exception
-     */
-    public void testStartTetheredHotspotWithChannelConfigAndSoftApStateAndInfoCallback()
-            throws Exception {
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        TestExecutor executor = new TestExecutor();
-        TestSoftApCallback callback = new TestSoftApCallback(mLock);
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            turnOffWifiAndTetheredHotspotIfEnabled();
-            verifyRegisterSoftApCallback(executor, callback);
-
-            SoftApConfiguration testSoftApConfig = new SoftApConfiguration.Builder()
-                    .setSsid(TEST_SSID_UNQUOTED)
-                    .setPassphrase(TEST_PASSPHRASE, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
-                    .setChannel(11, SoftApConfiguration.BAND_2GHZ) // Channel 11 = Freq 2462
-                    .build();
-
-            mWifiManager.setSoftApConfiguration(testSoftApConfig);
-
-            // start tethering which used to verify startTetheredHotspot
-            mTetheringManager.startTethering(ConnectivityManager.TETHERING_WIFI, executor,
-                new TetheringManager.StartTetheringCallback() {
-                    @Override
-                    public void onTetheringFailed(final int result) {
-                    }
-                });
-
-            // Verify state and info callback value as expected
-            PollingCheck.check(
-                    "SoftAp channel and state mismatch!!!", 5_000,
-                    () -> { executor.runAll();
-                    return WifiManager.WIFI_AP_STATE_ENABLED == callback.getCurrentState() &&
-                    2462 == callback.getCurrentSoftApInfo().getFrequency();
-                    });
-
-            // stop tethering which used to verify stopSoftAp
-            mTetheringManager.stopTethering(ConnectivityManager.TETHERING_WIFI);
-
-            // Verify clean up
-            PollingCheck.check(
-                    "Stop Softap failed", 2_000,
-                    () -> { executor.runAll();
-                    return WifiManager.WIFI_AP_STATE_DISABLED == callback.getCurrentState() &&
-                    0 == callback.getCurrentSoftApInfo().getBandwidth() &&
-                    0 == callback.getCurrentSoftApInfo().getFrequency();
-                    });
-        } finally {
-            mWifiManager.unregisterSoftApCallback(callback);
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    private static class TestActionListener implements WifiManager.ActionListener {
-        private final Object mLock;
-        public boolean onSuccessCalled = false;
-        public boolean onFailedCalled = false;
-        public int failureReason = -1;
-
-        TestActionListener(Object lock) {
-            mLock = lock;
-        }
-
-        @Override
-        public void onSuccess() {
-            synchronized (mLock) {
-                onSuccessCalled = true;
-                mLock.notify();
-            }
-        }
-
-        @Override
-        public void onFailure(int reason) {
-            synchronized (mLock) {
-                onFailedCalled = true;
-                failureReason = reason;
-                mLock.notify();
-            }
-        }
-    }
-
-    /**
-     * Triggers connection to one of the saved networks using {@link WifiManager#connect(
-     * int, WifiManager.ActionListener)} or {@link WifiManager#connect(WifiConfiguration,
-     * WifiManager.ActionListener)}
-     *
-     * @param withNetworkId Use networkId for triggering connection, false for using
-     *                      WifiConfiguration.
-     * @throws Exception
-     */
-    private void testConnect(boolean withNetworkId) throws Exception {
-        TestActionListener actionListener = new TestActionListener(mLock);
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        List<WifiConfiguration> savedNetworks = null;
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            // These below API's only work with privileged permissions (obtained via shell identity
-            // for test)
-            savedNetworks = mWifiManager.getConfiguredNetworks();
-
-            // Disable all the saved networks to trigger disconnect & disable autojoin.
-            for (WifiConfiguration network : savedNetworks) {
-                assertTrue(mWifiManager.disableNetwork(network.networkId));
-            }
-            waitForDisconnection();
-
-            // Now trigger connection to the first saved network.
-            synchronized (mLock) {
-                try {
-                    if (withNetworkId) {
-                        mWifiManager.connect(savedNetworks.get(0).networkId, actionListener);
-                    } else {
-                        mWifiManager.connect(savedNetworks.get(0), actionListener);
-                    }
-                    // now wait for callback
-                    mLock.wait(TEST_WAIT_DURATION_MS);
-                } catch (InterruptedException e) {
-                }
-            }
-            // check if we got the success callback
-            assertTrue(actionListener.onSuccessCalled);
-            // Wait for connection to complete & ensure we are connected to the saved network.
-            waitForConnection();
-            assertEquals(savedNetworks.get(0).networkId,
-                    mWifiManager.getConnectionInfo().getNetworkId());
-        } finally {
-            // Re-enable all saved networks before exiting.
-            if (savedNetworks != null) {
-                for (WifiConfiguration network : savedNetworks) {
-                    mWifiManager.enableNetwork(network.networkId, false);
-                }
-            }
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#connect(int, WifiManager.ActionListener)} to an existing saved
-     * network.
-     */
-    public void testConnectWithNetworkId() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        testConnect(true);
-    }
-
-    /**
-     * Tests {@link WifiManager#connect(WifiConfiguration, WifiManager.ActionListener)} to an
-     * existing saved network.
-     */
-    public void testConnectWithWifiConfiguration() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        testConnect(false);
-
-    }
-
-    private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
-        private final Object mLock;
-        public boolean onAvailableCalled = false;
-        public Network network;
-        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.network = network;
-                this.networkCapabilities = networkCapabilities;
-                mLock.notify();
-            }
-        }
-    }
-
-    private void waitForNetworkCallbackAndCheckForMeteredness(boolean expectMetered) {
-        TestNetworkCallback networkCallbackListener = new TestNetworkCallback(mLock);
-        synchronized (mLock) {
-            try {
-                // File a request for wifi network.
-                mConnectivityManager.registerNetworkCallback(
-                        new NetworkRequest.Builder()
-                                .addTransportType(TRANSPORT_WIFI)
-                                .build(),
-                        networkCallbackListener);
-                // now wait for callback
-                mLock.wait(TEST_WAIT_DURATION_MS);
-            } catch (InterruptedException e) {
-            }
-        }
-        assertTrue(networkCallbackListener.onAvailableCalled);
-        assertNotEquals(expectMetered, networkCallbackListener.networkCapabilities.hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_METERED));
-    }
-
-    /**
-     * Tests {@link WifiManager#save(WifiConfiguration, WifiManager.ActionListener)} by marking
-     * an existing saved network metered.
-     */
-    public void testSave() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        TestActionListener actionListener = new TestActionListener(mLock);
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        List<WifiConfiguration> savedNetworks = null;
-        WifiConfiguration savedNetwork = null;
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            // These below API's only work with privileged permissions (obtained via shell identity
-            // for test)
-            savedNetworks = mWifiManager.getConfiguredNetworks();
-
-            // Ensure that the saved network is not metered.
-            savedNetwork = savedNetworks.get(0);
-            assertNotEquals("Ensure that the saved network is configured as unmetered",
-                    savedNetwork.meteredOverride,
-                    WifiConfiguration.METERED_OVERRIDE_METERED);
-
-            // Trigger a scan & wait for connection to one of the saved networks.
-            mWifiManager.startScan();
-            waitForConnection();
-
-            // Check the network capabilities to ensure that the network is marked not metered.
-            waitForNetworkCallbackAndCheckForMeteredness(false);
-
-            // Now mark the network metered and save.
-            synchronized (mLock) {
-                try {
-                    WifiConfiguration modSavedNetwork = new WifiConfiguration(savedNetwork);
-                    modSavedNetwork.meteredOverride = WifiConfiguration.METERED_OVERRIDE_METERED;
-                    mWifiManager.save(modSavedNetwork, actionListener);
-                    // now wait for callback
-                    mLock.wait(TEST_WAIT_DURATION_MS);
-                } catch (InterruptedException e) {
-                }
-            }
-            // check if we got the success callback
-            assertTrue(actionListener.onSuccessCalled);
-            // Check the network capabilities to ensure that the network is marked metered now.
-            waitForNetworkCallbackAndCheckForMeteredness(true);
-
-        } finally {
-            // Restore original network config (restore the meteredness back);
-            if (savedNetwork != null) {
-                mWifiManager.updateNetwork(savedNetwork);
-            }
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#forget(int, WifiManager.ActionListener)} by adding/removing a new
-     * network.
-     */
-    public void testForget() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        TestActionListener actionListener = new TestActionListener(mLock);
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        int newNetworkId = INVALID_NETWORK_ID;
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            // These below API's only work with privileged permissions (obtained via shell identity
-            // for test)
-            List<WifiConfiguration> savedNetworks = mWifiManager.getConfiguredNetworks();
-
-            WifiConfiguration newOpenNetwork = new WifiConfiguration();
-            newOpenNetwork.SSID = "\"" + TEST_SSID_UNQUOTED + "\"";
-            newNetworkId = mWifiManager.addNetwork(newOpenNetwork);
-            assertNotEquals(INVALID_NETWORK_ID, newNetworkId);
-
-            assertEquals(savedNetworks.size() + 1, mWifiManager.getConfiguredNetworks().size());
-
-            // Now remove the network
-            synchronized (mLock) {
-                try {
-                    mWifiManager.forget(newNetworkId, actionListener);
-                    // now wait for callback
-                    mLock.wait(TEST_WAIT_DURATION_MS);
-                } catch (InterruptedException e) {
-                }
-            }
-            // check if we got the success callback
-            assertTrue(actionListener.onSuccessCalled);
-
-            // Ensure that the new network has been successfully removed.
-            assertEquals(savedNetworks.size(), mWifiManager.getConfiguredNetworks().size());
-        } finally {
-            // For whatever reason, if the forget fails, try removing using the public remove API.
-            if (newNetworkId != INVALID_NETWORK_ID) mWifiManager.removeNetwork(newNetworkId);
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#getFactoryMacAddresses()} returns at least one valid MAC address.
-     */
-    public void testGetFactoryMacAddresses() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        TestActionListener actionListener = new TestActionListener(mLock);
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        int newNetworkId = INVALID_NETWORK_ID;
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            // Obtain the factory MAC address
-            String[] macAddresses = mWifiManager.getFactoryMacAddresses();
-            assertTrue("At list one MAC address should be returned.", macAddresses.length > 0);
-            try {
-                MacAddress mac = MacAddress.fromString(macAddresses[0]);
-                assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, mac);
-                assertFalse(MacAddressUtils.isMulticastAddress(mac));
-            } catch (IllegalArgumentException e) {
-                fail("Factory MAC address is invalid");
-            }
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#isApMacRandomizationSupported()} does not crash.
-     */
-    public void testIsApMacRandomizationSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        mWifiManager.isApMacRandomizationSupported();
-    }
-
-    /**
-     * Tests {@link WifiManager#isConnectedMacRandomizationSupported()} does not crash.
-     */
-    public void testIsConnectedMacRandomizationSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        mWifiManager.isConnectedMacRandomizationSupported();
-    }
-
-    /**
-     * Tests {@link WifiManager#isPreferredNetworkOffloadSupported()} does not crash.
-     */
-    public void testIsPreferredNetworkOffloadSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        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.
-     */
-    public void testIsTdlsSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        mWifiManager.isTdlsSupported();
-    }
-
-    /**
-     * Tests {@link WifiManager#isStaApConcurrencySupported().
-     */
-    public void testIsStaApConcurrencySupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        // check that softap mode is supported by the device
-        if (!mWifiManager.isPortableHotspotSupported()) {
-            return;
-        }
-        assertTrue(mWifiManager.isWifiEnabled());
-
-        boolean isStaApConcurrencySupported = mWifiManager.isStaApConcurrencySupported();
-        // start local only hotspot.
-        TestLocalOnlyHotspotCallback callback = startLocalOnlyHotspot();
-        if (isStaApConcurrencySupported) {
-            assertTrue(mWifiManager.isWifiEnabled());
-        } else {
-            // no concurrency, wifi should be disabled.
-            assertFalse(mWifiManager.isWifiEnabled());
-        }
-        stopLocalOnlyHotspot(callback, true);
-
-        assertTrue(mWifiManager.isWifiEnabled());
-    }
-
-    private static class TestTrafficStateCallback implements WifiManager.TrafficStateCallback {
-        private final Object mLock;
-        private final int mWaitForState;
-        public boolean onStateChangedCalled = false;
-        public int state = -1;
-
-        TestTrafficStateCallback(Object lock, int waitForState) {
-            mLock = lock;
-            mWaitForState = waitForState;
-        }
-
-        @Override
-        public void onStateChanged(int state) {
-            synchronized (mLock) {
-                onStateChangedCalled = true;
-                this.state = state;
-                if (mWaitForState == state) { // only notify if we got the expected state.
-                    mLock.notify();
-                }
-            }
-        }
-    }
-
-    private void sendTraffic() {
-        for (int i = 0; i < 10; i ++) {
-            // Do some network operations
-            HttpURLConnection connection = null;
-            try {
-                URL url = new URL("http://www.google.com/");
-                connection = (HttpURLConnection) url.openConnection();
-                connection.setInstanceFollowRedirects(false);
-                connection.setConnectTimeout(TIMEOUT_MSEC);
-                connection.setReadTimeout(TIMEOUT_MSEC);
-                connection.setUseCaches(false);
-                connection.getInputStream();
-            } catch (Exception e) {
-                // ignore
-            } finally {
-                if (connection != null) connection.disconnect();
-            }
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#registerTrafficStateCallback(Executor,
-     * WifiManager.TrafficStateCallback)} by sending some traffic.
-     */
-    public void testTrafficStateCallback() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        TestTrafficStateCallback trafficStateCallback =
-                new TestTrafficStateCallback(mLock, DATA_ACTIVITY_INOUT);
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            // Trigger a scan & wait for connection to one of the saved networks.
-            mWifiManager.startScan();
-            waitForConnection();
-
-            // Turn screen on for wifi traffic polling.
-            turnScreenOn();
-            synchronized (mLock) {
-                try {
-                    mWifiManager.registerTrafficStateCallback(
-                            Executors.newSingleThreadExecutor(), trafficStateCallback);
-                    // Send some traffic to trigger the traffic state change callbacks.
-                    sendTraffic();
-                    // now wait for callback
-                    mLock.wait(TEST_WAIT_DURATION_MS);
-                } catch (InterruptedException e) {
-                }
-            }
-            // check if we got the state changed callback
-            assertTrue(trafficStateCallback.onStateChangedCalled);
-            assertEquals(DATA_ACTIVITY_INOUT, trafficStateCallback.state);
-        } finally {
-            turnScreenOff();
-            mWifiManager.unregisterTrafficStateCallback(trafficStateCallback);
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#setScanAlwaysAvailable(boolean)} &
-     * {@link WifiManager#isScanAlwaysAvailable()}.
-     */
-    public void testScanAlwaysAvailable() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        Boolean currState = null;
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            currState = mWifiManager.isScanAlwaysAvailable();
-            boolean newState = !currState;
-            mWifiManager.setScanAlwaysAvailable(newState);
-            PollingCheck.check(
-                    "Wifi settings toggle failed!",
-                    DURATION_SETTINGS_TOGGLE,
-                    () -> mWifiManager.isScanAlwaysAvailable() == newState);
-            assertEquals(newState, mWifiManager.isScanAlwaysAvailable());
-        } finally {
-            if (currState != null) mWifiManager.setScanAlwaysAvailable(currState);
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#setScanThrottleEnabled(boolean)} &
-     * {@link WifiManager#isScanThrottleEnabled()}.
-     */
-    public void testScanThrottleEnabled() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        Boolean currState = null;
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            currState = mWifiManager.isScanThrottleEnabled();
-            boolean newState = !currState;
-            mWifiManager.setScanThrottleEnabled(newState);
-            PollingCheck.check(
-                    "Wifi settings toggle failed!",
-                    DURATION_SETTINGS_TOGGLE,
-                    () -> mWifiManager.isScanThrottleEnabled() == newState);
-            assertEquals(newState, mWifiManager.isScanThrottleEnabled());
-        } finally {
-            if (currState != null) mWifiManager.setScanThrottleEnabled(currState);
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#setAutoWakeupEnabled(boolean)} &
-     * {@link WifiManager#isAutoWakeupEnabled()}.
-     */
-    public void testAutoWakeUpEnabled() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        Boolean currState = null;
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            currState = mWifiManager.isAutoWakeupEnabled();
-            boolean newState = !currState;
-            mWifiManager.setAutoWakeupEnabled(newState);
-            PollingCheck.check(
-                    "Wifi settings toggle failed!",
-                    DURATION_SETTINGS_TOGGLE,
-                    () -> mWifiManager.isAutoWakeupEnabled() == newState);
-            assertEquals(newState, mWifiManager.isAutoWakeupEnabled());
-        } finally {
-            if (currState != null) mWifiManager.setAutoWakeupEnabled(currState);
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#setVerboseLoggingEnabled(boolean)} &
-     * {@link WifiManager#isVerboseLoggingEnabled()}.
-     */
-    public void testVerboseLoggingEnabled() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        Boolean currState = null;
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            currState = mWifiManager.isVerboseLoggingEnabled();
-            boolean newState = !currState;
-            mWifiManager.setVerboseLoggingEnabled(newState);
-            PollingCheck.check(
-                    "Wifi settings toggle failed!",
-                    DURATION_SETTINGS_TOGGLE,
-                    () -> mWifiManager.isVerboseLoggingEnabled() == newState);
-            assertEquals(newState, mWifiManager.isVerboseLoggingEnabled());
-        } finally {
-            if (currState != null) mWifiManager.setVerboseLoggingEnabled(currState);
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests {@link WifiManager#factoryReset()}.
-     *
-     * Note: This test assumes that the device only has 1 or more saved networks before the test.
-     * The test will restore those when the test exits. But, it does not restore the softap
-     * configuration, suggestions, etc which will also have been lost on factory reset.
-     */
-    public void testFactoryReset() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        List<WifiConfiguration> savedNetworks = null;
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            // These below API's only work with privileged permissions (obtained via shell identity
-            // for test)
-            savedNetworks = mWifiManager.getPrivilegedConfiguredNetworks();
-
-            mWifiManager.factoryReset();
-            // Ensure all the saved networks are removed.
-            assertEquals(0, mWifiManager.getConfiguredNetworks().size());
-        } finally {
-            // Restore the original saved networks.
-            if (savedNetworks != null) {
-                for (WifiConfiguration network : savedNetworks) {
-                    network.networkId = WifiConfiguration.INVALID_NETWORK_ID;
-                    int networkId = mWifiManager.addNetwork(network);
-                    mWifiManager.enableNetwork(networkId, false);
-                }
-            }
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Test {@link WifiNetworkConnectionStatistics} does not crash.
-     * TODO(b/150891569): deprecate it in Android S, this API is not used anywhere.
-     */
-    public void testWifiNetworkConnectionStatistics() {
-        new WifiNetworkConnectionStatistics();
-        WifiNetworkConnectionStatistics stats = new WifiNetworkConnectionStatistics(0, 0);
-        new WifiNetworkConnectionStatistics(stats);
-    }
-
-    /**
-     * Test that the wifi country code is either null, or a length-2 string.
-     */
-    public void testGetCountryCode() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        String wifiCountryCode = ShellIdentityUtils.invokeWithShellPermissions(
-                mWifiManager::getCountryCode);
-
-        if (wifiCountryCode == null) {
-            return;
-        }
-        assertEquals(2, wifiCountryCode.length());
-
-        // assert that the country code is all uppercase
-        assertEquals(wifiCountryCode.toUpperCase(Locale.US), wifiCountryCode);
-
-        String telephonyCountryCode = getContext().getSystemService(TelephonyManager.class)
-                .getNetworkCountryIso();
-        assertEquals(telephonyCountryCode, wifiCountryCode.toLowerCase(Locale.US));
-    }
-
-    /**
-     * Test that {@link WifiManager#getCurrentNetwork()} returns a Network obeject consistent
-     * with {@link ConnectivityManager#registerNetworkCallback} when connected to a Wifi network,
-     * and returns null when not connected.
-     */
-    public void testGetCurrentNetwork() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // wait for Wifi to be connected
-        PollingCheck.check(
-                "Wifi not connected - Please ensure there is a saved network in range of this "
-                        + "device",
-                20000,
-                () -> mWifiManager.getConnectionInfo().getNetworkId() != -1);
-
-        Network wifiCurrentNetwork = ShellIdentityUtils.invokeWithShellPermissions(
-                mWifiManager::getCurrentNetwork);
-        assertNotNull(wifiCurrentNetwork);
-
-        TestNetworkCallback networkCallbackListener = new TestNetworkCallback(mLock);
-        synchronized (mLock) {
-            try {
-                // File a request for wifi network.
-                mConnectivityManager.registerNetworkCallback(
-                        new NetworkRequest.Builder()
-                                .addTransportType(TRANSPORT_WIFI)
-                                .build(),
-                        networkCallbackListener);
-                // now wait for callback
-                mLock.wait(TEST_WAIT_DURATION_MS);
-            } catch (InterruptedException e) {
-            }
-        }
-        assertTrue(networkCallbackListener.onAvailableCalled);
-        Network connectivityCurrentNetwork = networkCallbackListener.network;
-        assertEquals(connectivityCurrentNetwork, wifiCurrentNetwork);
-
-        setWifiEnabled(false);
-        PollingCheck.check(
-                "Wifi not disconnected!",
-                20000,
-                () -> mWifiManager.getConnectionInfo().getNetworkId() == -1);
-
-        assertNull(ShellIdentityUtils.invokeWithShellPermissions(mWifiManager::getCurrentNetwork));
-    }
-
-    /**
-     * Tests {@link WifiManager#isWpa3SaeSupported()} does not crash.
-     */
-    public void testIsWpa3SaeSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        mWifiManager.isWpa3SaeSupported();
-    }
-
-    /**
-     * Tests {@link WifiManager#isWpa3SuiteBSupported()} does not crash.
-     */
-    public void testIsWpa3SuiteBSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        mWifiManager.isWpa3SuiteBSupported();
-    }
-
-    /**
-     * Tests {@link WifiManager#isEnhancedOpenSupported()} does not crash.
-     */
-    public void testIsEnhancedOpenSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        mWifiManager.isEnhancedOpenSupported();
-    }
-
-    /**
-     * Test that {@link WifiManager#is5GHzBandSupported()} returns successfully in
-     * both WiFi enabled/disabled states.
-     * Note that the response depends on device support and hence both true/false
-     * are valid responses.
-     */
-    public void testIs5GhzBandSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // Check for 5GHz support with wifi enabled
-        setWifiEnabled(true);
-        PollingCheck.check(
-                "Wifi not enabled!",
-                20000,
-                () -> mWifiManager.isWifiEnabled());
-        boolean isSupportedEnabled = mWifiManager.is5GHzBandSupported();
-
-        // Check for 5GHz support with wifi disabled
-        setWifiEnabled(false);
-        PollingCheck.check(
-                "Wifi not disabled!",
-                20000,
-                () -> !mWifiManager.isWifiEnabled());
-        boolean isSupportedDisabled = mWifiManager.is5GHzBandSupported();
-
-        // If Support is true when WiFi is disable, then it has to be true when it is enabled.
-        // Note, the reverse is a valid case.
-        if (isSupportedDisabled) {
-            assertTrue(isSupportedEnabled);
-        }
-    }
-
-    /**
-     * Test that {@link WifiManager#is6GHzBandSupported()} returns successfully in
-     * both Wifi enabled/disabled states.
-     * Note that the response depends on device support and hence both true/false
-     * are valid responses.
-     */
-    public void testIs6GhzBandSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // Check for 6GHz support with wifi enabled
-        setWifiEnabled(true);
-        PollingCheck.check(
-                "Wifi not enabled!",
-                20000,
-                () -> mWifiManager.isWifiEnabled());
-        boolean isSupportedEnabled = mWifiManager.is6GHzBandSupported();
-
-        // Check for 6GHz support with wifi disabled
-        setWifiEnabled(false);
-        PollingCheck.check(
-                "Wifi not disabled!",
-                20000,
-                () -> !mWifiManager.isWifiEnabled());
-        boolean isSupportedDisabled = mWifiManager.is6GHzBandSupported();
-
-        // If Support is true when WiFi is disable, then it has to be true when it is enabled.
-        // Note, the reverse is a valid case.
-        if (isSupportedDisabled) {
-            assertTrue(isSupportedEnabled);
-        }
-    }
-
-    /**
-     * Test that {@link WifiManager#isWifiStandardSupported()} returns successfully in
-     * both Wifi enabled/disabled states. The test is to be performed on
-     * {@link WifiAnnotations}'s {@code WIFI_STANDARD_}
-     * Note that the response depends on device support and hence both true/false
-     * are valid responses.
-     */
-    public void testIsWifiStandardsSupported() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // Check for WiFi standards support with wifi enabled
-        setWifiEnabled(true);
-        PollingCheck.check(
-                "Wifi not enabled!",
-                20000,
-                () -> mWifiManager.isWifiEnabled());
-        boolean isLegacySupportedEnabled =
-                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_LEGACY);
-        boolean is11nSupporedEnabled =
-                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N);
-        boolean is11acSupportedEnabled =
-                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC);
-        boolean is11axSupportedEnabled =
-                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX);
-
-        // Check for WiFi standards support with wifi disabled
-        setWifiEnabled(false);
-        PollingCheck.check(
-                "Wifi not disabled!",
-                20000,
-                () -> !mWifiManager.isWifiEnabled());
-
-        boolean isLegacySupportedDisabled =
-                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_LEGACY);
-        boolean is11nSupportedDisabled =
-                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N);
-        boolean is11acSupportedDisabled =
-                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC);
-        boolean is11axSupportedDisabled =
-                mWifiManager.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX);
-
-        if (isLegacySupportedDisabled) {
-            assertTrue(isLegacySupportedEnabled);
-        }
-
-        if (is11nSupportedDisabled) {
-            assertTrue(is11nSupporedEnabled);
-        }
-
-        if (is11acSupportedDisabled) {
-            assertTrue(is11acSupportedEnabled);
-        }
-
-        if (is11axSupportedDisabled) {
-            assertTrue(is11axSupportedEnabled);
-        }
-    }
-
-    private static PasspointConfiguration createPasspointConfiguration() {
-        PasspointConfiguration config = new PasspointConfiguration();
-        HomeSp homeSp = new HomeSp();
-        homeSp.setFqdn("test.com");
-        homeSp.setFriendlyName("friendly name");
-        homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66});
-        config.setHomeSp(homeSp);
-        Credential.SimCredential simCred = new Credential.SimCredential();
-        simCred.setImsi("123456*");
-        simCred.setEapType(23 /* EAP_AKA */);
-        Credential cred = new Credential();
-        cred.setRealm("realm");
-        cred.setSimCredential(simCred);
-        config.setCredential(cred);
-
-        return config;
-    }
-
-    /**
-     * Tests {@link WifiManager#addOrUpdatePasspointConfiguration(PasspointConfiguration)}
-     * adds a Passpoint configuration correctly by getting it once it is added, and comparing it
-     * to the local copy of the configuration.
-     */
-    public void testAddOrUpdatePasspointConfiguration() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // Create and install a Passpoint configuration
-        PasspointConfiguration passpointConfiguration = createPasspointConfiguration();
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            mWifiManager.addOrUpdatePasspointConfiguration(passpointConfiguration);
-
-            // Compare configurations
-            List<PasspointConfiguration> configurations = mWifiManager.getPasspointConfigurations();
-            assertNotNull(configurations);
-            assertEquals(passpointConfiguration, configurations.get(0));
-
-            // Clean up
-            mWifiManager.removePasspointConfiguration(passpointConfiguration.getHomeSp().getFqdn());
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Tests that
-     * {@link WifiManager#startSubscriptionProvisioning(OsuProvider, Executor, ProvisioningCallback)}
-     * starts a subscription provisioning, and confirm a status callback invoked once.
-     */
-    public void testStartSubscriptionProvisioning() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-
-        // Using Java reflection to construct an OsuProvider instance because its constructor is
-        // hidden and not available to apps.
-        Class<?> osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider");
-        Constructor<?> osuProviderClassConstructor = osuProviderClass.getConstructor(String.class,
-                Map.class, String.class, Uri.class, String.class, List.class);
-
-        OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID,
-                TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI,
-                TEST_METHOD_LIST);
-
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            synchronized (mLock) {
-                // Start a subscription provisioning for a non-existent Passpoint R2 AP
-                mWifiManager.startSubscriptionProvisioning(osuProvider, mExecutor,
-                        mProvisioningCallback);
-                mLock.wait(TEST_WAIT_DURATION_MS);
-            }
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-
-        // Expect only a single callback event, connecting. Since AP doesn't exist, it ends here
-        assertEquals(ProvisioningCallback.OSU_STATUS_AP_CONNECTING, mProvisioningStatus);
-        // No failure callbacks expected
-        assertEquals(0, mProvisioningFailureStatus);
-        // No completion callback expected
-        assertFalse(mProvisioningComplete);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java
deleted file mode 100644
index c74c177..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiMigrationTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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 android.app.ActivityManager;
-import android.net.wifi.WifiMigration;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.test.AndroidTestCase;
-
-public class WifiMigrationTest extends AndroidTestCase {
-    private static final String TEST_SSID_UNQUOTED = "testSsid1";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            super.tearDown();
-            return;
-        }
-        super.tearDown();
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiMigration.SettingsMigrationData.Builder} class.
-     */
-    public void testWifiMigrationSettingsDataBuilder() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiMigration.SettingsMigrationData migrationData =
-                new WifiMigration.SettingsMigrationData.Builder()
-                        .setScanAlwaysAvailable(true)
-                        .setP2pFactoryResetPending(true)
-                        .setScanThrottleEnabled(true)
-                        .setSoftApTimeoutEnabled(true)
-                        .setWakeUpEnabled(true)
-                        .setVerboseLoggingEnabled(true)
-                        .setP2pDeviceName(TEST_SSID_UNQUOTED)
-                        .build();
-
-        assertNotNull(migrationData);
-        assertTrue(migrationData.isScanAlwaysAvailable());
-        assertTrue(migrationData.isP2pFactoryResetPending());
-        assertTrue(migrationData.isScanThrottleEnabled());
-        assertTrue(migrationData.isSoftApTimeoutEnabled());
-        assertTrue(migrationData.isWakeUpEnabled());
-        assertTrue(migrationData.isVerboseLoggingEnabled());
-        assertEquals(TEST_SSID_UNQUOTED, migrationData.getP2pDeviceName());
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiMigration.SettingsMigrationData} class.
-     */
-    public void testWifiMigrationSettings() throws Exception {
-        try {
-            WifiMigration.loadFromSettings(getContext());
-        } catch (Exception ignore) {
-        }
-    }
-
-    /**
-     * Tests {@link WifiMigration#convertAndRetrieveSharedConfigStoreFile(int)},
-     * {@link WifiMigration#convertAndRetrieveUserConfigStoreFile(int, UserHandle)},
-     * {@link WifiMigration#removeSharedConfigStoreFile(int)} and
-     * {@link WifiMigration#removeUserConfigStoreFile(int, UserHandle)}.
-     */
-    public void testWifiMigrationConfigStore() throws Exception {
-        try {
-            WifiMigration.convertAndRetrieveSharedConfigStoreFile(
-                    WifiMigration.STORE_FILE_SHARED_GENERAL);
-        } catch (Exception ignore) {
-        }
-        try {
-            WifiMigration.convertAndRetrieveSharedConfigStoreFile(
-                    WifiMigration.STORE_FILE_SHARED_SOFTAP);
-        } catch (Exception ignore) {
-        }
-        try {
-            WifiMigration.convertAndRetrieveUserConfigStoreFile(
-                    WifiMigration.STORE_FILE_USER_GENERAL,
-                    UserHandle.of(ActivityManager.getCurrentUser()));
-        } catch (Exception ignore) {
-        }
-        try {
-            WifiMigration.convertAndRetrieveUserConfigStoreFile(
-                    WifiMigration.STORE_FILE_USER_NETWORK_SUGGESTIONS,
-                    UserHandle.of(ActivityManager.getCurrentUser()));
-        } catch (Exception ignore) {
-        }
-        try {
-            WifiMigration.removeSharedConfigStoreFile(
-                    WifiMigration.STORE_FILE_SHARED_GENERAL);
-        } catch (Exception ignore) {
-        }
-        try {
-            WifiMigration.removeSharedConfigStoreFile(
-                    WifiMigration.STORE_FILE_SHARED_SOFTAP);
-        } catch (Exception ignore) {
-        }
-        try {
-            WifiMigration.removeUserConfigStoreFile(
-                    WifiMigration.STORE_FILE_USER_GENERAL,
-                    UserHandle.of(ActivityManager.getCurrentUser()));
-        } catch (Exception ignore) {
-        }
-        try {
-            WifiMigration.removeUserConfigStoreFile(
-                    WifiMigration.STORE_FILE_USER_NETWORK_SUGGESTIONS,
-                    UserHandle.of(ActivityManager.getCurrentUser()));
-        } catch (Exception ignore) {
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
deleted file mode 100644
index eb6d684..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSpecifierTest.java
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * 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.WifiEnterpriseConfig;
-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 boolean mWasScanThrottleEnabled;
-
-    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));
-        // Disable scan throttling for tests.
-        mWasScanThrottleEnabled = ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.isScanThrottleEnabled());
-        ShellIdentityUtils.invokeWithShellPermissions(
-                () -> mWifiManager.setScanThrottleEnabled(false));
-
-        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.setScanThrottleEnabled(mWasScanThrottleEnabled));
-        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 static String removeDoubleQuotes(String string) {
-        return WifiInfo.sanitizeSsid(string);
-    }
-
-    private WifiNetworkSpecifier.Builder createSpecifierBuilderWithCredentialFromSavedNetwork() {
-        WifiNetworkSpecifier.Builder specifierBuilder = new WifiNetworkSpecifier.Builder();
-        if (mTestNetwork.preSharedKey != null) {
-            if (mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
-                specifierBuilder.setWpa2Passphrase(removeDoubleQuotes(mTestNetwork.preSharedKey));
-            } else if (mTestNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
-                specifierBuilder.setWpa3Passphrase(removeDoubleQuotes(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(removeDoubleQuotes(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 = removeDoubleQuotes(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, removeDoubleQuotes(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(removeDoubleQuotes(mTestNetwork.SSID))
-                .build();
-        testUserRejectionWithSpecifier(specifier);
-    }
-
-    /**
-     * Tests the builder for WPA2 enterprise networks.
-     * Note: Can't do end to end tests for such networks in CTS environment.
-     */
-    public void testBuilderForWpa2Enterprise() {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder()
-                .setSsid(removeDoubleQuotes(mTestNetwork.SSID))
-                .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
-                .build();
-        WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder()
-                .setSsid(removeDoubleQuotes(mTestNetwork.SSID))
-                .setWpa2EnterpriseConfig(new WifiEnterpriseConfig())
-                .build();
-        assertThat(specifier1.satisfiedBy(specifier2)).isTrue();
-    }
-
-    /**
-     * Tests the builder for WPA3 enterprise networks.
-     * Note: Can't do end to end tests for such networks in CTS environment.
-     */
-    public void testBuilderForWpa3Enterprise() {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiNetworkSpecifier specifier1 = new WifiNetworkSpecifier.Builder()
-                .setSsid(removeDoubleQuotes(mTestNetwork.SSID))
-                .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
-                .build();
-        WifiNetworkSpecifier specifier2 = new WifiNetworkSpecifier.Builder()
-                .setSsid(removeDoubleQuotes(mTestNetwork.SSID))
-                .setWpa3EnterpriseConfig(new WifiEnterpriseConfig())
-                .build();
-        assertThat(specifier1.satisfiedBy(specifier2)).isTrue();
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
deleted file mode 100644
index e73abb8..0000000
--- a/tests/cts/net/src/android/net/wifi/cts/WifiNetworkSuggestionTest.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * 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.wifi.WifiEnterpriseConfig.Eap.AKA;
-import static android.net.wifi.WifiEnterpriseConfig.Eap.WAPI_CERT;
-
-import android.net.MacAddress;
-import android.net.wifi.WifiEnterpriseConfig;
-import android.net.wifi.WifiNetworkSuggestion;
-import android.net.wifi.hotspot2.PasspointConfiguration;
-import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSp;
-import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
-
-public class WifiNetworkSuggestionTest extends AndroidTestCase {
-    private static final String TEST_SSID = "testSsid";
-    private static final String TEST_BSSID = "00:df:aa:bc:12:23";
-    private static final String TEST_PASSPHRASE = "testPassword";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            super.tearDown();
-            return;
-        }
-        super.tearDown();
-    }
-
-    private WifiNetworkSuggestion.Builder createBuilderWithCommonParams() {
-        return createBuilderWithCommonParams(false);
-    }
-
-    private WifiNetworkSuggestion.Builder createBuilderWithCommonParams(boolean isPasspoint) {
-        WifiNetworkSuggestion.Builder builder = new WifiNetworkSuggestion.Builder();
-        if (!isPasspoint) {
-            builder.setSsid(TEST_SSID);
-            builder.setBssid(MacAddress.fromString(TEST_BSSID));
-            builder.setIsEnhancedOpen(false);
-            builder.setIsHiddenSsid(true);
-        }
-        builder.setPriority(0);
-        builder.setIsAppInteractionRequired(true);
-        builder.setIsUserInteractionRequired(true);
-        builder.setIsMetered(true);
-        builder.setCarrierId(TelephonyManager.UNKNOWN_CARRIER_ID);
-        builder.setCredentialSharedWithUser(true);
-        builder.setIsInitialAutojoinEnabled(true);
-        builder.setUntrusted(false);
-        return builder;
-    }
-
-    private void validateCommonParams(WifiNetworkSuggestion suggestion) {
-        validateCommonParams(suggestion, false);
-    }
-
-    private void validateCommonParams(WifiNetworkSuggestion suggestion, boolean isPasspoint) {
-        assertNotNull(suggestion);
-        assertNotNull(suggestion.getWifiConfiguration());
-        if (!isPasspoint) {
-            assertEquals(TEST_SSID, suggestion.getSsid());
-            assertEquals(TEST_BSSID, suggestion.getBssid().toString());
-            assertFalse(suggestion.isEnhancedOpen());
-            assertTrue(suggestion.isHiddenSsid());
-        }
-        assertEquals(0, suggestion.getPriority());
-        assertTrue(suggestion.isAppInteractionRequired());
-        assertTrue(suggestion.isUserInteractionRequired());
-        assertTrue(suggestion.isMetered());
-        assertTrue(suggestion.isCredentialSharedWithUser());
-        assertTrue(suggestion.isInitialAutojoinEnabled());
-        assertFalse(suggestion.isUntrusted());
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class.
-     */
-    public void testBuilderWithWpa2Passphrase() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiNetworkSuggestion suggestion =
-                createBuilderWithCommonParams()
-                .setWpa2Passphrase(TEST_PASSPHRASE)
-                .build();
-        validateCommonParams(suggestion);
-        assertEquals(TEST_PASSPHRASE, suggestion.getPassphrase());
-        assertNotNull(suggestion.getEnterpriseConfig());
-        assertNull(suggestion.getPasspointConfig());
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class.
-     */
-    public void testBuilderWithWpa3Passphrase() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiNetworkSuggestion suggestion =
-                createBuilderWithCommonParams()
-                        .setWpa3Passphrase(TEST_PASSPHRASE)
-                        .build();
-        validateCommonParams(suggestion);
-        assertEquals(TEST_PASSPHRASE, suggestion.getPassphrase());
-        assertNotNull(suggestion.getEnterpriseConfig());
-        assertNull(suggestion.getPasspointConfig());
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class.
-     */
-    public void testBuilderWithWapiPassphrase() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiNetworkSuggestion suggestion =
-                createBuilderWithCommonParams()
-                        .setWapiPassphrase(TEST_PASSPHRASE)
-                        .build();
-        validateCommonParams(suggestion);
-        assertEquals(TEST_PASSPHRASE, suggestion.getPassphrase());
-        assertNotNull(suggestion.getEnterpriseConfig());
-        assertNull(suggestion.getPasspointConfig());
-    }
-
-    private static WifiEnterpriseConfig createEnterpriseConfig() {
-        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
-        config.setEapMethod(AKA);
-        return config;
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class.
-     */
-    public void testBuilderWithWpa2Enterprise() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiEnterpriseConfig enterpriseConfig = createEnterpriseConfig();
-        WifiNetworkSuggestion suggestion =
-                createBuilderWithCommonParams()
-                        .setWpa2EnterpriseConfig(enterpriseConfig)
-                        .build();
-        validateCommonParams(suggestion);
-        assertNull(suggestion.getPassphrase());
-        assertNotNull(suggestion.getEnterpriseConfig());
-        assertEquals(enterpriseConfig.getEapMethod(),
-                suggestion.getEnterpriseConfig().getEapMethod());
-        assertNull(suggestion.getPasspointConfig());
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class.
-     */
-    public void testBuilderWithWpa3Enterprise() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiEnterpriseConfig enterpriseConfig = createEnterpriseConfig();
-        WifiNetworkSuggestion suggestion =
-                createBuilderWithCommonParams()
-                        .setWpa3EnterpriseConfig(enterpriseConfig)
-                        .build();
-        validateCommonParams(suggestion);
-        assertNull(suggestion.getPassphrase());
-        assertNotNull(suggestion.getEnterpriseConfig());
-        assertEquals(enterpriseConfig.getEapMethod(),
-                suggestion.getEnterpriseConfig().getEapMethod());
-        assertNull(suggestion.getPasspointConfig());
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class.
-     */
-    public void testBuilderWithWapiEnterprise() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
-        enterpriseConfig.setEapMethod(WAPI_CERT);
-        WifiNetworkSuggestion suggestion =
-                createBuilderWithCommonParams()
-                        .setWapiEnterpriseConfig(enterpriseConfig)
-                        .build();
-        validateCommonParams(suggestion);
-        assertNull(suggestion.getPassphrase());
-        assertNotNull(suggestion.getEnterpriseConfig());
-        assertEquals(enterpriseConfig.getEapMethod(),
-                suggestion.getEnterpriseConfig().getEapMethod());
-        assertNull(suggestion.getPasspointConfig());
-    }
-
-    /**
-     * Helper function for creating a {@link PasspointConfiguration} for testing.
-     *
-     * @return {@link PasspointConfiguration}
-     */
-    private static PasspointConfiguration createPasspointConfig() {
-        HomeSp homeSp = new HomeSp();
-        homeSp.setFqdn("fqdn");
-        homeSp.setFriendlyName("friendly name");
-        homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
-        Credential cred = new Credential();
-        cred.setRealm("realm");
-        cred.setUserCredential(null);
-        cred.setCertCredential(null);
-        cred.setSimCredential(new Credential.SimCredential());
-        cred.getSimCredential().setImsi("1234*");
-        cred.getSimCredential().setEapType(23); // EAP-AKA
-        cred.setCaCertificate(null);
-        cred.setClientCertificateChain(null);
-        cred.setClientPrivateKey(null);
-        PasspointConfiguration config = new PasspointConfiguration();
-        config.setHomeSp(homeSp);
-        config.setCredential(cred);
-        return config;
-    }
-
-    /**
-     * Tests {@link android.net.wifi.WifiNetworkSuggestion.Builder} class.
-     */
-    public void testBuilderWithPasspointConfig() throws Exception {
-        if (!WifiFeature.isWifiSupported(getContext())) {
-            // skip the test if WiFi is not supported
-            return;
-        }
-        PasspointConfiguration passpointConfig = createPasspointConfig();
-        WifiNetworkSuggestion suggestion =
-                createBuilderWithCommonParams(true)
-                        .setPasspointConfig(passpointConfig)
-                        .build();
-        validateCommonParams(suggestion, true);
-        assertNull(suggestion.getPassphrase());
-        assertNotNull(suggestion.getEnterpriseConfig());
-        assertEquals(passpointConfig, suggestion.getPasspointConfig());
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java
deleted file mode 100644
index d8f5e57..0000000
--- a/tests/cts/net/src/android/net/wifi/nl80211/cts/DeviceWiphyCapabilitiesTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.nl80211.cts;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.net.wifi.ScanResult;
-import android.net.wifi.cts.WifiFeature;
-import android.net.wifi.nl80211.DeviceWiphyCapabilities;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** CTS tests for {@link DeviceWiphyCapabilities}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class DeviceWiphyCapabilitiesTest {
-
-    @Before
-    public void setUp() {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        // skip tests if Wifi is not supported
-        assumeTrue(WifiFeature.isWifiSupported(context));
-    }
-
-    /**
-     *  Test that a {@link DeviceWiphyCapabilities} object can be serialized and deserialized,
-     *  while keeping its values unchanged.
-     */
-    @Test
-    public void canSerializeAndDeserialize() {
-        DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities();
-
-        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true);
-        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true);
-        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false);
-
-        Parcel parcel = Parcel.obtain();
-        capa.writeToParcel(parcel, 0);
-        // Rewind the pointer to the head of the parcel.
-        parcel.setDataPosition(0);
-        DeviceWiphyCapabilities capaDeserialized =
-                DeviceWiphyCapabilities.CREATOR.createFromParcel(parcel);
-
-        assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11N)).isTrue();
-        assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AC))
-                .isTrue();
-        assertThat(capaDeserialized.isWifiStandardSupported(ScanResult.WIFI_STANDARD_11AX))
-                .isFalse();
-        assertThat(capaDeserialized).isEqualTo(capa);
-        assertThat(capaDeserialized.hashCode()).isEqualTo(capa.hashCode());
-    }
-
-    /** Test mapping wifi standard support into channel width support */
-    @Test
-    public void testMappingWifiStandardIntoChannelWidthSupport() {
-        DeviceWiphyCapabilities capa = new DeviceWiphyCapabilities();
-
-        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, false);
-        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, false);
-        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AX, false);
-        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue();
-        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isFalse();
-        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isFalse();
-
-        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11N, true);
-        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue();
-        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isTrue();
-        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isFalse();
-
-        capa.setWifiStandardSupport(ScanResult.WIFI_STANDARD_11AC, true);
-        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_20MHZ)).isTrue();
-        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_40MHZ)).isTrue();
-        assertThat(capa.isChannelWidthSupported(ScanResult.CHANNEL_WIDTH_80MHZ)).isTrue();
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java
deleted file mode 100644
index 3149b54..0000000
--- a/tests/cts/net/src/android/net/wifi/nl80211/cts/NativeWifiClientTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.nl80211.cts;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.net.MacAddress;
-import android.net.wifi.cts.WifiFeature;
-import android.net.wifi.nl80211.NativeWifiClient;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** CTS tests for {@link NativeWifiClient}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NativeWifiClientTest {
-
-    private static final byte[] TEST_MAC = { 1, 2, 3, 4, 5, 6 };
-
-    @Before
-    public void setUp() {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        // skip tests if Wifi is not supported
-        assumeTrue(WifiFeature.isWifiSupported(context));
-    }
-
-    @Test
-    public void testGetters() {
-        NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC));
-
-        assertThat(client.getMacAddress().toByteArray()).isEqualTo(TEST_MAC);
-    }
-
-    @Test
-    public void canSerializeAndDeserialize() {
-        NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC));
-
-        Parcel parcel = Parcel.obtain();
-        client.writeToParcel(parcel, 0);
-        // Rewind the pointer to the head of the parcel.
-        parcel.setDataPosition(0);
-        NativeWifiClient clientDeserialized = NativeWifiClient.CREATOR.createFromParcel(parcel);
-
-        assertThat(clientDeserialized.getMacAddress().toByteArray()).isEqualTo(TEST_MAC);
-        assertThat(clientDeserialized).isEqualTo(client);
-        assertThat(clientDeserialized.hashCode()).isEqualTo(client.hashCode());
-    }
-
-    @Test
-    public void testEquals() {
-        NativeWifiClient client = new NativeWifiClient(MacAddress.fromBytes(TEST_MAC));
-        NativeWifiClient client2 =
-                new NativeWifiClient(MacAddress.fromBytes(new byte[] { 7, 8, 9, 10, 11, 12 }));
-
-        assertThat(client2).isNotEqualTo(client);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java
deleted file mode 100644
index f3a8f05..0000000
--- a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoNetworkTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.nl80211.cts;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.net.wifi.cts.WifiFeature;
-import android.net.wifi.nl80211.PnoNetwork;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** CTS tests for {@link PnoNetwork}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class PnoNetworkTest {
-
-    private static final byte[] TEST_SSID = { 's', 's', 'i', 'd' };
-    private static final int[] TEST_FREQUENCIES = { 2412, 2417, 5035 };
-
-    @Before
-    public void setUp() {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        // skip tests if Wifi is not supported
-        assumeTrue(WifiFeature.isWifiSupported(context));
-    }
-
-    @Test
-    public void testGetters() {
-        PnoNetwork network = new PnoNetwork();
-        network.setSsid(TEST_SSID);
-        network.setFrequenciesMhz(TEST_FREQUENCIES);
-        network.setHidden(true);
-
-        assertThat(network.getSsid()).isEqualTo(TEST_SSID);
-        assertThat(network.getFrequenciesMhz()).isEqualTo(TEST_FREQUENCIES);
-        assertThat(network.isHidden()).isTrue();
-    }
-
-    @Test
-    public void canSerializeAndDeserialize() {
-        PnoNetwork network = new PnoNetwork();
-        network.setSsid(TEST_SSID);
-        network.setFrequenciesMhz(TEST_FREQUENCIES);
-        network.setHidden(true);
-
-        Parcel parcel = Parcel.obtain();
-        network.writeToParcel(parcel, 0);
-        // Rewind the pointer to the head of the parcel.
-        parcel.setDataPosition(0);
-        PnoNetwork networkDeserialized = PnoNetwork.CREATOR.createFromParcel(parcel);
-
-        assertThat(networkDeserialized.getSsid()).isEqualTo(TEST_SSID);
-        assertThat(networkDeserialized.getFrequenciesMhz()).isEqualTo(TEST_FREQUENCIES);
-        assertThat(networkDeserialized.isHidden()).isTrue();
-        assertThat(networkDeserialized).isEqualTo(network);
-        assertThat(networkDeserialized.hashCode()).isEqualTo(network.hashCode());
-    }
-
-    @Test
-    public void testEquals() {
-        PnoNetwork network = new PnoNetwork();
-        network.setSsid(TEST_SSID);
-        network.setFrequenciesMhz(TEST_FREQUENCIES);
-        network.setHidden(true);
-
-        PnoNetwork network2 = new PnoNetwork();
-        network.setSsid(new byte[] { 'a', 's', 'd', 'f'});
-        network.setFrequenciesMhz(new int[] { 1, 2, 3 });
-        network.setHidden(false);
-
-        assertThat(network2).isNotEqualTo(network);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java
deleted file mode 100644
index 59f5d99..0000000
--- a/tests/cts/net/src/android/net/wifi/nl80211/cts/PnoSettingsTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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.nl80211.cts;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.net.wifi.cts.WifiFeature;
-import android.net.wifi.nl80211.PnoNetwork;
-import android.net.wifi.nl80211.PnoSettings;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.List;
-
-/** CTS tests for {@link PnoSettings}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class PnoSettingsTest {
-
-    private static List<PnoNetwork> createTestNetworks() {
-        PnoNetwork network1 = new PnoNetwork();
-        network1.setSsid(new byte[] { 's', 's', 'i', 'd' });
-        network1.setFrequenciesMhz(new int[] { 2412, 2417, 5035 });
-        network1.setHidden(true);
-
-        PnoNetwork network2 = new PnoNetwork();
-        network2.setSsid(new byte[] { 'a', 's', 'd', 'f' });
-        network2.setFrequenciesMhz(new int[] { 2422, 2427, 5040 });
-        network2.setHidden(false);
-
-        return Arrays.asList(network1, network2);
-    }
-
-    @Before
-    public void setUp() {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        // skip tests if Wifi is not supported
-        assumeTrue(WifiFeature.isWifiSupported(context));
-    }
-
-    @Test
-    public void testGetters() {
-        PnoSettings settings = new PnoSettings();
-        settings.setIntervalMillis(1000);
-        settings.setMin2gRssiDbm(-70);
-        settings.setMin5gRssiDbm(-60);
-        settings.setMin6gRssiDbm(-50);
-        settings.setPnoNetworks(createTestNetworks());
-
-        assertThat(settings.getIntervalMillis()).isEqualTo(1000);
-        assertThat(settings.getMin2gRssiDbm()).isEqualTo(-70);
-        assertThat(settings.getMin5gRssiDbm()).isEqualTo(-60);
-        assertThat(settings.getMin6gRssiDbm()).isEqualTo(-50);
-        assertThat(settings.getPnoNetworks()).isEqualTo(createTestNetworks());
-    }
-
-    @Test
-    public void canSerializeAndDeserialize() {
-        PnoSettings settings = new PnoSettings();
-        settings.setIntervalMillis(1000);
-        settings.setMin2gRssiDbm(-70);
-        settings.setMin5gRssiDbm(-60);
-        settings.setMin6gRssiDbm(-50);
-        settings.setPnoNetworks(createTestNetworks());
-
-        Parcel parcel = Parcel.obtain();
-        settings.writeToParcel(parcel, 0);
-        // Rewind the pointer to the head of the parcel.
-        parcel.setDataPosition(0);
-        PnoSettings settingsDeserialized = PnoSettings.CREATOR.createFromParcel(parcel);
-
-        assertThat(settingsDeserialized.getIntervalMillis()).isEqualTo(1000);
-        assertThat(settingsDeserialized.getMin2gRssiDbm()).isEqualTo(-70);
-        assertThat(settingsDeserialized.getMin5gRssiDbm()).isEqualTo(-60);
-        assertThat(settingsDeserialized.getMin6gRssiDbm()).isEqualTo(-50);
-        assertThat(settingsDeserialized.getPnoNetworks()).isEqualTo(createTestNetworks());
-        assertThat(settingsDeserialized).isEqualTo(settings);
-        assertThat(settingsDeserialized.hashCode()).isEqualTo(settings.hashCode());
-    }
-
-    @Test
-    public void testEquals() {
-        PnoSettings settings = new PnoSettings();
-        settings.setIntervalMillis(1000);
-        settings.setMin2gRssiDbm(-70);
-        settings.setMin5gRssiDbm(-60);
-        settings.setMin6gRssiDbm(-50);
-        settings.setPnoNetworks(createTestNetworks());
-
-        PnoSettings settings2 = new PnoSettings();
-        settings.setIntervalMillis(2000);
-        settings.setMin2gRssiDbm(-70);
-        settings.setMin5gRssiDbm(-60);
-        settings.setMin6gRssiDbm(-50);
-        settings.setPnoNetworks(createTestNetworks());
-
-        assertThat(settings2).isNotEqualTo(settings);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java
deleted file mode 100644
index 0a76bdb..0000000
--- a/tests/cts/net/src/android/net/wifi/nl80211/cts/RadioChainInfoTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.nl80211.cts;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.net.wifi.cts.WifiFeature;
-import android.net.wifi.nl80211.RadioChainInfo;
-import android.os.Parcel;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** CTS tests for {@link RadioChainInfo}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RadioChainInfoTest {
-
-    private static final int TEST_CHAIN_ID = 1;
-    private static final int TEST_CHAIN_ID2 = 2;
-    private static final int TEST_LEVEL_DBM = -50;
-    private static final int TEST_LEVEL_DBM2 = -80;
-
-    @Before
-    public void setUp() {
-        Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        // skip tests if Wifi is not supported
-        assumeTrue(WifiFeature.isWifiSupported(context));
-    }
-
-    @Test
-    public void testGetters() {
-        RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM);
-        assertThat(info.getChainId()).isEqualTo(TEST_CHAIN_ID);
-        assertThat(info.getLevelDbm()).isEqualTo(TEST_LEVEL_DBM);
-    }
-
-    @Test
-    public void canSerializeAndDeserialize() {
-        RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM);
-
-        Parcel parcel = Parcel.obtain();
-        info.writeToParcel(parcel, 0);
-        // Rewind the pointer to the head of the parcel.
-        parcel.setDataPosition(0);
-        RadioChainInfo infoDeserialized = RadioChainInfo.CREATOR.createFromParcel(parcel);
-
-        assertThat(infoDeserialized.getChainId()).isEqualTo(TEST_CHAIN_ID);
-        assertThat(infoDeserialized.getLevelDbm()).isEqualTo(TEST_LEVEL_DBM);
-        assertThat(infoDeserialized).isEqualTo(info);
-        assertThat(infoDeserialized.hashCode()).isEqualTo(info.hashCode());
-    }
-
-    @Test
-    public void testEquals() {
-        RadioChainInfo info = new RadioChainInfo(TEST_CHAIN_ID, TEST_LEVEL_DBM);
-        RadioChainInfo info2 = new RadioChainInfo(TEST_CHAIN_ID2, TEST_LEVEL_DBM2);
-
-        assertThat(info2).isNotEqualTo(info);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java b/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java
deleted file mode 100644
index f1f3010..0000000
--- a/tests/cts/net/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.nl80211.cts;
-
-import static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.net.wifi.ScanResult;
-import android.net.wifi.cts.WifiFeature;
-import android.net.wifi.nl80211.WifiNl80211Manager;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-
-/** CTS tests for {@link WifiNl80211Manager}. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class WifiNl80211ManagerTest {
-
-    private Context mContext;
-
-    @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getInstrumentation().getContext();
-        // skip tests if Wifi is not supported
-        assumeTrue(WifiFeature.isWifiSupported(mContext));
-    }
-
-    @Test
-    public void testOemSecurityTypeConstructor() {
-        OemSecurityType securityType = new OemSecurityType(
-                ScanResult.PROTOCOL_WPA,
-                Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE),
-                Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP),
-                ScanResult.CIPHER_CCMP);
-
-        assertThat(securityType.protocol).isEqualTo(ScanResult.PROTOCOL_WPA);
-        assertThat(securityType.keyManagement)
-                .isEqualTo(Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE));
-        assertThat(securityType.pairwiseCipher)
-                .isEqualTo(Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP));
-        assertThat(securityType.groupCipher).isEqualTo(ScanResult.CIPHER_CCMP);
-    }
-
-    @Test
-    public void testSendMgmtFrame() {
-        try {
-            WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
-            manager.sendMgmtFrame("wlan0", new byte[]{}, -1, Runnable::run,
-                    new WifiNl80211Manager.SendMgmtFrameCallback() {
-                        @Override
-                        public void onAck(int elapsedTimeMs) {}
-
-                        @Override
-                        public void onFailure(int reason) {}
-                    });
-        } catch (Exception ignore) {}
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java
deleted file mode 100644
index 0a2a2e6..0000000
--- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pConfigTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 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.p2p.cts;
-
-import android.net.MacAddress;
-import android.net.wifi.p2p.WifiP2pConfig;
-import android.net.wifi.p2p.WifiP2pGroup;
-import android.test.AndroidTestCase;
-
-public class WifiP2pConfigTest extends AndroidTestCase {
-    private static final String TEST_NETWORK_NAME = "DIRECT-xy-Hello";
-    private static final String TEST_PASSPHRASE = "8etterW0r1d";
-    private static final int TEST_OWNER_BAND = WifiP2pConfig.GROUP_OWNER_BAND_5GHZ;
-    private static final int TEST_OWNER_FREQ = 2447;
-    private static final String TEST_DEVICE_ADDRESS = "aa:bb:cc:dd:ee:ff";
-
-    public void testWifiP2pConfigCopyConstructor() {
-        WifiP2pConfig config = new WifiP2pConfig.Builder()
-                .setNetworkName(TEST_NETWORK_NAME)
-                .setPassphrase(TEST_PASSPHRASE)
-                .setGroupOperatingBand(TEST_OWNER_BAND)
-                .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS))
-                .enablePersistentMode(true)
-                .build();
-
-        WifiP2pConfig copiedConfig = new WifiP2pConfig(config);
-
-        assertEquals(copiedConfig.deviceAddress, TEST_DEVICE_ADDRESS);
-        assertEquals(copiedConfig.getNetworkName(), TEST_NETWORK_NAME);
-        assertEquals(copiedConfig.getPassphrase(), TEST_PASSPHRASE);
-        assertEquals(copiedConfig.getGroupOwnerBand(), TEST_OWNER_BAND);
-        assertEquals(copiedConfig.getNetworkId(), WifiP2pGroup.NETWORK_ID_PERSISTENT);
-    }
-
-    public void testWifiP2pConfigBuilderForPersist() {
-        WifiP2pConfig config = new WifiP2pConfig.Builder()
-                .setNetworkName(TEST_NETWORK_NAME)
-                .setPassphrase(TEST_PASSPHRASE)
-                .setGroupOperatingBand(TEST_OWNER_BAND)
-                .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS))
-                .enablePersistentMode(true)
-                .build();
-
-        assertEquals(config.deviceAddress, TEST_DEVICE_ADDRESS);
-        assertEquals(config.getNetworkName(), TEST_NETWORK_NAME);
-        assertEquals(config.getPassphrase(), TEST_PASSPHRASE);
-        assertEquals(config.getGroupOwnerBand(), TEST_OWNER_BAND);
-        assertEquals(config.getNetworkId(), WifiP2pGroup.NETWORK_ID_PERSISTENT);
-    }
-
-    public void testWifiP2pConfigBuilderForNonPersist() {
-        WifiP2pConfig config = new WifiP2pConfig.Builder()
-                .setNetworkName(TEST_NETWORK_NAME)
-                .setPassphrase(TEST_PASSPHRASE)
-                .setGroupOperatingFrequency(TEST_OWNER_FREQ)
-                .setDeviceAddress(MacAddress.fromString(TEST_DEVICE_ADDRESS))
-                .enablePersistentMode(false)
-                .build();
-
-        assertEquals(config.deviceAddress, TEST_DEVICE_ADDRESS);
-        assertEquals(config.getNetworkName(), TEST_NETWORK_NAME);
-        assertEquals(config.getPassphrase(), TEST_PASSPHRASE);
-        assertEquals(config.getGroupOwnerBand(), TEST_OWNER_FREQ);
-        assertEquals(config.getNetworkId(), WifiP2pGroup.NETWORK_ID_TEMPORARY);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java
deleted file mode 100644
index 1510d7c..0000000
--- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pDeviceTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.p2p.cts;
-
-import android.net.InetAddresses;
-import android.net.wifi.p2p.WifiP2pDevice;
-import android.test.AndroidTestCase;
-
-public class WifiP2pDeviceTest extends AndroidTestCase {
-
-    public void testDefaultWpsMethodSupportCheck() {
-        WifiP2pDevice dev = new WifiP2pDevice();
-
-        assertFalse(dev.wpsPbcSupported());
-        assertFalse(dev.wpsDisplaySupported());
-        assertFalse(dev.wpsKeypadSupported());
-    }
-
-    public void testDefaultDeviceCapabilityCheck() {
-        WifiP2pDevice dev = new WifiP2pDevice();
-
-        assertFalse(dev.isServiceDiscoveryCapable());
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java
deleted file mode 100644
index 8504f15..0000000
--- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pInfoTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.p2p.cts;
-
-import android.net.InetAddresses;
-import android.net.wifi.p2p.WifiP2pInfo;
-import android.test.AndroidTestCase;
-
-public class WifiP2pInfoTest extends AndroidTestCase {
-
-    public String TEST_GROUP_OWNER_ADDRESS = "192.168.43.1";
-
-    public void testWifiP2pInfoNoGroup() {
-        WifiP2pInfo info = new WifiP2pInfo();
-        info.groupFormed = false;
-
-        WifiP2pInfo copiedInfo = new WifiP2pInfo(info);
-        assertEquals(info.groupFormed, copiedInfo.groupFormed);
-        assertEquals(info.isGroupOwner, copiedInfo.isGroupOwner);
-        assertEquals(info.groupOwnerAddress, copiedInfo.groupOwnerAddress);
-    }
-
-    public void testWifiP2pInfoGroupOwner() {
-        WifiP2pInfo info = new WifiP2pInfo();
-        info.groupFormed = true;
-        info.isGroupOwner = true;
-        info.groupOwnerAddress = InetAddresses.parseNumericAddress(TEST_GROUP_OWNER_ADDRESS);
-
-        WifiP2pInfo copiedInfo = new WifiP2pInfo(info);
-        assertEquals(info.groupFormed, copiedInfo.groupFormed);
-        assertEquals(info.isGroupOwner, copiedInfo.isGroupOwner);
-        assertEquals(info.groupOwnerAddress, copiedInfo.groupOwnerAddress);
-    }
-
-    public void testWifiP2pInfoGroupClient() {
-        WifiP2pInfo info = new WifiP2pInfo();
-        info.groupFormed = true;
-        info.isGroupOwner = false;
-        info.groupOwnerAddress = InetAddresses.parseNumericAddress(TEST_GROUP_OWNER_ADDRESS);
-
-        WifiP2pInfo copiedInfo = new WifiP2pInfo(info);
-        assertEquals(info.groupFormed, copiedInfo.groupFormed);
-        assertEquals(info.isGroupOwner, copiedInfo.isGroupOwner);
-        assertEquals(info.groupOwnerAddress, copiedInfo.groupOwnerAddress);
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java
deleted file mode 100644
index b363b1e..0000000
--- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pServiceRequestTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.p2p.cts;
-
-import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
-import android.net.wifi.p2p.nsd.WifiP2pServiceRequest;
-import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceRequest;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-import java.util.stream.Collectors;
-
-public class WifiP2pServiceRequestTest extends AndroidTestCase {
-
-    private final int TEST_UPNP_VERSION = 0x10;
-    private final String TEST_UPNP_QUERY = "ssdp:all";
-
-    private String bin2HexStr(byte[] data) {
-        StringBuffer sb = new StringBuffer();
-        for (byte b: data) {
-            sb.append(String.format(Locale.US, "%02x", b & 0xff));
-        }
-        return sb.toString();
-    }
-
-    public void testValidRawRequest() throws IllegalArgumentException {
-        StringBuffer sb = new StringBuffer();
-        sb.append(String.format(Locale.US, "%02x", TEST_UPNP_VERSION));
-        sb.append(bin2HexStr(TEST_UPNP_QUERY.getBytes()));
-
-        WifiP2pServiceRequest rawRequest =
-                WifiP2pServiceRequest.newInstance(
-                        WifiP2pServiceInfo.SERVICE_TYPE_UPNP,
-                        sb.toString());
-
-        WifiP2pUpnpServiceRequest upnpRequest =
-                WifiP2pUpnpServiceRequest.newInstance(
-                        TEST_UPNP_QUERY);
-
-        assertEquals(rawRequest, upnpRequest);
-    }
-
-    public void testInvalidRawRequest() {
-        StringBuffer sb = new StringBuffer();
-        sb.append(String.format(Locale.US, "%02x", TEST_UPNP_VERSION));
-        sb.append(bin2HexStr(TEST_UPNP_QUERY.getBytes()));
-        sb.append("x");
-
-        try {
-            WifiP2pServiceRequest request =
-                    WifiP2pServiceRequest.newInstance(
-                            WifiP2pServiceInfo.SERVICE_TYPE_UPNP, sb.toString());
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException ex) {
-            return;
-        }
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java b/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java
deleted file mode 100644
index 75df5bf..0000000
--- a/tests/cts/net/src/android/net/wifi/p2p/cts/WifiP2pWfdInfoTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.p2p.cts;
-
-import android.net.wifi.p2p.WifiP2pWfdInfo;
-import android.test.AndroidTestCase;
-
-public class WifiP2pWfdInfoTest extends AndroidTestCase {
-
-    private final int TEST_DEVICE_TYPE = WifiP2pWfdInfo.DEVICE_TYPE_WFD_SOURCE;
-    private final boolean TEST_DEVICE_ENABLE_STATUS = true;
-    private final boolean TEST_SESSION_STATUS = true;
-    private final int TEST_CONTROL_PORT = 9999;
-    private final int TEST_MAX_THROUGHPUT = 1024;
-    private final boolean TEST_CONTENT_PROTECTION_SUPPORTED_STATUS = true;
-
-    public void testWifiP2pWfdInfo() {
-        WifiP2pWfdInfo info = new WifiP2pWfdInfo();
-
-        info.setDeviceType(TEST_DEVICE_TYPE);
-        info.setEnabled(TEST_DEVICE_ENABLE_STATUS);
-        info.setSessionAvailable(true);
-        info.setControlPort(TEST_CONTROL_PORT);
-        info.setMaxThroughput(TEST_MAX_THROUGHPUT);
-        info.setContentProtectionSupported(true);
-
-        WifiP2pWfdInfo copiedInfo = new WifiP2pWfdInfo(info);
-        assertEquals(TEST_DEVICE_TYPE, copiedInfo.getDeviceType());
-        assertEquals(TEST_DEVICE_ENABLE_STATUS, copiedInfo.isEnabled());
-        assertEquals(TEST_SESSION_STATUS, copiedInfo.isSessionAvailable());
-        assertEquals(TEST_CONTROL_PORT, copiedInfo.getControlPort());
-        assertEquals(TEST_MAX_THROUGHPUT, copiedInfo.getMaxThroughput());
-        assertEquals(TEST_CONTENT_PROTECTION_SUPPORTED_STATUS,
-                copiedInfo.isContentProtectionSupported());
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java b/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java
deleted file mode 100644
index 07d5718..0000000
--- a/tests/cts/net/src/android/net/wifi/rtt/cts/TestBase.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2018 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.rtt.cts;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.location.LocationManager;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiManager;
-import android.net.wifi.rtt.RangingResult;
-import android.net.wifi.rtt.RangingResultCallback;
-import android.net.wifi.rtt.WifiRttManager;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.HandlerThread;
-import android.test.AndroidTestCase;
-
-import com.android.compatibility.common.util.SystemUtil;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Base class for Wi-Fi RTT CTS test cases. Provides a uniform configuration and event management
- * facility.
- */
-public class TestBase extends AndroidTestCase {
-    protected static final String TAG = "WifiRttCtsTests";
-
-    // wait for Wi-Fi RTT to become available
-    private static final int WAIT_FOR_RTT_CHANGE_SECS = 10;
-
-    // wait for Wi-Fi scan results to become available
-    private static final int WAIT_FOR_SCAN_RESULTS_SECS = 20;
-
-    protected WifiRttManager mWifiRttManager;
-    protected WifiManager mWifiManager;
-    private LocationManager mLocationManager;
-    private WifiManager.WifiLock mWifiLock;
-
-    private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest");
-    protected final Executor mExecutor;
-    {
-        mHandlerThread.start();
-        mExecutor = new HandlerExecutor(new Handler(mHandlerThread.getLooper()));
-    }
-
-    /**
-     * Returns a flag indicating whether or not Wi-Fi RTT should be tested. Wi-Fi RTT
-     * should be tested if the feature is supported on the current device.
-     */
-    static boolean shouldTestWifiRtt(Context context) {
-        final PackageManager pm = context.getPackageManager();
-        return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        if (!shouldTestWifiRtt(getContext())) {
-            return;
-        }
-
-        mLocationManager = (LocationManager) getContext().getSystemService(
-                Context.LOCATION_SERVICE);
-        assertTrue("RTT testing requires Location to be enabled",
-                mLocationManager.isLocationEnabled());
-
-        mWifiRttManager = (WifiRttManager) getContext().getSystemService(
-                Context.WIFI_RTT_RANGING_SERVICE);
-        assertNotNull("Wi-Fi RTT Manager", mWifiRttManager);
-
-        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
-        assertNotNull("Wi-Fi Manager", mWifiManager);
-        mWifiLock = mWifiManager.createWifiLock(TAG);
-        mWifiLock.acquire();
-        if (!mWifiManager.isWifiEnabled()) {
-            SystemUtil.runShellCommand("svc wifi enable");
-        }
-
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED);
-        WifiRttBroadcastReceiver receiver = new WifiRttBroadcastReceiver();
-        mContext.registerReceiver(receiver, intentFilter);
-        if (!mWifiRttManager.isAvailable()) {
-            assertTrue("Timeout waiting for Wi-Fi RTT to change status",
-                    receiver.waitForStateChange());
-            assertTrue("Wi-Fi RTT is not available (should be)", mWifiRttManager.isAvailable());
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (!shouldTestWifiRtt(getContext())) {
-            super.tearDown();
-            return;
-        }
-
-        super.tearDown();
-    }
-
-    class WifiRttBroadcastReceiver extends BroadcastReceiver {
-        private CountDownLatch mBlocker = new CountDownLatch(1);
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED.equals(intent.getAction())) {
-                mBlocker.countDown();
-            }
-        }
-
-        boolean waitForStateChange() throws InterruptedException {
-            return mBlocker.await(WAIT_FOR_RTT_CHANGE_SECS, TimeUnit.SECONDS);
-        }
-    }
-
-    class WifiScansBroadcastReceiver extends BroadcastReceiver {
-        private CountDownLatch mBlocker = new CountDownLatch(1);
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) {
-                mBlocker.countDown();
-            }
-        }
-
-        boolean waitForStateChange() throws InterruptedException {
-            return mBlocker.await(WAIT_FOR_SCAN_RESULTS_SECS, TimeUnit.SECONDS);
-        }
-    }
-
-    class ResultCallback extends RangingResultCallback {
-        private CountDownLatch mBlocker = new CountDownLatch(1);
-        private int mCode; // 0: success, otherwise RangingResultCallback STATUS_CODE_*.
-        private List<RangingResult> mResults;
-
-        @Override
-        public void onRangingFailure(int code) {
-            mCode = code;
-            mResults = null; // not necessary since intialized to null - but for completeness
-            mBlocker.countDown();
-        }
-
-        @Override
-        public void onRangingResults(List<RangingResult> results) {
-            mCode = 0; // not necessary since initialized to 0 - but for completeness
-            mResults = results;
-            mBlocker.countDown();
-        }
-
-        /**
-         * Waits for the listener callback to be called - or an error (timeout, interruption).
-         * Returns true on callback called, false on error (timeout, interruption).
-         */
-        boolean waitForCallback() throws InterruptedException {
-            return mBlocker.await(WAIT_FOR_RTT_CHANGE_SECS, TimeUnit.SECONDS);
-        }
-
-        /**
-         * Returns the code of the callback operation. Will be 0 for success (onRangingResults
-         * called), else (if onRangingFailure called) will be one of the STATUS_CODE_* values.
-         */
-        int getCode() {
-            return mCode;
-        }
-
-        /**
-         * Returns the list of ranging results. In cases of error (getCode() != 0) will return null.
-         */
-        List<RangingResult> getResults() {
-            return mResults;
-        }
-    }
-
-    /**
-     * Start a scan and return a list of observed ScanResults (APs).
-     */
-    protected List<ScanResult> scanAps() throws InterruptedException {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        WifiScansBroadcastReceiver receiver = new WifiScansBroadcastReceiver();
-        mContext.registerReceiver(receiver, intentFilter);
-
-        mWifiManager.startScan();
-        receiver.waitForStateChange();
-        mContext.unregisterReceiver(receiver);
-        return mWifiManager.getScanResults();
-    }
-
-    /**
-     * Start a scan and return a test AP which supports IEEE 802.11mc and which has the highest
-     * RSSI. Will perform N (parameterized) scans and get the best AP across both scans.
-     *
-     * Returns null if test AP is not found in the specified number of scans.
-     *
-     * @param numScanRetries Maximum number of scans retries (in addition to first scan).
-     */
-    protected ScanResult scanForTestAp(int numScanRetries)
-            throws InterruptedException {
-        int scanCount = 0;
-        ScanResult bestTestAp = null;
-        while (scanCount <= numScanRetries) {
-            for (ScanResult scanResult : scanAps()) {
-                if (!scanResult.is80211mcResponder()) {
-                    continue;
-                }
-                if (bestTestAp == null || scanResult.level > bestTestAp.level) {
-                    bestTestAp = scanResult;
-                }
-            }
-
-            scanCount++;
-        }
-
-        return bestTestAp;
-    }
-}
diff --git a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
deleted file mode 100644
index 9cbaf39..0000000
--- a/tests/cts/net/src/android/net/wifi/rtt/cts/WifiRttTest.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright (C) 2018 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.rtt.cts;
-
-import static org.mockito.Mockito.mock;
-
-import android.net.MacAddress;
-import android.net.wifi.ScanResult;
-import android.net.wifi.aware.PeerHandle;
-import android.net.wifi.rtt.RangingRequest;
-import android.net.wifi.rtt.RangingResult;
-import android.net.wifi.rtt.ResponderLocation;
-import android.platform.test.annotations.AppModeFull;
-
-import com.android.compatibility.common.util.DeviceReportLog;
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Wi-Fi RTT CTS test: range to all available Access Points which support IEEE 802.11mc.
- */
-@AppModeFull(reason = "Cannot get WifiManager in instant app mode")
-public class WifiRttTest extends TestBase {
-    // Number of scans to do while searching for APs supporting IEEE 802.11mc
-    private static final int NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP = 2;
-
-    // Number of RTT measurements per AP
-    private static final int NUM_OF_RTT_ITERATIONS = 10;
-
-    // Maximum failure rate of RTT measurements (percentage)
-    private static final int MAX_FAILURE_RATE_PERCENT = 10;
-
-    // Maximum variation from the average measurement (measures consistency)
-    private static final int MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM = 1000;
-
-    // Minimum valid RSSI value
-    private static final int MIN_VALID_RSSI = -100;
-
-    // Valid Mac Address
-    private static final MacAddress MAC = MacAddress.fromString("00:01:02:03:04:05");
-
-    /**
-     * Test Wi-Fi RTT ranging operation:
-     * - Scan for visible APs for the test AP (which is validated to support IEEE 802.11mc)
-     * - Perform N (constant) RTT operations
-     * - Validate:
-     *   - Failure ratio < threshold (constant)
-     *   - Result margin < threshold (constant)
-     */
-    public void testRangingToTestAp() throws InterruptedException {
-        if (!shouldTestWifiRtt(getContext())) {
-            return;
-        }
-
-        // Scan for IEEE 802.11mc supporting APs
-        ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP);
-        assertNotNull(
-                "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that "
-                        + "your test setup includes them!", testAp);
-
-        // Perform RTT operations
-        RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build();
-        List<RangingResult> allResults = new ArrayList<>();
-        int numFailures = 0;
-        int distanceSum = 0;
-        int distanceMin = 0;
-        int distanceMax = 0;
-        int[] statuses = new int[NUM_OF_RTT_ITERATIONS];
-        int[] distanceMms = new int[NUM_OF_RTT_ITERATIONS];
-        int[] distanceStdDevMms = new int[NUM_OF_RTT_ITERATIONS];
-        int[] rssis = new int[NUM_OF_RTT_ITERATIONS];
-        int[] numAttempted = new int[NUM_OF_RTT_ITERATIONS];
-        int[] numSuccessful = new int[NUM_OF_RTT_ITERATIONS];
-        long[] timestampsMs = new long[NUM_OF_RTT_ITERATIONS];
-        byte[] lastLci = null;
-        byte[] lastLcr = null;
-        for (int i = 0; i < NUM_OF_RTT_ITERATIONS; ++i) {
-            ResultCallback callback = new ResultCallback();
-            mWifiRttManager.startRanging(request, mExecutor, callback);
-            assertTrue("Wi-Fi RTT results: no callback on iteration " + i,
-                    callback.waitForCallback());
-
-            List<RangingResult> currentResults = callback.getResults();
-            assertNotNull("Wi-Fi RTT results: null results (onRangingFailure) on iteration " + i,
-                    currentResults);
-            assertEquals("Wi-Fi RTT results: unexpected # of results (expect 1) on iteration " + i,
-                    1, currentResults.size());
-            RangingResult result = currentResults.get(0);
-            assertEquals("Wi-Fi RTT results: invalid result (wrong BSSID) entry on iteration " + i,
-                    result.getMacAddress().toString(), testAp.BSSID);
-            assertNull("Wi-Fi RTT results: invalid result (non-null PeerHandle) entry on iteration "
-                    + i, result.getPeerHandle());
-
-            allResults.add(result);
-            int status = result.getStatus();
-            statuses[i] = status;
-            if (status == RangingResult.STATUS_SUCCESS) {
-                distanceSum += result.getDistanceMm();
-                if (i == 0) {
-                    distanceMin = result.getDistanceMm();
-                    distanceMax = result.getDistanceMm();
-                } else {
-                    distanceMin = Math.min(distanceMin, result.getDistanceMm());
-                    distanceMax = Math.max(distanceMax, result.getDistanceMm());
-                }
-
-                assertTrue("Wi-Fi RTT results: invalid RSSI on iteration " + i,
-                        result.getRssi() >= MIN_VALID_RSSI);
-
-                distanceMms[i - numFailures] = result.getDistanceMm();
-                distanceStdDevMms[i - numFailures] = result.getDistanceStdDevMm();
-                rssis[i - numFailures] = result.getRssi();
-                numAttempted[i - numFailures] = result.getNumAttemptedMeasurements();
-                numSuccessful[i - numFailures] = result.getNumSuccessfulMeasurements();
-                timestampsMs[i - numFailures] = result.getRangingTimestampMillis();
-
-                byte[] currentLci = result.getLci();
-                byte[] currentLcr = result.getLcr();
-                if (i - numFailures > 0) {
-                    assertTrue("Wi-Fi RTT results: invalid result (LCI mismatch) on iteration " + i,
-                            Arrays.equals(currentLci, lastLci));
-                    assertTrue("Wi-Fi RTT results: invalid result (LCR mismatch) on iteration " + i,
-                            Arrays.equals(currentLcr, lastLcr));
-                }
-                lastLci = currentLci;
-                lastLcr = currentLcr;
-            } else {
-                numFailures++;
-            }
-        }
-
-        // Save results to log
-        int numGoodResults = NUM_OF_RTT_ITERATIONS - numFailures;
-        DeviceReportLog reportLog = new DeviceReportLog(TAG, "testRangingToTestAp");
-        reportLog.addValues("status_codes", statuses, ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValues("distance_mm", Arrays.copyOf(distanceMms, numGoodResults),
-                ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValues("distance_stddev_mm", Arrays.copyOf(distanceStdDevMms, numGoodResults),
-                ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValues("rssi_dbm", Arrays.copyOf(rssis, numGoodResults), ResultType.NEUTRAL,
-                ResultUnit.NONE);
-        reportLog.addValues("num_attempted", Arrays.copyOf(numAttempted, numGoodResults),
-                ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValues("num_successful", Arrays.copyOf(numSuccessful, numGoodResults),
-                ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.addValues("timestamps", Arrays.copyOf(timestampsMs, numGoodResults),
-                ResultType.NEUTRAL, ResultUnit.NONE);
-        reportLog.submit();
-
-        // Analyze results
-        assertTrue("Wi-Fi RTT failure rate exceeds threshold: FAIL=" + numFailures + ", ITERATIONS="
-                        + NUM_OF_RTT_ITERATIONS + ", AP RSSI=" + testAp.level
-                        + ", AP SSID=" + testAp.SSID,
-                numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100);
-        if (numFailures != NUM_OF_RTT_ITERATIONS) {
-            double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
-            assertTrue("Wi-Fi RTT: Variation (max direction) exceeds threshold",
-                    (distanceMax - distanceAvg) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
-            assertTrue("Wi-Fi RTT: Variation (min direction) exceeds threshold",
-                    (distanceAvg - distanceMin) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
-            for (int i = 0; i < numGoodResults; ++i) {
-                assertNotSame("Number of attempted measurements is 0", 0, numAttempted[i]);
-                assertNotSame("Number of successful measurements is 0", 0, numSuccessful[i]);
-            }
-        }
-    }
-
-    /**
-     * Validate that when a request contains more range operations than allowed (by API) that we
-     * get an exception.
-     */
-    public void testRequestTooLarge() throws InterruptedException {
-        if (!shouldTestWifiRtt(getContext())) {
-            return;
-        }
-        ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP);
-        assertNotNull(
-                "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that "
-                        + "your test setup includes them!", testAp);
-
-        RangingRequest.Builder builder = new RangingRequest.Builder();
-        for (int i = 0; i < RangingRequest.getMaxPeers() - 2; ++i) {
-            builder.addAccessPoint(testAp);
-        }
-
-        List<ScanResult> scanResults = new ArrayList<>();
-        scanResults.add(testAp);
-        scanResults.add(testAp);
-        scanResults.add(testAp);
-
-        builder.addAccessPoints(scanResults);
-
-        try {
-            mWifiRttManager.startRanging(builder.build(), mExecutor, new ResultCallback());
-        } catch (IllegalArgumentException e) {
-            return;
-        }
-
-        fail("Did not receive expected IllegalArgumentException when tried to range to too "
-                + "many peers");
-    }
-
-    /**
-     * Verify ResponderLocation API
-     */
-    public void testRangingToTestApWithResponderLocation() throws InterruptedException {
-        if (!shouldTestWifiRtt(getContext())) {
-            return;
-        }
-        // Scan for IEEE 802.11mc supporting APs
-        ScanResult testAp = scanForTestAp(NUM_SCANS_SEARCHING_FOR_IEEE80211MC_AP);
-        assertNotNull(
-                "Cannot find any test APs which support RTT / IEEE 802.11mc - please verify that "
-                        + "your test setup includes them!", testAp);
-
-        // Perform RTT operations
-        RangingRequest request = new RangingRequest.Builder().addAccessPoint(testAp).build();
-        ResultCallback callback = new ResultCallback();
-        mWifiRttManager.startRanging(request, mExecutor, callback);
-        assertTrue("Wi-Fi RTT results: no callback! ",
-                callback.waitForCallback());
-
-        RangingResult result = callback.getResults().get(0);
-        assertEquals("Ranging request not success",
-                result.getStatus(), RangingResult.STATUS_SUCCESS);
-        ResponderLocation responderLocation = result.getUnverifiedResponderLocation();
-        assertNotNull("ResponderLocation should not be null", responderLocation);
-        assertTrue("ResponderLocation is not valid", responderLocation.isLciSubelementValid());
-
-        // Check LCI related APIs
-        int exceptionCount = 0;
-        int apiCount = 0;
-        try {
-            apiCount++;
-            responderLocation.getLatitudeUncertainty();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            responderLocation.getLatitude();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            responderLocation.getLongitudeUncertainty();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            responderLocation.getLongitude();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            responderLocation.getAltitudeType();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            responderLocation.getAltitudeUncertainty();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            responderLocation.getAltitude();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            responderLocation.getDatum();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            responderLocation.getRegisteredLocationAgreementIndication();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            responderLocation.getLciVersion();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        try {
-            apiCount++;
-            assertNotNull(responderLocation.toLocation());
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        // If LCI is not valid, all APIs should throw exception, otherwise no exception.
-        assertEquals("Exception number should equal to API number",
-                responderLocation.isLciSubelementValid()? 0 : apiCount, exceptionCount);
-
-        // Verify ZaxisSubelement APIs
-        apiCount = 0;
-        exceptionCount = 0;
-
-        try {
-            apiCount++;
-            responderLocation.getExpectedToMove();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-
-        try {
-            apiCount++;
-            responderLocation.getFloorNumber();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-
-        try {
-            apiCount++;
-            responderLocation.getHeightAboveFloorMeters();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-
-        try {
-            apiCount++;
-            responderLocation.getHeightAboveFloorUncertaintyMeters();
-        } catch (IllegalStateException e) {
-            exceptionCount++;
-        }
-        // If Zaxis is not valid, all APIs should throw exception, otherwise no exception.
-        assertEquals("Exception number should equal to API number",
-                responderLocation.isZaxisSubelementValid() ? 0 : apiCount, exceptionCount);
-        // Verify civic location
-        if (responderLocation.toCivicLocationAddress() == null) {
-            assertNull(responderLocation.toCivicLocationSparseArray());
-        } else {
-            assertNotNull(responderLocation.toCivicLocationSparseArray());
-        }
-        // Verify map image
-        if (responderLocation.getMapImageUri() == null) {
-            assertNull(responderLocation.getMapImageMimeType());
-        } else {
-            assertNotNull(responderLocation.getMapImageMimeType());
-        }
-        boolean extraInfoOnAssociationIndication =
-                responderLocation.getExtraInfoOnAssociationIndication();
-        assertNotNull("ColocatedBSSID list should be nonNull",
-                responderLocation.getColocatedBssids());
-    }
-
-    /**
-     * Verify ranging request with aware peer Mac address and peer handle.
-     */
-    public void testAwareRttWithMacAddress() throws InterruptedException {
-        RangingRequest request = new RangingRequest.Builder()
-                .addWifiAwarePeer(MAC).build();
-        ResultCallback callback = new ResultCallback();
-        mWifiRttManager.startRanging(request, mExecutor, callback);
-        assertTrue("Wi-Fi RTT results: no callback",
-                callback.waitForCallback());
-        List<RangingResult> rangingResults = callback.getResults();
-        assertNotNull("Wi-Fi RTT results: null results", rangingResults);
-        assertEquals(1, rangingResults.size());
-        assertEquals(RangingResult.STATUS_FAIL, rangingResults.get(0).getStatus());
-    }
-
-    /**
-     * Verify ranging request with aware peer handle.
-     */
-    public void testAwareRttWithPeerHandle() throws InterruptedException {
-        PeerHandle peerHandle = mock(PeerHandle.class);
-        RangingRequest request = new RangingRequest.Builder()
-                .addWifiAwarePeer(peerHandle).build();
-        ResultCallback callback = new ResultCallback();
-        mWifiRttManager.startRanging(request, mExecutor, callback);
-        assertTrue("Wi-Fi RTT results: no callback",
-                callback.waitForCallback());
-        List<RangingResult> rangingResults = callback.getResults();
-        assertNotNull("Wi-Fi RTT results: null results", rangingResults);
-        assertEquals("Invalid peerHandle should return 0 result", 0, rangingResults.size());
-    }
-}
