/*
 * 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.app.UiAutomation;
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.MacAddress;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pConfig;
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.WifiP2pManager.ExternalApproverRequestListener;
import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
import android.os.Build;
import android.platform.test.annotations.AppModeFull;
import android.provider.Settings;
import android.util.Log;

import androidx.test.filters.SdkSuppress;
import androidx.test.platform.app.InstrumentationRegistry;

import com.android.compatibility.common.util.ApiLevelUtil;
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;

import java.util.ArrayList;
import java.util.Arrays;
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 WifiJUnit3TestBase {
    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 failureReason;
        public int p2pState;
        public int discoveryState;
        public NetworkInfo networkInfo;
        public WifiP2pInfo p2pInfo;
        public String deviceName;
        public WifiP2pGroupList persistentGroups;
        public WifiP2pGroup group = new WifiP2pGroup();

        // External approver
        public boolean isAttached;
        public boolean isDetached;
        public int detachReason;
        public MacAddress targetPeer;

        public void reset() {
            valid = false;

            networkInfo = null;
            p2pInfo = null;
            deviceName = null;
            persistentGroups = null;
            group = null;

            isAttached = false;
            isDetached = false;
            targetPeer = null;
        }
    }

    private WifiManager mWifiManager;
    private WifiP2pManager mWifiP2pManager;
    private WifiP2pManager.Channel mWifiP2pChannel;
    private MySync mMySync = new MySync();
    private MyResponse mMyResponse = new MyResponse();
    private boolean mWasVerboseLoggingEnabled;
    private WifiP2pConfig mTestWifiP2pPeerConfig;

    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 = 5000;
    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);
                    Log.d(TAG, "Get WIFI_P2P_CONNECTION_CHANGED_ACTION: "
                            + mMySync.expectedNetworkInfo);
                    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.failureReason = reason;
                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;

        // for general connect command
        mTestWifiP2pPeerConfig = new WifiP2pConfig();
        mTestWifiP2pPeerConfig.deviceAddress = "aa:bb:cc:dd:ee:ff";
    }

    @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;
        }
        if (null != mWifiP2pManager) {
            removeAllPersistentGroups();
        }
        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 NetworkInfo.DetailedState waitForNextNetworkState() {
        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
        assertNotNull(mMySync.expectedNetworkInfo);
        return mMySync.expectedNetworkInfo.getDetailedState();
    }

    private boolean waitForConnectedNetworkState() {
        // The possible orders of network states are:
        // * IDLE > CONNECTING > CONNECTED for lazy initialization
        // * DISCONNECTED > CONNECTING > CONNECTED for previous group removal
        // * CONNECTING > CONNECTED
        NetworkInfo.DetailedState state = waitForNextNetworkState();
        if (state == NetworkInfo.DetailedState.IDLE
                || state == NetworkInfo.DetailedState.DISCONNECTED) {
            state = waitForNextNetworkState();
        }
        if (ApiLevelUtil.isAtLeast(Build.VERSION_CODES.TIRAMISU)) {
            if (state != NetworkInfo.DetailedState.CONNECTING) {
                return false;
            }
            state = waitForNextNetworkState();
        }
        return state == NetworkInfo.DetailedState.CONNECTED;
    }

    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.reset();
        }
    }

    /*
     * 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 void removeAllPersistentGroups() {
        WifiP2pGroupList persistentGroups = getPersistentGroups();
        assertNotNull(persistentGroups);
        for (WifiP2pGroup group: persistentGroups.getGroupList()) {
            resetResponse(mMyResponse);
            ShellIdentityUtils.invokeWithShellPermissions(() -> {
                mWifiP2pManager.deletePersistentGroup(mWifiP2pChannel,
                        group.getNetworkId(),
                        mActionListener);
                assertTrue(waitForServiceResponse(mMyResponse));
                assertTrue(mMyResponse.success);
            });
        }
        persistentGroups = getPersistentGroups();
        assertNotNull(persistentGroups);
        assertEquals(0, persistentGroups.getGroupList().size());
    }

    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.");
        }

        long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
        while (!mWifiManager.isWifiEnabled() && System.currentTimeMillis() < timeout) {
            try {
                enableWifi();
            } catch (InterruptedException e) { }
        }

        assertTrue(mWifiManager.isWifiEnabled());

        mWifiP2pManager =
                (WifiP2pManager) getContext().getSystemService(Context.WIFI_P2P_SERVICE);
        mWifiP2pChannel = mWifiP2pManager.initialize(
                getContext(), getContext().getMainLooper(), null);

        assertNotNull(mWifiP2pManager);
        assertNotNull(mWifiP2pChannel);

        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);
        removeAllPersistentGroups();

        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);

        // If there is any saved network and this device is connecting to this saved network,
        // p2p discovery might be blocked during DHCP provision.
        int retryCount = 3;
        while (retryCount > 0) {
            resetResponse(mMyResponse);
            mWifiP2pManager.discoverPeers(mWifiP2pChannel, mActionListener);
            assertTrue(waitForServiceResponse(mMyResponse));
            if (mMyResponse.success
                    || mMyResponse.failureReason != WifiP2pManager.BUSY) {
                break;
            }
            Log.w(TAG, "Discovery is blocked, try again!");
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {}
            retryCount--;
        }
        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(waitForConnectedNetworkState());

        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);
        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
        assertNotNull(mMySync.expectedNetworkInfo);
        assertEquals(NetworkInfo.DetailedState.DISCONNECTED,
                mMySync.expectedNetworkInfo.getDetailedState());
    }

    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);

        resetResponse(mMyResponse);
        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
        resetResponse(mMyResponse);
        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(waitForConnectedNetworkState());

        resetResponse(mMyResponse);
        mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
        assertTrue(waitForServiceResponse(mMyResponse));
        assertTrue(mMyResponse.success);
        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
        assertNotNull(mMySync.expectedNetworkInfo);
        assertEquals(NetworkInfo.DetailedState.DISCONNECTED,
                mMySync.expectedNetworkInfo.getDetailedState());

        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(waitForConnectedNetworkState());

        resetResponse(mMyResponse);
        mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
        assertTrue(waitForServiceResponse(mMyResponse));
        assertTrue(mMyResponse.success);
        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
        assertNotNull(mMySync.expectedNetworkInfo);
        assertEquals(NetworkInfo.DetailedState.DISCONNECTED,
                mMySync.expectedNetworkInfo.getDetailedState());

        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);
        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);
    }

    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
    public void testRemoveClient() {
        if (!setupWifiP2p()) {
            return;
        }

        if (!mWifiP2pManager.isGroupClientRemovalSupported()) return;

        resetResponse(mMyResponse);
        mWifiP2pManager.createGroup(mWifiP2pChannel, mActionListener);
        assertTrue(waitForServiceResponse(mMyResponse));
        assertTrue(mMyResponse.success);
        assertTrue(waitForConnectedNetworkState());

        resetResponse(mMyResponse);
        MacAddress peerMacAddress = MacAddress.fromString(mTestWifiP2pPeerConfig.deviceAddress);
        mWifiP2pManager.removeClient(
                mWifiP2pChannel, peerMacAddress, mActionListener);
        assertTrue(waitForServiceResponse(mMyResponse));
        assertTrue(mMyResponse.success);
    }

    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
    public void testDiscoverPeersOnSpecificFreq() {
        if (!setupWifiP2p()) {
            return;
        }

        if (!mWifiP2pManager.isChannelConstrainedDiscoverySupported()) 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);

        // If there is any saved network and this device is connecting to this saved network,
        // p2p discovery might be blocked during DHCP provision.
        int retryCount = 3;
        while (retryCount > 0) {
            resetResponse(mMyResponse);
            mWifiP2pManager.discoverPeersOnSpecificFrequency(mWifiP2pChannel,
                    2412, mActionListener);
            assertTrue(waitForServiceResponse(mMyResponse));
            if (mMyResponse.success
                    || mMyResponse.failureReason != WifiP2pManager.BUSY) {
                break;
            }
            Log.w(TAG, "Discovery is blocked, try again!");
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) { }
            retryCount--;
        }
        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);
    }

    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
    public void testDiscoverPeersOnSocialChannelsOnly() {
        if (!setupWifiP2p()) {
            return;
        }

        if (!mWifiP2pManager.isChannelConstrainedDiscoverySupported()) 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);

        // If there is any saved network and this device is connecting to this saved network,
        // p2p discovery might be blocked during DHCP provision.
        int retryCount = 3;
        while (retryCount > 0) {
            resetResponse(mMyResponse);
            mWifiP2pManager.discoverPeersOnSocialChannels(mWifiP2pChannel, mActionListener);
            assertTrue(waitForServiceResponse(mMyResponse));
            if (mMyResponse.success
                    || mMyResponse.failureReason != WifiP2pManager.BUSY) {
                break;
            }
            Log.w(TAG, "Discovery is blocked, try again!");
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) { }
            retryCount--;
        }
        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 testP2pSetVendorElements() {
        if (!setupWifiP2p()) {
            return;
        }

        if (!mWifiP2pManager.isSetVendorElementsSupported()) return;

        // Vendor-Specific EID is 221.
        List<ScanResult.InformationElement> ies = new ArrayList<>(Arrays.asList(
                new ScanResult.InformationElement(221, 0,
                        new byte[]{(byte) 1, (byte) 2, (byte) 3, (byte) 4})));
        resetResponse(mMyResponse);
        ShellIdentityUtils.invokeWithShellPermissions(() -> {
            mWifiP2pManager.setVendorElements(mWifiP2pChannel, ies, mActionListener);
            assertTrue(waitForServiceResponse(mMyResponse));
            assertTrue(mMyResponse.success);
        });

        resetResponse(mMyResponse);
        mWifiP2pManager.discoverPeers(mWifiP2pChannel, mActionListener);
        assertTrue(waitForServiceResponse(mMyResponse));
    }

    /** Test IEs whose size is greater than the maximum allowed size. */
    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
    public void testP2pSetVendorElementsOverMaximumAllowedSize() {
        if (!setupWifiP2p()) {
            return;
        }

        if (!mWifiP2pManager.isSetVendorElementsSupported()) return;

        List<ScanResult.InformationElement> ies = new ArrayList<>();
        ies.add(new ScanResult.InformationElement(221, 0,
                new byte[WifiP2pManager.getP2pMaxAllowedVendorElementsLengthBytes() + 1]));
        resetResponse(mMyResponse);
        ShellIdentityUtils.invokeWithShellPermissions(() -> {
            try {
                mWifiP2pManager.setVendorElements(mWifiP2pChannel, ies, mActionListener);
                fail("Should raise IllegalArgumentException");
            } catch (IllegalArgumentException ex) {
                // expected
                return;
            }
        });
    }

    /** Test that external approver APIs. */
    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
    public void testP2pExternalApprover() {
        final MacAddress peer = MacAddress.fromString("11:22:33:44:55:66");
        if (!setupWifiP2p()) {
            return;
        }

        ExternalApproverRequestListener listener =
                new ExternalApproverRequestListener() {
                    @Override
                    public void onAttached(MacAddress deviceAddress) {
                        synchronized (mMyResponse) {
                            mMyResponse.targetPeer = deviceAddress;
                            mMyResponse.valid = true;
                            mMyResponse.isAttached = true;
                            mMyResponse.notify();
                        }
                    }
                    @Override
                    public void onDetached(MacAddress deviceAddress, int reason) {
                        synchronized (mMyResponse) {
                            mMyResponse.targetPeer = deviceAddress;
                            mMyResponse.detachReason = reason;
                            mMyResponse.valid = true;
                            mMyResponse.isDetached = true;
                            mMyResponse.notify();
                        }
                    }
                    @Override
                    public void onConnectionRequested(int requestType, WifiP2pConfig config,
                            WifiP2pDevice device) {
                    }
                    @Override
                    public void onPinGenerated(MacAddress deviceAddress, String pin) {
                    }
            };

        resetResponse(mMyResponse);

        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
        try {
            uiAutomation.adoptShellPermissionIdentity();
            mWifiP2pManager.addExternalApprover(mWifiP2pChannel, peer, listener);
            assertTrue(waitForServiceResponse(mMyResponse));
            assertTrue(mMyResponse.isAttached);
            assertFalse(mMyResponse.isDetached);
            assertEquals(peer, mMyResponse.targetPeer);

            // Just ignore the result as there is no real incoming request.
            mWifiP2pManager.setConnectionRequestResult(mWifiP2pChannel, peer,
                    WifiP2pManager.CONNECTION_REQUEST_ACCEPT, null);
            mWifiP2pManager.setConnectionRequestResult(mWifiP2pChannel, peer,
                    WifiP2pManager.CONNECTION_REQUEST_ACCEPT, "12345678", null);

            resetResponse(mMyResponse);
            mWifiP2pManager.removeExternalApprover(mWifiP2pChannel, peer, null);
            assertTrue(waitForServiceResponse(mMyResponse));
            assertTrue(mMyResponse.isDetached);
            assertFalse(mMyResponse.isAttached);
            assertEquals(peer, mMyResponse.targetPeer);
            assertEquals(ExternalApproverRequestListener.APPROVER_DETACH_REASON_REMOVE,
                    mMyResponse.detachReason);
        } finally {
            uiAutomation.dropShellPermissionIdentity();
        }

    }
}
