/*
 * 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 com.googlecode.android_scripting.facade.wifi;

import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.wifi.WifiScanner.WIFI_BAND_24_GHZ;
import static android.net.wifi.WifiScanner.WIFI_BAND_5_GHZ;

import static com.googlecode.android_scripting.jsonrpc.JsonBuilder.build;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.DhcpInfo;
import android.net.MacAddress;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.Uri;
import android.net.wifi.CoexUnsafeChannel;
import android.net.wifi.EasyConnectStatusCallback;
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.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.KeyMgmt;
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.WifiManager.NetworkRequestUserSelectionCallback;
import android.net.wifi.WifiManager.SubsystemRestartTrackingCallback;
import android.net.wifi.WifiManager.WifiLock;
import android.net.wifi.WifiNetworkSpecifier;
import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WpsInfo;
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.os.Bundle;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerThread;
import android.os.PatternMatcher;
import android.os.connectivity.WifiActivityEnergyInfo;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.util.Base64;
import android.util.SparseArray;
import android.util.SparseIntArray;


import com.android.internal.annotations.GuardedBy;
import com.android.modules.utils.build.SdkLevel;

import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.facade.EventFacade;
import com.googlecode.android_scripting.facade.FacadeManager;
import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
import com.googlecode.android_scripting.rpc.Rpc;
import com.googlecode.android_scripting.rpc.RpcOptional;
import com.googlecode.android_scripting.rpc.RpcParameter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/**
 * WifiManager functions.
 */
// TODO: make methods handle various wifi states properly
// e.g. wifi connection result will be null when flight mode is on
public class WifiManagerFacade extends RpcReceiver {
    private static final String mEventType = "WifiManager";
    // MIME type for passpoint config.
    private static final String TYPE_WIFICONFIG = "application/x-wifi-config";
    private static final int TIMEOUT_MILLIS = 5000;

    private final Service mService;
    private final WifiManager mWifi;
    private final ConnectivityManager mCm;
    private final EventFacade mEventFacade;

    private final IntentFilter mScanFilter;
    private final IntentFilter mStateChangeFilter;
    private final IntentFilter mTetherFilter;
    private final IntentFilter mNetworkSuggestionStateChangeFilter;
    private final WifiScanReceiver mScanResultsAvailableReceiver;
    private final WifiScanResultsReceiver mWifiScanResultsReceiver;
    private final WifiStateChangeReceiver mStateChangeReceiver;
    private final WifiNetworkSuggestionStateChangeReceiver mNetworkSuggestionStateChangeReceiver;
    private SubsystemRestartTrackingCallbackFacade mSubsystemRestartTrackingCallback = null;
    private final HandlerThread mCallbackHandlerThread;
    private final Object mCallbackLock = new Object();
    private boolean mTrackingWifiStateChange;
    private boolean mTrackingTetherStateChange;
    private boolean mTrackingNetworkSuggestionStateChange;
    @GuardedBy("mCallbackLock")
    private NetworkRequestUserSelectionCallback mNetworkRequestUserSelectionCallback;
    private final SparseArray<SoftApCallbackImp> mSoftapCallbacks;
    // This is null if SdkLevel is not at least S
    @Nullable private WifiManager.CoexCallback mCoexCallback;

