diff --git a/wifi/non-updatable/java/Android.bp b/wifi/non-updatable/java/Android.bp
new file mode 100644
index 0000000..b35b4be
--- /dev/null
+++ b/wifi/non-updatable/java/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This directory contains framework Wifi APIs that are not part of the Wifi module (i.e. not
+// updatable), and are generally only called by the Wifi module.
+
+// necessary since we only want the `path` property to only refer to these files
+filegroup {
+    name: "framework-wifi-non-updatable-sources-internal",
+    srcs: ["src/**/*.java"],
+    path: "src",
+    visibility: ["//visibility:private"],
+}
+
+filegroup {
+    name: "framework-wifi-non-updatable-sources",
+    srcs: [
+        // TODO(b/146011398) package android.net.wifi is now split amongst 2 jars: framework.jar and
+        // framework-wifi.jar. This is not a good idea, should move WifiNetworkScoreCache
+        // to a separate package.
+        ":framework-wifi-non-updatable-sources-internal",
+        ":libwificond_ipc_aidl",
+    ],
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java b/wifi/non-updatable/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
new file mode 100755
index 0000000..c5472ce
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/SoftApConfToXmlMigrationUtil.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static android.os.Environment.getDataMiscDirectory;
+
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Utility class to convert the legacy softap.conf file format to the new XML format.
+ * Note:
+ * <li>This should be modified by the OEM if they want to migrate configuration for existing
+ * devices for new softap features supported by AOSP in Android 11.
+ * For ex: client allowlist/blocklist feature was already supported by some OEM's before Android 10
+ * while AOSP only supported it in Android 11. </li>
+ * <li>Most of this class was copied over from WifiApConfigStore class in Android 10 and
+ * SoftApStoreData class in Android 11</li>
+ * @hide
+ */
+public final class SoftApConfToXmlMigrationUtil {
+    private static final String TAG = "SoftApConfToXmlMigrationUtil";
+
+    /**
+     * Directory to read the wifi config store files from under.
+     */
+    private static final String LEGACY_WIFI_STORE_DIRECTORY_NAME = "wifi";
+    /**
+     * The legacy Softap config file which contained key/value pairs.
+     */
+    private static final String LEGACY_AP_CONFIG_FILE = "softap.conf";
+
+    /**
+     * Pre-apex wifi shared folder.
+     */
+    private static File getLegacyWifiSharedDirectory() {
+        return new File(getDataMiscDirectory(), LEGACY_WIFI_STORE_DIRECTORY_NAME);
+    }
+
+    /* @hide constants copied from WifiConfiguration */
+    /**
+     * 2GHz band.
+     */
+    private static final int WIFICONFIG_AP_BAND_2GHZ = 0;
+    /**
+     * 5GHz band.
+     */
+    private static final int WIFICONFIG_AP_BAND_5GHZ = 1;
+    /**
+     * Device is allowed to choose the optimal band (2Ghz or 5Ghz) based on device capability,
+     * operating country code and current radio conditions.
+     */
+    private static final int WIFICONFIG_AP_BAND_ANY = -1;
+    /**
+     * Convert band from WifiConfiguration into SoftApConfiguration
+     *
+     * @param wifiConfigBand band encoded as WIFICONFIG_AP_BAND_xxxx
+     * @return band as encoded as SoftApConfiguration.BAND_xxx
+     */
+    @VisibleForTesting
+    public static int convertWifiConfigBandToSoftApConfigBand(int wifiConfigBand) {
+        switch (wifiConfigBand) {
+            case WIFICONFIG_AP_BAND_2GHZ:
+                return SoftApConfiguration.BAND_2GHZ;
+            case WIFICONFIG_AP_BAND_5GHZ:
+                return SoftApConfiguration.BAND_5GHZ;
+            case WIFICONFIG_AP_BAND_ANY:
+                return SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ;
+            default:
+                return SoftApConfiguration.BAND_2GHZ;
+        }
+    }
+
+    /**
+     * Load AP configuration from legacy persistent storage.
+     * Note: This is deprecated and only used for migrating data once on reboot.
+     */
+    private static SoftApConfiguration loadFromLegacyFile(InputStream fis) {
+        SoftApConfiguration config = null;
+        DataInputStream in = null;
+        try {
+            SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder();
+            in = new DataInputStream(new BufferedInputStream(fis));
+
+            int version = in.readInt();
+            if (version < 1 || version > 3) {
+                Log.e(TAG, "Bad version on hotspot configuration file");
+                return null;
+            }
+            configBuilder.setSsid(in.readUTF());
+
+            if (version >= 2) {
+                int band = in.readInt();
+                int channel = in.readInt();
+                if (channel == 0) {
+                    configBuilder.setBand(
+                            convertWifiConfigBandToSoftApConfigBand(band));
+                } else {
+                    configBuilder.setChannel(channel,
+                            convertWifiConfigBandToSoftApConfigBand(band));
+                }
+            }
+            if (version >= 3) {
+                configBuilder.setHiddenSsid(in.readBoolean());
+            }
+            int authType = in.readInt();
+            if (authType == WifiConfiguration.KeyMgmt.WPA2_PSK) {
+                configBuilder.setPassphrase(in.readUTF(),
+                        SoftApConfiguration.SECURITY_TYPE_WPA2_PSK);
+            }
+            config = configBuilder.build();
+        } catch (IOException e) {
+            Log.e(TAG, "Error reading hotspot configuration ",  e);
+            config = null;
+        } catch (IllegalArgumentException ie) {
+            Log.e(TAG, "Invalid hotspot configuration ", ie);
+            config = null;
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    Log.e(TAG, "Error closing hotspot configuration during read", e);
+                }
+            }
+        }
+        // NOTE: OEM's should add their customized parsing code here.
+        return config;
+    }
+
+    // This is the version that Android 11 released with.
+    private static final int CONFIG_STORE_DATA_VERSION = 3;
+
+    private static final String XML_TAG_DOCUMENT_HEADER = "WifiConfigStoreData";
+    private static final String XML_TAG_VERSION = "Version";
+    private static final String XML_TAG_SECTION_HEADER_SOFTAP = "SoftAp";
+    private static final String XML_TAG_SSID = "SSID";
+    private static final String XML_TAG_BSSID = "Bssid";
+    private static final String XML_TAG_CHANNEL = "Channel";
+    private static final String XML_TAG_HIDDEN_SSID = "HiddenSSID";
+    private static final String XML_TAG_SECURITY_TYPE = "SecurityType";
+    private static final String XML_TAG_AP_BAND = "ApBand";
+    private static final String XML_TAG_PASSPHRASE = "Passphrase";
+    private static final String XML_TAG_MAX_NUMBER_OF_CLIENTS = "MaxNumberOfClients";
+    private static final String XML_TAG_AUTO_SHUTDOWN_ENABLED = "AutoShutdownEnabled";
+    private static final String XML_TAG_SHUTDOWN_TIMEOUT_MILLIS = "ShutdownTimeoutMillis";
+    private static final String XML_TAG_CLIENT_CONTROL_BY_USER = "ClientControlByUser";
+    private static final String XML_TAG_BLOCKED_CLIENT_LIST = "BlockedClientList";
+    private static final String XML_TAG_ALLOWED_CLIENT_LIST = "AllowedClientList";
+    public static final String XML_TAG_CLIENT_MACADDRESS = "ClientMacAddress";
+
+    private static byte[] convertConfToXml(SoftApConfiguration softApConf) {
+        try {
+            final XmlSerializer out = new FastXmlSerializer();
+            final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+
+            // Header for the XML file.
+            out.startDocument(null, true);
+            out.startTag(null, XML_TAG_DOCUMENT_HEADER);
+            XmlUtils.writeValueXml(CONFIG_STORE_DATA_VERSION, XML_TAG_VERSION, out);
+            out.startTag(null, XML_TAG_SECTION_HEADER_SOFTAP);
+
+            // SoftAp conf
+            XmlUtils.writeValueXml(softApConf.getSsid(), XML_TAG_SSID, out);
+            if (softApConf.getBssid() != null) {
+                XmlUtils.writeValueXml(softApConf.getBssid().toString(), XML_TAG_BSSID, out);
+            }
+            XmlUtils.writeValueXml(softApConf.getBand(), XML_TAG_AP_BAND, out);
+            XmlUtils.writeValueXml(softApConf.getChannel(), XML_TAG_CHANNEL, out);
+            XmlUtils.writeValueXml(softApConf.isHiddenSsid(), XML_TAG_HIDDEN_SSID, out);
+            XmlUtils.writeValueXml(softApConf.getSecurityType(), XML_TAG_SECURITY_TYPE, out);
+            if (softApConf.getSecurityType() != SoftApConfiguration.SECURITY_TYPE_OPEN) {
+                XmlUtils.writeValueXml(softApConf.getPassphrase(), XML_TAG_PASSPHRASE, out);
+            }
+            XmlUtils.writeValueXml(softApConf.getMaxNumberOfClients(),
+                    XML_TAG_MAX_NUMBER_OF_CLIENTS, out);
+            XmlUtils.writeValueXml(softApConf.isClientControlByUserEnabled(),
+                    XML_TAG_CLIENT_CONTROL_BY_USER, out);
+            XmlUtils.writeValueXml(softApConf.isAutoShutdownEnabled(),
+                    XML_TAG_AUTO_SHUTDOWN_ENABLED, out);
+            XmlUtils.writeValueXml(softApConf.getShutdownTimeoutMillis(),
+                    XML_TAG_SHUTDOWN_TIMEOUT_MILLIS, out);
+            out.startTag(null, XML_TAG_BLOCKED_CLIENT_LIST);
+            for (MacAddress mac: softApConf.getBlockedClientList()) {
+                XmlUtils.writeValueXml(mac.toString(), XML_TAG_CLIENT_MACADDRESS, out);
+            }
+            out.endTag(null, XML_TAG_BLOCKED_CLIENT_LIST);
+            out.startTag(null, XML_TAG_ALLOWED_CLIENT_LIST);
+            for (MacAddress mac: softApConf.getAllowedClientList()) {
+                XmlUtils.writeValueXml(mac.toString(), XML_TAG_CLIENT_MACADDRESS, out);
+            }
+            out.endTag(null, XML_TAG_ALLOWED_CLIENT_LIST);
+
+            // Footer for the XML file.
+            out.endTag(null, XML_TAG_SECTION_HEADER_SOFTAP);
+            out.endTag(null, XML_TAG_DOCUMENT_HEADER);
+            out.endDocument();
+
+            return outputStream.toByteArray();
+        } catch (IOException | XmlPullParserException e) {
+            Log.e(TAG, "Failed to convert softap conf to XML", e);
+            return null;
+        }
+    }
+
+    private SoftApConfToXmlMigrationUtil() { }
+
+    /**
+     * Read the legacy /data/misc/wifi/softap.conf file format and convert to the new XML
+     * format understood by WifiConfigStore.
+     * Note: Used for unit testing.
+     */
+    @VisibleForTesting
+    @Nullable
+    public static InputStream convert(InputStream fis) {
+        SoftApConfiguration softApConf = loadFromLegacyFile(fis);
+        if (softApConf == null) return null;
+
+        byte[] xmlBytes = convertConfToXml(softApConf);
+        if (xmlBytes == null) return null;
+
+        return new ByteArrayInputStream(xmlBytes);
+    }
+
+    /**
+     * Read the legacy /data/misc/wifi/softap.conf file format and convert to the new XML
+     * format understood by WifiConfigStore.
+     */
+    @Nullable
+    public static InputStream convert() {
+        File file = new File(getLegacyWifiSharedDirectory(), LEGACY_AP_CONFIG_FILE);
+        FileInputStream fis = null;
+        try {
+            fis = new FileInputStream(file);
+        } catch (FileNotFoundException e) {
+            return null;
+        }
+        if (fis == null) return null;
+        return convert(fis);
+    }
+
+    /**
+     * Remove the legacy /data/misc/wifi/softap.conf file.
+     */
+    @Nullable
+    public static void remove() {
+        File file = new File(getLegacyWifiSharedDirectory(), LEGACY_AP_CONFIG_FILE);
+        file.delete();
+    }
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/WifiMigration.java b/wifi/non-updatable/java/src/android/net/wifi/WifiMigration.java
new file mode 100755
index 0000000..5792d27
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/WifiMigration.java
@@ -0,0 +1,558 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static android.os.Environment.getDataMiscCeDirectory;
+import static android.os.Environment.getDataMiscDirectory;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.AtomicFile;
+import android.util.SparseArray;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Class used to provide one time hooks for existing OEM devices to migrate their config store
+ * data and other settings to the wifi apex.
+ * @hide
+ */
+@SystemApi
+public final class WifiMigration {
+    /**
+     * Directory to read the wifi config store files from under.
+     */
+    private static final String LEGACY_WIFI_STORE_DIRECTORY_NAME = "wifi";
+    /**
+     * Config store file for general shared store file.
+     * AOSP Path on Android 10: /data/misc/wifi/WifiConfigStore.xml
+     */
+    public static final int STORE_FILE_SHARED_GENERAL = 0;
+    /**
+     * Config store file for softap shared store file.
+     * AOSP Path on Android 10: /data/misc/wifi/softap.conf
+     */
+    public static final int STORE_FILE_SHARED_SOFTAP = 1;
+    /**
+     * Config store file for general user store file.
+     * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStore.xml
+     */
+    public static final int STORE_FILE_USER_GENERAL = 2;
+    /**
+     * Config store file for network suggestions user store file.
+     * AOSP Path on Android 10: /data/misc_ce/<userId>/wifi/WifiConfigStoreNetworkSuggestions.xml
+     */
+    public static final int STORE_FILE_USER_NETWORK_SUGGESTIONS = 3;
+
+    /** @hide */
+    @IntDef(prefix = { "STORE_FILE_SHARED_" }, value = {
+            STORE_FILE_SHARED_GENERAL,
+            STORE_FILE_SHARED_SOFTAP,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SharedStoreFileId { }
+
+    /** @hide */
+    @IntDef(prefix = { "STORE_FILE_USER_" }, value = {
+            STORE_FILE_USER_GENERAL,
+            STORE_FILE_USER_NETWORK_SUGGESTIONS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UserStoreFileId { }
+
+    /**
+     * Mapping of Store file Id to Store file names.
+     *
+     * NOTE: This is the default path for the files on AOSP devices. If the OEM has modified
+     * the path or renamed the files, please edit this appropriately.
+     */
+    private static final SparseArray<String> STORE_ID_TO_FILE_NAME =
+            new SparseArray<String>() {{
+                put(STORE_FILE_SHARED_GENERAL, "WifiConfigStore.xml");
+                put(STORE_FILE_SHARED_SOFTAP, "WifiConfigStoreSoftAp.xml");
+                put(STORE_FILE_USER_GENERAL, "WifiConfigStore.xml");
+                put(STORE_FILE_USER_NETWORK_SUGGESTIONS, "WifiConfigStoreNetworkSuggestions.xml");
+            }};
+
+    /**
+     * Pre-apex wifi shared folder.
+     */
+    private static File getLegacyWifiSharedDirectory() {
+        return new File(getDataMiscDirectory(), LEGACY_WIFI_STORE_DIRECTORY_NAME);
+    }
+
+    /**
+     * Pre-apex wifi user folder.
+     */
+    private static File getLegacyWifiUserDirectory(int userId) {
+        return new File(getDataMiscCeDirectory(userId), LEGACY_WIFI_STORE_DIRECTORY_NAME);
+    }
+
+    /**
+     * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
+     * data integrity.
+     */
+    private static AtomicFile getSharedAtomicFile(@SharedStoreFileId int storeFileId) {
+        return new AtomicFile(new File(
+                getLegacyWifiSharedDirectory(),
+                STORE_ID_TO_FILE_NAME.get(storeFileId)));
+    }
+
+    /**
+     * Legacy files were stored as AtomicFile. So, always use AtomicFile to operate on it to ensure
+     * data integrity.
+     */
+    private static AtomicFile getUserAtomicFile(@UserStoreFileId  int storeFileId, int userId) {
+        return new AtomicFile(new File(
+                getLegacyWifiUserDirectory(userId),
+                STORE_ID_TO_FILE_NAME.get(storeFileId)));
+    }
+
+    private WifiMigration() { }
+
+    /**
+     * Load data from legacy shared wifi config store file.
+     * <p>
+     * Expected AOSP format is available in the sample files under {@code /frameworks/base/wifi/
+     * java/android/net/wifi/migration_samples}.
+     * </p>
+     * <p>
+     * Note:
+     * <li>OEMs need to change the implementation of
+     * {@link #convertAndRetrieveSharedConfigStoreFile(int)} only if their existing config store
+     * format or file locations differs from the vanilla AOSP implementation.</li>
+     * <li>The wifi apex will invoke
+     * {@link #convertAndRetrieveSharedConfigStoreFile(int)}
+     * method on every bootup, it is the responsibility of the OEM implementation to ensure that
+     * they perform the necessary in place conversion of their config store file to conform to the
+     * AOSP format. The OEM should ensure that the method should only return the
+     * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
+     * <li>Once the migration is done, the apex will invoke
+     * {@link #removeSharedConfigStoreFile(int)} to delete the store file.</li>
+     * <li>The only relevant invocation of {@link #convertAndRetrieveSharedConfigStoreFile(int)}
+     * occurs when a previously released device upgrades to the wifi apex from an OEM
+     * implementation of the wifi stack.
+     * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
+     * permissions, etc). Since the wifi service continues to run inside system_server process, this
+     * method will be called from the same context (so ideally the file should still be accessible).
+     * </li>
+     *
+     * @param storeFileId Identifier for the config store file. One of
+     * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
+     * @return Instance of {@link InputStream} for migrating data, null if no migration is
+     * necessary.
+     * @throws IllegalArgumentException on invalid storeFileId.
+     */
+    @Nullable
+    public static InputStream convertAndRetrieveSharedConfigStoreFile(
+            @SharedStoreFileId int storeFileId) {
+        if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId !=  STORE_FILE_SHARED_SOFTAP) {
+            throw new IllegalArgumentException("Invalid shared store file id");
+        }
+        try {
+            // OEMs should do conversions necessary here before returning the stream.
+            return getSharedAtomicFile(storeFileId).openRead();
+        } catch (FileNotFoundException e) {
+            // Special handling for softap.conf.
+            // Note: OEM devices upgrading from Q -> R will only have the softap.conf file.
+            // Test devices running previous R builds however may have already migrated to the
+            // XML format. So, check for that above before falling back to check for legacy file.
+            if (storeFileId == STORE_FILE_SHARED_SOFTAP) {
+                return SoftApConfToXmlMigrationUtil.convert();
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Remove the legacy shared wifi config store file.
+     *
+     * @param storeFileId Identifier for the config store file. One of
+     * {@link #STORE_FILE_SHARED_GENERAL} or {@link #STORE_FILE_SHARED_GENERAL}
+     * @throws IllegalArgumentException on invalid storeFileId.
+     */
+    public static void removeSharedConfigStoreFile(@SharedStoreFileId int storeFileId) {
+        if (storeFileId != STORE_FILE_SHARED_GENERAL && storeFileId !=  STORE_FILE_SHARED_SOFTAP) {
+            throw new IllegalArgumentException("Invalid shared store file id");
+        }
+        AtomicFile file = getSharedAtomicFile(storeFileId);
+        if (file.exists()) {
+            file.delete();
+            return;
+        }
+        // Special handling for softap.conf.
+        // Note: OEM devices upgrading from Q -> R will only have the softap.conf file.
+        // Test devices running previous R builds however may have already migrated to the
+        // XML format. So, check for that above before falling back to check for legacy file.
+        if (storeFileId == STORE_FILE_SHARED_SOFTAP) {
+            SoftApConfToXmlMigrationUtil.remove();
+        }
+    }
+
+    /**
+     * Load data from legacy user wifi config store file.
+     * <p>
+     * Expected AOSP format is available in the sample files under {@code /frameworks/base/wifi/
+     * java/android/net/wifi/migration_samples}.
+     * </p>
+     * <p>
+     * Note:
+     * <li>OEMs need to change the implementation of
+     * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} only if their existing config
+     * store format or file locations differs from the vanilla AOSP implementation.</li>
+     * <li>The wifi apex will invoke
+     * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)}
+     * method on every bootup, it is the responsibility of the OEM implementation to ensure that
+     * they perform the necessary in place conversion of their config store file to conform to the
+     * AOSP format. The OEM should ensure that the method should only return the
+     * {@link InputStream} stream for the data to be migrated only on the first bootup.</li>
+     * <li>Once the migration is done, the apex will invoke
+     * {@link #removeUserConfigStoreFile(int, UserHandle)} to delete the store file.</li>
+     * <li>The only relevant invocation of
+     * {@link #convertAndRetrieveUserConfigStoreFile(int, UserHandle)} occurs when a previously
+     * released device upgrades to the wifi apex from an OEM implementation of the wifi
+     * stack.
+     * </li>
+     * <li>Ensure that the legacy file paths are accessible to the wifi module (sepolicy rules, file
+     * permissions, etc). Since the wifi service continues to run inside system_server process, this
+     * method will be called from the same context (so ideally the file should still be accessible).
+     * </li>
+     *
+     * @param storeFileId Identifier for the config store file. One of
+     * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
+     * @param userHandle User handle.
+     * @return Instance of {@link InputStream} for migrating data, null if no migration is
+     * necessary.
+     * @throws IllegalArgumentException on invalid storeFileId or userHandle.
+     */
+    @Nullable
+    public static InputStream convertAndRetrieveUserConfigStoreFile(
+            @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
+        if (storeFileId != STORE_FILE_USER_GENERAL
+                && storeFileId !=  STORE_FILE_USER_NETWORK_SUGGESTIONS) {
+            throw new IllegalArgumentException("Invalid user store file id");
+        }
+        Objects.requireNonNull(userHandle);
+        try {
+            // OEMs should do conversions necessary here before returning the stream.
+            return getUserAtomicFile(storeFileId, userHandle.getIdentifier()).openRead();
+        } catch (FileNotFoundException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Remove the legacy user wifi config store file.
+     *
+     * @param storeFileId Identifier for the config store file. One of
+     * {@link #STORE_FILE_USER_GENERAL} or {@link #STORE_FILE_USER_NETWORK_SUGGESTIONS}
+     * @param userHandle User handle.
+     * @throws IllegalArgumentException on invalid storeFileId or userHandle.
+    */
+    public static void removeUserConfigStoreFile(
+            @UserStoreFileId int storeFileId, @NonNull UserHandle userHandle) {
+        if (storeFileId != STORE_FILE_USER_GENERAL
+                && storeFileId !=  STORE_FILE_USER_NETWORK_SUGGESTIONS) {
+            throw new IllegalArgumentException("Invalid user store file id");
+        }
+        Objects.requireNonNull(userHandle);
+        AtomicFile file = getUserAtomicFile(storeFileId, userHandle.getIdentifier());
+        if (file.exists()) {
+            file.delete();
+        }
+    }
+
+    /**
+     * Container for all the wifi settings data to migrate.
+     */
+    public static final class SettingsMigrationData implements Parcelable {
+        private final boolean mScanAlwaysAvailable;
+        private final boolean mP2pFactoryResetPending;
+        private final String mP2pDeviceName;
+        private final boolean mSoftApTimeoutEnabled;
+        private final boolean mWakeupEnabled;
+        private final boolean mScanThrottleEnabled;
+        private final boolean mVerboseLoggingEnabled;
+
+        private SettingsMigrationData(boolean scanAlwaysAvailable, boolean p2pFactoryResetPending,
+                @Nullable String p2pDeviceName, boolean softApTimeoutEnabled, boolean wakeupEnabled,
+                boolean scanThrottleEnabled, boolean verboseLoggingEnabled) {
+            mScanAlwaysAvailable = scanAlwaysAvailable;
+            mP2pFactoryResetPending = p2pFactoryResetPending;
+            mP2pDeviceName = p2pDeviceName;
+            mSoftApTimeoutEnabled = softApTimeoutEnabled;
+            mWakeupEnabled = wakeupEnabled;
+            mScanThrottleEnabled = scanThrottleEnabled;
+            mVerboseLoggingEnabled = verboseLoggingEnabled;
+        }
+
+        public static final @NonNull Parcelable.Creator<SettingsMigrationData> CREATOR =
+                new Parcelable.Creator<SettingsMigrationData>() {
+                    @Override
+                    public SettingsMigrationData createFromParcel(Parcel in) {
+                        boolean scanAlwaysAvailable = in.readBoolean();
+                        boolean p2pFactoryResetPending = in.readBoolean();
+                        String p2pDeviceName = in.readString();
+                        boolean softApTimeoutEnabled = in.readBoolean();
+                        boolean wakeupEnabled = in.readBoolean();
+                        boolean scanThrottleEnabled = in.readBoolean();
+                        boolean verboseLoggingEnabled = in.readBoolean();
+                        return new SettingsMigrationData(
+                                scanAlwaysAvailable, p2pFactoryResetPending,
+                                p2pDeviceName, softApTimeoutEnabled, wakeupEnabled,
+                                scanThrottleEnabled, verboseLoggingEnabled);
+                    }
+
+                    @Override
+                    public SettingsMigrationData[] newArray(int size) {
+                        return new SettingsMigrationData[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeBoolean(mScanAlwaysAvailable);
+            dest.writeBoolean(mP2pFactoryResetPending);
+            dest.writeString(mP2pDeviceName);
+            dest.writeBoolean(mSoftApTimeoutEnabled);
+            dest.writeBoolean(mWakeupEnabled);
+            dest.writeBoolean(mScanThrottleEnabled);
+            dest.writeBoolean(mVerboseLoggingEnabled);
+        }
+
+        /**
+         * @return True if scans are allowed even when wifi is toggled off, false otherwise.
+         */
+        public boolean isScanAlwaysAvailable() {
+            return mScanAlwaysAvailable;
+        }
+
+        /**
+         * @return indicate whether factory reset request is pending.
+         */
+        public boolean isP2pFactoryResetPending() {
+            return mP2pFactoryResetPending;
+        }
+
+        /**
+         * @return the Wi-Fi peer-to-peer device name
+         */
+        public @Nullable String getP2pDeviceName() {
+            return mP2pDeviceName;
+        }
+
+        /**
+         * @return Whether soft AP will shut down after a timeout period when no devices are
+         * connected.
+         */
+        public boolean isSoftApTimeoutEnabled() {
+            return mSoftApTimeoutEnabled;
+        }
+
+        /**
+         * @return whether Wi-Fi Wakeup feature is enabled.
+         */
+        public boolean isWakeUpEnabled() {
+            return mWakeupEnabled;
+        }
+
+        /**
+         * @return Whether wifi scan throttle is enabled or not.
+         */
+        public boolean isScanThrottleEnabled() {
+            return mScanThrottleEnabled;
+        }
+
+        /**
+         * @return Whether to enable verbose logging in Wi-Fi.
+         */
+        public boolean isVerboseLoggingEnabled() {
+            return mVerboseLoggingEnabled;
+        }
+
+        /**
+         * Builder to create instance of {@link SettingsMigrationData}.
+         */
+        public static final class Builder {
+            private boolean mScanAlwaysAvailable;
+            private boolean mP2pFactoryResetPending;
+            private String mP2pDeviceName;
+            private boolean mSoftApTimeoutEnabled;
+            private boolean mWakeupEnabled;
+            private boolean mScanThrottleEnabled;
+            private boolean mVerboseLoggingEnabled;
+
+            public Builder() {
+            }
+
+            /**
+             * Setting to allow scans even when wifi is toggled off.
+             *
+             * @param available true if available, false otherwise.
+             * @return Instance of {@link Builder} to enable chaining of the builder method.
+             */
+            public @NonNull Builder setScanAlwaysAvailable(boolean available) {
+                mScanAlwaysAvailable = available;
+                return this;
+            }
+
+            /**
+             * Indicate whether factory reset request is pending.
+             *
+             * @param pending true if pending, false otherwise.
+             * @return Instance of {@link Builder} to enable chaining of the builder method.
+             */
+            public @NonNull Builder setP2pFactoryResetPending(boolean pending) {
+                mP2pFactoryResetPending = pending;
+                return this;
+            }
+
+            /**
+             * The Wi-Fi peer-to-peer device name
+             *
+             * @param name Name if set, null otherwise.
+             * @return Instance of {@link Builder} to enable chaining of the builder method.
+             */
+            public @NonNull Builder setP2pDeviceName(@Nullable String name) {
+                mP2pDeviceName = name;
+                return this;
+            }
+
+            /**
+             * Whether soft AP will shut down after a timeout period when no devices are connected.
+             *
+             * @param enabled true if enabled, false otherwise.
+             * @return Instance of {@link Builder} to enable chaining of the builder method.
+             */
+            public @NonNull Builder setSoftApTimeoutEnabled(boolean enabled) {
+                mSoftApTimeoutEnabled = enabled;
+                return this;
+            }
+
+            /**
+             * Value to specify if Wi-Fi Wakeup feature is enabled.
+             *
+             * @param enabled true if enabled, false otherwise.
+             * @return Instance of {@link Builder} to enable chaining of the builder method.
+             */
+            public @NonNull Builder setWakeUpEnabled(boolean enabled) {
+                mWakeupEnabled = enabled;
+                return this;
+            }
+
+            /**
+             * Whether wifi scan throttle is enabled or not.
+             *
+             * @param enabled true if enabled, false otherwise.
+             * @return Instance of {@link Builder} to enable chaining of the builder method.
+             */
+            public @NonNull Builder setScanThrottleEnabled(boolean enabled) {
+                mScanThrottleEnabled = enabled;
+                return this;
+            }
+
+            /**
+             * Setting to enable verbose logging in Wi-Fi.
+             *
+             * @param enabled true if enabled, false otherwise.
+             * @return Instance of {@link Builder} to enable chaining of the builder method.
+             */
+            public @NonNull Builder setVerboseLoggingEnabled(boolean enabled) {
+                mVerboseLoggingEnabled = enabled;
+                return this;
+            }
+
+            /**
+             * Build an instance of {@link SettingsMigrationData}.
+             *
+             * @return Instance of {@link SettingsMigrationData}.
+             */
+            public @NonNull SettingsMigrationData build() {
+                return new SettingsMigrationData(mScanAlwaysAvailable, mP2pFactoryResetPending,
+                        mP2pDeviceName, mSoftApTimeoutEnabled, mWakeupEnabled, mScanThrottleEnabled,
+                        mVerboseLoggingEnabled);
+            }
+        }
+    }
+
+    /**
+     * Load data from Settings.Global values.
+     *
+     * <p>
+     * Note:
+     * <li> This is method is invoked once on the first bootup. OEM can safely delete these settings
+     * once the migration is complete. The first & only relevant invocation of
+     * {@link #loadFromSettings(Context)} ()} occurs when a previously released
+     * device upgrades to the wifi apex from an OEM implementation of the wifi stack.
+     * </li>
+     *
+     * @param context Context to use for loading the settings provider.
+     * @return Instance of {@link SettingsMigrationData} for migrating data.
+     */
+    @NonNull
+    public static SettingsMigrationData loadFromSettings(@NonNull Context context) {
+        if (Settings.Global.getInt(
+                context.getContentResolver(), Settings.Global.WIFI_MIGRATION_COMPLETED, 0) == 1) {
+            // migration already complete, ignore.
+            return null;
+        }
+        SettingsMigrationData data = new SettingsMigrationData.Builder()
+                .setScanAlwaysAvailable(
+                        Settings.Global.getInt(context.getContentResolver(),
+                                Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1)
+                .setP2pFactoryResetPending(
+                        Settings.Global.getInt(context.getContentResolver(),
+                                Settings.Global.WIFI_P2P_PENDING_FACTORY_RESET, 0) == 1)
+                .setP2pDeviceName(
+                        Settings.Global.getString(context.getContentResolver(),
+                                Settings.Global.WIFI_P2P_DEVICE_NAME))
+                .setSoftApTimeoutEnabled(
+                        Settings.Global.getInt(context.getContentResolver(),
+                                Settings.Global.SOFT_AP_TIMEOUT_ENABLED, 1) == 1)
+                .setWakeUpEnabled(
+                        Settings.Global.getInt(context.getContentResolver(),
+                                Settings.Global.WIFI_WAKEUP_ENABLED, 0) == 1)
+                .setScanThrottleEnabled(
+                        Settings.Global.getInt(context.getContentResolver(),
+                                Settings.Global.WIFI_SCAN_THROTTLE_ENABLED, 1) == 1)
+                .setVerboseLoggingEnabled(
+                        Settings.Global.getInt(context.getContentResolver(),
+                                Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0) == 1)
+                .build();
+        Settings.Global.putInt(
+                context.getContentResolver(), Settings.Global.WIFI_MIGRATION_COMPLETED, 1);
+        return data;
+
+    }
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/WifiNetworkScoreCache.java b/wifi/non-updatable/java/src/android/net/wifi/WifiNetworkScoreCache.java
new file mode 100755
index 0000000..3903658
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/WifiNetworkScoreCache.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.Manifest.permission;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.net.INetworkScoreCache;
+import android.net.NetworkKey;
+import android.net.ScoredNetwork;
+import android.os.Handler;
+import android.os.Process;
+import android.util.Log;
+import android.util.LruCache;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * {@link INetworkScoreCache} implementation for Wifi Networks.
+ *
+ * TODO: This should not be part of wifi mainline module.
+ * @hide
+ */
+public class WifiNetworkScoreCache extends INetworkScoreCache.Stub {
+    private static final String TAG = "WifiNetworkScoreCache";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+
+    // A Network scorer returns a score in the range [-128, +127]
+    // We treat the lowest possible score as though there were no score, effectively allowing the
+    // scorer to provide an RSSI threshold below which a network should not be used.
+    public static final int INVALID_NETWORK_SCORE = Byte.MIN_VALUE;
+
+    /** Default number entries to be stored in the {@link LruCache}. */
+    private static final int DEFAULT_MAX_CACHE_SIZE = 100;
+
+    // See {@link #CacheListener}.
+    @Nullable
+    @GuardedBy("mLock")
+    private CacheListener mListener;
+
+    private final Context mContext;
+    private final Object mLock = new Object();
+
+    // The key is of the form "<ssid>"<bssid>
+    // TODO: What about SSIDs that can't be encoded as UTF-8?
+    @GuardedBy("mLock")
+    private final LruCache<String, ScoredNetwork> mCache;
+
+    public WifiNetworkScoreCache(Context context) {
+        this(context, null /* listener */);
+    }
+
+    /**
+     * Instantiates a WifiNetworkScoreCache.
+     *
+     * @param context Application context
+     * @param listener CacheListener for cache updates
+     */
+    public WifiNetworkScoreCache(Context context, @Nullable CacheListener listener) {
+        this(context, listener, DEFAULT_MAX_CACHE_SIZE);
+    }
+
+    public WifiNetworkScoreCache(
+            Context context, @Nullable CacheListener listener, int maxCacheSize) {
+        mContext = context.getApplicationContext();
+        mListener = listener;
+        mCache = new LruCache<>(maxCacheSize);
+    }
+
+    @Override public final void updateScores(List<ScoredNetwork> networks) {
+        if (networks == null || networks.isEmpty()) {
+            return;
+        }
+        if (DBG) {
+            Log.d(TAG, "updateScores list size=" + networks.size());
+        }
+
+        boolean changed = false;
+
+        synchronized (mLock) {
+            for (ScoredNetwork network : networks) {
+                String networkKey = buildNetworkKey(network);
+                if (networkKey == null) {
+                    if (DBG) {
+                        Log.d(TAG, "Failed to build network key for ScoredNetwork" + network);
+                    }
+                    continue;
+                }
+                mCache.put(networkKey, network);
+                changed = true;
+            }
+
+            if (mListener != null && changed) {
+                mListener.post(networks);
+            }
+        }
+    }
+
+    @Override public final void clearScores() {
+        synchronized (mLock) {
+            mCache.evictAll();
+        }
+    }
+
+    /**
+     * Returns whether there is any score info for the given ScanResult.
+     *
+     * This includes null-score info, so it should only be used when determining whether to request
+     * scores from the network scorer.
+     */
+    public boolean isScoredNetwork(ScanResult result) {
+        return getScoredNetwork(result) != null;
+    }
+
+    /**
+     * Returns whether there is a non-null score curve for the given ScanResult.
+     *
+     * A null score curve has special meaning - we should never connect to an ephemeral network if
+     * the score curve is null.
+     */
+    public boolean hasScoreCurve(ScanResult result) {
+        ScoredNetwork network = getScoredNetwork(result);
+        return network != null && network.rssiCurve != null;
+    }
+
+    public int getNetworkScore(ScanResult result) {
+        int score = INVALID_NETWORK_SCORE;
+
+        ScoredNetwork network = getScoredNetwork(result);
+        if (network != null && network.rssiCurve != null) {
+            score = network.rssiCurve.lookupScore(result.level);
+            if (DBG) {
+                Log.d(TAG, "getNetworkScore found scored network " + network.networkKey
+                        + " score " + Integer.toString(score)
+                        + " RSSI " + result.level);
+            }
+        }
+        return score;
+    }
+
+    /**
+     * Returns the ScoredNetwork metered hint for a given ScanResult.
+     *
+     * If there is no ScoredNetwork associated with the ScanResult then false will be returned.
+     */
+    public boolean getMeteredHint(ScanResult result) {
+        ScoredNetwork network = getScoredNetwork(result);
+        return network != null && network.meteredHint;
+    }
+
+    public int getNetworkScore(ScanResult result, boolean isActiveNetwork) {
+        int score = INVALID_NETWORK_SCORE;
+
+        ScoredNetwork network = getScoredNetwork(result);
+        if (network != null && network.rssiCurve != null) {
+            score = network.rssiCurve.lookupScore(result.level, isActiveNetwork);
+            if (DBG) {
+                Log.d(TAG, "getNetworkScore found scored network " + network.networkKey
+                        + " score " + Integer.toString(score)
+                        + " RSSI " + result.level
+                        + " isActiveNetwork " + isActiveNetwork);
+            }
+        }
+        return score;
+    }
+
+    @Nullable
+    public ScoredNetwork getScoredNetwork(ScanResult result) {
+        String key = buildNetworkKey(result);
+        if (key == null) return null;
+
+        synchronized (mLock) {
+            ScoredNetwork network = mCache.get(key);
+            return network;
+        }
+    }
+
+    /** Returns the ScoredNetwork for the given key. */
+    @Nullable
+    public ScoredNetwork getScoredNetwork(NetworkKey networkKey) {
+        String key = buildNetworkKey(networkKey);
+        if (key == null) {
+            if (DBG) {
+                Log.d(TAG, "Could not build key string for Network Key: " + networkKey);
+            }
+            return null;
+        }
+        synchronized (mLock) {
+            return mCache.get(key);
+        }
+    }
+
+    private String buildNetworkKey(ScoredNetwork network) {
+        if (network == null) {
+            return null;
+        }
+        return buildNetworkKey(network.networkKey);
+    }
+
+    private String buildNetworkKey(NetworkKey networkKey) {
+        if (networkKey == null) {
+            return null;
+        }
+        if (networkKey.wifiKey == null) return null;
+        if (networkKey.type == NetworkKey.TYPE_WIFI) {
+            String key = networkKey.wifiKey.ssid;
+            if (key == null) return null;
+            if (networkKey.wifiKey.bssid != null) {
+                key = key + networkKey.wifiKey.bssid;
+            }
+            return key;
+        }
+        return null;
+    }
+
+    private String buildNetworkKey(ScanResult result) {
+        if (result == null || result.SSID == null) {
+            return null;
+        }
+        StringBuilder key = new StringBuilder("\"");
+        key.append(result.SSID);
+        key.append("\"");
+        if (result.BSSID != null) {
+            key.append(result.BSSID);
+        }
+        return key.toString();
+    }
+
+    @Override protected final void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
+        String header = String.format("WifiNetworkScoreCache (%s/%d)",
+                mContext.getPackageName(), Process.myUid());
+        writer.println(header);
+        writer.println("  All score curves:");
+        synchronized (mLock) {
+            for (ScoredNetwork score : mCache.snapshot().values()) {
+                writer.println("    " + score);
+            }
+            writer.println("  Network scores for latest ScanResults:");
+            WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+            for (ScanResult scanResult : wifiManager.getScanResults()) {
+                writer.println(
+                        "    " + buildNetworkKey(scanResult) + ": " + getNetworkScore(scanResult));
+            }
+        }
+    }
+
+    /** Registers a CacheListener instance, replacing the previous listener if it existed. */
+    public void registerListener(CacheListener listener) {
+        synchronized (mLock) {
+            mListener = listener;
+        }
+    }
+
+    /** Removes the registered CacheListener. */
+    public void unregisterListener() {
+        synchronized (mLock) {
+            mListener = null;
+        }
+    }
+
+    /** Listener for updates to the cache inside WifiNetworkScoreCache. */
+    public abstract static class CacheListener {
+        private Handler mHandler;
+
+        /**
+         * Constructor for CacheListener.
+         *
+         * @param handler the Handler on which to invoke the {@link #networkCacheUpdated} method.
+         *          This cannot be null.
+         */
+        public CacheListener(@NonNull Handler handler) {
+            Objects.requireNonNull(handler);
+            mHandler = handler;
+        }
+
+        /** Invokes the {@link #networkCacheUpdated(List<ScoredNetwork>)} method on the handler. */
+        void post(List<ScoredNetwork> updatedNetworks) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    networkCacheUpdated(updatedNetworks);
+                }
+            });
+        }
+
+        /**
+         * Invoked whenever the cache is updated.
+         *
+         * <p>Clearing the cache does not invoke this method.
+         *
+         * @param updatedNetworks the networks that were updated
+         */
+        public abstract void networkCacheUpdated(List<ScoredNetwork> updatedNetworks);
+    }
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/ChannelSettings.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/ChannelSettings.java
new file mode 100644
index 0000000..4c14fd4
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/ChannelSettings.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.Objects;
+
+/**
+ * ChannelSettings for wificond
+ *
+ * @hide
+ */
+public class ChannelSettings implements Parcelable {
+    private static final String TAG = "ChannelSettings";
+
+    public int frequency;
+
+    /** public constructor */
+    public ChannelSettings() { }
+
+    /** override comparator */
+    @Override
+    public boolean equals(Object rhs) {
+        if (this == rhs) return true;
+        if (!(rhs instanceof ChannelSettings)) {
+            return false;
+        }
+        ChannelSettings channel = (ChannelSettings) rhs;
+        if (channel == null) {
+            return false;
+        }
+        return frequency == channel.frequency;
+    }
+
+    /** override hash code */
+    @Override
+    public int hashCode() {
+        return Objects.hash(frequency);
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * implement Parcelable interface
+     * |flags| is ignored.
+     **/
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(frequency);
+    }
+
+    /** implement Parcelable interface */
+    public static final Parcelable.Creator<ChannelSettings> CREATOR =
+            new Parcelable.Creator<ChannelSettings>() {
+        /**
+         * Caller is responsible for providing a valid parcel.
+         */
+        @Override
+        public ChannelSettings createFromParcel(Parcel in) {
+            ChannelSettings result = new ChannelSettings();
+            result.frequency = in.readInt();
+            if (in.dataAvail() != 0) {
+                Log.e(TAG, "Found trailing data after parcel parsing.");
+            }
+
+            return result;
+        }
+
+        @Override
+        public ChannelSettings[] newArray(int size) {
+            return new ChannelSettings[size];
+        }
+    };
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
new file mode 100644
index 0000000..bb0cc97
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/DeviceWiphyCapabilities.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiAnnotations.ChannelWidth;
+import android.net.wifi.WifiAnnotations.WifiStandard;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.Objects;
+
+/**
+ * DeviceWiphyCapabilities for wificond
+ *
+ * Contains the WiFi physical layer attributes and capabilities of the device.
+ * It is used to collect these attributes from the device driver via wificond.
+ *
+ * @hide
+ */
+@SystemApi
+public final class DeviceWiphyCapabilities implements Parcelable {
+    private static final String TAG = "DeviceWiphyCapabilities";
+
+    private boolean m80211nSupported;
+    private boolean m80211acSupported;
+    private boolean m80211axSupported;
+    private boolean mChannelWidth160MhzSupported;
+    private boolean mChannelWidth80p80MhzSupported;
+    private int mMaxNumberTxSpatialStreams;
+    private int mMaxNumberRxSpatialStreams;
+
+
+    /** public constructor */
+    public DeviceWiphyCapabilities() {
+        m80211nSupported = false;
+        m80211acSupported = false;
+        m80211axSupported = false;
+        mChannelWidth160MhzSupported = false;
+        mChannelWidth80p80MhzSupported = false;
+        mMaxNumberTxSpatialStreams = 1;
+        mMaxNumberRxSpatialStreams = 1;
+    }
+
+    /**
+     * Get the IEEE 802.11 standard support
+     *
+     * @param standard the IEEE 802.11 standard to check on its support.
+     *        valid values from {@link ScanResult}'s {@code WIFI_STANDARD_}
+     * @return {@code true} if supported, {@code false} otherwise.
+     */
+    public boolean isWifiStandardSupported(@WifiStandard int standard) {
+        switch (standard) {
+            case ScanResult.WIFI_STANDARD_LEGACY:
+                return true;
+            case ScanResult.WIFI_STANDARD_11N:
+                return m80211nSupported;
+            case ScanResult.WIFI_STANDARD_11AC:
+                return m80211acSupported;
+            case ScanResult.WIFI_STANDARD_11AX:
+                return m80211axSupported;
+            default:
+                Log.e(TAG, "isWifiStandardSupported called with invalid standard: " + standard);
+                return false;
+        }
+    }
+
+    /**
+     * Set the IEEE 802.11 standard support
+     *
+     * @param standard the IEEE 802.11 standard to set its support.
+     *        valid values from {@link ScanResult}'s {@code WIFI_STANDARD_}
+     * @param support {@code true} if supported, {@code false} otherwise.
+     */
+    public void setWifiStandardSupport(@WifiStandard int standard, boolean support) {
+        switch (standard) {
+            case ScanResult.WIFI_STANDARD_11N:
+                m80211nSupported = support;
+                break;
+            case ScanResult.WIFI_STANDARD_11AC:
+                m80211acSupported = support;
+                break;
+            case ScanResult.WIFI_STANDARD_11AX:
+                m80211axSupported = support;
+                break;
+            default:
+                Log.e(TAG, "setWifiStandardSupport called with invalid standard: " + standard);
+        }
+    }
+
+    /**
+     * Get the support for channel bandwidth
+     *
+     * @param chWidth valid values from {@link ScanResult}'s {@code CHANNEL_WIDTH_}
+     *
+     * @return {@code true} if supported, {@code false} otherwise.
+     */
+    public boolean isChannelWidthSupported(@ChannelWidth int chWidth) {
+        switch (chWidth) {
+            case ScanResult.CHANNEL_WIDTH_20MHZ:
+                return true;
+            case ScanResult.CHANNEL_WIDTH_40MHZ:
+                return (m80211nSupported || m80211acSupported || m80211axSupported);
+            case ScanResult.CHANNEL_WIDTH_80MHZ:
+                return (m80211acSupported || m80211axSupported);
+            case ScanResult.CHANNEL_WIDTH_160MHZ:
+                return mChannelWidth160MhzSupported;
+            case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
+                return mChannelWidth80p80MhzSupported;
+            default:
+                Log.e(TAG, "isChannelWidthSupported called with invalid channel width: " + chWidth);
+        }
+        return false;
+    }
+
+    /**
+     * Set support for channel bandwidth
+     *
+     * @param chWidth valid values are {@link ScanResult#CHANNEL_WIDTH_160MHZ} and
+     *        {@link ScanResult#CHANNEL_WIDTH_80MHZ_PLUS_MHZ}
+     * @param support {@code true} if supported, {@code false} otherwise.
+     *
+     * @hide
+     */
+    public void setChannelWidthSupported(@ChannelWidth int chWidth, boolean support) {
+        switch (chWidth) {
+            case ScanResult.CHANNEL_WIDTH_160MHZ:
+                mChannelWidth160MhzSupported = support;
+                break;
+            case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ:
+                mChannelWidth80p80MhzSupported = support;
+                break;
+            default:
+                Log.e(TAG, "setChannelWidthSupported called with Invalid channel width: "
+                        + chWidth);
+        }
+    }
+
+    /**
+     * Get maximum number of transmit spatial streams
+     *
+     * @return number of spatial streams
+     */
+    public int getMaxNumberTxSpatialStreams() {
+        return mMaxNumberTxSpatialStreams;
+    }
+
+    /**
+     * Set maximum number of transmit spatial streams
+     *
+     * @param streams number of spatial streams
+     *
+     * @hide
+     */
+    public void setMaxNumberTxSpatialStreams(int streams) {
+        mMaxNumberTxSpatialStreams = streams;
+    }
+
+    /**
+     * Get maximum number of receive spatial streams
+     *
+     * @return number of streams
+     */
+    public int getMaxNumberRxSpatialStreams() {
+        return mMaxNumberRxSpatialStreams;
+    }
+
+    /**
+     * Set maximum number of receive spatial streams
+     *
+     * @param streams number of streams
+     *
+     * @hide
+     */
+    public void setMaxNumberRxSpatialStreams(int streams) {
+        mMaxNumberRxSpatialStreams = streams;
+    }
+
+    /** override comparator */
+    @Override
+    public boolean equals(Object rhs) {
+        if (this == rhs) return true;
+        if (!(rhs instanceof DeviceWiphyCapabilities)) {
+            return false;
+        }
+        DeviceWiphyCapabilities capa = (DeviceWiphyCapabilities) rhs;
+
+        return m80211nSupported == capa.m80211nSupported
+                && m80211acSupported == capa.m80211acSupported
+                && m80211axSupported == capa.m80211axSupported
+                && mChannelWidth160MhzSupported == capa.mChannelWidth160MhzSupported
+                && mChannelWidth80p80MhzSupported == capa.mChannelWidth80p80MhzSupported
+                && mMaxNumberTxSpatialStreams == capa.mMaxNumberTxSpatialStreams
+                && mMaxNumberRxSpatialStreams == capa.mMaxNumberRxSpatialStreams;
+    }
+
+    /** override hash code */
+    @Override
+    public int hashCode() {
+        return Objects.hash(m80211nSupported, m80211acSupported, m80211axSupported,
+                mChannelWidth160MhzSupported, mChannelWidth80p80MhzSupported,
+                mMaxNumberTxSpatialStreams, mMaxNumberRxSpatialStreams);
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * implement Parcelable interface
+     * |flags| is ignored.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeBoolean(m80211nSupported);
+        out.writeBoolean(m80211acSupported);
+        out.writeBoolean(m80211axSupported);
+        out.writeBoolean(mChannelWidth160MhzSupported);
+        out.writeBoolean(mChannelWidth80p80MhzSupported);
+        out.writeInt(mMaxNumberTxSpatialStreams);
+        out.writeInt(mMaxNumberRxSpatialStreams);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("m80211nSupported:").append(m80211nSupported ? "Yes" : "No");
+        sb.append("m80211acSupported:").append(m80211acSupported ? "Yes" : "No");
+        sb.append("m80211axSupported:").append(m80211axSupported ? "Yes" : "No");
+        sb.append("mChannelWidth160MhzSupported: ")
+                .append(mChannelWidth160MhzSupported ? "Yes" : "No");
+        sb.append("mChannelWidth80p80MhzSupported: ")
+                .append(mChannelWidth80p80MhzSupported ? "Yes" : "No");
+        sb.append("mMaxNumberTxSpatialStreams: ").append(mMaxNumberTxSpatialStreams);
+        sb.append("mMaxNumberRxSpatialStreams: ").append(mMaxNumberRxSpatialStreams);
+
+        return sb.toString();
+    }
+
+    /** implement Parcelable interface */
+    public static final @NonNull Parcelable.Creator<DeviceWiphyCapabilities> CREATOR =
+            new Parcelable.Creator<DeviceWiphyCapabilities>() {
+        /**
+         * Caller is responsible for providing a valid parcel.
+         */
+        @Override
+        public DeviceWiphyCapabilities createFromParcel(Parcel in) {
+            DeviceWiphyCapabilities capabilities = new DeviceWiphyCapabilities();
+            capabilities.m80211nSupported = in.readBoolean();
+            capabilities.m80211acSupported = in.readBoolean();
+            capabilities.m80211axSupported = in.readBoolean();
+            capabilities.mChannelWidth160MhzSupported = in.readBoolean();
+            capabilities.mChannelWidth80p80MhzSupported = in.readBoolean();
+            capabilities.mMaxNumberTxSpatialStreams = in.readInt();
+            capabilities.mMaxNumberRxSpatialStreams = in.readInt();
+            return capabilities;
+        }
+
+        @Override
+        public DeviceWiphyCapabilities[] newArray(int size) {
+            return new DeviceWiphyCapabilities[size];
+        }
+    };
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/HiddenNetwork.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/HiddenNetwork.java
new file mode 100644
index 0000000..b1475b2
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/HiddenNetwork.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+/**
+ * HiddenNetwork for wificond
+ *
+ * @hide
+ */
+public class HiddenNetwork implements Parcelable {
+    private static final String TAG = "HiddenNetwork";
+
+    public byte[] ssid;
+
+    /** public constructor */
+    public HiddenNetwork() { }
+
+    /** override comparator */
+    @Override
+    public boolean equals(Object rhs) {
+        if (this == rhs) return true;
+        if (!(rhs instanceof HiddenNetwork)) {
+            return false;
+        }
+        HiddenNetwork network = (HiddenNetwork) rhs;
+        return Arrays.equals(ssid, network.ssid);
+    }
+
+    /** override hash code */
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(ssid);
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * implement Parcelable interface
+     * |flags| is ignored.
+     */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeByteArray(ssid);
+    }
+
+    /** implement Parcelable interface */
+    public static final Parcelable.Creator<HiddenNetwork> CREATOR =
+            new Parcelable.Creator<HiddenNetwork>() {
+        /**
+         * Caller is responsible for providing a valid parcel.
+         */
+        @Override
+        public HiddenNetwork createFromParcel(Parcel in) {
+            HiddenNetwork result = new HiddenNetwork();
+            result.ssid = in.createByteArray();
+            return result;
+        }
+
+        @Override
+        public HiddenNetwork[] newArray(int size) {
+            return new HiddenNetwork[size];
+        }
+    };
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeScanResult.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeScanResult.java
new file mode 100644
index 0000000..a8e9999
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeScanResult.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.MacAddress;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Raw scan result data from the wificond daemon.
+ *
+ * @hide
+ */
+@SystemApi
+public final class NativeScanResult implements Parcelable {
+    private static final String TAG = "NativeScanResult";
+
+    /** @hide */
+    @VisibleForTesting
+    public byte[] ssid;
+    /** @hide */
+    @VisibleForTesting
+    public byte[] bssid;
+    /** @hide */
+    @VisibleForTesting
+    public byte[] infoElement;
+    /** @hide */
+    @VisibleForTesting
+    public int frequency;
+    /** @hide */
+    @VisibleForTesting
+    public int signalMbm;
+    /** @hide */
+    @VisibleForTesting
+    public long tsf;
+    /** @hide */
+    @VisibleForTesting
+    @BssCapabilityBits public int capability;
+    /** @hide */
+    @VisibleForTesting
+    public boolean associated;
+    /** @hide */
+    @VisibleForTesting
+    public List<RadioChainInfo> radioChainInfos;
+
+    /**
+     * Returns the SSID raw byte array of the AP represented by this scan result.
+     *
+     * @return A byte array.
+     */
+    @NonNull public byte[] getSsid() {
+        return ssid;
+    }
+
+    /**
+     * Returns the MAC address (BSSID) of the AP represented by this scan result.
+     *
+     * @return a MacAddress or null on error.
+     */
+    @Nullable public MacAddress getBssid() {
+        try {
+            return MacAddress.fromBytes(bssid);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Illegal argument " + Arrays.toString(bssid), e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns the raw bytes of the information element advertised by the AP represented by this
+     * scan result.
+     *
+     * @return A byte array, possibly null or containing an invalid TLV configuration.
+     */
+    @NonNull public byte[] getInformationElements() {
+        return infoElement;
+    }
+
+    /**
+     * Returns the frequency (in MHz) on which the AP represented by this scan result was observed.
+     *
+     * @return The frequency in MHz.
+     */
+    public int getFrequencyMhz() {
+        return frequency;
+    }
+
+    /**
+     * Return the signal strength of probe response/beacon in (100 * dBm).
+     *
+     * @return Signal strenght in (100 * dBm).
+     */
+    public int getSignalMbm() {
+        return signalMbm;
+    }
+
+    /**
+     * Return the TSF (Timing Synchronization Function) of the received probe response/beacon.
+     * @return
+     */
+    public long getTsf() {
+        return tsf;
+    }
+
+    /**
+     * Return a boolean indicating whether or not we're associated to the AP represented by this
+     * scan result.
+     *
+     * @return A boolean indicating association.
+     */
+    public boolean isAssociated() {
+        return associated;
+    }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = {"BSS_CAPABILITY_"},
+            value = {BSS_CAPABILITY_ESS,
+                    BSS_CAPABILITY_IBSS,
+                    BSS_CAPABILITY_CF_POLLABLE,
+                    BSS_CAPABILITY_CF_POLL_REQUEST,
+                    BSS_CAPABILITY_PRIVACY,
+                    BSS_CAPABILITY_SHORT_PREAMBLE,
+                    BSS_CAPABILITY_PBCC,
+                    BSS_CAPABILITY_CHANNEL_AGILITY,
+                    BSS_CAPABILITY_SPECTRUM_MANAGEMENT,
+                    BSS_CAPABILITY_QOS,
+                    BSS_CAPABILITY_SHORT_SLOT_TIME,
+                    BSS_CAPABILITY_APSD,
+                    BSS_CAPABILITY_RADIO_MANAGEMENT,
+                    BSS_CAPABILITY_DSSS_OFDM,
+                    BSS_CAPABILITY_DELAYED_BLOCK_ACK,
+                    BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK
+            })
+    public @interface BssCapabilityBits { }
+
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): ESS.
+     */
+    public static final int BSS_CAPABILITY_ESS = 0x1 << 0;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): IBSS.
+     */
+    public static final int BSS_CAPABILITY_IBSS = 0x1 << 1;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): CF Pollable.
+     */
+    public static final int BSS_CAPABILITY_CF_POLLABLE = 0x1 << 2;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): CF-Poll Request.
+     */
+    public static final int BSS_CAPABILITY_CF_POLL_REQUEST = 0x1 << 3;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Privacy.
+     */
+    public static final int BSS_CAPABILITY_PRIVACY = 0x1 << 4;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Short Preamble.
+     */
+    public static final int BSS_CAPABILITY_SHORT_PREAMBLE = 0x1 << 5;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): PBCC.
+     */
+    public static final int BSS_CAPABILITY_PBCC = 0x1 << 6;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Channel Agility.
+     */
+    public static final int BSS_CAPABILITY_CHANNEL_AGILITY = 0x1 << 7;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Spectrum Management.
+     */
+    public static final int BSS_CAPABILITY_SPECTRUM_MANAGEMENT = 0x1 << 8;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): QoS.
+     */
+    public static final int BSS_CAPABILITY_QOS = 0x1 << 9;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Short Slot Time.
+     */
+    public static final int BSS_CAPABILITY_SHORT_SLOT_TIME = 0x1 << 10;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): APSD.
+     */
+    public static final int BSS_CAPABILITY_APSD = 0x1 << 11;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Radio Management.
+     */
+    public static final int BSS_CAPABILITY_RADIO_MANAGEMENT = 0x1 << 12;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): DSSS-OFDM.
+     */
+    public static final int BSS_CAPABILITY_DSSS_OFDM = 0x1 << 13;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Delayed Block Ack.
+     */
+    public static final int BSS_CAPABILITY_DELAYED_BLOCK_ACK = 0x1 << 14;
+    /**
+     * BSS capability bit (see IEEE Std 802.11: 9.4.1.4): Immediate Block Ack.
+     */
+    public static final int BSS_CAPABILITY_IMMEDIATE_BLOCK_ACK = 0x1 << 15;
+
+    /**
+     *  Returns the capabilities of the AP repseresented by this scan result as advertised in the
+     *  received probe response or beacon.
+     *
+     *  This is a bit mask describing the capabilities of a BSS. See IEEE Std 802.11: 9.4.1.4: one
+     *  of the {@code BSS_CAPABILITY_*} flags.
+     *
+     * @return a bit mask of capabilities.
+     */
+    @BssCapabilityBits public int getCapabilities() {
+        return capability;
+    }
+
+    /**
+     * Returns details of the signal received on each radio chain for the AP represented by this
+     * scan result in a list of {@link RadioChainInfo} elements.
+     *
+     * @return A list of {@link RadioChainInfo} - possibly empty in case of error.
+     */
+    @NonNull public List<RadioChainInfo> getRadioChainInfos() {
+        return radioChainInfos;
+    }
+
+    /**
+     * Construct an empty native scan result.
+     */
+    public NativeScanResult() { }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeByteArray(ssid);
+        out.writeByteArray(bssid);
+        out.writeByteArray(infoElement);
+        out.writeInt(frequency);
+        out.writeInt(signalMbm);
+        out.writeLong(tsf);
+        out.writeInt(capability);
+        out.writeInt(associated ? 1 : 0);
+        out.writeTypedList(radioChainInfos);
+    }
+
+    /** implement Parcelable interface */
+    @NonNull public static final Parcelable.Creator<NativeScanResult> CREATOR =
+            new Parcelable.Creator<NativeScanResult>() {
+        @Override
+        public NativeScanResult createFromParcel(Parcel in) {
+            NativeScanResult result = new NativeScanResult();
+            result.ssid = in.createByteArray();
+            if (result.ssid == null) {
+                result.ssid = new byte[0];
+            }
+            result.bssid = in.createByteArray();
+            if (result.bssid == null) {
+                result.bssid = new byte[0];
+            }
+            result.infoElement = in.createByteArray();
+            if (result.infoElement == null) {
+                result.infoElement = new byte[0];
+            }
+            result.frequency = in.readInt();
+            result.signalMbm = in.readInt();
+            result.tsf = in.readLong();
+            result.capability = in.readInt();
+            result.associated = (in.readInt() != 0);
+            result.radioChainInfos = new ArrayList<>();
+            in.readTypedList(result.radioChainInfos, RadioChainInfo.CREATOR);
+            return result;
+        }
+
+        @Override
+        public NativeScanResult[] newArray(int size) {
+            return new NativeScanResult[size];
+        }
+    };
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeWifiClient.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeWifiClient.java
new file mode 100644
index 0000000..984d7d0
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/NativeWifiClient.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.MacAddress;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Structure providing information about clients (STAs) associated with a SoftAp.
+ *
+ * @hide
+ */
+@SystemApi
+public final class NativeWifiClient implements Parcelable {
+    private final MacAddress mMacAddress;
+
+    /**
+     * The MAC address of the client (STA) represented by this object. The MAC address may be null
+     * in case of an error.
+     */
+    @Nullable public MacAddress getMacAddress() {
+        return mMacAddress;
+    }
+
+    /**
+     * Construct a native Wi-Fi client.
+     */
+    public NativeWifiClient(@Nullable MacAddress macAddress) {
+        this.mMacAddress = macAddress;
+    }
+
+    /** override comparator */
+    @Override
+    public boolean equals(Object rhs) {
+        if (this == rhs) return true;
+        if (!(rhs instanceof NativeWifiClient)) {
+            return false;
+        }
+        NativeWifiClient other = (NativeWifiClient) rhs;
+        return Objects.equals(mMacAddress, other.mMacAddress);
+    }
+
+    /** override hash code */
+    @Override
+    public int hashCode() {
+        return mMacAddress.hashCode();
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * implement Parcelable interface
+     * |flag| is ignored.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeByteArray(mMacAddress.toByteArray());
+    }
+
+    /** implement Parcelable interface */
+    @NonNull public static final Parcelable.Creator<NativeWifiClient> CREATOR =
+            new Parcelable.Creator<NativeWifiClient>() {
+                @Override
+                public NativeWifiClient createFromParcel(Parcel in) {
+                    MacAddress macAddress;
+                    try {
+                        macAddress = MacAddress.fromBytes(in.createByteArray());
+                    } catch (IllegalArgumentException e) {
+                        macAddress = null;
+                    }
+                    return new NativeWifiClient(macAddress);
+                }
+
+                @Override
+                public NativeWifiClient[] newArray(int size) {
+                    return new NativeWifiClient[size];
+                }
+            };
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoNetwork.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoNetwork.java
new file mode 100644
index 0000000..e8eff09
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoNetwork.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Configuration for a PNO (preferred network offload) network used in {@link PnoSettings}. A PNO
+ * network allows configuration of a specific network to search for.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PnoNetwork implements Parcelable {
+    private boolean mIsHidden;
+    private byte[] mSsid;
+    private int[] mFrequencies;
+
+    /**
+     * Indicates whether the PNO network configuration is for a hidden SSID - i.e. a network which
+     * does not broadcast its SSID and must be queried explicitly.
+     *
+     * @return True if the configuration is for a hidden network, false otherwise.
+     */
+    public boolean isHidden() {
+        return mIsHidden;
+    }
+
+    /**
+     * Configure whether the PNO network configuration is for a hidden SSID - i.e. a network which
+     * does not broadcast its SSID and must be queried explicitly.
+     *
+     * @param isHidden True if the configuration is for a hidden network, false otherwise.
+     */
+    public void setHidden(boolean isHidden) {
+        mIsHidden = isHidden;
+    }
+
+    /**
+     * Get the raw bytes for the SSID of the PNO network being scanned for.
+     *
+     * @return A byte array.
+     */
+    @NonNull public byte[] getSsid() {
+        return mSsid;
+    }
+
+    /**
+     * Set the raw bytes for the SSID of the PNO network being scanned for.
+     *
+     * @param ssid A byte array.
+     */
+    public void setSsid(@NonNull byte[] ssid) {
+        if (ssid == null) {
+            throw new IllegalArgumentException("null argument");
+        }
+        this.mSsid = ssid;
+    }
+
+    /**
+     * Get the frequencies (in MHz) on which to PNO scan for the current network is being searched
+     * for. A null return (i.e. no frequencies configured) indicates that the network is search for
+     * on all supported frequencies.
+     *
+     * @return A array of frequencies (in MHz), a null indicates no configured frequencies.
+     */
+    @NonNull public int[] getFrequenciesMhz() {
+        return mFrequencies;
+    }
+
+    /**
+     * Set the frequencies (in MHz) on which to PNO scan for the current network is being searched
+     * for. A null configuration (i.e. no frequencies configured) indicates that the network is
+     * search for on all supported frequencies.
+     *
+     * @param frequenciesMhz an array of frequencies (in MHz), null indicating no configured
+     *                       frequencies.
+     */
+    public void setFrequenciesMhz(@NonNull int[] frequenciesMhz) {
+        if (frequenciesMhz == null) {
+            throw new IllegalArgumentException("null argument");
+        }
+        this.mFrequencies = frequenciesMhz;
+    }
+
+    /** Construct an uninitialized PnoNetwork object */
+    public PnoNetwork() { }
+
+    /** override comparator */
+    @Override
+    public boolean equals(Object rhs) {
+        if (this == rhs) return true;
+        if (!(rhs instanceof PnoNetwork)) {
+            return false;
+        }
+        PnoNetwork network = (PnoNetwork) rhs;
+        return Arrays.equals(mSsid, network.mSsid)
+                && Arrays.equals(mFrequencies, network.mFrequencies)
+                && mIsHidden == network.mIsHidden;
+    }
+
+    /** override hash code */
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                mIsHidden,
+                Arrays.hashCode(mSsid),
+                Arrays.hashCode(mFrequencies));
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * implement Parcelable interface
+     * |flag| is ignored.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(mIsHidden ? 1 : 0);
+        out.writeByteArray(mSsid);
+        out.writeIntArray(mFrequencies);
+    }
+
+    /** implement Parcelable interface */
+    @NonNull public static final Parcelable.Creator<PnoNetwork> CREATOR =
+            new Parcelable.Creator<PnoNetwork>() {
+        @Override
+        public PnoNetwork createFromParcel(Parcel in) {
+            PnoNetwork result = new PnoNetwork();
+            result.mIsHidden = in.readInt() != 0 ? true : false;
+            result.mSsid = in.createByteArray();
+            if (result.mSsid == null) {
+                result.mSsid = new byte[0];
+            }
+            result.mFrequencies = in.createIntArray();
+            if (result.mFrequencies == null) {
+                result.mFrequencies = new int[0];
+            }
+            return result;
+        }
+
+        @Override
+        public PnoNetwork[] newArray(int size) {
+            return new PnoNetwork[size];
+        }
+    };
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoSettings.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoSettings.java
new file mode 100644
index 0000000..00ebe62
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/PnoSettings.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.annotation.DurationMillisLong;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Configuration for a PNO (preferred network offload). A mechanism by which scans are offloaded
+ * from the host device to the Wi-Fi chip.
+ *
+ * @hide
+ */
+@SystemApi
+public final class PnoSettings implements Parcelable {
+    private long mIntervalMs;
+    private int mMin2gRssi;
+    private int mMin5gRssi;
+    private int mMin6gRssi;
+    private List<PnoNetwork> mPnoNetworks;
+
+    /** Construct an uninitialized PnoSettings object */
+    public PnoSettings() { }
+
+    /**
+     * Get the requested PNO scan interval in milliseconds.
+     *
+     * @return An interval in milliseconds.
+     */
+    public @DurationMillisLong long getIntervalMillis() {
+        return mIntervalMs;
+    }
+
+    /**
+     * Set the requested PNO scan interval in milliseconds.
+     *
+     * @param intervalMillis An interval in milliseconds.
+     */
+    public void setIntervalMillis(@DurationMillisLong long intervalMillis) {
+        this.mIntervalMs = intervalMillis;
+    }
+
+    /**
+     * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the
+     * 2.4GHz band.
+     *
+     * @return An RSSI value in dBm.
+     */
+    public int getMin2gRssiDbm() {
+        return mMin2gRssi;
+    }
+
+    /**
+     * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in
+     * the 2.4GHz band.
+     *
+     * @param min2gRssiDbm An RSSI value in dBm.
+     */
+    public void setMin2gRssiDbm(int min2gRssiDbm) {
+        this.mMin2gRssi = min2gRssiDbm;
+    }
+
+    /**
+     * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the
+     * 5GHz band.
+     *
+     * @return An RSSI value in dBm.
+     */
+    public int getMin5gRssiDbm() {
+        return mMin5gRssi;
+    }
+
+    /**
+     * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in
+     * the 5GHz band.
+     *
+     * @param min5gRssiDbm An RSSI value in dBm.
+     */
+    public void setMin5gRssiDbm(int min5gRssiDbm) {
+        this.mMin5gRssi = min5gRssiDbm;
+    }
+
+    /**
+     * Get the requested minimum RSSI threshold (in dBm) for APs to report in scan results in the
+     * 6GHz band.
+     *
+     * @return An RSSI value in dBm.
+     */
+    public int getMin6gRssiDbm() {
+        return mMin6gRssi;
+    }
+
+    /**
+     * Set the requested minimum RSSI threshold (in dBm) for APs to report in scan scan results in
+     * the 6GHz band.
+     *
+     * @param min6gRssiDbm An RSSI value in dBm.
+     */
+    public void setMin6gRssiDbm(int min6gRssiDbm) {
+        this.mMin6gRssi = min6gRssiDbm;
+    }
+
+    /**
+     * Return the configured list of specific networks to search for in a PNO scan.
+     *
+     * @return A list of {@link PnoNetwork} objects, possibly empty if non configured.
+     */
+    @NonNull public List<PnoNetwork> getPnoNetworks() {
+        return mPnoNetworks;
+    }
+
+    /**
+     * Set the list of specified networks to scan for in a PNO scan. The networks (APs) are
+     * specified using {@link PnoNetwork}s. An empty list indicates that all networks are scanned
+     * for.
+     *
+     * @param pnoNetworks A (possibly empty) list of {@link PnoNetwork} objects.
+     */
+    public void setPnoNetworks(@NonNull List<PnoNetwork> pnoNetworks) {
+        this.mPnoNetworks = pnoNetworks;
+    }
+
+    /** override comparator */
+    @Override
+    public boolean equals(Object rhs) {
+        if (this == rhs) return true;
+        if (!(rhs instanceof PnoSettings)) {
+            return false;
+        }
+        PnoSettings settings = (PnoSettings) rhs;
+        if (settings == null) {
+            return false;
+        }
+        return mIntervalMs == settings.mIntervalMs
+                && mMin2gRssi == settings.mMin2gRssi
+                && mMin5gRssi == settings.mMin5gRssi
+                && mMin6gRssi == settings.mMin6gRssi
+                && mPnoNetworks.equals(settings.mPnoNetworks);
+    }
+
+    /** override hash code */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mIntervalMs, mMin2gRssi, mMin5gRssi, mMin6gRssi, mPnoNetworks);
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * implement Parcelable interface
+     * |flag| is ignored.
+     **/
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeLong(mIntervalMs);
+        out.writeInt(mMin2gRssi);
+        out.writeInt(mMin5gRssi);
+        out.writeInt(mMin6gRssi);
+        out.writeTypedList(mPnoNetworks);
+    }
+
+    /** implement Parcelable interface */
+    @NonNull public static final Parcelable.Creator<PnoSettings> CREATOR =
+            new Parcelable.Creator<PnoSettings>() {
+        @Override
+        public PnoSettings createFromParcel(Parcel in) {
+            PnoSettings result = new PnoSettings();
+            result.mIntervalMs = in.readLong();
+            result.mMin2gRssi = in.readInt();
+            result.mMin5gRssi = in.readInt();
+            result.mMin6gRssi = in.readInt();
+
+            result.mPnoNetworks = new ArrayList<>();
+            in.readTypedList(result.mPnoNetworks, PnoNetwork.CREATOR);
+
+            return result;
+        }
+
+        @Override
+        public PnoSettings[] newArray(int size) {
+            return new PnoSettings[size];
+        }
+    };
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/RadioChainInfo.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/RadioChainInfo.java
new file mode 100644
index 0000000..2c12163
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/RadioChainInfo.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Objects;
+
+/**
+ * A class representing the radio chains of the Wi-Fi modems. Use to provide raw information about
+ * signals received on different radio chains.
+ *
+ * @hide
+ */
+@SystemApi
+public final class RadioChainInfo implements Parcelable {
+    private static final String TAG = "RadioChainInfo";
+
+    /** @hide */
+    @VisibleForTesting
+    public int chainId;
+    /** @hide */
+    @VisibleForTesting
+    public int level;
+
+    /**
+     * Return an identifier for this radio chain. This is an arbitrary ID which is consistent for
+     * the same device.
+     *
+     * @return The radio chain ID.
+     */
+    public int getChainId() {
+        return chainId;
+    }
+
+    /**
+     * Returns the detected signal level on this radio chain in dBm (aka RSSI).
+     *
+     * @return A signal level in dBm.
+     */
+    public int getLevelDbm() {
+        return level;
+    }
+
+    /**
+     * Construct a RadioChainInfo.
+     */
+    public RadioChainInfo(int chainId, int level) {
+        this.chainId = chainId;
+        this.level = level;
+    }
+
+    /** override comparator */
+    @Override
+    public boolean equals(Object rhs) {
+        if (this == rhs) return true;
+        if (!(rhs instanceof RadioChainInfo)) {
+            return false;
+        }
+        RadioChainInfo chainInfo = (RadioChainInfo) rhs;
+        if (chainInfo == null) {
+            return false;
+        }
+        return chainId == chainInfo.chainId && level == chainInfo.level;
+    }
+
+    /** override hash code */
+    @Override
+    public int hashCode() {
+        return Objects.hash(chainId, level);
+    }
+
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * implement Parcelable interface
+     * |flags| is ignored.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeInt(chainId);
+        out.writeInt(level);
+    }
+
+    /** implement Parcelable interface */
+    @NonNull public static final Parcelable.Creator<RadioChainInfo> CREATOR =
+            new Parcelable.Creator<RadioChainInfo>() {
+        /**
+         * Caller is responsible for providing a valid parcel.
+         */
+        @Override
+        public RadioChainInfo createFromParcel(Parcel in) {
+            return new RadioChainInfo(in.readInt(), in.readInt());
+        }
+
+        @Override
+        public RadioChainInfo[] newArray(int size) {
+            return new RadioChainInfo[size];
+        }
+    };
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/SingleScanSettings.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/SingleScanSettings.java
new file mode 100644
index 0000000..24b1854
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/SingleScanSettings.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+/**
+ * SingleScanSettings for wificond
+ *
+ * @hide
+ */
+public class SingleScanSettings implements Parcelable {
+    private static final String TAG = "SingleScanSettings";
+
+    public int scanType;
+    public ArrayList<ChannelSettings> channelSettings;
+    public ArrayList<HiddenNetwork> hiddenNetworks;
+
+    /** public constructor */
+    public SingleScanSettings() { }
+
+    /** override comparator */
+    @Override
+    public boolean equals(Object rhs) {
+        if (this == rhs) return true;
+        if (!(rhs instanceof SingleScanSettings)) {
+            return false;
+        }
+        SingleScanSettings settings = (SingleScanSettings) rhs;
+        if (settings == null) {
+            return false;
+        }
+        return scanType == settings.scanType
+                && channelSettings.equals(settings.channelSettings)
+                && hiddenNetworks.equals(settings.hiddenNetworks);
+    }
+
+    /** override hash code */
+    @Override
+    public int hashCode() {
+        return Objects.hash(scanType, channelSettings, hiddenNetworks);
+    }
+
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    private static boolean isValidScanType(int scanType) {
+        return scanType == IWifiScannerImpl.SCAN_TYPE_LOW_SPAN
+                || scanType == IWifiScannerImpl.SCAN_TYPE_LOW_POWER
+                || scanType == IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY;
+    }
+
+    /**
+     * implement Parcelable interface
+     * |flags| is ignored.
+     */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        if (!isValidScanType(scanType)) {
+            Log.wtf(TAG, "Invalid scan type " + scanType);
+        }
+        out.writeInt(scanType);
+        out.writeTypedList(channelSettings);
+        out.writeTypedList(hiddenNetworks);
+    }
+
+    /** implement Parcelable interface */
+    public static final Parcelable.Creator<SingleScanSettings> CREATOR =
+            new Parcelable.Creator<SingleScanSettings>() {
+        /**
+         * Caller is responsible for providing a valid parcel.
+         */
+        @Override
+        public SingleScanSettings createFromParcel(Parcel in) {
+            SingleScanSettings result = new SingleScanSettings();
+            result.scanType = in.readInt();
+            if (!isValidScanType(result.scanType)) {
+                Log.wtf(TAG, "Invalid scan type " + result.scanType);
+            }
+            result.channelSettings = new ArrayList<ChannelSettings>();
+            in.readTypedList(result.channelSettings, ChannelSettings.CREATOR);
+            result.hiddenNetworks = new ArrayList<HiddenNetwork>();
+            in.readTypedList(result.hiddenNetworks, HiddenNetwork.CREATOR);
+            if (in.dataAvail() != 0) {
+                Log.e(TAG, "Found trailing data after parcel parsing.");
+            }
+            return result;
+        }
+
+        @Override
+        public SingleScanSettings[] newArray(int size) {
+            return new SingleScanSettings[size];
+        }
+    };
+}
diff --git a/wifi/non-updatable/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/non-updatable/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
new file mode 100644
index 0000000..4116234
--- /dev/null
+++ b/wifi/non-updatable/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
@@ -0,0 +1,1287 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi.nl80211;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.app.AlarmManager;
+import android.content.Context;
+import android.net.wifi.SoftApInfo;
+import android.net.wifi.WifiAnnotations;
+import android.net.wifi.WifiScanner;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This class encapsulates the interface the wificond daemon presents to the Wi-Fi framework - used
+ * to encapsulate the Wi-Fi 80211nl management interface. The
+ * interface is only for use by the Wi-Fi framework and access is protected by SELinux permissions.
+ *
+ * @hide
+ */
+@SystemApi
+@SystemService(Context.WIFI_NL80211_SERVICE)
+public class WifiNl80211Manager {
+    private static final String TAG = "WifiNl80211Manager";
+    private boolean mVerboseLoggingEnabled = false;
+
+    /**
+     * The {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}
+     * timeout, in milliseconds, after which
+     * {@link SendMgmtFrameCallback#onFailure(int)} will be called with reason
+     * {@link #SEND_MGMT_FRAME_ERROR_TIMEOUT}.
+     */
+    private static final int SEND_MGMT_FRAME_TIMEOUT_MS = 1000;
+
+    private static final String TIMEOUT_ALARM_TAG = TAG + " Send Management Frame Timeout";
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"SCAN_TYPE_"},
+            value = {SCAN_TYPE_SINGLE_SCAN,
+                    SCAN_TYPE_PNO_SCAN})
+    public @interface ScanResultType {}
+
+    /**
+     * Specifies a scan type: single scan initiated by the framework. Can be used in
+     * {@link #getScanResults(String, int)} to specify the type of scan result to fetch.
+     */
+    public static final int SCAN_TYPE_SINGLE_SCAN = 0;
+
+    /**
+     * Specifies a scan type: PNO scan. Can be used in {@link #getScanResults(String, int)} to
+     * specify the type of scan result to fetch.
+     */
+    public static final int SCAN_TYPE_PNO_SCAN = 1;
+
+    private AlarmManager mAlarmManager;
+    private Handler mEventHandler;
+
+    // Cached wificond binder handlers.
+    private IWificond mWificond;
+    private HashMap<String, IClientInterface> mClientInterfaces = new HashMap<>();
+    private HashMap<String, IApInterface> mApInterfaces = new HashMap<>();
+    private HashMap<String, IWifiScannerImpl> mWificondScanners = new HashMap<>();
+    private HashMap<String, IScanEvent> mScanEventHandlers = new HashMap<>();
+    private HashMap<String, IPnoScanEvent> mPnoScanEventHandlers = new HashMap<>();
+    private HashMap<String, IApInterfaceEventCallback> mApInterfaceListeners = new HashMap<>();
+    private Runnable mDeathEventHandler;
+    /**
+     * Ensures that no more than one sendMgmtFrame operation runs concurrently.
+     */
+    private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false);
+
+    /**
+     * Interface used when waiting for scans to be completed (with results).
+     */
+    public interface ScanEventCallback {
+        /**
+         * Called when scan results are available. Scans results should then be obtained from
+         * {@link #getScanResults(String, int)}.
+         */
+        void onScanResultReady();
+
+        /**
+         * Called when a scan has failed.
+         */
+        void onScanFailed();
+    }
+
+    /**
+     * Interface for a callback to provide information about PNO scan request requested with
+     * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}. Note that the
+     * callback are for the status of the request - not the scan itself. The results of the scan
+     * are returned with {@link ScanEventCallback}.
+     */
+    public interface PnoScanRequestCallback {
+        /**
+         * Called when a PNO scan request has been successfully submitted.
+         */
+        void onPnoRequestSucceeded();
+
+        /**
+         * Called when a PNO scan request fails.
+         */
+        void onPnoRequestFailed();
+    }
+
+    private class ScanEventHandler extends IScanEvent.Stub {
+        private Executor mExecutor;
+        private ScanEventCallback mCallback;
+
+        ScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) {
+            mExecutor = executor;
+            mCallback = callback;
+        }
+
+        @Override
+        public void OnScanResultReady() {
+            Log.d(TAG, "Scan result ready event");
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> mCallback.onScanResultReady());
+        }
+
+        @Override
+        public void OnScanFailed() {
+            Log.d(TAG, "Scan failed event");
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> mCallback.onScanFailed());
+        }
+    }
+
+    /**
+     * Result of a signal poll requested using {@link #signalPoll(String)}.
+     */
+    public static class SignalPollResult {
+        /** @hide */
+        public SignalPollResult(int currentRssiDbm, int txBitrateMbps, int rxBitrateMbps,
+                int associationFrequencyMHz) {
+            this.currentRssiDbm = currentRssiDbm;
+            this.txBitrateMbps = txBitrateMbps;
+            this.rxBitrateMbps = rxBitrateMbps;
+            this.associationFrequencyMHz = associationFrequencyMHz;
+        }
+
+        /**
+         * RSSI value in dBM.
+         */
+        public final int currentRssiDbm;
+
+        /**
+         * Transmission bit rate in Mbps.
+         */
+        public final int txBitrateMbps;
+
+        /**
+         * Last received packet bit rate in Mbps.
+         */
+        public final int rxBitrateMbps;
+
+        /**
+         * Association frequency in MHz.
+         */
+        public final int associationFrequencyMHz;
+    }
+
+    /**
+     * Transmission counters obtained using {@link #getTxPacketCounters(String)}.
+     */
+    public static class TxPacketCounters {
+        /** @hide */
+        public TxPacketCounters(int txPacketSucceeded, int txPacketFailed) {
+            this.txPacketSucceeded = txPacketSucceeded;
+            this.txPacketFailed = txPacketFailed;
+        }
+
+        /**
+         * Number of successfully transmitted packets.
+         */
+        public final int txPacketSucceeded;
+
+        /**
+         * Number of packet transmission failures.
+         */
+        public final int txPacketFailed;
+    }
+
+    /**
+     * Callbacks for SoftAp interface registered using
+     * {@link #registerApCallback(String, Executor, SoftApCallback)}.
+     */
+    public interface SoftApCallback {
+        /**
+         * Invoked when there is a fatal failure and the SoftAp is shutdown.
+         */
+        void onFailure();
+
+        /**
+         * Invoked when there is a change in the associated station (STA).
+         * @param client Information about the client whose status has changed.
+         * @param isConnected Indication as to whether the client is connected (true), or
+         *                    disconnected (false).
+         */
+        void onConnectedClientsChanged(@NonNull NativeWifiClient client, boolean isConnected);
+
+        /**
+         * Invoked when a channel switch event happens - i.e. the SoftAp is moved to a different
+         * channel. Also called on initial registration.
+         * @param frequencyMhz The new frequency of the SoftAp. A value of 0 is invalid and is an
+         *                     indication that the SoftAp is not enabled.
+         * @param bandwidth The new bandwidth of the SoftAp.
+         */
+        void onSoftApChannelSwitched(int frequencyMhz, @WifiAnnotations.Bandwidth int bandwidth);
+    }
+
+    /**
+     * Callback to notify the results of a
+     * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} call.
+     * Note: no callbacks will be triggered if the interface dies while sending a frame.
+     */
+    public interface SendMgmtFrameCallback {
+        /**
+         * Called when the management frame was successfully sent and ACKed by the recipient.
+         * @param elapsedTimeMs The elapsed time between when the management frame was sent and when
+         *                      the ACK was processed, in milliseconds, as measured by wificond.
+         *                      This includes the time that the send frame spent queuing before it
+         *                      was sent, any firmware retries, and the time the received ACK spent
+         *                      queuing before it was processed.
+         */
+        void onAck(int elapsedTimeMs);
+
+        /**
+         * Called when the send failed.
+         * @param reason The error code for the failure.
+         */
+        void onFailure(@SendMgmtFrameError int reason);
+    }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"SEND_MGMT_FRAME_ERROR_"},
+            value = {SEND_MGMT_FRAME_ERROR_UNKNOWN,
+                    SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED,
+                    SEND_MGMT_FRAME_ERROR_NO_ACK,
+                    SEND_MGMT_FRAME_ERROR_TIMEOUT,
+                    SEND_MGMT_FRAME_ERROR_ALREADY_STARTED})
+    public @interface SendMgmtFrameError {}
+
+    // Send management frame error codes
+
+    /**
+     * Unknown error occurred during call to
+     * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}.
+     */
+    public static final int SEND_MGMT_FRAME_ERROR_UNKNOWN = 1;
+
+    /**
+     * Specifying the MCS rate in
+     * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)} is not
+     * supported by this device.
+     */
+    public static final int SEND_MGMT_FRAME_ERROR_MCS_UNSUPPORTED = 2;
+
+    /**
+     * Driver reported that no ACK was received for the frame transmitted using
+     * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}.
+     */
+    public static final int SEND_MGMT_FRAME_ERROR_NO_ACK = 3;
+
+    /**
+     * Error code for when the driver fails to report on the status of the frame sent by
+     * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}
+     * after {@link #SEND_MGMT_FRAME_TIMEOUT_MS} milliseconds.
+     */
+    public static final int SEND_MGMT_FRAME_ERROR_TIMEOUT = 4;
+
+    /**
+     * An existing call to
+     * {@link #sendMgmtFrame(String, byte[], int, Executor, SendMgmtFrameCallback)}
+     * is in progress. Another frame cannot be sent until the first call completes.
+     */
+    public static final int SEND_MGMT_FRAME_ERROR_ALREADY_STARTED = 5;
+
+    /** @hide */
+    public WifiNl80211Manager(Context context) {
+        mAlarmManager = context.getSystemService(AlarmManager.class);
+        mEventHandler = new Handler(context.getMainLooper());
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public WifiNl80211Manager(Context context, IWificond wificond) {
+        this(context);
+        mWificond = wificond;
+    }
+
+    private class PnoScanEventHandler extends IPnoScanEvent.Stub {
+        private Executor mExecutor;
+        private ScanEventCallback mCallback;
+
+        PnoScanEventHandler(@NonNull Executor executor, @NonNull ScanEventCallback callback) {
+            mExecutor = executor;
+            mCallback = callback;
+        }
+
+        @Override
+        public void OnPnoNetworkFound() {
+            Log.d(TAG, "Pno scan result event");
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> mCallback.onScanResultReady());
+        }
+
+        @Override
+        public void OnPnoScanFailed() {
+            Log.d(TAG, "Pno Scan failed event");
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> mCallback.onScanFailed());
+        }
+    }
+
+    /**
+     * Listener for AP Interface events.
+     */
+    private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub {
+        private Executor mExecutor;
+        private SoftApCallback mSoftApListener;
+
+        ApInterfaceEventCallback(Executor executor, SoftApCallback listener) {
+            mExecutor = executor;
+            mSoftApListener = listener;
+        }
+
+        @Override
+        public void onConnectedClientsChanged(NativeWifiClient client, boolean isConnected) {
+            if (mVerboseLoggingEnabled) {
+                Log.d(TAG, "onConnectedClientsChanged called with "
+                        + client.getMacAddress() + " isConnected: " + isConnected);
+            }
+
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> mSoftApListener.onConnectedClientsChanged(client, isConnected));
+        }
+
+        @Override
+        public void onSoftApChannelSwitched(int frequency, int bandwidth) {
+            Binder.clearCallingIdentity();
+            mExecutor.execute(() -> mSoftApListener.onSoftApChannelSwitched(frequency,
+                    toFrameworkBandwidth(bandwidth)));
+        }
+
+        private @WifiAnnotations.Bandwidth int toFrameworkBandwidth(int bandwidth) {
+            switch(bandwidth) {
+                case IApInterfaceEventCallback.BANDWIDTH_INVALID:
+                    return SoftApInfo.CHANNEL_WIDTH_INVALID;
+                case IApInterfaceEventCallback.BANDWIDTH_20_NOHT:
+                    return SoftApInfo.CHANNEL_WIDTH_20MHZ_NOHT;
+                case IApInterfaceEventCallback.BANDWIDTH_20:
+                    return SoftApInfo.CHANNEL_WIDTH_20MHZ;
+                case IApInterfaceEventCallback.BANDWIDTH_40:
+                    return SoftApInfo.CHANNEL_WIDTH_40MHZ;
+                case IApInterfaceEventCallback.BANDWIDTH_80:
+                    return SoftApInfo.CHANNEL_WIDTH_80MHZ;
+                case IApInterfaceEventCallback.BANDWIDTH_80P80:
+                    return SoftApInfo.CHANNEL_WIDTH_80MHZ_PLUS_MHZ;
+                case IApInterfaceEventCallback.BANDWIDTH_160:
+                    return SoftApInfo.CHANNEL_WIDTH_160MHZ;
+                default:
+                    return SoftApInfo.CHANNEL_WIDTH_INVALID;
+            }
+        }
+    }
+
+    /**
+     * Callback triggered by wificond.
+     */
+    private class SendMgmtFrameEvent extends ISendMgmtFrameEvent.Stub {
+        private Executor mExecutor;
+        private SendMgmtFrameCallback mCallback;
+        private AlarmManager.OnAlarmListener mTimeoutCallback;
+        /**
+         * ensures that mCallback is only called once
+         */
+        private boolean mWasCalled;
+
+        private void runIfFirstCall(Runnable r) {
+            if (mWasCalled) return;
+            mWasCalled = true;
+
+            mSendMgmtFrameInProgress.set(false);
+            r.run();
+        }
+
+        SendMgmtFrameEvent(@NonNull Executor executor, @NonNull SendMgmtFrameCallback callback) {
+            mExecutor = executor;
+            mCallback = callback;
+            // called in main thread
+            mTimeoutCallback = () -> runIfFirstCall(() -> {
+                if (mVerboseLoggingEnabled) {
+                    Log.e(TAG, "Timed out waiting for ACK");
+                }
+                Binder.clearCallingIdentity();
+                mExecutor.execute(() -> mCallback.onFailure(SEND_MGMT_FRAME_ERROR_TIMEOUT));
+            });
+            mWasCalled = false;
+
+            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                    SystemClock.elapsedRealtime() + SEND_MGMT_FRAME_TIMEOUT_MS,
+                    TIMEOUT_ALARM_TAG, mTimeoutCallback, mEventHandler);
+        }
+
+        // called in binder thread
+        @Override
+        public void OnAck(int elapsedTimeMs) {
+            // post to main thread
+            mEventHandler.post(() -> runIfFirstCall(() -> {
+                mAlarmManager.cancel(mTimeoutCallback);
+                Binder.clearCallingIdentity();
+                mExecutor.execute(() -> mCallback.onAck(elapsedTimeMs));
+            }));
+        }
+
+        // called in binder thread
+        @Override
+        public void OnFailure(int reason) {
+            // post to main thread
+            mEventHandler.post(() -> runIfFirstCall(() -> {
+                mAlarmManager.cancel(mTimeoutCallback);
+                Binder.clearCallingIdentity();
+                mExecutor.execute(() -> mCallback.onFailure(reason));
+            }));
+        }
+    }
+
+    /**
+     * Called by the binder subsystem upon remote object death.
+     * Invoke all the register death handlers and clear state.
+     * @hide
+     */
+    @VisibleForTesting
+    public void binderDied() {
+        mEventHandler.post(() -> {
+            Log.e(TAG, "Wificond died!");
+            clearState();
+            // Invalidate the global wificond handle on death. Will be refreshed
+            // on the next setup call.
+            mWificond = null;
+            if (mDeathEventHandler != null) {
+                mDeathEventHandler.run();
+            }
+        });
+    }
+
+    /**
+     * Enable or disable verbose logging of the WifiNl80211Manager module.
+     * @param enable True to enable verbose logging. False to disable verbose logging.
+     */
+    public void enableVerboseLogging(boolean enable) {
+        mVerboseLoggingEnabled = enable;
+    }
+
+    /**
+     * Register a death notification for the WifiNl80211Manager which acts as a proxy for the
+     * wificond daemon (i.e. the death listener will be called when and if the wificond daemon
+     * dies).
+     *
+     * @param deathEventHandler A {@link Runnable} to be called whenever the wificond daemon dies.
+     */
+    public void setOnServiceDeadCallback(@NonNull Runnable deathEventHandler) {
+        if (mDeathEventHandler != null) {
+            Log.e(TAG, "Death handler already present");
+        }
+        mDeathEventHandler = deathEventHandler;
+    }
+
+    /**
+     * Helper method to retrieve the global wificond handle and register for
+     * death notifications.
+     */
+    private boolean retrieveWificondAndRegisterForDeath() {
+        if (mWificond != null) {
+            if (mVerboseLoggingEnabled) {
+                Log.d(TAG, "Wificond handle already retrieved");
+            }
+            // We already have a wificond handle.
+            return true;
+        }
+        IBinder binder = ServiceManager.getService(Context.WIFI_NL80211_SERVICE);
+        mWificond = IWificond.Stub.asInterface(binder);
+        if (mWificond == null) {
+            Log.e(TAG, "Failed to get reference to wificond");
+            return false;
+        }
+        try {
+            mWificond.asBinder().linkToDeath(() -> binderDied(), 0);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to register death notification for wificond");
+            // The remote has already died.
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Set up an interface for client (STA) mode.
+     *
+     * @param ifaceName Name of the interface to configure.
+     * @param executor The Executor on which to execute the callbacks.
+     * @param scanCallback A callback for framework initiated scans.
+     * @param pnoScanCallback A callback for PNO (offloaded) scans.
+     * @return true on success.
+     */
+    public boolean setupInterfaceForClientMode(@NonNull String ifaceName,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull ScanEventCallback scanCallback, @NonNull ScanEventCallback pnoScanCallback) {
+        Log.d(TAG, "Setting up interface for client mode");
+        if (!retrieveWificondAndRegisterForDeath()) {
+            return false;
+        }
+
+        if (scanCallback == null || pnoScanCallback == null || executor == null) {
+            Log.e(TAG, "setupInterfaceForClientMode invoked with null callbacks");
+            return false;
+        }
+
+        IClientInterface clientInterface = null;
+        try {
+            clientInterface = mWificond.createClientInterface(ifaceName);
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to get IClientInterface due to remote exception");
+            return false;
+        }
+
+        if (clientInterface == null) {
+            Log.e(TAG, "Could not get IClientInterface instance from wificond");
+            return false;
+        }
+        Binder.allowBlocking(clientInterface.asBinder());
+
+        // Refresh Handlers
+        mClientInterfaces.put(ifaceName, clientInterface);
+        try {
+            IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl();
+            if (wificondScanner == null) {
+                Log.e(TAG, "Failed to get WificondScannerImpl");
+                return false;
+            }
+            mWificondScanners.put(ifaceName, wificondScanner);
+            Binder.allowBlocking(wificondScanner.asBinder());
+            ScanEventHandler scanEventHandler = new ScanEventHandler(executor, scanCallback);
+            mScanEventHandlers.put(ifaceName,  scanEventHandler);
+            wificondScanner.subscribeScanEvents(scanEventHandler);
+            PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(executor,
+                    pnoScanCallback);
+            mPnoScanEventHandlers.put(ifaceName,  pnoScanEventHandler);
+            wificondScanner.subscribePnoScanEvents(pnoScanEventHandler);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to refresh wificond scanner due to remote exception");
+        }
+
+        return true;
+    }
+
+    /**
+     * Tear down a specific client (STA) interface configured using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}.
+     *
+     * @param ifaceName Name of the interface to tear down.
+     * @return Returns true on success, false on failure (e.g. when called before an interface was
+     * set up).
+     */
+    public boolean tearDownClientInterface(@NonNull String ifaceName) {
+        if (getClientInterface(ifaceName) == null) {
+            Log.e(TAG, "No valid wificond client interface handler");
+            return false;
+        }
+        try {
+            IWifiScannerImpl scannerImpl = mWificondScanners.get(ifaceName);
+            if (scannerImpl != null) {
+                scannerImpl.unsubscribeScanEvents();
+                scannerImpl.unsubscribePnoScanEvents();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception");
+            return false;
+        }
+
+        if (mWificond == null) {
+            Log.e(TAG, "Reference to wifiCond is null");
+            return false;
+        }
+
+        boolean success;
+        try {
+            success = mWificond.tearDownClientInterface(ifaceName);
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to teardown client interface due to remote exception");
+            return false;
+        }
+        if (!success) {
+            Log.e(TAG, "Failed to teardown client interface");
+            return false;
+        }
+
+        mClientInterfaces.remove(ifaceName);
+        mWificondScanners.remove(ifaceName);
+        mScanEventHandlers.remove(ifaceName);
+        mPnoScanEventHandlers.remove(ifaceName);
+        return true;
+    }
+
+    /**
+     * Set up interface as a Soft AP.
+     *
+     * @param ifaceName Name of the interface to configure.
+     * @return true on success.
+     */
+    public boolean setupInterfaceForSoftApMode(@NonNull String ifaceName) {
+        Log.d(TAG, "Setting up interface for soft ap mode");
+        if (!retrieveWificondAndRegisterForDeath()) {
+            return false;
+        }
+
+        IApInterface apInterface = null;
+        try {
+            apInterface = mWificond.createApInterface(ifaceName);
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to get IApInterface due to remote exception");
+            return false;
+        }
+
+        if (apInterface == null) {
+            Log.e(TAG, "Could not get IApInterface instance from wificond");
+            return false;
+        }
+        Binder.allowBlocking(apInterface.asBinder());
+
+        // Refresh Handlers
+        mApInterfaces.put(ifaceName, apInterface);
+        return true;
+    }
+
+    /**
+     * Tear down a Soft AP interface configured using
+     * {@link #setupInterfaceForSoftApMode(String)}.
+     *
+     * @param ifaceName Name of the interface to tear down.
+     * @return Returns true on success, false on failure (e.g. when called before an interface was
+     * set up).
+     */
+    public boolean tearDownSoftApInterface(@NonNull String ifaceName) {
+        if (getApInterface(ifaceName) == null) {
+            Log.e(TAG, "No valid wificond ap interface handler");
+            return false;
+        }
+
+        if (mWificond == null) {
+            Log.e(TAG, "Reference to wifiCond is null");
+            return false;
+        }
+
+        boolean success;
+        try {
+            success = mWificond.tearDownApInterface(ifaceName);
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to teardown AP interface due to remote exception");
+            return false;
+        }
+        if (!success) {
+            Log.e(TAG, "Failed to teardown AP interface");
+            return false;
+        }
+        mApInterfaces.remove(ifaceName);
+        mApInterfaceListeners.remove(ifaceName);
+        return true;
+    }
+
+    /**
+    * Tear down all interfaces, whether clients (STA) or Soft AP.
+     *
+    * @return Returns true on success.
+    */
+    public boolean tearDownInterfaces() {
+        Log.d(TAG, "tearing down interfaces in wificond");
+        // Explicitly refresh the wificodn handler because |tearDownInterfaces()|
+        // could be used to cleanup before we setup any interfaces.
+        if (!retrieveWificondAndRegisterForDeath()) {
+            return false;
+        }
+
+        try {
+            for (Map.Entry<String, IWifiScannerImpl> entry : mWificondScanners.entrySet()) {
+                entry.getValue().unsubscribeScanEvents();
+                entry.getValue().unsubscribePnoScanEvents();
+            }
+            mWificond.tearDownInterfaces();
+            clearState();
+            return true;
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to tear down interfaces due to remote exception");
+        }
+
+        return false;
+    }
+
+    /** Helper function to look up the interface handle using name */
+    private IClientInterface getClientInterface(@NonNull String ifaceName) {
+        return mClientInterfaces.get(ifaceName);
+    }
+
+    /**
+     * Request signal polling.
+     *
+     * @param ifaceName Name of the interface on which to poll. The interface must have been
+     *                  already set up using
+     *{@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}
+     *                  or {@link #setupInterfaceForSoftApMode(String)}.
+     *
+     * @return A {@link SignalPollResult} object containing interface statistics, or a null on
+     * error (e.g. the interface hasn't been set up yet).
+     */
+    @Nullable public SignalPollResult signalPoll(@NonNull String ifaceName) {
+        IClientInterface iface = getClientInterface(ifaceName);
+        if (iface == null) {
+            Log.e(TAG, "No valid wificond client interface handler");
+            return null;
+        }
+
+        int[] resultArray;
+        try {
+            resultArray = iface.signalPoll();
+            if (resultArray == null || resultArray.length != 4) {
+                Log.e(TAG, "Invalid signal poll result from wificond");
+                return null;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to do signal polling due to remote exception");
+            return null;
+        }
+        return new SignalPollResult(resultArray[0], resultArray[1], resultArray[3], resultArray[2]);
+    }
+
+    /**
+     * Get current transmit (Tx) packet counters of the specified interface. The interface must
+     * have been already set up using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}
+     * or {@link #setupInterfaceForSoftApMode(String)}.
+     *
+     * @param ifaceName Name of the interface.
+     * @return {@link TxPacketCounters} of the current interface or null on error (e.g. when
+     * called before the interface has been set up).
+     */
+    @Nullable public TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) {
+        IClientInterface iface = getClientInterface(ifaceName);
+        if (iface == null) {
+            Log.e(TAG, "No valid wificond client interface handler");
+            return null;
+        }
+
+        int[] resultArray;
+        try {
+            resultArray = iface.getPacketCounters();
+            if (resultArray == null || resultArray.length != 2) {
+                Log.e(TAG, "Invalid signal poll result from wificond");
+                return null;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to do signal polling due to remote exception");
+            return null;
+        }
+        return new TxPacketCounters(resultArray[0], resultArray[1]);
+    }
+
+    /** Helper function to look up the scanner impl handle using name */
+    private IWifiScannerImpl getScannerImpl(@NonNull String ifaceName) {
+        return mWificondScanners.get(ifaceName);
+    }
+
+    /**
+     * Fetch the latest scan results of the indicated type for the specified interface. Note that
+     * this method fetches the latest results - it does not initiate a scan. Initiating a scan can
+     * be done using {@link #startScan(String, int, Set, List)} or
+     * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}.
+     *
+     * Note: The interface must have been already set up using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}
+     * or {@link #setupInterfaceForSoftApMode(String)}.
+     *
+     * @param ifaceName Name of the interface.
+     * @param scanType The type of scan result to be returned, can be
+     * {@link #SCAN_TYPE_SINGLE_SCAN} or {@link #SCAN_TYPE_PNO_SCAN}.
+     * @return Returns an array of {@link NativeScanResult} or an empty array on failure (e.g. when
+     * called before the interface has been set up).
+     */
+    @NonNull public List<NativeScanResult> getScanResults(@NonNull String ifaceName,
+            @ScanResultType int scanType) {
+        IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
+        if (scannerImpl == null) {
+            Log.e(TAG, "No valid wificond scanner interface handler");
+            return new ArrayList<>();
+        }
+        List<NativeScanResult> results = null;
+        try {
+            if (scanType == SCAN_TYPE_SINGLE_SCAN) {
+                results = Arrays.asList(scannerImpl.getScanResults());
+            } else {
+                results = Arrays.asList(scannerImpl.getPnoScanResults());
+            }
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to create ScanDetail ArrayList");
+        }
+        if (results == null) {
+            results = new ArrayList<>();
+        }
+        if (mVerboseLoggingEnabled) {
+            Log.d(TAG, "get " + results.size() + " scan results from wificond");
+        }
+
+        return results;
+    }
+
+    /**
+     * Return scan type for the parcelable {@link SingleScanSettings}
+     */
+    private static int getScanType(@WifiAnnotations.ScanType int scanType) {
+        switch (scanType) {
+            case WifiScanner.SCAN_TYPE_LOW_LATENCY:
+                return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN;
+            case WifiScanner.SCAN_TYPE_LOW_POWER:
+                return IWifiScannerImpl.SCAN_TYPE_LOW_POWER;
+            case WifiScanner.SCAN_TYPE_HIGH_ACCURACY:
+                return IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY;
+            default:
+                throw new IllegalArgumentException("Invalid scan type " + scanType);
+        }
+    }
+
+    /**
+     * Start a scan using the specified parameters. A scan is an asynchronous operation. The
+     * result of the operation is returned in the {@link ScanEventCallback} registered when
+     * setting up an interface using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}.
+     * The latest scans can be obtained using {@link #getScanResults(String, int)} and using a
+     * {@link #SCAN_TYPE_SINGLE_SCAN} for the {@code scanType}.
+     *
+     * Note: The interface must have been already set up using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}
+     * or {@link #setupInterfaceForSoftApMode(String)}.
+     *
+     * @param ifaceName Name of the interface on which to initiate the scan.
+     * @param scanType Type of scan to perform, can be any of
+     * {@link WifiScanner#SCAN_TYPE_HIGH_ACCURACY}, {@link WifiScanner#SCAN_TYPE_LOW_POWER}, or
+     * {@link WifiScanner#SCAN_TYPE_LOW_LATENCY}.
+     * @param freqs list of frequencies to scan for, if null scan all supported channels.
+     * @param hiddenNetworkSSIDs List of hidden networks to be scanned for, a null indicates that
+     *                           no hidden frequencies will be scanned for.
+     * @return Returns true on success, false on failure (e.g. when called before the interface
+     * has been set up).
+     */
+    public boolean startScan(@NonNull String ifaceName, @WifiAnnotations.ScanType int scanType,
+            @Nullable Set<Integer> freqs, @Nullable List<byte[]> hiddenNetworkSSIDs) {
+        IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
+        if (scannerImpl == null) {
+            Log.e(TAG, "No valid wificond scanner interface handler");
+            return false;
+        }
+        SingleScanSettings settings = new SingleScanSettings();
+        try {
+            settings.scanType = getScanType(scanType);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Invalid scan type ", e);
+            return false;
+        }
+        settings.channelSettings  = new ArrayList<>();
+        settings.hiddenNetworks  = new ArrayList<>();
+
+        if (freqs != null) {
+            for (Integer freq : freqs) {
+                ChannelSettings channel = new ChannelSettings();
+                channel.frequency = freq;
+                settings.channelSettings.add(channel);
+            }
+        }
+        if (hiddenNetworkSSIDs != null) {
+            for (byte[] ssid : hiddenNetworkSSIDs) {
+                HiddenNetwork network = new HiddenNetwork();
+                network.ssid = ssid;
+
+                // settings.hiddenNetworks is expected to be very small, so this shouldn't cause
+                // any performance issues.
+                if (!settings.hiddenNetworks.contains(network)) {
+                    settings.hiddenNetworks.add(network);
+                }
+            }
+        }
+
+        try {
+            return scannerImpl.scan(settings);
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to request scan due to remote exception");
+        }
+        return false;
+    }
+
+    /**
+     * Request a PNO (Preferred Network Offload). The offload request and the scans are asynchronous
+     * operations. The result of the request are returned in the {@code callback} parameter which
+     * is an {@link PnoScanRequestCallback}. The scan results are are return in the
+     * {@link ScanEventCallback} which is registered when setting up an interface using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}.
+     * The latest PNO scans can be obtained using {@link #getScanResults(String, int)} with the
+     * {@code scanType} set to {@link #SCAN_TYPE_PNO_SCAN}.
+     *
+     * Note: The interface must have been already set up using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}
+     * or {@link #setupInterfaceForSoftApMode(String)}.
+     *
+     * @param ifaceName Name of the interface on which to request a PNO.
+     * @param pnoSettings PNO scan configuration.
+     * @param executor The Executor on which to execute the callback.
+     * @param callback Callback for the results of the offload request.
+     * @return true on success, false on failure (e.g. when called before the interface has been set
+     * up).
+     */
+    public boolean startPnoScan(@NonNull String ifaceName, @NonNull PnoSettings pnoSettings,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull PnoScanRequestCallback callback) {
+        IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
+        if (scannerImpl == null) {
+            Log.e(TAG, "No valid wificond scanner interface handler");
+            return false;
+        }
+
+        if (callback == null || executor == null) {
+            Log.e(TAG, "startPnoScan called with a null callback");
+            return false;
+        }
+
+        try {
+            boolean success = scannerImpl.startPnoScan(pnoSettings);
+            if (success) {
+                executor.execute(callback::onPnoRequestSucceeded);
+            } else {
+                executor.execute(callback::onPnoRequestFailed);
+            }
+            return success;
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to start pno scan due to remote exception");
+        }
+        return false;
+    }
+
+    /**
+     * Stop PNO scan configured with
+     * {@link #startPnoScan(String, PnoSettings, Executor, PnoScanRequestCallback)}.
+     *
+     * Note: The interface must have been already set up using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}
+     * or {@link #setupInterfaceForSoftApMode(String)}.
+     *
+     * @param ifaceName Name of the interface on which the PNO scan was configured.
+     * @return true on success, false on failure (e.g. when called before the interface has been
+     * set up).
+     */
+    public boolean stopPnoScan(@NonNull String ifaceName) {
+        IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
+        if (scannerImpl == null) {
+            Log.e(TAG, "No valid wificond scanner interface handler");
+            return false;
+        }
+        try {
+            return scannerImpl.stopPnoScan();
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to stop pno scan due to remote exception");
+        }
+        return false;
+    }
+
+    /**
+     * Abort ongoing single scan started with {@link #startScan(String, int, Set, List)}. No failure
+     * callback, e.g. {@link ScanEventCallback#onScanFailed()}, is triggered by this operation.
+     *
+     * Note: The interface must have been already set up using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}
+     * or {@link #setupInterfaceForSoftApMode(String)}. If the interface has not been set up then
+     * this method has no impact.
+     *
+     * @param ifaceName Name of the interface on which the scan was started.
+     */
+    public void abortScan(@NonNull String ifaceName) {
+        IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);
+        if (scannerImpl == null) {
+            Log.e(TAG, "No valid wificond scanner interface handler");
+            return;
+        }
+        try {
+            scannerImpl.abortScan();
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to request abortScan due to remote exception");
+        }
+    }
+
+    /**
+     * Query the list of valid frequencies (in MHz) for the provided band.
+     * The result depends on the on the country code that has been set.
+     *
+     * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
+     * The following bands are supported:
+     * {@link WifiScanner#WIFI_BAND_24_GHZ},
+     * {@link WifiScanner#WIFI_BAND_5_GHZ},
+     * {@link WifiScanner#WIFI_BAND_5_GHZ_DFS_ONLY},
+     * {@link WifiScanner#WIFI_BAND_6_GHZ}
+     * @return frequencies vector of valid frequencies (MHz), or an empty array for error.
+     * @throws IllegalArgumentException if band is not recognized.
+     */
+    public @NonNull int[] getChannelsMhzForBand(@WifiAnnotations.WifiBandBasic int band) {
+        if (mWificond == null) {
+            Log.e(TAG, "No valid wificond scanner interface handler");
+            return new int[0];
+        }
+        int[] result = null;
+        try {
+            switch (band) {
+                case WifiScanner.WIFI_BAND_24_GHZ:
+                    result = mWificond.getAvailable2gChannels();
+                    break;
+                case WifiScanner.WIFI_BAND_5_GHZ:
+                    result = mWificond.getAvailable5gNonDFSChannels();
+                    break;
+                case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY:
+                    result = mWificond.getAvailableDFSChannels();
+                    break;
+                case WifiScanner.WIFI_BAND_6_GHZ:
+                    result = mWificond.getAvailable6gChannels();
+                    break;
+                default:
+                    throw new IllegalArgumentException("unsupported band " + band);
+            }
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to request getChannelsForBand due to remote exception");
+        }
+        if (result == null) {
+            result = new int[0];
+        }
+        return result;
+    }
+
+    /** Helper function to look up the interface handle using name */
+    private IApInterface getApInterface(@NonNull String ifaceName) {
+        return mApInterfaces.get(ifaceName);
+    }
+
+    /**
+     * Get the device phy capabilities for a given interface.
+     *
+     * Note: The interface must have been already set up using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}
+     * or {@link #setupInterfaceForSoftApMode(String)}.
+     *
+     * @return DeviceWiphyCapabilities or null on error (e.g. when called on an interface which has
+     * not been set up).
+     */
+    @Nullable public DeviceWiphyCapabilities getDeviceWiphyCapabilities(@NonNull String ifaceName) {
+        if (mWificond == null) {
+            Log.e(TAG, "Can not query for device wiphy capabilities at this time");
+            return null;
+        }
+
+        try {
+            return mWificond.getDeviceWiphyCapabilities(ifaceName);
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Register the provided callback handler for SoftAp events. The interface must first be created
+     * using {@link #setupInterfaceForSoftApMode(String)}. The callback registration is valid until
+     * the interface is deleted using {@link #tearDownSoftApInterface(String)} (no deregistration
+     * method is provided).
+     * <p>
+     * Note that only one callback can be registered at a time - any registration overrides previous
+     * registrations.
+     *
+     * @param ifaceName Name of the interface on which to register the callback.
+     * @param executor The Executor on which to execute the callbacks.
+     * @param callback Callback for AP events.
+     * @return true on success, false on failure (e.g. when called on an interface which has not
+     * been set up).
+     */
+    public boolean registerApCallback(@NonNull String ifaceName,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull SoftApCallback callback) {
+        IApInterface iface = getApInterface(ifaceName);
+        if (iface == null) {
+            Log.e(TAG, "No valid ap interface handler");
+            return false;
+        }
+
+        if (callback == null || executor == null) {
+            Log.e(TAG, "registerApCallback called with a null callback");
+            return false;
+        }
+
+        try {
+            IApInterfaceEventCallback wificondCallback = new ApInterfaceEventCallback(executor,
+                    callback);
+            mApInterfaceListeners.put(ifaceName, wificondCallback);
+            boolean success = iface.registerCallback(wificondCallback);
+            if (!success) {
+                Log.e(TAG, "Failed to register ap callback.");
+                return false;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception in registering AP callback: " + e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Send a management frame on the specified interface at the specified rate. Useful for probing
+     * the link with arbitrary frames.
+     *
+     * Note: The interface must have been already set up using
+     * {@link #setupInterfaceForClientMode(String, Executor, ScanEventCallback, ScanEventCallback)}
+     * or {@link #setupInterfaceForSoftApMode(String)}.
+     *
+     * @param ifaceName The interface on which to send the frame.
+     * @param frame The raw byte array of the management frame to tramit.
+     * @param mcs The MCS (modulation and coding scheme), i.e. rate, at which to transmit the
+     *            frame. Specified per IEEE 802.11.
+     * @param executor The Executor on which to execute the callbacks.
+     * @param callback A {@link SendMgmtFrameCallback} callback for results of the operation.
+     */
+    public void sendMgmtFrame(@NonNull String ifaceName, @NonNull byte[] frame, int mcs,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull SendMgmtFrameCallback callback) {
+
+        if (callback == null || executor == null) {
+            Log.e(TAG, "callback cannot be null!");
+            return;
+        }
+
+        if (frame == null) {
+            Log.e(TAG, "frame cannot be null!");
+            executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN));
+            return;
+        }
+
+        // TODO (b/112029045) validate mcs
+        IClientInterface clientInterface = getClientInterface(ifaceName);
+        if (clientInterface == null) {
+            Log.e(TAG, "No valid wificond client interface handler");
+            executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN));
+            return;
+        }
+
+        if (!mSendMgmtFrameInProgress.compareAndSet(false, true)) {
+            Log.e(TAG, "An existing management frame transmission is in progress!");
+            executor.execute(() -> callback.onFailure(SEND_MGMT_FRAME_ERROR_ALREADY_STARTED));
+            return;
+        }
+
+        SendMgmtFrameEvent sendMgmtFrameEvent = new SendMgmtFrameEvent(executor, callback);
+        try {
+            clientInterface.SendMgmtFrame(frame, sendMgmtFrameEvent, mcs);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Exception while starting link probe: " + e);
+            // Call sendMgmtFrameEvent.OnFailure() instead of callback.onFailure() so that
+            // sendMgmtFrameEvent can clean up internal state, such as cancelling the timer.
+            sendMgmtFrameEvent.OnFailure(SEND_MGMT_FRAME_ERROR_UNKNOWN);
+        }
+    }
+
+    /**
+     * Clear all internal handles.
+     */
+    private void clearState() {
+        // Refresh handlers
+        mClientInterfaces.clear();
+        mWificondScanners.clear();
+        mPnoScanEventHandlers.clear();
+        mScanEventHandlers.clear();
+        mApInterfaces.clear();
+        mApInterfaceListeners.clear();
+        mSendMgmtFrameInProgress.set(false);
+    }
+
+    /**
+     * OEM parsed security type
+     */
+    public static class OemSecurityType {
+        /** The protocol defined in {@link android.net.wifi.WifiAnnotations.Protocol}. */
+        public final @WifiAnnotations.Protocol int protocol;
+        /**
+         * Supported key management types defined
+         * in {@link android.net.wifi.WifiAnnotations.KeyMgmt}.
+         */
+        @NonNull public final List<Integer> keyManagement;
+        /**
+         * Supported pairwise cipher types defined
+         * in {@link android.net.wifi.WifiAnnotations.Cipher}.
+         */
+        @NonNull public final List<Integer> pairwiseCipher;
+        /** The group cipher type defined in {@link android.net.wifi.WifiAnnotations.Cipher}. */
+        public final @WifiAnnotations.Cipher int groupCipher;
+        /**
+         * Default constructor for OemSecurityType
+         *
+         * @param protocol The protocol defined in
+         *                 {@link android.net.wifi.WifiAnnotations.Protocol}.
+         * @param keyManagement Supported key management types defined
+         *                      in {@link android.net.wifi.WifiAnnotations.KeyMgmt}.
+         * @param pairwiseCipher Supported pairwise cipher types defined
+         *                       in {@link android.net.wifi.WifiAnnotations.Cipher}.
+         * @param groupCipher The group cipher type defined
+         *                    in {@link android.net.wifi.WifiAnnotations.Cipher}.
+         */
+        public OemSecurityType(
+                @WifiAnnotations.Protocol int protocol,
+                @NonNull List<Integer> keyManagement,
+                @NonNull List<Integer> pairwiseCipher,
+                @WifiAnnotations.Cipher int groupCipher) {
+            this.protocol = protocol;
+            this.keyManagement = (keyManagement != null)
+                ? keyManagement : new ArrayList<Integer>();
+            this.pairwiseCipher = (pairwiseCipher != null)
+                ? pairwiseCipher : new ArrayList<Integer>();
+            this.groupCipher = groupCipher;
+        }
+    }
+
+    /**
+     * OEM information element parser for security types not parsed by the framework.
+     *
+     * The OEM method should use the method inputs {@code id}, {@code idExt}, and {@code bytes}
+     * to perform the parsing. The method should place the results in an OemSecurityType objct.
+     *
+     * @param id The information element id.
+     * @param idExt The information element extension id. This is valid only when id is
+     *        the extension id, {@code 255}.
+     * @param bytes The raw bytes of information element data, 'Element ID' and 'Length' are
+     *              stripped off already.
+     * @return an OemSecurityType object if this IE is parsed successfully, null otherwise.
+     */
+    @Nullable public static OemSecurityType parseOemSecurityTypeElement(
+            int id,
+            int idExt,
+            @NonNull byte[] bytes) {
+        return null;
+    }
+}