    private final BroadcastReceiver mTetherStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) {
                Log.d("Wifi AP state changed.");
                int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE,
                        WifiManager.WIFI_AP_STATE_FAILED);
                if (state == WifiManager.WIFI_AP_STATE_ENABLED) {
                    mEventFacade.postEvent("WifiManagerApEnabled", null);
                } else if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
                    mEventFacade.postEvent("WifiManagerApDisabled", null);
                }
            } else if (ConnectivityManager.ACTION_TETHER_STATE_CHANGED.equals(action)) {
                Log.d("Tether state changed.");
                ArrayList<String> available = intent.getStringArrayListExtra(
                        ConnectivityManager.EXTRA_AVAILABLE_TETHER);
                ArrayList<String> active = intent.getStringArrayListExtra(
                        ConnectivityManager.EXTRA_ACTIVE_TETHER);
                ArrayList<String> errored = intent.getStringArrayListExtra(
                        ConnectivityManager.EXTRA_ERRORED_TETHER);
                Bundle msg = new Bundle();
                msg.putStringArrayList("AVAILABLE_TETHER", available);
                msg.putStringArrayList("ACTIVE_TETHER", active);
                msg.putStringArrayList("ERRORED_TETHER", errored);
                mEventFacade.postEvent("TetherStateChanged", msg);
            }
        }
    };

    private final NetworkRequestMatchCallback mNetworkRequestMatchCallback =
            new NetworkRequestMatchCallback() {
                private static final String EVENT_TAG = mEventType + "NetworkRequestMatchCallback";

                @Override
                public void onUserSelectionCallbackRegistration(
                        NetworkRequestUserSelectionCallback userSelectionCallback) {
                    synchronized (mCallbackLock) {
                        mNetworkRequestUserSelectionCallback = userSelectionCallback;
                    }
                }

                @Override
                public void onAbort() {
                    mEventFacade.postEvent(EVENT_TAG + "OnAbort", null);
                }

                @Override
                public void onMatch(List<ScanResult> scanResults) {
                    mEventFacade.postEvent(EVENT_TAG + "OnMatch", scanResults);
                }

                @Override
                public void onUserSelectionConnectSuccess(WifiConfiguration wifiConfiguration) {
                    mEventFacade.postEvent(EVENT_TAG + "OnUserSelectionConnectSuccess",
                            wifiConfiguration);
                }

                @Override
                public void onUserSelectionConnectFailure(WifiConfiguration wifiConfiguration) {
                    mEventFacade.postEvent(EVENT_TAG + "OnUserSelectionConnectFailure",
                            wifiConfiguration);
                }
            };

    private static class SoftApCallbackImp implements WifiManager.SoftApCallback {
        // A monotonic increasing counter for softap callback ids.
        private static int sCount = 0;

        private final int mId;
        private final EventFacade mEventFacade;
        private final String mEventStr;

        SoftApCallbackImp(EventFacade eventFacade) {
            sCount++;
            mId = sCount;
            mEventFacade = eventFacade;
            mEventStr = mEventType + "SoftApCallback-" + mId + "-";
        }

        @Override
        public void onStateChanged(int state, int failureReason) {
            Bundle msg = new Bundle();
            msg.putInt("State", state);
            msg.putInt("FailureReason", failureReason);
            mEventFacade.postEvent(mEventStr + "OnStateChanged", msg);
        }

        @Override
        public void onConnectedClientsChanged(List<WifiClient> clients) {
            ArrayList<MacAddress> macAddresses = new ArrayList<>();
            clients.forEach(x -> macAddresses.add(x.getMacAddress()));
            Bundle msg = new Bundle();
            msg.putInt("NumClients", clients.size());
            msg.putParcelableArrayList("MacAddresses", macAddresses);
            mEventFacade.postEvent(mEventStr + "OnNumClientsChanged", msg);
            mEventFacade.postEvent(mEventStr + "OnConnectedClientsChanged", clients);
        }

        @Override
        public void onConnectedClientsChanged(SoftApInfo info, List<WifiClient> clients) {
            ArrayList<MacAddress> macAddresses = new ArrayList<>();
            clients.forEach(x -> macAddresses.add(x.getMacAddress()));
            Bundle msg = new Bundle();
            msg.putParcelable("Info", info);
            msg.putParcelableArrayList("ClientsMacAddress", macAddresses);
            mEventFacade.postEvent(mEventStr + "OnConnectedClientsChangedWithInfo", msg);
        }

        @Override
        public void onInfoChanged(SoftApInfo softApInfo) {
            mEventFacade.postEvent(mEventStr + "OnInfoChanged", softApInfo);
        }

        @Override
        public void onInfoChanged(List<SoftApInfo> infos) {
            mEventFacade.postEvent(mEventStr + "OnInfoListChanged", infos);
        }

        @Override
        public void onCapabilityChanged(SoftApCapability softApCapability) {
            mEventFacade.postEvent(mEventStr + "OnCapabilityChanged", softApCapability);
        }

        @Override
        public void onBlockedClientConnecting(WifiClient client, int blockedReason) {
            Bundle msg = new Bundle();
            msg.putString("WifiClient", client.getMacAddress().toString());
            msg.putInt("BlockedReason", blockedReason);
            mEventFacade.postEvent(mEventStr + "OnBlockedClientConnecting", msg);
        }
    };

    private static class CoexCallbackImpl extends WifiManager.CoexCallback {
        private final EventFacade mEventFacade;
        private final String mEventStr;

        CoexCallbackImpl(EventFacade eventFacade) {
            mEventFacade = eventFacade;
            mEventStr = mEventType + "CoexCallback";
        }

        @Override
        public void onCoexUnsafeChannelsChanged(
                @NonNull List<CoexUnsafeChannel> unsafeChannels, int restrictions) {
            Bundle event = new Bundle();
            try {
                event.putString("KEY_COEX_UNSAFE_CHANNELS",
                        coexUnsafeChannelsToJson(unsafeChannels).toString());
                event.putString("KEY_COEX_RESTRICTIONS",
                        coexRestrictionsToJson(restrictions).toString());
                mEventFacade.postEvent(mEventStr + "#onCoexUnsafeChannelsChanged", event);
            } catch (JSONException e) {
                Log.e("Failed to post event for onCoexUnsafeChannelsChanged: " + e);
            }
        }
    };

    private WifiLock mLock = null;
    private boolean mIsConnected = false;

    public WifiManagerFacade(FacadeManager manager) {
        super(manager);
        mService = manager.getService();
        mWifi = (WifiManager) mService.getSystemService(Context.WIFI_SERVICE);
        mCm = (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE);
        mEventFacade = manager.getReceiver(EventFacade.class);
        mCallbackHandlerThread = new HandlerThread("WifiManagerFacade");

        mScanFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        mStateChangeFilter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mStateChangeFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
        mStateChangeFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
        mStateChangeFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        mStateChangeFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY - 1);

        mTetherFilter = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
        mTetherFilter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);

        mNetworkSuggestionStateChangeFilter = new IntentFilter(
                WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);

        mScanResultsAvailableReceiver = new WifiScanReceiver(mEventFacade);
        mWifiScanResultsReceiver = new WifiScanResultsReceiver(mEventFacade);
        mStateChangeReceiver = new WifiStateChangeReceiver();
        mNetworkSuggestionStateChangeReceiver = new WifiNetworkSuggestionStateChangeReceiver();
        mTrackingWifiStateChange = false;
        mTrackingTetherStateChange = false;
        mTrackingNetworkSuggestionStateChange = false;
        mCallbackHandlerThread.start();
        mSoftapCallbacks = new SparseArray<>();
        if (SdkLevel.isAtLeastS()) {
            mCoexCallback = new CoexCallbackImpl(mEventFacade);
        }
    }

    private void makeLock(int wifiMode) {
        if (mLock == null) {
            mLock = mWifi.createWifiLock(wifiMode, "sl4a");
            mLock.acquire();
        }
    }

    /**
     * Handle Broadcast receiver for Scan Result
     *
     * @parm eventFacade Object of EventFacade
     */
    class WifiScanReceiver extends BroadcastReceiver {
        private final EventFacade mEventFacade;

        WifiScanReceiver(EventFacade eventFacade) {
            mEventFacade = eventFacade;
        }

        @Override
        public void onReceive(Context c, Intent intent) {
            String action = intent.getAction();
            if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                if (!intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) {
                    Log.w("Wifi connection scan failed, ignoring.");
                    mEventFacade.postEvent(mEventType + "ScanFailure", null);
                } else {
                    Bundle mResults = new Bundle();
                    Log.d("Wifi connection scan finished, results available.");
                    mResults.putLong("Timestamp", System.currentTimeMillis() / 1000);
                    mEventFacade.postEvent(mEventType + "ScanResultsAvailable", mResults);
                }
                mService.unregisterReceiver(mScanResultsAvailableReceiver);
            }
        }
    }

    class WifiScanResultsReceiver extends WifiManager.ScanResultsCallback {
        private final EventFacade mEventFacade;

        WifiScanResultsReceiver(EventFacade eventFacade) {
            mEventFacade = eventFacade;
        }
        @Override
        public void onScanResultsAvailable() {
            Bundle mResults = new Bundle();
            Log.d("Wifi connection scan finished, results available.");
            mResults.putLong("Timestamp", System.currentTimeMillis() / 1000);
            mEventFacade.postEvent(mEventType + "ScanResultsCallbackOnSuccess", mResults);
            mWifi.unregisterScanResultsCallback(mWifiScanResultsReceiver);
        }
    }

    class WifiActionListener implements WifiManager.ActionListener {
        private final EventFacade mEventFacade;
        private final String TAG;

        public WifiActionListener(EventFacade eventFacade, String tag) {
            mEventFacade = eventFacade;
            this.TAG = tag;
        }

        @Override
        public void onSuccess() {
            Log.d("WifiActionListener  onSuccess called for " + mEventType + TAG + "OnSuccess");
            mEventFacade.postEvent(mEventType + TAG + "OnSuccess", null);
        }

        @Override
        public void onFailure(int reason) {
            Log.d("WifiActionListener  onFailure called for" + mEventType);
            Bundle msg = new Bundle();
            msg.putInt("reason", reason);
            mEventFacade.postEvent(mEventType + TAG + "OnFailure", msg);
        }
    }

    public class WifiStateChangeReceiver extends BroadcastReceiver {
        String mCachedWifiInfo = "";

        /**
         * When a peer to peer request is active, WifiManager.getConnectionInfo() returns
         * the peer to peer connection details. Hence use networking API's to retrieve the
         * internet connection details.
         *
         * But on Android R, we will need to fallback to the legacy getConnectionInfo() API since
         * WifiInfo doesn't implement TransportInfo.
         */
        private WifiInfo getInternetConnectivityWifiInfo() {
            if (!SdkLevel.isAtLeastS()) {
                return mWifi.getConnectionInfo();
            }
            // TODO (b/156867433): We need a location sensitive synchronous API proposed
            // in aosp/1629501.
            final CountDownLatch waitForNetwork = new CountDownLatch(1);
            final class AnswerBox {
                public WifiInfo wifiInfo;
            }
            final AnswerBox answerBox = new AnswerBox();
            final NetworkCallback networkCallback =
                    new NetworkCallback(NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) {
                @Override
                public void onCapabilitiesChanged(@NonNull Network network,
                        @NonNull NetworkCapabilities networkCapabilities) {
                    answerBox.wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
                    waitForNetwork.countDown();
                }
            };
            mCm.registerNetworkCallback(
                    new NetworkRequest.Builder()
                            .addTransportType(TRANSPORT_WIFI)
                            .addCapability(NET_CAPABILITY_INTERNET)
                            .build(), networkCallback);
            try {
                if (!waitForNetwork.await(5, TimeUnit.SECONDS)) {
                    Log.e("Timed out waiting for network to connect");
                    return null;
                }
                return answerBox.wifiInfo;
            } catch (InterruptedException e) {
                Log.e("Waiting for onAvailable failed", e);
                return null;
            } finally {
                mCm.unregisterNetworkCallback(networkCallback);
            }
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                Log.d("Wifi network state changed.");
                NetworkInfo nInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                Log.d("NetworkInfo " + nInfo);
                // If network info is of type wifi, send wifi events.
                if (nInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                    if (nInfo.getDetailedState().equals(DetailedState.CONNECTED)) {
                        WifiInfo wInfo = getInternetConnectivityWifiInfo();
                        if (wInfo == null) {
                            Log.e("Failed to get WifiInfo for internet connection. "
                                    + "Not sending wifi network connection event");
                            return;
                        }
                        String bssid = wInfo.getBSSID();
                        if (bssid != null && !mCachedWifiInfo.equals(wInfo.toString())) {
                            Log.d("WifiNetworkConnected");
                            mEventFacade.postEvent("WifiNetworkConnected", wInfo);
                        }
                        mCachedWifiInfo = wInfo.toString();
                    } else {
                        if (nInfo.getDetailedState().equals(DetailedState.DISCONNECTED)) {
                            if (!mCachedWifiInfo.equals("")) {
                                mCachedWifiInfo = "";
                                mEventFacade.postEvent("WifiNetworkDisconnected", null);
                            }
                        }
                    }
                }
            } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
                Log.d("Supplicant connection state changed.");
                mIsConnected = intent
                        .getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false);
                Bundle msg = new Bundle();
                msg.putBoolean("Connected", mIsConnected);
                mEventFacade.postEvent("SupplicantConnectionChanged", msg);
            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                int state = intent.getIntExtra(
                        WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED);
                Log.d("Wifi state changed to " + state);
                boolean enabled;
                if (state == WifiManager.WIFI_STATE_DISABLED) {
                    enabled = false;
                } else if (state == WifiManager.WIFI_STATE_ENABLED) {
                    enabled = true;
                } else {
                    // we only care about enabled/disabled.
                    Log.v("Ignoring intermediate wifi state change event...");
                    return;
                }
                Bundle msg = new Bundle();
                msg.putBoolean("enabled", enabled);
                mEventFacade.postEvent("WifiStateChanged", msg);
            }
        }
    }

    public class WifiNetworkSuggestionStateChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
                WifiNetworkSuggestion networkSuggestion =
                        intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_SUGGESTION);
                mEventFacade.postEvent(
                        "WifiNetworkSuggestionPostConnection",
                        networkSuggestion.wifiConfiguration.SSID);
            }
        }
    }

    public class WifiWpsCallback extends WifiManager.WpsCallback {
        private static final String tag = "WifiWps";

        @Override
        public void onStarted(String pin) {
            Bundle msg = new Bundle();
            msg.putString("pin", pin);
            mEventFacade.postEvent(tag + "OnStarted", msg);
        }

        @Override
        public void onSucceeded() {
            Log.d("Wps op succeeded");
            mEventFacade.postEvent(tag + "OnSucceeded", null);
        }

        @Override
        public void onFailed(int reason) {
            Bundle msg = new Bundle();
            msg.putInt("reason", reason);
            mEventFacade.postEvent(tag + "OnFailed", msg);
        }
    }

    private void applyingkeyMgmt(WifiConfiguration config, ScanResult result) {
        if (result.capabilities.contains("WEP")) {
            config.allowedKeyManagement.set(KeyMgmt.NONE);
            config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
            config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
        } else if (result.capabilities.contains("PSK")) {
            config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
        } else if (result.capabilities.contains("EAP")) {
            // this is probably wrong, as we don't have a way to enter the enterprise config
            config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
            config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
        } else {
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        }
    }

    private WifiConfiguration genWifiConfig(JSONObject j) throws JSONException {
        if (j == null) {
            return null;
        }
        WifiConfiguration config = new WifiConfiguration();
        if (j.has("SSID")) {
            config.SSID = "\"" + j.getString("SSID") + "\"";
        } else if (j.has("ssid")) {
            config.SSID = "\"" + j.getString("ssid") + "\"";
        }
        if (j.has("password")) {
            String security;

            // Check if new security type SAE (WPA3) is present. Default to PSK
            if (j.has("security")) {
                if (TextUtils.equals(j.getString("security"), "SAE")) {
                    config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
                } else {
                    config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
                }
            } else {
                config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
            }
            config.preSharedKey = "\"" + j.getString("password") + "\"";
        } else if (j.has("preSharedKey")) {
            config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
            config.preSharedKey = j.getString("preSharedKey");
        } else {
            if (j.has("security")) {
                if (TextUtils.equals(j.getString("security"), "OWE")) {
                    config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE);
                } else {
                    config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
                }
            } else {
                config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN);
            }
        }
        if (j.has("BSSID")) {
            config.BSSID = j.getString("BSSID");
        }
        if (j.has("hiddenSSID")) {
            config.hiddenSSID = j.getBoolean("hiddenSSID");
        }
        if (j.has("priority")) {
            config.priority = j.getInt("priority");
        }
        if (j.has("apBand")) {
            config.apBand = j.getInt("apBand");
        }
        if (j.has("wepKeys")) {
            // Looks like we only support static WEP.
            config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_WEP);
            JSONArray keys = j.getJSONArray("wepKeys");
            String[] wepKeys = new String[keys.length()];
            for (int i = 0; i < keys.length(); i++) {
                wepKeys[i] = keys.getString(i);
            }
            config.wepKeys = wepKeys;
        }
        if (j.has("wepTxKeyIndex")) {
            config.wepTxKeyIndex = j.getInt("wepTxKeyIndex");
        }
        if (j.has("meteredOverride")) {
            config.meteredOverride = j.getInt("meteredOverride");
        }
        if (j.has("macRand")) {
            config.macRandomizationSetting = j.getInt("macRand");
        }
        if (j.has("carrierId")) {
            config.carrierId = j.getInt("carrierId");
        }
        return config;
    }

    private static WifiEnterpriseConfig genWifiEnterpriseConfig(JSONObject j) throws JSONException,
            GeneralSecurityException {
        WifiEnterpriseConfig eConfig = new WifiEnterpriseConfig();
        if (j.has(WifiEnterpriseConfig.EAP_KEY)) {
            int eap = j.getInt(WifiEnterpriseConfig.EAP_KEY);
            eConfig.setEapMethod(eap);
        }
        if (j.has(WifiEnterpriseConfig.PHASE2_KEY)) {
            int p2Method = j.getInt(WifiEnterpriseConfig.PHASE2_KEY);
            eConfig.setPhase2Method(p2Method);
        }
        if (j.has(WifiEnterpriseConfig.CA_CERT_KEY)) {
            String certStr = j.getString(WifiEnterpriseConfig.CA_CERT_KEY);
            Log.v("CA Cert String is " + certStr);
            eConfig.setCaCertificate(strToX509Cert(certStr));
        }
        if (j.has(WifiEnterpriseConfig.CLIENT_CERT_KEY)
                && j.has(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY)) {
            String certStr = j.getString(WifiEnterpriseConfig.CLIENT_CERT_KEY);
            String keyStr = j.getString(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY);
            Log.v("Client Cert String is " + certStr);
            Log.v("Client Key String is " + keyStr);
            X509Certificate cert = strToX509Cert(certStr);
            String certAlgo = "RSA";
            if (j.has("cert_algo")) {
                certAlgo = j.getString("cert_algo");
            }
            PrivateKey privKey = strToPrivateKey(keyStr, certAlgo);
            Log.v("Cert is " + cert);
            Log.v("Private Key is " + privKey);
            eConfig.setClientKeyEntry(privKey, cert);
        }
        if (j.has(WifiEnterpriseConfig.IDENTITY_KEY)) {
            String identity = j.getString(WifiEnterpriseConfig.IDENTITY_KEY);
            Log.v("Setting identity to " + identity);
            eConfig.setIdentity(identity);
        }
        if (j.has(WifiEnterpriseConfig.PASSWORD_KEY)) {
            String pwd = j.getString(WifiEnterpriseConfig.PASSWORD_KEY);
            Log.v("Setting password to " + pwd);
            eConfig.setPassword(pwd);
        }
        if (j.has(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY)) {
            String altSub = j.getString(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY);
            Log.v("Setting Alt Subject to " + altSub);
            eConfig.setAltSubjectMatch(altSub);
        }
        if (j.has(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY)) {
            String domSuffix = j.getString(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY);
            Log.v("Setting Domain Suffix Match to " + domSuffix);
            eConfig.setDomainSuffixMatch(domSuffix);
        }
        if (j.has(WifiEnterpriseConfig.REALM_KEY)) {
            String realm = j.getString(WifiEnterpriseConfig.REALM_KEY);
            Log.v("Setting Domain Suffix Match to " + realm);
            eConfig.setRealm(realm);
        }
        if (j.has(WifiEnterpriseConfig.OCSP)) {
            int ocsp = j.getInt(WifiEnterpriseConfig.OCSP);
            Log.v("Setting OCSP to " + ocsp);
            eConfig.setOcsp(ocsp);
        }
        return eConfig;
    }

    private WifiConfiguration genWifiConfigWithEnterpriseConfig(JSONObject j) throws JSONException,
            GeneralSecurityException {
        if (j == null) {
            return null;
        }
        WifiConfiguration config = new WifiConfiguration();
        config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);

        if (j.has("security")) {
            if (TextUtils.equals(j.getString("security"), "SUITE_B_192")) {
                config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP_SUITE_B);
            }
        }

        if (j.has("SSID")) {
            config.SSID = "\"" + j.getString("SSID") + "\"";
        } else if (j.has("ssid")) {
            config.SSID = "\"" + j.getString("ssid") + "\"";
        }
        if (j.has("FQDN")) {
            config.FQDN = j.getString("FQDN");
        }
        if (j.has("providerFriendlyName")) {
            config.providerFriendlyName = j.getString("providerFriendlyName");
        }
        if (j.has("roamingConsortiumIds")) {
            JSONArray ids = j.getJSONArray("roamingConsortiumIds");
            long[] rIds = new long[ids.length()];
            for (int i = 0; i < ids.length(); i++) {
                rIds[i] = ids.getLong(i);
            }
            config.roamingConsortiumIds = rIds;
        }
        if (j.has("carrierId")) {
            config.carrierId = j.getInt("carrierId");
        }
        config.enterpriseConfig = genWifiEnterpriseConfig(j);
        return config;
    }

    /**
     * Generate {@link WifiNetworkSpecifier} from the specified json.
     */
    public static NetworkSpecifier genWifiNetworkSpecifier(JSONObject j) throws JSONException,
            GeneralSecurityException {
        if (j == null) {
            return null;
        }
        WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder();
        if (j.has("SSID")) {
            builder = builder.setSsid(j.getString("SSID"));
        } else if (j.has("ssidPattern")) {
            builder = builder.setSsidPattern(
                    new PatternMatcher(j.getString("ssidPattern"),
                            PatternMatcher.PATTERN_ADVANCED_GLOB));
        }
        if (j.has("BSSID")) {
            builder = builder.setBssid(MacAddress.fromString(j.getString("BSSID")));
        } else if (j.has("bssidPattern")) {
            builder = builder.setBssidPattern(
                    MacAddress.fromString(j.getJSONArray("bssidPattern").getString(0)),
                    MacAddress.fromString(j.getJSONArray("bssidPattern").getString(1)));
        }
        if (j.has("hiddenSSID")) {
            builder = builder.setIsHiddenSsid(j.getBoolean("hiddenSSID"));
        }
        if (j.has("isEnhancedOpen")) {
            builder = builder.setIsEnhancedOpen(j.getBoolean("isEnhancedOpen"));
        }
        boolean isWpa3 = false;
        if (j.has("isWpa3") && j.getBoolean("isWpa3")) {
            isWpa3 = true;
        }
        if (j.has("password") && !j.has(WifiEnterpriseConfig.EAP_KEY)) {
            if (!isWpa3) {
                builder = builder.setWpa2Passphrase(j.getString("password"));
            } else {
                builder = builder.setWpa3Passphrase(j.getString("password"));
            }
        }
        if (j.has(WifiEnterpriseConfig.EAP_KEY)) {
            if (!isWpa3) {
                builder = builder.setWpa2EnterpriseConfig(genWifiEnterpriseConfig(j));
            } else {
                builder = builder.setWpa3EnterpriseConfig(genWifiEnterpriseConfig(j));
            }
        }
        return builder.build();
    }

    private WifiNetworkSuggestion genWifiNetworkSuggestion(JSONObject j) throws JSONException,
            GeneralSecurityException, IOException {
        if (j == null) {
            return null;
        }
        WifiNetworkSuggestion.Builder builder = new WifiNetworkSuggestion.Builder();
        if (j.has("isAppInteractionRequired")) {
            builder = builder.setIsAppInteractionRequired(j.getBoolean("isAppInteractionRequired"));
        }
        if (j.has("isUserInteractionRequired")) {
            builder = builder.setIsUserInteractionRequired(
                    j.getBoolean("isUserInteractionRequired"));
        }
        if (j.has("isMetered")) {
            builder = builder.setIsMetered(j.getBoolean("isMetered"));
        }
        if (j.has("priority")) {
            builder = builder.setPriority(j.getInt("priority"));
        }
        if (j.has("carrierId")) {
            builder.setCarrierId(j.getInt("carrierId"));
        }
        if (j.has("enableAutojoin")) {
            builder.setIsInitialAutojoinEnabled(j.getBoolean("enableAutojoin"));
        }
        if (j.has("untrusted")) {
            builder.setUntrusted(j.getBoolean("untrusted"));
        }
        if (j.has("profile")) {
            builder = builder.setPasspointConfig(genWifiPasspointConfig(j));
        } else {
            if (j.has("SSID")) {
                builder = builder.setSsid(j.getString("SSID"));
            }
            if (j.has("BSSID")) {
                builder = builder.setBssid(MacAddress.fromString(j.getString("BSSID")));
            }
            if (j.has("hiddenSSID")) {
                builder = builder.setIsHiddenSsid(j.getBoolean("hiddenSSID"));
            }
            if (j.has("isEnhancedOpen")) {
                builder = builder.setIsEnhancedOpen(j.getBoolean("isEnhancedOpen"));
            }
            boolean isWpa3 = false;
            if (j.has("isWpa3") && j.getBoolean("isWpa3")) {
                isWpa3 = true;
            }
            if (j.has("password") && !j.has(WifiEnterpriseConfig.EAP_KEY)) {
                if (!isWpa3) {
                    builder = builder.setWpa2Passphrase(j.getString("password"));
                } else {
                    builder = builder.setWpa3Passphrase(j.getString("password"));
                }
            }
            if (j.has(WifiEnterpriseConfig.EAP_KEY)) {
                if (!isWpa3) {
                    builder = builder.setWpa2EnterpriseConfig(genWifiEnterpriseConfig(j));
                } else {
                    builder = builder.setWpa3EnterpriseConfig(genWifiEnterpriseConfig(j));
                }
            }
        }
        if (j.has("enhancedMacRandomizationEnabled")
                && j.getBoolean("enhancedMacRandomizationEnabled")) {
            builder = builder.setMacRandomizationSetting(
                WifiNetworkSuggestion.RANDOMIZATION_NON_PERSISTENT);
        }

        return builder.build();
    }

    private List<WifiNetworkSuggestion> genWifiNetworkSuggestions(
            JSONArray jsonNetworkSuggestionsArray) throws JSONException, GeneralSecurityException,
            IOException {
        if (jsonNetworkSuggestionsArray == null) {
            return null;
        }
        List<WifiNetworkSuggestion> networkSuggestions = new ArrayList<>();
        for (int i = 0; i < jsonNetworkSuggestionsArray.length(); i++) {
            networkSuggestions.add(
                    genWifiNetworkSuggestion(jsonNetworkSuggestionsArray.getJSONObject(i)));
        }
        return networkSuggestions;
    }

    private boolean matchScanResult(ScanResult result, String id) {
        if (result.BSSID.equals(id) || result.SSID.equals(id)) {
            return true;
        }
        return false;
    }

    private WpsInfo parseWpsInfo(String infoStr) throws JSONException {
        if (infoStr == null) {
            return null;
        }
        JSONObject j = new JSONObject(infoStr);
        WpsInfo info = new WpsInfo();
        if (j.has("setup")) {
            info.setup = j.getInt("setup");
        }
        if (j.has("BSSID")) {
            info.BSSID = j.getString("BSSID");
        }
        if (j.has("pin")) {
            info.pin = j.getString("pin");
        }
        return info;
    }

    private static byte[] base64StrToBytes(String input) {
        return Base64.decode(input, Base64.DEFAULT);
    }

    private static X509Certificate strToX509Cert(String certStr) throws CertificateException {
        byte[] certBytes = base64StrToBytes(certStr);
        InputStream certStream = new ByteArrayInputStream(certBytes);
        CertificateFactory cf = CertificateFactory.getInstance("X509");
        return (X509Certificate) cf.generateCertificate(certStream);
    }

    private static PrivateKey strToPrivateKey(String key, String algo)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyBytes = base64StrToBytes(key);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory fact = KeyFactory.getInstance(algo);
        PrivateKey priv = fact.generatePrivate(keySpec);
        return priv;
    }

    private PublicKey strToPublicKey(String key) throws NoSuchAlgorithmException,
            InvalidKeySpecException {
        byte[] keyBytes = base64StrToBytes(key);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory fact = KeyFactory.getInstance("RSA");
        PublicKey pub = fact.generatePublic(keySpec);
        return pub;
    }

    private WifiConfiguration wifiConfigurationFromScanResult(ScanResult result) {
        if (result == null)
            return null;
        WifiConfiguration config = new WifiConfiguration();
        config.SSID = "\"" + result.SSID + "\"";
        applyingkeyMgmt(config, result);
        config.BSSID = result.BSSID;
        return config;
    }

    @Rpc(description = "test.")
    public String wifiTest(
            @RpcParameter(name = "certString") String certString) throws CertificateException, IOException {
        // TODO(angli): Make this work. Convert a X509Certificate back to a string.
        X509Certificate caCert = strToX509Cert(certString);
        caCert.getEncoded();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutput out = new ObjectOutputStream(bos);
        out.writeObject(caCert);
        byte[] data = bos.toByteArray();
        bos.close();
        return Base64.encodeToString(data, Base64.DEFAULT);
    }

    @Rpc(description = "Add a network.")
    @Deprecated
    public Integer wifiAddNetwork(@RpcParameter(name = "wifiConfig") JSONObject wifiConfig)
            throws JSONException {
        return wifiaddOrUpdateNetwork(wifiConfig);
    }

    @Rpc(description = "Add or update a network.")
    public Integer wifiaddOrUpdateNetwork(@RpcParameter(name = "wifiConfig") JSONObject wifiConfig)
            throws JSONException {
        return mWifi.addNetwork(genWifiConfig(wifiConfig));
    }

    @Rpc(description = "Cancel Wi-fi Protected Setup.")
    public void wifiCancelWps() throws JSONException {
        WifiWpsCallback listener = new WifiWpsCallback();
        mWifi.cancelWps(listener);
    }

    @Rpc(description = "Checks Wifi state.", returns = "True if Wifi is enabled.")
    public Boolean wifiCheckState() {
        return mWifi.getWifiState() == WifiManager.WIFI_STATE_ENABLED;
    }

    /**
    * @deprecated Use {@link #wifiConnectByConfig(config)} instead.
    */
    @Rpc(description = "Connects to the network with the given configuration")
    @Deprecated
    public Boolean wifiConnect(@RpcParameter(name = "config") JSONObject config)
            throws JSONException {
        try {
            wifiConnectByConfig(config);
        } catch (GeneralSecurityException e) {
            String msg = "Caught GeneralSecurityException with the provided"
                         + "configuration";
            throw new RuntimeException(msg);
        }
        return true;
    }

    /**
    * @deprecated Use {@link #wifiConnectByConfig(config)} instead.
    */
    @Rpc(description = "Connects to the network with the given configuration")
    @Deprecated
    public Boolean wifiEnterpriseConnect(@RpcParameter(name = "config")
            JSONObject config) throws JSONException, GeneralSecurityException {
        try {
            wifiConnectByConfig(config);
        } catch (GeneralSecurityException e) {
            throw e;
        }
        return true;
    }

    /**
     * Connects to a wifi network using configuration.
     * @param config JSONObject Dictionary of wifi connection parameters
     * @throws JSONException
     * @throws GeneralSecurityException
     */
    @Rpc(description = "Connects to the network with the given configuration")
    public void wifiConnectByConfig(@RpcParameter(name = "config") JSONObject config)
            throws JSONException, GeneralSecurityException {
        WifiConfiguration wifiConfig;
        WifiActionListener listener;
        // Check if this is 802.1x or 802.11x config.
        if (config.has(WifiEnterpriseConfig.EAP_KEY)) {
            wifiConfig = genWifiConfigWithEnterpriseConfig(config);
        } else {
            wifiConfig = genWifiConfig(config);
        }
        listener = new WifiActionListener(mEventFacade,
                WifiConstants.WIFI_CONNECT_BY_CONFIG_CALLBACK);
        mWifi.connect(wifiConfig, listener);
    }

    /**
    * Gets the Wi-Fi factory MAC addresses.
    * @return An array of String represnting Wi-Fi MAC addresses,
    *         Or an empty Srting if failed.
    */
    @Rpc(description = "Gets the Wi-Fi factory MAC addresses", returns = "An array of String, representing the MAC address")
    public String[] wifigetFactorymacAddresses(){
        return mWifi.getFactoryMacAddresses();
    }

    @Rpc(description = "Gets the randomized MAC address", returns = "A MAC address or null")
    public MacAddress wifigetRandomizedMacAddress(@RpcParameter(name = "config") JSONObject config)
            throws JSONException{
        List<WifiConfiguration> configList = mWifi.getConfiguredNetworks();
        for(WifiConfiguration WifiConfig : configList){
            String ssid = WifiConfig.SSID;
            ssid = ssid.replace("\"", "");
            if (ssid.equals(config.getString("SSID"))){
                return WifiConfig.getRandomizedMacAddress();
            }
        }
        Log.d("Did not find a matching object in wifiManager.");
        return null;
    }
    /**
     * Generate a Passpoint configuration from JSON config.
     * @param config JSON config containing base64 encoded Passpoint profile
     */
    @Rpc(description = "Generate Passpoint configuration", returns = "PasspointConfiguration object")
    public PasspointConfiguration genWifiPasspointConfig(@RpcParameter(
            name = "config") JSONObject config)
            throws JSONException,CertificateException, IOException {
        String profileStr = "";
        if (config == null) {
            return null;
        }
        if (config.has("profile")) {
            profileStr =  config.getString("profile");
        }
        return ConfigParser.parsePasspointConfig(TYPE_WIFICONFIG,
                profileStr.getBytes());
    }

    /**
     * Add or update a Passpoint configuration.
     * @param config base64 encoded message containing Passpoint profile
     * @throws JSONException
     */
    @Rpc(description = "Add or update a Passpoint configuration")
    public void addUpdatePasspointConfig(@RpcParameter(
            name = "config") JSONObject config)
            throws JSONException,CertificateException, IOException {
        PasspointConfiguration passpointConfig = genWifiPasspointConfig(config);
        mWifi.addOrUpdatePasspointConfiguration(passpointConfig);
    }

    /**
     * Remove a Passpoint configuration.
     * @param fqdn The FQDN of the passpoint configuration to be removed
     * @return true on success; false otherwise
     */
    @Rpc(description = "Remove a Passpoint configuration")
    public void removePasspointConfig(
            @RpcParameter(name = "fqdn") String fqdn) {
        mWifi.removePasspointConfiguration(fqdn);
    }

    /**
     * Get list of Passpoint configurations.
     * @return A list of FQDNs of the Passpoint configurations
     */
    @Rpc(description = "Return the list of installed Passpoint configurations", returns = "A list of Passpoint configurations")
    public List<String> getPasspointConfigs() {
        List<String> fqdnList = new ArrayList<String>();
        for(PasspointConfiguration passpoint :
            mWifi.getPasspointConfigurations()) {
            fqdnList.add(passpoint.getHomeSp().getFqdn());
        }
        return fqdnList;
    }

    private class ProvisioningCallbackFacade extends ProvisioningCallback {
        private final EventFacade mEventFacade;

        ProvisioningCallbackFacade(EventFacade eventFacade) {
            mEventFacade = eventFacade;
        }

        @Override
        public void onProvisioningFailure(int status) {
            Log.v("Provisioning Failure " + status);
            Bundle msg = new Bundle();
            msg.putString("tag", "failure");
            msg.putInt("reason", status);
            mEventFacade.postEvent("onProvisioningCallback", msg);
        }

        @Override
        public void onProvisioningStatus(int status) {
            Log.v("Provisioning status " + status);
            Bundle msg = new Bundle();
            msg.putString("tag", "status");
            msg.putInt("status", status);
            mEventFacade.postEvent("onProvisioningCallback", msg);
        }

        @Override
        public void onProvisioningComplete() {
            Log.v("Provisioning Complete");
            Bundle msg = new Bundle();
            msg.putString("tag", "success");
            mEventFacade.postEvent("onProvisioningCallback", msg);
        }
    }

    private class SubsystemRestartTrackingCallbackFacade extends SubsystemRestartTrackingCallback {
        private final EventFacade mEventFacade;

        SubsystemRestartTrackingCallbackFacade(EventFacade eventFacade) {
            super();
            mEventFacade = eventFacade;
        }

        @Override
        public void onSubsystemRestarting() {
            Log.v("onSubsystemRestarting");
            mEventFacade.postEvent("WifiSubsystemRestarting", null);
        }

        @Override
        public void onSubsystemRestarted() {
            Log.v("onSubsystemRestarted");
            mEventFacade.postEvent("WifiSubsystemRestarted", null);
        }
    }

    private OsuProvider buildTestOsuProvider(JSONObject config) {
        String osuServiceDescription = "Google Passpoint Test Service";
        List<Integer> osuMethodList =
                Arrays.asList(OsuProvider.METHOD_SOAP_XML_SPP);

        try {
            if (!config.has("osuSSID")) {
                Log.e("missing osuSSID from the config");
                return null;
            }
            String osuSsid = config.getString("osuSSID");

            if (!config.has("osuUri")) {
                Log.e("missing osuUri from the config");
                return null;
            }
            Uri osuServerUri = Uri.parse(config.getString("osuUri"));

            Log.v("OSU Server URI " + osuServerUri.toString());
            if (!config.has("osuFriendlyName")) {
                Log.e("missing osuFriendlyName from the config");
                return null;
            }
            String osuFriendlyName = config.getString("osuFriendlyName");

            if (config.has("description")) {
                osuServiceDescription = config.getString("description");
            }
            Map<String, String> osuFriendlyNames = new HashMap<>();
            osuFriendlyNames.put("eng", osuFriendlyName);
            return new OsuProvider(osuSsid, osuFriendlyNames, osuServiceDescription,
                    osuServerUri, null, osuMethodList);
        } catch (JSONException e) {
            Log.e("JSON Parsing error: " + e);
            return null;
        }
    }

    /**
     * Start subscription provisioning
     */
    @Rpc(description = "Starts subscription provisioning flow")
    public void startSubscriptionProvisioning(
            @RpcParameter(name = "configJson") JSONObject configJson) {
        ProvisioningCallback callback = new ProvisioningCallbackFacade(mEventFacade);
        mWifi.startSubscriptionProvisioning(buildTestOsuProvider(configJson),
                mService.getMainExecutor(), callback);
    }

    /**
     * Connects to a wifi network using networkId.
     * @param networkId the network identity for the network in the supplicant
     */
    @Rpc(description = "Connects to the network with the given networkId")
    public void wifiConnectByNetworkId(
            @RpcParameter(name = "networkId") Integer networkId) {
        WifiActionListener listener;
        listener = new WifiActionListener(mEventFacade,
                WifiConstants.WIFI_CONNECT_BY_NETID_CALLBACK);
        mWifi.connect(networkId, listener);
    }

    @Rpc(description = "Disconnects from the currently active access point.", returns = "True if the operation succeeded.")
    public Boolean wifiDisconnect() {
        return mWifi.disconnect();
    }

    @Rpc(description = "Enable/disable autojoin scan and switch network when connected.")
    public Boolean wifiSetEnableAutoJoinWhenAssociated(@RpcParameter(name = "enable") Boolean enable) {
        return mWifi.setEnableAutoJoinWhenAssociated(enable);
    }

    @Rpc(description = "Enable a configured network. Initiate a connection if disableOthers is true", returns = "True if the operation succeeded.")
    public Boolean wifiEnableNetwork(@RpcParameter(name = "netId") Integer netId,
            @RpcParameter(name = "disableOthers") Boolean disableOthers) {
        return mWifi.enableNetwork(netId, disableOthers);
    }

    @Rpc(description = "Enable WiFi verbose logging.")
    public void wifiEnableVerboseLogging(@RpcParameter(name = "level") Integer level) {
        mWifi.setVerboseLoggingEnabled(level > 0);
    }

    @Rpc(description = "Resets all WifiManager settings.")
    public void wifiFactoryReset() {
        mWifi.factoryReset();
    }

    /**
     * Forget a wifi network by networkId.
     *
     * @param networkId Id of wifi network
     */
    @Rpc(description = "Forget a wifi network by networkId")
    public void wifiForgetNetwork(@RpcParameter(name = "wifiSSID") Integer networkId) {
        WifiActionListener listener = new WifiActionListener(mEventFacade,
                WifiConstants.WIFI_FORGET_NETWORK_CALLBACK);
        mWifi.forget(networkId, listener);
    }

    /**
     * User disconnect network.
     *
     * @param ssid SSID of wifi network
     */
    @Rpc(description = "Disconnect a wifi network by SSID")
    public void wifiUserDisconnectNetwork(@RpcParameter(name = "ssid") String ssid) {
        mWifi.disableEphemeralNetwork("\"" + ssid + "\"");
        mWifi.disconnect();
    }

    /**
     * User disconnect passpoint network.
     *
     * @param fqdn FQDN of the passpoint network
     */
    @Rpc(description = "Disconnect a wifi network by FQDN")
    public void wifiUserDisconnectPasspointNetwork(@RpcParameter(name = "fqdn") String fqdn) {
        mWifi.disableEphemeralNetwork(fqdn);
        mWifi.disconnect();
    }

    /**
     * Get SoftAp Configuration with SoftApConfiguration.
     */
    @Rpc(description = "Gets the Wi-Fi AP Configuration.")
    public SoftApConfiguration wifiGetApConfiguration() {
        return mWifi.getSoftApConfiguration();
    }

    /**
     * Get SoftAp Configuration with WifiConfiguration.
     *
     * Used to test deprecated API to check backward compatible
     */
    @Rpc(description = "Gets the Wi-Fi AP Configuration with WifiConfiguration.")
    public WifiConfiguration wifiGetApConfigurationWithWifiConfiguration() {
        return mWifi.getWifiApConfiguration();
    }

    @Rpc(description = "Return a list of all the configured wifi networks.")
    public List<WifiConfiguration> wifiGetConfiguredNetworks() {
        return mWifi.getConfiguredNetworks();
    }

    @Rpc(description = "Returns information about the currently active access point.")
    public WifiInfo wifiGetConnectionInfo() {
        return mWifi.getConnectionInfo();
    }

    /**
     * Check if wifi network is temporary disabled.
     * @param config JSONObject Dictionary of wifi connection parameters.
     * @return True if network is disabled temporarily, False if not.
     */
    @Rpc(description = "Check if network is temporary disabled")
    public boolean wifiIsNetworkTemporaryDisabledForNetwork(
            @RpcParameter(name = "config") JSONObject config)
                throws JSONException, GeneralSecurityException {
        WifiConfiguration wifiConfig;
        if (config.has(WifiEnterpriseConfig.EAP_KEY)) {
            wifiConfig = genWifiConfigWithEnterpriseConfig(config);
        } else {
            wifiConfig = genWifiConfig(config);
        }
        List<WifiConfiguration> wifiConfigList = wifiGetConfiguredNetworks();
        for (WifiConfiguration conf : wifiConfigList) {
            if (conf.getSsidAndSecurityTypeString().equals(
                    wifiConfig.getSsidAndSecurityTypeString())) {
                Log.d("Found matching config in the configured networks.");
                return conf.getNetworkSelectionStatus().isNetworkTemporaryDisabled();
            }
        }
        Log.d("Wifi config is not in list of configured wifi networks.");
        return false;
    }

    /**
     * Get wifi standard for wifi connection.
     */
    @Rpc(description = "Return connection WiFi standard")
    public Integer wifiGetConnectionStandard() {
        return mWifi.getConnectionInfo().getWifiStandard();
    }

    @Rpc(description = "Returns wifi activity and energy usage info.")
    public WifiActivityEnergyInfo wifiGetControllerActivityEnergyInfo() {
        WifiActivityEnergyInfo[] mutable = {null};
        CountDownLatch latch = new CountDownLatch(1);
        mWifi.getWifiActivityEnergyInfoAsync(new Executor() {
            @Override
            public void execute(Runnable runnable) {
                runnable.run();
            }
        }, info -> {
            mutable[0] = info;
            latch.countDown();
        });
        boolean completedSuccessfully = false;
        try {
            completedSuccessfully = latch.await(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Log.w("Interrupted while awaiting for WifiManager.getWifiActivityEnergyInfoAsync()");
        }
        if (completedSuccessfully) {
            return mutable[0];
        } else {
            Log.w("WifiManager.getWifiActivityEnergyInfoAsync() timed out after "
                    + TIMEOUT_MILLIS + " milliseconds");
            return null;
        }
    }

    @Rpc(description = "Get the country code used by WiFi.")
    public String wifiGetCountryCode() {
        return mWifi.getCountryCode();
    }

    @Rpc(description = "Get the current network.")
    public Network wifiGetCurrentNetwork() {
        return mWifi.getCurrentNetwork();
    }

    @Rpc(description = "Get the info from last successful DHCP request.")
    public DhcpInfo wifiGetDhcpInfo() {
        return mWifi.getDhcpInfo();
    }

    @Rpc(description = "Get setting for Framework layer autojoin enable status.")
    public Boolean wifiGetEnableAutoJoinWhenAssociated() {
        return mWifi.getEnableAutoJoinWhenAssociated();
    }

    @Rpc(description = "Get privileged configured networks.")
    public List<WifiConfiguration> wifiGetPrivilegedConfiguredNetworks() {
        return mWifi.getPrivilegedConfiguredNetworks();
    }

    @Rpc(description = "Returns the list of access points found during the most recent Wifi scan.")
    public List<ScanResult> wifiGetScanResults() {
        return mWifi.getScanResults();
    }

    @Rpc(description = "Get the current level of WiFi verbose logging.")
    public Integer wifiGetVerboseLoggingLevel() {
        return mWifi.isVerboseLoggingEnabled() ? 1 : 0;
    }

    /**
     * Query whether or not the device supports concurrency of Station (STA) + multiple access
     * points (AP) (where the APs bridged together).
     *
     * @return true if this device supports concurrency of STA + multiple APs which are bridged
     *         together, false otherwise.
     */
    @Rpc(description = "true if this adapter supports STA + bridged Soft AP concurrency.")
    public Boolean wifiIsStaBridgedApConcurrencySupported() {
        return mWifi.isStaBridgedApConcurrencySupported();
    }

    /**
     * Query whether or not the device supports multiple Access point (AP) which are bridged
     * together.
     *
     * @return true if this device supports concurrency of multiple AP which bridged together,
     *         false otherwise.
     */
    @Rpc(description = "true if this adapter supports bridged Soft AP concurrency.")
    public Boolean wifiIsBridgedApConcurrencySupported() {
        return mWifi.isBridgedApConcurrencySupported();
    }

    @Rpc(description = "true if this adapter supports 5 GHz band.")
    public Boolean wifiIs5GHzBandSupported() {
        return mWifi.is5GHzBandSupported();
    }

    @Rpc(description = "true if this adapter supports multiple simultaneous connections for"
            + "local only use-case.")
    public Boolean wifiIsStaConcurrencyForLocalOnlyConnectionsSupported() {
        return mWifi.isStaConcurrencyForLocalOnlyConnectionsSupported();
    }

    @Rpc(description = "true if this adapter supports multiple simultaneous connections for mbb "
            + "wifi to wifi switching.")
    public Boolean wifiIsMakeBeforeBreakWifiSwitchingSupported() {
        return mWifi.isMakeBeforeBreakWifiSwitchingSupported();
    }

    @Rpc(description = "true if this adapter supports multiple simultaneous connections for "
            + "restricted connection use-case.")
    public Boolean wifiIsStaConcurrencyForRestrictedConnectionsSupported() {
        return mWifi.isStaConcurrencyForRestrictedConnectionsSupported();
    }

    @Rpc(description = "Return true if WiFi is enabled.")
    public Boolean wifiGetisWifiEnabled() {
        return mWifi.isWifiEnabled();
    }

    @Rpc(description = "Return whether Wi-Fi AP is enabled or disabled.")
    public Boolean wifiIsApEnabled() {
        return mWifi.isWifiApEnabled();
    }

    @Rpc(description = "Check if Device-to-AP RTT is supported.")
    public Boolean wifiIsDeviceToApRttSupported() {
        return mWifi.isDeviceToApRttSupported();
    }

    @Rpc(description = "Check if Device-to-device RTT is supported.")
    public Boolean wifiIsDeviceToDeviceRttSupported() {
        return mWifi.isDeviceToDeviceRttSupported();
    }

    /**
     * @return true if chipset supports 5GHz band and false otherwise.
     */
    @Rpc(description = "Check if the chipset supports 5GHz frequency band.")
    public Boolean is5GhzBandSupported() {
        return mWifi.is5GHzBandSupported();
    }

    /**
     * @return true if chipset supports 6GHz band and false otherwise.
     */
    @Rpc(description = "Check if the chipset supports 6GHz frequency band.")
    public Boolean is6GhzBandSupported() {
        return mWifi.is6GHzBandSupported();
    }

    @Rpc(description = "Check if this adapter supports advanced power/performance counters.")
    public Boolean wifiIsEnhancedPowerReportingSupported() {
        return mWifi.isEnhancedPowerReportingSupported();
    }

    @Rpc(description = "Check if multicast is enabled.")
    public Boolean wifiIsMulticastEnabled() {
        return mWifi.isMulticastEnabled();
    }

    @Rpc(description = "true if this adapter supports Wi-Fi Aware APIs.")
    public Boolean wifiIsAwareSupported() {
        return mWifi.isWifiAwareSupported();
    }

    @Rpc(description = "true if this adapter supports Off Channel Tunnel Directed Link Setup.")
    public Boolean wifiIsOffChannelTdlsSupported() {
        return mWifi.isOffChannelTdlsSupported();
    }

    @Rpc(description = "true if this adapter supports WifiP2pManager (Wi-Fi Direct).")
    public Boolean wifiIsP2pSupported() {
        return mWifi.isP2pSupported();
    }

    @Rpc(description = "true if this adapter supports passpoint.")
    public Boolean wifiIsPasspointSupported() {
        return mWifi.isPasspointSupported();
    }

    @Rpc(description = "true if this adapter supports portable Wi-Fi hotspot.")
    public Boolean wifiIsPortableHotspotSupported() {
        return mWifi.isPortableHotspotSupported();
    }

    @Rpc(description = "true if this adapter supports offloaded connectivity scan.")
    public Boolean wifiIsPreferredNetworkOffloadSupported() {
        return mWifi.isPreferredNetworkOffloadSupported();
    }

    @Rpc(description = "Check if wifi scanner is supported on this device.")
    public Boolean wifiIsScannerSupported() {
        return mWifi.isWifiScannerSupported();
    }

    @Rpc(description = "Check if tdls is supported on this device.")
    public Boolean wifiIsTdlsSupported() {
        return mWifi.isTdlsSupported();
    }

    /**
     * @return true if this device supports WPA3-Personal SAE
     */
    @Rpc(description = "Check if WPA3-Personal SAE is supported on this device.")
    public Boolean wifiIsWpa3SaeSupported() {
        return mWifi.isWpa3SaeSupported();
    }
    /**
     * @return true if this device supports WPA3-Enterprise Suite-B-192
     */
    @Rpc(description = "Check if WPA3-Enterprise Suite-B-192 is supported on this device.")
    public Boolean wifiIsWpa3SuiteBSupported() {
        return mWifi.isWpa3SuiteBSupported();
    }
    /**
     * @return true if this device supports Wi-Fi Enhanced Open (OWE)
     */
    @Rpc(description = "Check if Enhanced Open (OWE) is supported on this device.")
    public Boolean wifiIsEnhancedOpenSupported() {
        return mWifi.isEnhancedOpenSupported();
    }

    /**
     * @return true if this device supports Wi-Fi Device Provisioning Protocol (Easy-connect)
     * Enrollee Responder mode
     */
    @Rpc(description = "Check if Easy Connect (DPP) Enrollee responder mode is supported "
            + "on this device.")
    public Boolean wifiIsEasyConnectEnrolleeResponderModeSupported() {
        return mWifi.isEasyConnectEnrolleeResponderModeSupported();
    }

    /**
     * @return true if this device supports Wi-Fi Device Provisioning Protocol (Easy-connect)
     */
    @Rpc(description = "Check if Easy Connect (DPP) is supported on this device.")
    public Boolean wifiIsEasyConnectSupported() {
        return mWifi.isEasyConnectSupported();
    }

    @Rpc(description = "Acquires a full Wifi lock.")
    public void wifiLockAcquireFull() {
        makeLock(WifiManager.WIFI_MODE_FULL);
    }

    @Rpc(description = "Acquires a scan only Wifi lock.")
    public void wifiLockAcquireScanOnly() {
        makeLock(WifiManager.WIFI_MODE_SCAN_ONLY);
    }

    @Rpc(description = "Acquires a high performance Wifi lock.")
    public void wifiLockAcquireFullHighPerf() {
        makeLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF);
    }

    @Rpc(description = "Acquires a low latency Wifi lock.")
    public void wifiLockAcquireFullLowLatency() {
        makeLock(WifiManager.WIFI_MODE_FULL_LOW_LATENCY);
    }

    @Rpc(description = "Releases a previously acquired Wifi lock.")
    public void wifiLockRelease() {
        if (mLock != null) {
            mLock.release();
            mLock = null;
        }
    }

    @Rpc(description = "Reassociates with the currently active access point.", returns = "True if the operation succeeded.")
    public Boolean wifiReassociate() {
        return mWifi.reassociate();
    }

    @Rpc(description = "Reconnects to the currently active access point.", returns = "True if the operation succeeded.")
    public Boolean wifiReconnect() {
        return mWifi.reconnect();
    }

    @Rpc(description = "Remove a configured network.", returns = "True if the operation succeeded.")
    public Boolean wifiRemoveNetwork(@RpcParameter(name = "netId") Integer netId) {
        return mWifi.removeNetwork(netId);
    }

    private int getApBandFromChannelFrequency(int freq) {
        if (ScanResult.is24GHz(freq)) {
            return SoftApConfiguration.BAND_2GHZ;
        } else if (ScanResult.is5GHz(freq)) {
            return SoftApConfiguration.BAND_5GHZ;
        } else if (ScanResult.is6GHz(freq)) {
            return SoftApConfiguration.BAND_6GHZ;
        } else if (ScanResult.is60GHz(freq)) {
            return SoftApConfiguration.BAND_60GHZ;
        }
        return -1;
    }

    private int[] convertJSONArrayToIntArray(JSONArray jArray) throws JSONException {
        if (jArray == null) {
            return null;
        }
        int[] iArray = new int[jArray.length()];
        for (int i = 0; i < jArray.length(); i++) {
            iArray[i] = jArray.getInt(i);
        }
        return iArray;
    }

    private SoftApConfiguration createSoftApConfiguration(JSONObject configJson)
            throws JSONException {
        if (configJson == null) {
            return null;
        }
        SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
        if (configJson.has("SSID")) {
            configBuilder.setSsid(configJson.getString("SSID"));
        }
        if (configJson.has("password")) {
            String pwd = configJson.getString("password");
            // Check if new security type SAE (WPA3) is present. Default to PSK
            if (configJson.has("security")) {
                String securityType = configJson.getString("security");
                if (TextUtils.equals(securityType, "WPA2_PSK")) {
                    configBuilder.setPassphrase(pwd, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
                } else if (TextUtils.equals(securityType, "WPA3_SAE_TRANSITION")) {
                    configBuilder.setPassphrase(pwd,
                            SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION);
                } else if (TextUtils.equals(securityType, "WPA3_SAE")) {
                    configBuilder.setPassphrase(pwd, SoftApConfiguration.SECURITY_TYPE_WPA3_SAE);
                }
            } else {
                configBuilder.setPassphrase(pwd, SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
            }
        }
        if (configJson.has("BSSID")) {
            configBuilder.setBssid(MacAddress.fromString(configJson.getString("BSSID")));
        }
        if (configJson.has("hiddenSSID")) {
            configBuilder.setHiddenSsid(configJson.getBoolean("hiddenSSID"));
        }
        if (configJson.has("apBand")) {
            configBuilder.setBand(configJson.getInt("apBand"));
        }
        if (configJson.has("apChannel") && configJson.has("apBand")) {
            configBuilder.setChannel(configJson.getInt("apChannel"), configJson.getInt("apBand"));
        }

        if (configJson.has("MaxNumberOfClients")) {
            configBuilder.setMaxNumberOfClients(configJson.getInt("MaxNumberOfClients"));
        }

        if (configJson.has("ShutdownTimeoutMillis")) {
            configBuilder.setShutdownTimeoutMillis(configJson.getLong("ShutdownTimeoutMillis"));
        }

        if (configJson.has("AutoShutdownEnabled")) {
            configBuilder.setAutoShutdownEnabled(configJson.getBoolean("AutoShutdownEnabled"));
        }

        if (configJson.has("ClientControlByUserEnabled")) {
            configBuilder.setClientControlByUserEnabled(
                    configJson.getBoolean("ClientControlByUserEnabled"));
        }

        List allowedClientList = new ArrayList<>();
        if (configJson.has("AllowedClientList")) {
            JSONArray allowedList = configJson.getJSONArray("AllowedClientList");
            for (int i = 0; i < allowedList.length(); i++) {
                allowedClientList.add(MacAddress.fromString(allowedList.getString(i)));
            }
        }

        List blockedClientList = new ArrayList<>();
        if (configJson.has("BlockedClientList")) {
            JSONArray blockedList = configJson.getJSONArray("BlockedClientList");
            for (int j = 0; j < blockedList.length(); j++) {
                blockedClientList.add(MacAddress.fromString(blockedList.getString(j)));
            }
        }

        configBuilder.setAllowedClientList(allowedClientList);
        configBuilder.setBlockedClientList(blockedClientList);

        if (configJson.has("apBands")) {
            JSONArray jBands = configJson.getJSONArray("apBands");
            int[] bands = convertJSONArrayToIntArray(jBands);
            configBuilder.setBands(bands);
        }

        if (configJson.has("apChannelFrequencies")) {
            JSONArray jChannelFrequencys = configJson.getJSONArray("apChannelFrequencies");
            int[] channelFrequencies = convertJSONArrayToIntArray(jChannelFrequencys);
            SparseIntArray channels = new SparseIntArray();
            for (int channelFrequency : channelFrequencies) {
                if (channelFrequency != 0) {
                    channels.put(getApBandFromChannelFrequency(channelFrequency),
                            ScanResult.convertFrequencyMhzToChannelIfSupported(channelFrequency));
                }
            }
            if (channels.size() != 0) {
                configBuilder.setChannels(channels);
            }
        }

        if (configJson.has("MacRandomizationSetting")) {
            configBuilder.setMacRandomizationSetting(configJson.getInt("MacRandomizationSetting"));
        }

        if (configJson.has("BridgedModeOpportunisticShutdownEnabled")) {
            configBuilder.setBridgedModeOpportunisticShutdownEnabled(
                    configJson.getBoolean("BridgedModeOpportunisticShutdownEnabled"));
        }

        if (configJson.has("Ieee80211axEnabled")) {
            configBuilder.setIeee80211axEnabled(configJson.getBoolean("Ieee80211axEnabled"));
        }

        return configBuilder.build();
    }

    private WifiConfiguration createSoftApWifiConfiguration(JSONObject configJson)
            throws JSONException {
        WifiConfiguration config = genWifiConfig(configJson);
        // Need to strip of extra quotation marks for SSID and password.
        String ssid = config.SSID;
        if (ssid != null) {
            config.SSID = ssid.substring(1, ssid.length() - 1);
        }

        config.allowedKeyManagement.clear();
        String pwd = config.preSharedKey;
        if (pwd != null) {
            config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
            config.preSharedKey = pwd.substring(1, pwd.length() - 1);
        } else {
            config.allowedKeyManagement.set(KeyMgmt.NONE);
        }
        return config;
    }

    /**
     * Set SoftAp Configuration with SoftApConfiguration.
     */
    @Rpc(description = "Set configuration for soft AP.")
    public Boolean wifiSetWifiApConfiguration(
            @RpcParameter(name = "configJson") JSONObject configJson) throws JSONException {
        return mWifi.setSoftApConfiguration(createSoftApConfiguration(configJson));
    }

    /**
     * Set SoftAp Configuration with WifiConfiguration.
     *
     * Used to test deprecated API to check backward compatible.
     */
    @Rpc(description = "Set configuration for soft AP with WifiConfig.")
    public Boolean wifiSetWifiApConfigurationWithWifiConfiguration(
            @RpcParameter(name = "configJson") JSONObject configJson) throws JSONException {
        return mWifi.setWifiApConfiguration(createSoftApWifiConfiguration(configJson));
    }

    /**
     * Register softap callback.
     *
     * @return the id associated with the {@link SoftApCallbackImp}
     * used for registering callback.
     */
    @Rpc(description = "Register softap callback function.",
            returns = "Id of the callback associated with registering.")
    public Integer registerSoftApCallback() {
        SoftApCallbackImp softApCallback = new SoftApCallbackImp(mEventFacade);
        mSoftapCallbacks.put(softApCallback.mId, softApCallback);
        mWifi.registerSoftApCallback(
                new HandlerExecutor(new Handler(mCallbackHandlerThread.getLooper())),
                softApCallback);
        return softApCallback.mId;
    }

    /**
     * Unregister softap callback role for the {@link SoftApCallbackImp} identified by the given
     * {@code callbackId}.
     *
     * @param callbackId the id associated with the {@link SoftApCallbackImp}
     * used for registering callback.
     *
     */
    @Rpc(description = "Unregister softap callback function.")
    public void unregisterSoftApCallback(@RpcParameter(name = "callbackId") Integer callbackId) {
        mWifi.unregisterSoftApCallback(mSoftapCallbacks.get(callbackId));
        mSoftapCallbacks.delete(callbackId);
    }

    @Rpc(description = "Enable/disable tdls with a mac address.")
    public void wifiSetTdlsEnabledWithMacAddress(
            @RpcParameter(name = "remoteMacAddress") String remoteMacAddress,
            @RpcParameter(name = "enable") Boolean enable) {
        mWifi.setTdlsEnabledWithMacAddress(remoteMacAddress, enable);
    }

    @Rpc(description = "Starts a scan for Wifi access points.", returns = "True if the scan was initiated successfully.")
    public Boolean wifiStartScan() {
        mService.registerReceiver(mScanResultsAvailableReceiver, mScanFilter);
        return mWifi.startScan();
    }

    @Rpc(description = "Starts a scan for Wifi access points with scanResultCallback.",
            returns = "True if the scan was initiated successfully.")
    public Boolean wifiStartScanWithListener() {
        mWifi.registerScanResultsCallback(mService.getMainExecutor(), mWifiScanResultsReceiver);
        return mWifi.startScan();
    }

    @Rpc(description = "Start Wi-fi Protected Setup.")
    public void wifiStartWps(
            @RpcParameter(name = "config", description = "A json string with fields \"setup\", \"BSSID\", and \"pin\"") String config)
                    throws JSONException {
        WpsInfo info = parseWpsInfo(config);
        WifiWpsCallback listener = new WifiWpsCallback();
        Log.d("Starting wps with: " + info);
        mWifi.startWps(info, listener);
    }

    @Rpc(description = "Start listening for wifi state change related broadcasts.")
    public void wifiStartTrackingStateChange() {
        mService.registerReceiver(mStateChangeReceiver, mStateChangeFilter);
        mTrackingWifiStateChange = true;
    }

    @Rpc(description = "Stop listening for wifi state change related broadcasts.")
    public void wifiStopTrackingStateChange() {
        if (mTrackingWifiStateChange == true) {
            mService.unregisterReceiver(mStateChangeReceiver);
            mTrackingWifiStateChange = false;
        }
    }

    @Rpc(description = "Start listening for tether state change related broadcasts.")
    public void wifiStartTrackingTetherStateChange() {
        mService.registerReceiver(mTetherStateReceiver, mTetherFilter);
        mTrackingTetherStateChange = true;
    }

    @Rpc(description = "Stop listening for wifi state change related broadcasts.")
    public void wifiStopTrackingTetherStateChange() {
        if (mTrackingTetherStateChange == true) {
            mService.unregisterReceiver(mTetherStateReceiver);
            mTrackingTetherStateChange = false;
        }
    }

    @Rpc(description = "Start listening for network suggestion change related broadcasts.")
    public void wifiStartTrackingNetworkSuggestionStateChange() {
        mService.registerReceiver(
                mNetworkSuggestionStateChangeReceiver, mNetworkSuggestionStateChangeFilter);
        mTrackingNetworkSuggestionStateChange = true;
    }

    @Rpc(description = "Stop listening for network suggestion change related broadcasts.")
    public void wifiStopTrackingNetworkSuggestionStateChange() {
        if (mTrackingNetworkSuggestionStateChange) {
            mService.unregisterReceiver(mNetworkSuggestionStateChangeReceiver);
            mTrackingNetworkSuggestionStateChange = false;
        }
    }

    @Rpc(description = "Toggle Wifi on and off.", returns = "True if Wifi is enabled.")
    public Boolean wifiToggleState(@RpcParameter(name = "enabled") @RpcOptional Boolean enabled) {
        if (enabled == null) {
            enabled = !wifiCheckState();
        }
        mWifi.setWifiEnabled(enabled);
        return enabled;
    }

    @Rpc(description = "Restart the WiFi subsystem.")
    public void restartWifiSubsystem() {
        if (mSubsystemRestartTrackingCallback == null) {
            // one-time registration if needed
            mSubsystemRestartTrackingCallback = new SubsystemRestartTrackingCallbackFacade(
                    mEventFacade);
        }
        mWifi.restartWifiSubsystem();
    }

    @Rpc(description = "Toggle Wifi scan always available on and off.", returns = "True if Wifi scan is always available.")
    public Boolean wifiToggleScanAlwaysAvailable(
            @RpcParameter(name = "enabled") @RpcOptional Boolean enabled)
                    throws SettingNotFoundException {
        boolean isSet = (enabled == null) ? !mWifi.isScanAlwaysAvailable() : enabled;
        mWifi.setScanAlwaysAvailable(isSet);
        return isSet;
    }

    @Rpc(description = "Enable/disable WifiConnectivityManager.")
    public void wifiEnableWifiConnectivityManager(
            @RpcParameter(name = "enable") Boolean enable) {
        mWifi.allowAutojoinGlobal(enable);
    }

    /**
     * Register network request match callback to simulate the UI flow.
     *
     * @throws JSONException
     * @throws GeneralSecurityException
     */
    @Rpc(description = "Register network request match callback")
    public void wifiRegisterNetworkRequestMatchCallback()
            throws JSONException, GeneralSecurityException {
        // Listen for UI interaction callbacks
        mWifi.registerNetworkRequestMatchCallback(
                new HandlerExecutor(new Handler(mCallbackHandlerThread.getLooper())),
                mNetworkRequestMatchCallback);
    }

    /**
     * Triggers connect to a specific wifi network.
     *
     * @param jsonConfig JSONObject Dictionary of wifi connection parameters
     * @throws JSONException
     * @throws GeneralSecurityException
     */
    @Rpc(description = "Connects to the specified network for the ongoing network request")
    public void wifiSendUserSelectionForNetworkRequestMatch(
            @RpcParameter(name = "jsonConfig") JSONObject jsonConfig)
            throws JSONException, GeneralSecurityException {
        synchronized (mCallbackLock) {
            if (mNetworkRequestUserSelectionCallback == null) {
                throw new IllegalStateException("user callback is null");
            }
            // Copy the SSID for user selection.
            WifiConfiguration config = new WifiConfiguration();
            if (jsonConfig.has("SSID")) {
                config.SSID = "\"" + jsonConfig.getString("SSID") + "\"";
            }
            mNetworkRequestUserSelectionCallback.select(config);
        }
    }

    /**
     * Rejects network request.
     *
     * @throws JSONException
     * @throws GeneralSecurityException
     */
    @Rpc(description = "Rejects ongoing network request")
    public void wifiSendUserRejectionForNetworkRequestMatch()
            throws JSONException, GeneralSecurityException {
        synchronized (mCallbackLock) {
            if (mNetworkRequestUserSelectionCallback == null) {
                throw new IllegalStateException("user callback is null");
            }
            mNetworkRequestUserSelectionCallback.reject();
        }
    }

    /**
     * Add network suggestions.

     * @param wifiNetworkSuggestions Array of JSONObject Dictionary of wifi network suggestion
     *                               parameters
     * @throws JSONException
     * @throws GeneralSecurityException
     */
    @Rpc(description = "Add network suggestions to the platform")
    public boolean wifiAddNetworkSuggestions(
            @RpcParameter(name = "wifiNetworkSuggestions") JSONArray wifiNetworkSuggestions)
            throws JSONException, GeneralSecurityException, IOException {
        return mWifi.addNetworkSuggestions(genWifiNetworkSuggestions(wifiNetworkSuggestions))
                == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
    }

    /**
     * Remove network suggestions.

     * @param wifiNetworkSuggestions Array of JSONObject Dictionary of wifi network suggestion
     *                               parameters
     * @throws JSONException
     * @throws GeneralSecurityException
     */
    @Rpc(description = "Remove network suggestions from the platform")
    public boolean wifiRemoveNetworkSuggestions(
            @RpcParameter(name = "wifiNetworkSuggestions") JSONArray wifiNetworkSuggestions)
            throws JSONException, GeneralSecurityException, IOException {
        return mWifi.removeNetworkSuggestions(genWifiNetworkSuggestions(wifiNetworkSuggestions))
                == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS;
    }

    @Override
    public void shutdown() {
        wifiLockRelease();
        if (mTrackingWifiStateChange == true) {
            wifiStopTrackingStateChange();
        }
        if (mTrackingTetherStateChange == true) {
            wifiStopTrackingTetherStateChange();
        }
    }

    private class EasyConnectCallback extends EasyConnectStatusCallback {
        private static final String EASY_CONNECT_CALLBACK_TAG = "onDppCallback";

        @Override
        public void onEnrolleeSuccess(int newWifiConfigurationId) {
            Bundle msg = new Bundle();
            msg.putString("Type", "onEnrolleeSuccess");
            msg.putInt("NetworkId", newWifiConfigurationId);
            Log.d("Posting event: onEnrolleeSuccess");
            mEventFacade.postEvent(EASY_CONNECT_CALLBACK_TAG, msg);
        }

        @Override
        public void onConfiguratorSuccess(int code) {
            Bundle msg = new Bundle();
            msg.putString("Type", "onConfiguratorSuccess");
            msg.putInt("Status", code);
            Log.d("Posting event: onConfiguratorSuccess");
            mEventFacade.postEvent(EASY_CONNECT_CALLBACK_TAG, msg);
        }

        @Override
        public void onFailure(int code, String ssid, SparseArray<int[]> channelList,
                int[] bandList) {
            Bundle msg = new Bundle();
            msg.putString("Type", "onFailure");
            msg.putInt("Status", code);
            Log.d("Posting event: onFailure");
            if (ssid != null) {
                Log.d("onFailure SSID: " + ssid);
                msg.putString("onFailureSsid", ssid);
            } else {
                msg.putString("onFailureSsid", "");
            }
            if (channelList != null) {
                Log.d("onFailure list of tried channels: " + channelList);
                int key;
                int index = 0;
                JSONObject formattedChannelList = new JSONObject();

                // Build a JSON array of classes, with an array of channels for each class.
                do {
                    try {
                        key = channelList.keyAt(index);
                    } catch (java.lang.ArrayIndexOutOfBoundsException e) {
                        break;
                    }
                    try {
                        JSONArray channelsInClassArray = new JSONArray();

                        int[] output = channelList.get(key);
                        for (int i = 0; i < output.length; i++) {
                            channelsInClassArray.put(output[i]);
                        }
                        formattedChannelList.put(Integer.toString(key),
                                build(channelsInClassArray));
                    } catch (org.json.JSONException e) {
                        msg.putString("onFailureChannelList", "");
                        break;
                    }
                    index++;
                } while (true);

                msg.putString("onFailureChannelList", formattedChannelList.toString());
            } else {
                msg.putString("onFailureChannelList", "");
            }

            if (bandList != null) {
                // Build a JSON array of bands represented as operating classes
                Log.d("onFailure list of supported bands: " + bandList);
                JSONArray formattedBandList = new JSONArray();
                for (int i = 0; i < bandList.length; i++) {
                    formattedBandList.put(bandList[i]);
                }
                msg.putString("onFailureBandList", formattedBandList.toString());
            } else {
                msg.putString("onFailureBandList", "");
            }
            mEventFacade.postEvent(EASY_CONNECT_CALLBACK_TAG, msg);
        }

        @Override
        public void onProgress(int code) {
            Bundle msg = new Bundle();
            msg.putString("Type", "onProgress");
            msg.putInt("Status", code);
            Log.d("Posting event: onProgress");
            mEventFacade.postEvent(EASY_CONNECT_CALLBACK_TAG, msg);
        }

        @Override
        public void onBootstrapUriGenerated(@NonNull Uri dppUri) {
            Bundle msg = new Bundle();
            msg.putString("Type", "onBootstrapUriGenerated");
            Log.d("onBootstrapUriGenerated uri: " + dppUri.toString());
            msg.putString("generatedUri", dppUri.toString());
            Log.d("Posting event: onBootstrapUriGenerated");
            mEventFacade.postEvent(EASY_CONNECT_CALLBACK_TAG, msg);
        }
    }

    private static @WifiManager.EasyConnectCryptographyCurve
            int getEasyConnectCryptographyCurve(String curve) {

        switch (curve) {
            case "secp384r1":
                return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_SECP384R1;
            case "secp521r1":
                return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_SECP521R1;
            case "brainpoolP256r1":
                return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_BRAINPOOLP256R1;
            case "brainpoolP384r1":
                return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_BRAINPOOLP384R1;
            case "brainpoolP512r1":
                return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_BRAINPOOLP512R1;
            case "prime256v1":
            default:
                return WifiManager.EASY_CONNECT_CRYPTOGRAPHY_CURVE_PRIME256V1;
        }
    }

    /**
     * Start Easy Connect (DPP) in Initiator-Configurator role: Send Wi-Fi configuration to a peer
     *
     * @param enrolleeUri Peer URI
     * @param selectedNetworkId Wi-Fi configuration ID
     */
    @Rpc(description = "Easy Connect Initiator-Configurator: Send Wi-Fi configuration to peer")
    public void startEasyConnectAsConfiguratorInitiator(@RpcParameter(name = "enrolleeUri") String
            enrolleeUri, @RpcParameter(name = "selectedNetworkId") Integer selectedNetworkId,
            @RpcParameter(name = "netRole") String netRole)
            throws JSONException {
        EasyConnectCallback dppStatusCallback = new EasyConnectCallback();
        int netRoleInternal;

        if (netRole.equals("ap")) {
            netRoleInternal = WifiManager.EASY_CONNECT_NETWORK_ROLE_AP;
        } else {
            netRoleInternal = WifiManager.EASY_CONNECT_NETWORK_ROLE_STA;
        }

        // Start Easy Connect
        mWifi.startEasyConnectAsConfiguratorInitiator(enrolleeUri, selectedNetworkId,
                netRoleInternal, mService.getMainExecutor(), dppStatusCallback);
    }

    /**
     * Start Easy Connect (DPP) in Initiator-Enrollee role: Receive Wi-Fi configuration from a peer
     *
     * @param configuratorUri
     */
    @Rpc(description = "Easy Connect Initiator-Enrollee: Receive Wi-Fi configuration from peer")
    public void startEasyConnectAsEnrolleeInitiator(@RpcParameter(name = "configuratorUri") String
            configuratorUri) {
        EasyConnectCallback dppStatusCallback = new EasyConnectCallback();

        // Start Easy Connect
        mWifi.startEasyConnectAsEnrolleeInitiator(configuratorUri, mService.getMainExecutor(),
                dppStatusCallback);
    }

    /**
     * Start Easy Connect (DPP) in Responder-Enrollee role: Receive Wi-Fi configuration from a peer
     *
     * @param deviceInfo The device specific info to attach in the generated URI
     * @param cryptographyCurve Elliptic curve cryptography used to generate DPP
     *        public/private key pair
     */
    @Rpc(description = "Easy Connect Responder-Enrollee: Receive Wi-Fi configuration from peer")
    public void startEasyConnectAsEnrolleeResponder(@RpcParameter(name = "deviceInfo") String
            deviceInfo, @RpcParameter(name = "cryptographyCurve") String cryptographyCurve) {
        EasyConnectCallback dppStatusCallback = new EasyConnectCallback();

        // Start Easy Connect
        mWifi.startEasyConnectAsEnrolleeResponder(deviceInfo,
                getEasyConnectCryptographyCurve(cryptographyCurve), mService.getMainExecutor(),
                dppStatusCallback);
    }

    /**
     * Stop Easy Connect (DPP) session
     *
     */
    @Rpc(description = "Stop Easy Connect session")
    public void stopEasyConnectSession() {
        // Stop Easy Connect
        mWifi.stopEasyConnectSession();
    }

    /**
     * Enable/Disable auto join for target network
     */
    @Rpc(description = "Set network auto join enable/disable")
    public void wifiEnableAutojoin(@RpcParameter(name = "netId") Integer netId,
            @RpcParameter(name = "enableAutojoin") Boolean enableAutojoin) {
        mWifi.allowAutojoin(netId, enableAutojoin);
    }

    /**
     * Enable/Disable auto join for target Passpoint network
     */
    @Rpc(description = "Set passpoint network auto join enable/disable")
    public void wifiEnableAutojoinPasspoint(@RpcParameter(name = "FQDN") String fqdn,
            @RpcParameter(name = "enableAutojoin") Boolean enableAutojoin) {
        mWifi.allowAutojoinPasspoint(fqdn, enableAutojoin);
    }

    private static CoexUnsafeChannel genCoexUnsafeChannel(JSONObject j) throws JSONException {
        if (j == null || !j.has("band") || !j.has("channel")) {
            return null;
        }

        final int band;
        final String jsonBand = j.getString("band");
        if (TextUtils.equals(jsonBand, "24_GHZ")) {
            band = WIFI_BAND_24_GHZ;
        } else if (TextUtils.equals(jsonBand, "5_GHZ")) {
            band = WIFI_BAND_5_GHZ;
        } else {
            return null;
        }
        if (j.has("powerCapDbm")) {
            return new CoexUnsafeChannel(band, j.getInt("channel"), j.getInt("powerCapDbm"));
        }
        return new CoexUnsafeChannel(band, j.getInt("channel"));
    }

    private static List<CoexUnsafeChannel> genCoexUnsafeChannels(
            JSONArray jsonCoexUnsafeChannelsArray) throws JSONException {
        if (jsonCoexUnsafeChannelsArray == null) {
            return Collections.emptyList();
        }
        List<CoexUnsafeChannel> unsafeChannels = new ArrayList<>();
        for (int i = 0; i < jsonCoexUnsafeChannelsArray.length(); i++) {
            unsafeChannels.add(
                    genCoexUnsafeChannel(jsonCoexUnsafeChannelsArray.getJSONObject(i)));
        }
        return unsafeChannels;
    }

    private static int genCoexRestrictions(JSONArray jsonCoexRestrictionArray)
            throws JSONException {
        if (jsonCoexRestrictionArray == null) {
            return 0;
        }
        int coexRestrictions = 0;
        for (int i = 0; i < jsonCoexRestrictionArray.length(); i++) {
            final String jsonRestriction = jsonCoexRestrictionArray.getString(i);
            if (TextUtils.equals(jsonRestriction, "WIFI_DIRECT")) {
                coexRestrictions |= WifiManager.COEX_RESTRICTION_WIFI_DIRECT;
            }
            if (TextUtils.equals(jsonRestriction, "SOFTAP")) {
                coexRestrictions |= WifiManager.COEX_RESTRICTION_SOFTAP;
            }
            if (TextUtils.equals(jsonRestriction, "WIFI_AWARE")) {
                coexRestrictions |= WifiManager.COEX_RESTRICTION_WIFI_AWARE;
            }
        }
        return coexRestrictions;
    }

    /**
     * Converts a set of {@link CoexUnsafeChannel} to a {@link JSONArray} of {@link JSONObject} of
     * format:
     *     {
     *         "band": <"24_GHZ" or "5_GHZ">
     *         "channel" : <Channel Number>
     *         (Optional) "powerCapDbm" : <Power Cap in Dbm>
     *     }
     */
    private static JSONArray coexUnsafeChannelsToJson(List<CoexUnsafeChannel> unsafeChannels)
            throws JSONException {
        final JSONArray jsonCoexUnsafeChannelArray = new JSONArray();
        for (CoexUnsafeChannel unsafeChannel : unsafeChannels) {
            final String jsonBand;
            if (unsafeChannel.getBand() == WIFI_BAND_24_GHZ) {
                jsonBand = "24_GHZ";
            } else if (unsafeChannel.getBand() == WIFI_BAND_5_GHZ) {
                jsonBand = "5_GHZ";
            } else {
                continue;
            }
            final JSONObject jsonUnsafeChannel = new JSONObject();
            jsonUnsafeChannel.put("band", jsonBand);
            jsonUnsafeChannel.put("channel", unsafeChannel.getChannel());
            final int powerCapDbm = unsafeChannel.getPowerCapDbm();
            if (powerCapDbm != CoexUnsafeChannel.POWER_CAP_NONE) {
                jsonUnsafeChannel.put("powerCapDbm", powerCapDbm);
            }
            jsonCoexUnsafeChannelArray.put(jsonUnsafeChannel);
        }
        return jsonCoexUnsafeChannelArray;
    }

    /**
     * Converts a coex restriction bitmask {@link WifiManager#getCoexRestrictions()} to a JSON array
     * of possible values "WIFI_DIRECT", "SOFTAP", "WIFI_AWARE".
     */
    private static JSONArray coexRestrictionsToJson(int coexRestrictions) {
        final JSONArray jsonCoexRestrictionArray = new JSONArray();
        if ((coexRestrictions & WifiManager.COEX_RESTRICTION_WIFI_DIRECT) != 0) {
            jsonCoexRestrictionArray.put("WIFI_DIRECT");
        }
        if ((coexRestrictions & WifiManager.COEX_RESTRICTION_SOFTAP) != 0) {
            jsonCoexRestrictionArray.put("SOFTAP");
        }
        if ((coexRestrictions & WifiManager.COEX_RESTRICTION_WIFI_AWARE) != 0) {
            jsonCoexRestrictionArray.put("WIFI_AWARE");
        }
        return jsonCoexRestrictionArray;
    }

    /**
     * Returns whether the default coex algorithm is enabled or not
     *
     * @return {@code true} if the default coex algorithm is enabled, {@code false} otherwise.
     */
    @Rpc(description = "Returns whether the default coex algorithm is enabled or not")
    public boolean wifiIsDefaultCoexAlgorithmEnabled() {
        if (!SdkLevel.isAtLeastS()) {
            return false;
        }
        return mWifi.isDefaultCoexAlgorithmEnabled();
    }

    /**
     * Sets the active list of unsafe channels to avoid for coex and the restricted Wifi interfaces.
     *
     * @param unsafeChannels JSONArray representation of {@link CoexUnsafeChannel}.
     *                       See {@link #coexUnsafeChannelsToJson(List)}.
     * @param restrictions JSONArray representation of coex restrictions.
     *                     See {@link #coexRestrictionsToJson(int)}.
     * @throws JSONException
     */
    @Rpc(description = "Set the unsafe channels to avoid for coex")
    public void wifiSetCoexUnsafeChannels(
            @RpcParameter(name = "unsafeChannels") JSONArray unsafeChannels,
            @RpcParameter(name = "restrictions") JSONArray restrictions) throws JSONException {
        if (!SdkLevel.isAtLeastS()) {
            return;
        }
        mWifi.setCoexUnsafeChannels(
                genCoexUnsafeChannels(unsafeChannels), genCoexRestrictions(restrictions));
    }

    /**
     * Registers a coex callback to start receiving coex update events.
     */
    @Rpc(description = "Registers a coex callback to start receiving coex update events")
    public void wifiRegisterCoexCallback() {
        if (!SdkLevel.isAtLeastS()) {
            return;
        }
        mWifi.registerCoexCallback(
                new HandlerExecutor(mCallbackHandlerThread.getThreadHandler()), mCoexCallback);
    }

    /**
     * Unregisters the coex callback to stop receiving coex update events.
     */
    @Rpc(description = "Unregisters the coex callback to stop receiving coex update events")
    public void wifiUnregisterCoexCallback() {
        if (!SdkLevel.isAtLeastS()) {
            return;
        }
        mWifi.unregisterCoexCallback(mCoexCallback);
    }
}
