diff --git a/libwifi_hal/Android.mk b/libwifi_hal/Android.mk
new file mode 100644
index 0000000..f39617c
--- /dev/null
+++ b/libwifi_hal/Android.mk
@@ -0,0 +1,128 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+ifneq ($(TARGET_BUILD_PDK), true)
+
+wifi_hal_cflags := \
+    -Wall \
+    -Werror \
+    -Wextra \
+    -Winit-self \
+    -Wno-unused-function \
+    -Wno-unused-parameter \
+    -Wshadow \
+    -Wunused-variable \
+    -Wwrite-strings
+ifdef WIFI_DRIVER_MODULE_PATH
+wifi_hal_cflags += -DWIFI_DRIVER_MODULE_PATH=\"$(WIFI_DRIVER_MODULE_PATH)\"
+endif
+ifdef WIFI_DRIVER_MODULE_ARG
+wifi_hal_cflags += -DWIFI_DRIVER_MODULE_ARG=\"$(WIFI_DRIVER_MODULE_ARG)\"
+endif
+ifdef WIFI_DRIVER_MODULE_NAME
+wifi_hal_cflags += -DWIFI_DRIVER_MODULE_NAME=\"$(WIFI_DRIVER_MODULE_NAME)\"
+endif
+ifdef WIFI_DRIVER_FW_PATH_STA
+wifi_hal_cflags += -DWIFI_DRIVER_FW_PATH_STA=\"$(WIFI_DRIVER_FW_PATH_STA)\"
+endif
+ifdef WIFI_DRIVER_FW_PATH_AP
+wifi_hal_cflags += -DWIFI_DRIVER_FW_PATH_AP=\"$(WIFI_DRIVER_FW_PATH_AP)\"
+endif
+ifdef WIFI_DRIVER_FW_PATH_P2P
+wifi_hal_cflags += -DWIFI_DRIVER_FW_PATH_P2P=\"$(WIFI_DRIVER_FW_PATH_P2P)\"
+endif
+ifdef WIFI_DRIVER_FW_PATH_PARAM
+wifi_hal_cflags += -DWIFI_DRIVER_FW_PATH_PARAM=\"$(WIFI_DRIVER_FW_PATH_PARAM)\"
+endif
+
+ifdef WIFI_DRIVER_STATE_CTRL_PARAM
+wifi_hal_cflags += -DWIFI_DRIVER_STATE_CTRL_PARAM=\"$(WIFI_DRIVER_STATE_CTRL_PARAM)\"
+endif
+ifdef WIFI_DRIVER_STATE_ON
+wifi_hal_cflags += -DWIFI_DRIVER_STATE_ON=\"$(WIFI_DRIVER_STATE_ON)\"
+endif
+ifdef WIFI_DRIVER_STATE_OFF
+wifi_hal_cflags += -DWIFI_DRIVER_STATE_OFF=\"$(WIFI_DRIVER_STATE_OFF)\"
+endif
+
+# Common code shared between the HALs.
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-hal-common
+LOCAL_CFLAGS := $(wifi_hal_cflags)
+LOCAL_SRC_FILES := wifi_hal_common.cpp
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+include $(BUILD_STATIC_LIBRARY)
+
+# A fallback "vendor" HAL library.
+# Don't link this, link libwifi-hal.
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-hal-fallback
+LOCAL_CFLAGS := $(wifi_hal_cflags)
+LOCAL_SRC_FILES := wifi_hal_fallback.cpp
+LOCAL_C_INCLUDES := $(call include-path-for, libhardware_legacy)
+include $(BUILD_STATIC_LIBRARY)
+
+# Pick a vendor provided HAL implementation library.
+# ============================================================
+LIB_WIFI_HAL := libwifi-hal-fallback
+ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
+  LIB_WIFI_HAL := libwifi-hal-bcm
+else ifeq ($(BOARD_WLAN_DEVICE), qcwcn)
+  LIB_WIFI_HAL := libwifi-hal-qcom
+else ifeq ($(BOARD_WLAN_DEVICE), mrvl)
+  # this is commented because none of the nexus devices
+  # that sport Marvell's wifi have support for HAL
+  # LIB_WIFI_HAL := libwifi-hal-mrvl
+else ifeq ($(BOARD_WLAN_DEVICE), MediaTek)
+  # support MTK WIFI HAL
+  LIB_WIFI_HAL := libwifi-hal-mt66xx
+endif
+
+# The WiFi HAL that you should be linking.
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-hal
+LOCAL_CFLAGS := $(wifi_hal_cflags)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(LOCAL_PATH)/include \
+    $(call include-path-for, libhardware_legacy)
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    liblog \
+    libnl \
+    libutils
+LOCAL_SRC_FILES := \
+    driver_tool.cpp
+LOCAL_WHOLE_STATIC_LIBRARIES := $(LIB_WIFI_HAL) libwifi-hal-common
+include $(BUILD_SHARED_LIBRARY)
+
+# Test utilities (e.g. mock classes) for libwifi-hal
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-hal-test
+LOCAL_CFLAGS := $(wifi_hal_cflags)
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/include \
+    $(LOCAL_PATH)/testlib/include
+LOCAL_STATIC_LIBRARIES := libgmock
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(LOCAL_PATH)/include \
+    $(LOCAL_PATH)/testlib/include
+include $(BUILD_STATIC_LIBRARY)
+
+endif
diff --git a/libwifi_hal/driver_tool.cpp b/libwifi_hal/driver_tool.cpp
new file mode 100644
index 0000000..688017b
--- /dev/null
+++ b/libwifi_hal/driver_tool.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#include "wifi_hal/driver_tool.h"
+
+#include "hardware_legacy/wifi.h"
+
+namespace android {
+namespace wifi_hal {
+
+const int DriverTool::kFirmwareModeSta = WIFI_GET_FW_PATH_STA;
+const int DriverTool::kFirmwareModeAp = WIFI_GET_FW_PATH_AP;
+const int DriverTool::kFirmwareModeP2p = WIFI_GET_FW_PATH_P2P;
+
+bool DriverTool::LoadDriver() {
+  return ::wifi_load_driver() == 0;
+}
+
+bool DriverTool::UnloadDriver() {
+  return ::wifi_unload_driver() == 0;
+}
+
+bool DriverTool::IsDriverLoaded() {
+  return ::wifi_unload_driver() != 0;
+}
+
+bool DriverTool::ChangeFirmwareMode(int mode) {
+  const char* fwpath = wifi_get_fw_path(mode);
+  if (!fwpath) {
+    return true;  // HAL doesn't think we need to load firmware for this mode.
+  }
+  if (wifi_change_fw_path(fwpath) != 0) {
+    // Not all devices actually require firmware reloads, but
+    // failure to change the firmware path when it is defined is an error.
+    return false;
+  }
+  return true;
+}
+
+}  // namespace wifi_hal
+}  // namespace android
diff --git a/libwifi_hal/include/hardware_legacy/wifi.h b/libwifi_hal/include/hardware_legacy/wifi.h
new file mode 100644
index 0000000..defff0a
--- /dev/null
+++ b/libwifi_hal/include/hardware_legacy/wifi.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#ifndef HARDWARE_LEGACY_WIFI_H
+#define HARDWARE_LEGACY_WIFI_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/**
+ * Load the Wi-Fi driver.
+ *
+ * @return 0 on success, < 0 on failure.
+ */
+int wifi_load_driver();
+
+/**
+ * Unload the Wi-Fi driver.
+ *
+ * @return 0 on success, < 0 on failure.
+ */
+int wifi_unload_driver();
+
+/**
+ * Check if the Wi-Fi driver is loaded.
+ * Check if the Wi-Fi driver is loaded.
+
+ * @return 0 on success, < 0 on failure.
+ */
+int is_wifi_driver_loaded();
+
+/**
+ * Return the path to requested firmware
+ */
+#define WIFI_GET_FW_PATH_STA  0
+#define WIFI_GET_FW_PATH_AP 1
+#define WIFI_GET_FW_PATH_P2P  2
+const char *wifi_get_fw_path(int fw_type);
+
+/**
+ * Change the path to firmware for the wlan driver
+ */
+int wifi_change_fw_path(const char *fwpath);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif  /* HARDWARE_LEGACY_WIFI_H */
diff --git a/libwifi_hal/include/wifi_hal/driver_tool.h b/libwifi_hal/include/wifi_hal/driver_tool.h
new file mode 100644
index 0000000..f1a43cc
--- /dev/null
+++ b/libwifi_hal/include/wifi_hal/driver_tool.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_WIFI_SYSTEM_DRIVER_TOOL_H
+#define ANDROID_WIFI_SYSTEM_DRIVER_TOOL_H
+
+namespace android {
+namespace wifi_hal {
+
+// Utilities for interacting with the driver.
+class DriverTool {
+ public:
+  static const int kFirmwareModeSta;
+  static const int kFirmwareModeAp;
+  static const int kFirmwareModeP2p;
+
+  DriverTool() = default;
+  virtual ~DriverTool() = default;
+
+  // These methods allow manipulation of the WiFi driver.
+  // They all return true on success, and false otherwise.
+  virtual bool LoadDriver();
+  virtual bool UnloadDriver();
+  virtual bool IsDriverLoaded();
+
+  // Change the firmware mode.
+  // |mode| is one of the kFirmwareMode* constants defined above.
+  // Returns true on success, and false otherwise.
+  virtual bool ChangeFirmwareMode(int mode);
+
+};  // class DriverTool
+
+}  // namespace wifi_hal
+}  // namespace android
+
+#endif  // ANDROID_WIFI_SYSTEM_DRIVER_TOOL_H
+
diff --git a/libwifi_hal/testlib/include/wifi_hal_test/mock_driver_tool.h b/libwifi_hal/testlib/include/wifi_hal_test/mock_driver_tool.h
new file mode 100644
index 0000000..fef0dab
--- /dev/null
+++ b/libwifi_hal/testlib/include/wifi_hal_test/mock_driver_tool.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_WIFI_HAL_MOCK_DRIVER_TOOL_H
+#define ANDROID_WIFI_HAL_MOCK_DRIVER_TOOL_H
+
+#include <wifi_hal/driver_tool.h>
+
+namespace android {
+namespace wifi_hal {
+
+class MockDriverTool : public DriverTool {
+ public:
+  ~MockDriverTool() override = default;
+  MOCK_METHOD0(LoadDriver, bool());
+  MOCK_METHOD0(UnloadDriver, bool());
+  MOCK_METHOD0(IsDriverLoaded, bool());
+  MOCK_METHOD1(ChangeFirmwareMode, bool(int mode));
+
+};  // class MockDriverTool
+
+}  // namespace wifi_hal
+}  // namespace android
+
+#endif  // ANDROID_WIFI_HAL_MOCK_DRIVER_TOOL_H
+
diff --git a/libwifi_hal/wifi_hal_common.cpp b/libwifi_hal/wifi_hal_common.cpp
new file mode 100644
index 0000000..54c38e1
--- /dev/null
+++ b/libwifi_hal/wifi_hal_common.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright 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.
+ */
+
+#include "hardware_legacy/wifi.h"
+
+#define LOG_TAG "WifiHalCommon"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <cutils/log.h>
+#include <cutils/misc.h>
+#include <cutils/properties.h>
+
+extern int init_module(void *, unsigned long, const char *);
+extern int delete_module(const char *, unsigned int);
+
+#ifndef WIFI_DRIVER_FW_PATH_STA
+#define WIFI_DRIVER_FW_PATH_STA		NULL
+#endif
+#ifndef WIFI_DRIVER_FW_PATH_AP
+#define WIFI_DRIVER_FW_PATH_AP		NULL
+#endif
+#ifndef WIFI_DRIVER_FW_PATH_P2P
+#define WIFI_DRIVER_FW_PATH_P2P		NULL
+#endif
+#ifndef WIFI_DRIVER_FW_PATH_PARAM
+#define WIFI_DRIVER_FW_PATH_PARAM	"/sys/module/wlan/parameters/fwpath"
+#endif
+
+#ifndef WIFI_DRIVER_MODULE_ARG
+#define WIFI_DRIVER_MODULE_ARG          ""
+#endif
+
+static const char DRIVER_PROP_NAME[]    = "wlan.driver.status";
+#ifdef WIFI_DRIVER_MODULE_PATH
+static const char DRIVER_MODULE_NAME[]  = WIFI_DRIVER_MODULE_NAME;
+static const char DRIVER_MODULE_TAG[]   = WIFI_DRIVER_MODULE_NAME " ";
+static const char DRIVER_MODULE_PATH[]  = WIFI_DRIVER_MODULE_PATH;
+static const char DRIVER_MODULE_ARG[]   = WIFI_DRIVER_MODULE_ARG;
+static const char MODULE_FILE[]         = "/proc/modules";
+#endif
+
+static int insmod(const char *filename, const char *args)
+{
+    void *module;
+    unsigned int size;
+    int ret;
+
+    module = load_file(filename, &size);
+    if (!module)
+        return -1;
+
+    ret = init_module(module, size, args);
+
+    free(module);
+
+    return ret;
+}
+
+static int rmmod(const char *modname)
+{
+    int ret = -1;
+    int maxtry = 10;
+
+    while (maxtry-- > 0) {
+        ret = delete_module(modname, O_NONBLOCK | O_EXCL);
+        if (ret < 0 && errno == EAGAIN)
+            usleep(500000);
+        else
+            break;
+    }
+
+    if (ret != 0)
+        ALOGD("Unable to unload driver module \"%s\": %s\n",
+             modname, strerror(errno));
+    return ret;
+}
+
+#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
+int wifi_change_driver_state(const char *state)
+{
+    int len;
+    int fd;
+    int ret = 0;
+
+    if (!state)
+        return -1;
+    fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_STATE_CTRL_PARAM, O_WRONLY));
+    if (fd < 0) {
+        ALOGE("Failed to open driver state control param (%s)", strerror(errno));
+        return -1;
+    }
+    len = strlen(state) + 1;
+    if (TEMP_FAILURE_RETRY(write(fd, state, len)) != len) {
+        ALOGE("Failed to write driver state control param (%s)", strerror(errno));
+        ret = -1;
+    }
+    close(fd);
+    return ret;
+}
+#endif
+
+int is_wifi_driver_loaded() {
+    char driver_status[PROPERTY_VALUE_MAX];
+#ifdef WIFI_DRIVER_MODULE_PATH
+    FILE *proc;
+    char line[sizeof(DRIVER_MODULE_TAG)+10];
+#endif
+
+    if (!property_get(DRIVER_PROP_NAME, driver_status, NULL)
+            || strcmp(driver_status, "ok") != 0) {
+        return 0;  /* driver not loaded */
+    }
+#ifdef WIFI_DRIVER_MODULE_PATH
+    /*
+     * If the property says the driver is loaded, check to
+     * make sure that the property setting isn't just left
+     * over from a previous manual shutdown or a runtime
+     * crash.
+     */
+    if ((proc = fopen(MODULE_FILE, "r")) == NULL) {
+        ALOGW("Could not open %s: %s", MODULE_FILE, strerror(errno));
+        property_set(DRIVER_PROP_NAME, "unloaded");
+        return 0;
+    }
+    while ((fgets(line, sizeof(line), proc)) != NULL) {
+        if (strncmp(line, DRIVER_MODULE_TAG, strlen(DRIVER_MODULE_TAG)) == 0) {
+            fclose(proc);
+            return 1;
+        }
+    }
+    fclose(proc);
+    property_set(DRIVER_PROP_NAME, "unloaded");
+    return 0;
+#else
+    return 1;
+#endif
+}
+
+int wifi_load_driver()
+{
+#ifdef WIFI_DRIVER_MODULE_PATH
+    if (is_wifi_driver_loaded()) {
+        return 0;
+    }
+
+    if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0)
+        return -1;
+
+#elif defined WIFI_DRIVER_STATE_CTRL_PARAM
+    if (is_wifi_driver_loaded()) {
+        return 0;
+    }
+
+    if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0)
+        return -1;
+#endif
+    property_set(DRIVER_PROP_NAME, "ok");
+    return 0;
+}
+
+int wifi_unload_driver()
+{
+    usleep(200000); /* allow to finish interface down */
+#ifdef WIFI_DRIVER_MODULE_PATH
+    if (rmmod(DRIVER_MODULE_NAME) == 0) {
+        int count = 20; /* wait at most 10 seconds for completion */
+        while (count-- > 0) {
+            if (!is_wifi_driver_loaded())
+                break;
+            usleep(500000);
+        }
+        usleep(500000); /* allow card removal */
+        if (count) {
+            return 0;
+        }
+        return -1;
+    } else
+        return -1;
+#else
+#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
+    if (is_wifi_driver_loaded()) {
+        if (wifi_change_driver_state(WIFI_DRIVER_STATE_OFF) < 0)
+            return -1;
+    }
+#endif
+    property_set(DRIVER_PROP_NAME, "unloaded");
+    return 0;
+#endif
+}
+
+const char *wifi_get_fw_path(int fw_type)
+{
+    switch (fw_type) {
+    case WIFI_GET_FW_PATH_STA:
+        return WIFI_DRIVER_FW_PATH_STA;
+    case WIFI_GET_FW_PATH_AP:
+        return WIFI_DRIVER_FW_PATH_AP;
+    case WIFI_GET_FW_PATH_P2P:
+        return WIFI_DRIVER_FW_PATH_P2P;
+    }
+    return NULL;
+}
+
+int wifi_change_fw_path(const char *fwpath)
+{
+    int len;
+    int fd;
+    int ret = 0;
+
+    if (!fwpath)
+        return ret;
+    fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_FW_PATH_PARAM, O_WRONLY));
+    if (fd < 0) {
+        ALOGE("Failed to open wlan fw path param (%s)", strerror(errno));
+        return -1;
+    }
+    len = strlen(fwpath) + 1;
+    if (TEMP_FAILURE_RETRY(write(fd, fwpath, len)) != len) {
+        ALOGE("Failed to write wlan fw path param (%s)", strerror(errno));
+        ret = -1;
+    }
+    close(fd);
+    return ret;
+}
diff --git a/libwifi_hal/wifi_hal_fallback.cpp b/libwifi_hal/wifi_hal_fallback.cpp
new file mode 100644
index 0000000..64259a1
--- /dev/null
+++ b/libwifi_hal/wifi_hal_fallback.cpp
@@ -0,0 +1,21 @@
+/*
+ * Copyright 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.
+ */
+
+#include "hardware_legacy/wifi_hal.h"
+
+wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) {
+    return WIFI_ERROR_NOT_SUPPORTED;
+}
diff --git a/libwifi_system/Android.mk b/libwifi_system/Android.mk
new file mode 100644
index 0000000..61d340a
--- /dev/null
+++ b/libwifi_system/Android.mk
@@ -0,0 +1,91 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(TARGET_BUILD_PDK), true)
+
+wifi_system_cflags := \
+    -Wall \
+    -Werror \
+    -Wextra \
+    -Winit-self \
+    -Wno-unused-function \
+    -Wno-unused-parameter \
+    -Wshadow \
+    -Wunused-variable \
+    -Wwrite-strings
+
+# Device independent wifi system logic.
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-system
+LOCAL_CFLAGS := $(wifi_system_cflags)
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbase
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    libcrypto \
+    libcutils \
+    liblog \
+    libnetutils \
+    libnl \
+    libwifi-hal
+
+# Tolerate certain emulators which apparently don't have supplicant installed.
+ifdef WPA_SUPPLICANT_VERSION
+LOCAL_CFLAGS += -DLIBWPA_CLIENT_EXISTS
+LOCAL_SHARED_LIBRARIES += libwpa_client
+endif
+
+LOCAL_SRC_FILES := \
+    hostapd_manager.cpp \
+    interface_tool.cpp \
+    hal_tool.cpp \
+    wifi.cpp
+include $(BUILD_SHARED_LIBRARY)
+
+# Test utilities (e.g. mock classes) for libwifi-system
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-system-test
+LOCAL_CFLAGS := $(wifi_system_cflags)
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/include \
+    $(LOCAL_PATH)/testlib/include
+LOCAL_STATIC_LIBRARIES := libgmock
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+    $(LOCAL_PATH)/include \
+    $(LOCAL_PATH)/testlib/include
+include $(BUILD_STATIC_LIBRARY)
+
+
+# Unit tests for libwifi-system
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := libwifi-system_tests
+LOCAL_CPPFLAGS := $(wificond_cpp_flags)
+LOCAL_SRC_FILES := \
+    tests/main.cpp \
+    tests/hostapd_manager_unittest.cpp
+LOCAL_STATIC_LIBRARIES := \
+    libgmock \
+    libgtest
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    libwifi-system
+include $(BUILD_NATIVE_TEST)
+
+endif
diff --git a/libwifi_system/hal_tool.cpp b/libwifi_system/hal_tool.cpp
new file mode 100644
index 0000000..4c7401d
--- /dev/null
+++ b/libwifi_system/hal_tool.cpp
@@ -0,0 +1,585 @@
+/*
+ * 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.
+ */
+
+#include "wifi_system/hal_tool.h"
+
+#include <log/log.h>
+
+namespace android {
+namespace wifi_system {
+namespace {
+
+wifi_error wifi_initialize_stub(wifi_handle* handle) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+void wifi_cleanup_stub(wifi_handle handle, wifi_cleaned_up_handler handler) {}
+
+void wifi_event_loop_stub(wifi_handle handle) {}
+
+void wifi_get_error_info_stub(wifi_error err, const char** msg) { *msg = NULL; }
+
+wifi_error wifi_get_supported_feature_set_stub(wifi_interface_handle handle,
+                                               feature_set* set) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_get_concurrency_matrix_stub(wifi_interface_handle handle,
+                                            int max_size, feature_set* matrix,
+                                            int* size) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_set_scanning_mac_oui_stub(wifi_interface_handle handle,
+                                          unsigned char* oui_data) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+/* List of all supported channels, including 5GHz channels */
+wifi_error wifi_get_supported_channels_stub(wifi_handle handle, int* size,
+                                            wifi_channel* list) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+/* Enhanced power reporting */
+wifi_error wifi_is_epr_supported_stub(wifi_handle handle) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+/* multiple interface support */
+wifi_error wifi_get_ifaces_stub(wifi_handle handle, int* num_ifaces,
+                                wifi_interface_handle** ifaces) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_get_iface_name_stub(wifi_interface_handle iface, char* name,
+                                    size_t size) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_set_iface_event_handler_stub(wifi_request_id id,
+                                             wifi_interface_handle iface,
+                                             wifi_event_handler eh) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_reset_iface_event_handler_stub(wifi_request_id id,
+                                               wifi_interface_handle iface) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_start_gscan_stub(wifi_request_id id,
+                                 wifi_interface_handle iface,
+                                 wifi_scan_cmd_params params,
+                                 wifi_scan_result_handler handler) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_stop_gscan_stub(wifi_request_id id,
+                                wifi_interface_handle iface) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_get_cached_gscan_results_stub(wifi_interface_handle iface,
+                                              byte flush, int max,
+                                              wifi_cached_scan_results* results,
+                                              int* num) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_set_bssid_hotlist_stub(wifi_request_id id,
+                                       wifi_interface_handle iface,
+                                       wifi_bssid_hotlist_params params,
+                                       wifi_hotlist_ap_found_handler handler) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_reset_bssid_hotlist_stub(wifi_request_id id,
+                                         wifi_interface_handle iface) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_set_significant_change_handler_stub(
+    wifi_request_id id, wifi_interface_handle iface,
+    wifi_significant_change_params params,
+    wifi_significant_change_handler handler) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_reset_significant_change_handler_stub(
+    wifi_request_id id, wifi_interface_handle iface) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_get_gscan_capabilities_stub(
+    wifi_interface_handle handle, wifi_gscan_capabilities* capabilities) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_set_link_stats_stub(wifi_interface_handle iface,
+                                    wifi_link_layer_params params) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_get_link_stats_stub(wifi_request_id id,
+                                    wifi_interface_handle iface,
+                                    wifi_stats_result_handler handler) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_clear_link_stats_stub(wifi_interface_handle iface,
+                                      u32 stats_clear_req_mask,
+                                      u32* stats_clear_rsp_mask, u8 stop_req,
+                                      u8* stop_rsp) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+wifi_error wifi_get_valid_channels_stub(wifi_interface_handle handle, int band,
+                                        int max_channels,
+                                        wifi_channel* channels,
+                                        int* num_channels) {
+  return WIFI_ERROR_UNINITIALIZED;
+}
+
+/* API to request RTT measurement */
+wifi_error wifi_rtt_range_request_stub(wifi_request_id id,
+                                       wifi_interface_handle iface,
+                                       unsigned num_rtt_config,
+                                       wifi_rtt_config rtt_config[],
+                                       wifi_rtt_event_handler handler) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+/* API to cancel RTT measurements */
+wifi_error wifi_rtt_range_cancel_stub(wifi_request_id id,
+                                      wifi_interface_handle iface,
+                                      unsigned num_devices, mac_addr addr[]) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+/* API to get RTT capability */
+wifi_error wifi_get_rtt_capabilities_stub(wifi_interface_handle iface,
+                                          wifi_rtt_capabilities* capabilities) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+/* API to enable RTT responder role */
+wifi_error wifi_enable_responder_stub(wifi_request_id id,
+                                      wifi_interface_handle iface,
+                                      wifi_channel_info channel_hint,
+                                      unsigned max_duration_seconds,
+                                      wifi_channel_info* channel_used) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+/* API to disable RTT responder role */
+wifi_error wifi_disable_responder_stub(wifi_request_id id,
+                                       wifi_interface_handle iface) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+/* API to get available channel for RTT responder role */
+wifi_error wifi_rtt_get_available_channel_stub(wifi_interface_handle iface,
+                                               wifi_channel_info* channel) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_set_nodfs_flag_stub(wifi_interface_handle iface, u32 nodfs) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_start_logging_stub(wifi_interface_handle iface,
+                                   u32 verbose_level, u32 flags,
+                                   u32 max_interval_sec, u32 min_data_size,
+                                   char* buffer_name) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_set_epno_list_stub(int id, wifi_interface_info* iface,
+                                   const wifi_epno_params* params,
+                                   wifi_epno_handler handler) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_reset_epno_list_stub(int id, wifi_interface_info* iface) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_set_country_code_stub(wifi_interface_handle iface,
+                                      const char* code) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_firmware_memory_dump_stub(
+    wifi_interface_handle iface, wifi_firmware_memory_dump_handler handler) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_set_log_handler_stub(wifi_request_id id,
+                                     wifi_interface_handle iface,
+                                     wifi_ring_buffer_data_handler handler) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_reset_log_handler_stub(wifi_request_id id,
+                                       wifi_interface_handle iface) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_set_alert_handler_stub(wifi_request_id id,
+                                       wifi_interface_handle iface,
+                                       wifi_alert_handler handler) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_reset_alert_handler_stub(wifi_request_id id,
+                                         wifi_interface_handle iface) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_firmware_version_stub(wifi_interface_handle iface,
+                                          char* buffer, int buffer_size) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_ring_buffers_status_stub(wifi_interface_handle iface,
+                                             u32* num_rings,
+                                             wifi_ring_buffer_status* status) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_logger_supported_feature_set_stub(
+    wifi_interface_handle iface, unsigned int* support) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_ring_data_stub(wifi_interface_handle iface,
+                                   char* ring_name) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_driver_version_stub(wifi_interface_handle iface,
+                                        char* buffer, int buffer_size) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_enable_tdls_stub(wifi_interface_handle iface, mac_addr addr,
+                                 wifi_tdls_params* params,
+                                 wifi_tdls_handler handler) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_disable_tdls_stub(wifi_interface_handle iface, mac_addr addr) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_tdls_status_stub(wifi_interface_handle iface, mac_addr addr,
+                                     wifi_tdls_status* status) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_tdls_capabilities_stub(
+    wifi_interface_handle iface, wifi_tdls_capabilities* capabilities) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_set_bssid_blacklist_stub(wifi_request_id id,
+                                         wifi_interface_handle iface,
+                                         wifi_bssid_params params) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_start_sending_offloaded_packet_stub(
+    wifi_request_id id, wifi_interface_handle iface, u8* ip_packet,
+    u16 ip_packet_len, u8* src_mac_addr, u8* dst_mac_addr, u32 period_msec) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_stop_sending_offloaded_packet_stub(
+    wifi_request_id id, wifi_interface_handle iface) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_wake_reason_stats_stub(
+    wifi_interface_handle iface,
+    WLAN_DRIVER_WAKE_REASON_CNT* wifi_wake_reason_cnt) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_configure_nd_offload_stub(wifi_interface_handle iface,
+                                          u8 enable) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_driver_memory_dump_stub(
+    wifi_interface_handle iface, wifi_driver_memory_dump_callbacks callbacks) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_start_pkt_fate_monitoring_stub(wifi_interface_handle iface) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_tx_pkt_fates_stub(wifi_interface_handle handle,
+                                      wifi_tx_report* tx_report_bufs,
+                                      size_t n_requested_fates,
+                                      size_t* n_provided_fates) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_rx_pkt_fates_stub(wifi_interface_handle handle,
+                                      wifi_rx_report* rx_report_bufs,
+                                      size_t n_requested_fates,
+                                      size_t* n_provided_fates) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+wifi_error wifi_nan_enable_request_stub(transaction_id id,
+                                        wifi_interface_handle iface,
+                                        NanEnableRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_disable_request_stub(transaction_id id,
+                                         wifi_interface_handle iface) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_publish_request_stub(transaction_id id,
+                                         wifi_interface_handle iface,
+                                         NanPublishRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_publish_cancel_request_stub(transaction_id id,
+                                                wifi_interface_handle iface,
+                                                NanPublishCancelRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_subscribe_request_stub(transaction_id id,
+                                           wifi_interface_handle iface,
+                                           NanSubscribeRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_subscribe_cancel_request_stub(
+    transaction_id id, wifi_interface_handle iface,
+    NanSubscribeCancelRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_transmit_followup_request_stub(
+    transaction_id id, wifi_interface_handle iface,
+    NanTransmitFollowupRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_stats_request_stub(transaction_id id,
+                                       wifi_interface_handle iface,
+                                       NanStatsRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_config_request_stub(transaction_id id,
+                                        wifi_interface_handle iface,
+                                        NanConfigRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_tca_request_stub(transaction_id id,
+                                     wifi_interface_handle iface,
+                                     NanTCARequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_beacon_sdf_payload_request_stub(
+    transaction_id id, wifi_interface_handle iface,
+    NanBeaconSdfPayloadRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_register_handler_stub(wifi_interface_handle iface,
+                                          NanCallbackHandler handlers) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_get_version_stub(wifi_handle handle, NanVersion* version) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_get_capabilities_stub(transaction_id id,
+                                          wifi_interface_handle iface) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_data_interface_create_stub(transaction_id id,
+                                               wifi_interface_handle iface,
+                                               char* iface_name) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_data_interface_delete_stub(transaction_id id,
+                                               wifi_interface_handle iface,
+                                               char* iface_name) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_data_request_initiator_stub(
+    transaction_id id, wifi_interface_handle iface,
+    NanDataPathInitiatorRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_data_indication_response_stub(
+    transaction_id id, wifi_interface_handle iface,
+    NanDataPathIndicationResponse* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_nan_data_end_stub(transaction_id id,
+                                  wifi_interface_handle iface,
+                                  NanDataPathEndRequest* msg) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_get_packet_filter_capabilities_stub(
+    wifi_interface_handle handle, u32* version, u32* max_len) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+wifi_error wifi_set_packet_filter_stub(wifi_interface_handle handle,
+                                       const u8* program, u32 len) {
+  return WIFI_ERROR_NOT_SUPPORTED;
+}
+
+bool init_wifi_stub_hal_func_table(wifi_hal_fn* hal_fn) {
+  if (hal_fn == NULL) {
+    return false;
+  }
+  hal_fn->wifi_initialize = wifi_initialize_stub;
+  hal_fn->wifi_cleanup = wifi_cleanup_stub;
+  hal_fn->wifi_event_loop = wifi_event_loop_stub;
+  hal_fn->wifi_get_error_info = wifi_get_error_info_stub;
+  hal_fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set_stub;
+  hal_fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix_stub;
+  hal_fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui_stub;
+  hal_fn->wifi_get_supported_channels = wifi_get_supported_channels_stub;
+  hal_fn->wifi_is_epr_supported = wifi_is_epr_supported_stub;
+  hal_fn->wifi_get_ifaces = wifi_get_ifaces_stub;
+  hal_fn->wifi_get_iface_name = wifi_get_iface_name_stub;
+  hal_fn->wifi_reset_iface_event_handler = wifi_reset_iface_event_handler_stub;
+  hal_fn->wifi_start_gscan = wifi_start_gscan_stub;
+  hal_fn->wifi_stop_gscan = wifi_stop_gscan_stub;
+  hal_fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results_stub;
+  hal_fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist_stub;
+  hal_fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist_stub;
+  hal_fn->wifi_set_significant_change_handler =
+      wifi_set_significant_change_handler_stub;
+  hal_fn->wifi_reset_significant_change_handler =
+      wifi_reset_significant_change_handler_stub;
+  hal_fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities_stub;
+  hal_fn->wifi_set_link_stats = wifi_set_link_stats_stub;
+  hal_fn->wifi_get_link_stats = wifi_get_link_stats_stub;
+  hal_fn->wifi_clear_link_stats = wifi_clear_link_stats_stub;
+  hal_fn->wifi_get_valid_channels = wifi_get_valid_channels_stub;
+  hal_fn->wifi_rtt_range_request = wifi_rtt_range_request_stub;
+  hal_fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel_stub;
+  hal_fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities_stub;
+  hal_fn->wifi_start_logging = wifi_start_logging_stub;
+  hal_fn->wifi_set_epno_list = wifi_set_epno_list_stub;
+  hal_fn->wifi_set_country_code = wifi_set_country_code_stub;
+  hal_fn->wifi_enable_tdls = wifi_enable_tdls_stub;
+  hal_fn->wifi_disable_tdls = wifi_disable_tdls_stub;
+  hal_fn->wifi_get_tdls_status = wifi_get_tdls_status_stub;
+  hal_fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities_stub;
+  hal_fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag_stub;
+  hal_fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump_stub;
+  hal_fn->wifi_set_log_handler = wifi_set_log_handler_stub;
+  hal_fn->wifi_reset_log_handler = wifi_reset_log_handler_stub;
+  hal_fn->wifi_set_alert_handler = wifi_set_alert_handler_stub;
+  hal_fn->wifi_reset_alert_handler = wifi_reset_alert_handler_stub;
+  hal_fn->wifi_get_firmware_version = wifi_get_firmware_version_stub;
+  hal_fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status_stub;
+  hal_fn->wifi_get_logger_supported_feature_set =
+      wifi_get_logger_supported_feature_set_stub;
+  hal_fn->wifi_get_ring_data = wifi_get_ring_data_stub;
+  hal_fn->wifi_get_driver_version = wifi_get_driver_version_stub;
+  hal_fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist_stub;
+  hal_fn->wifi_start_sending_offloaded_packet =
+      wifi_start_sending_offloaded_packet_stub;
+  hal_fn->wifi_stop_sending_offloaded_packet =
+      wifi_stop_sending_offloaded_packet_stub;
+  hal_fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats_stub;
+  hal_fn->wifi_configure_nd_offload = wifi_configure_nd_offload_stub;
+  hal_fn->wifi_get_driver_memory_dump = wifi_get_driver_memory_dump_stub;
+  hal_fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring_stub;
+  hal_fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates_stub;
+  hal_fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates_stub;
+  hal_fn->wifi_nan_enable_request = wifi_nan_enable_request_stub;
+  hal_fn->wifi_nan_disable_request = wifi_nan_disable_request_stub;
+  hal_fn->wifi_nan_publish_request = wifi_nan_publish_request_stub;
+  hal_fn->wifi_nan_publish_cancel_request =
+      wifi_nan_publish_cancel_request_stub;
+  hal_fn->wifi_nan_subscribe_request = wifi_nan_subscribe_request_stub;
+  hal_fn->wifi_nan_subscribe_cancel_request =
+      wifi_nan_subscribe_cancel_request_stub;
+  hal_fn->wifi_nan_transmit_followup_request =
+      wifi_nan_transmit_followup_request_stub;
+  hal_fn->wifi_nan_stats_request = wifi_nan_stats_request_stub;
+  hal_fn->wifi_nan_config_request = wifi_nan_config_request_stub;
+  hal_fn->wifi_nan_tca_request = wifi_nan_tca_request_stub;
+  hal_fn->wifi_nan_beacon_sdf_payload_request =
+      wifi_nan_beacon_sdf_payload_request_stub;
+  hal_fn->wifi_nan_register_handler = wifi_nan_register_handler_stub;
+  hal_fn->wifi_nan_get_version = wifi_nan_get_version_stub;
+  hal_fn->wifi_nan_get_capabilities = wifi_nan_get_capabilities_stub;
+  hal_fn->wifi_nan_data_interface_create = wifi_nan_data_interface_create_stub;
+  hal_fn->wifi_nan_data_interface_delete = wifi_nan_data_interface_delete_stub;
+  hal_fn->wifi_nan_data_request_initiator =
+      wifi_nan_data_request_initiator_stub;
+  hal_fn->wifi_nan_data_indication_response =
+      wifi_nan_data_indication_response_stub;
+  hal_fn->wifi_nan_data_end = wifi_nan_data_end_stub;
+  hal_fn->wifi_get_packet_filter_capabilities =
+      wifi_get_packet_filter_capabilities_stub;
+  hal_fn->wifi_set_packet_filter = wifi_set_packet_filter_stub;
+
+  return true;
+}
+
+}  // namespace
+
+bool HalTool::InitFunctionTable(wifi_hal_fn* hal_fn) {
+  if (!init_wifi_stub_hal_func_table(hal_fn)) {
+    ALOGE("Can not initialize the basic function pointer table");
+    return false;
+  }
+
+  if (init_wifi_vendor_hal_func_table(hal_fn) != WIFI_SUCCESS) {
+    ALOGE("Can not initialize the vendor function pointer table");
+    return false;
+  }
+
+  return true;
+}
+
+bool HalTool::CanGetValidChannels(wifi_hal_fn* hal_fn) {
+  return hal_fn &&
+         (hal_fn->wifi_get_valid_channels != wifi_get_valid_channels_stub);
+}
+
+}  // namespace wifi_system
+}  // namespace android
diff --git a/libwifi_system/hostapd_manager.cpp b/libwifi_system/hostapd_manager.cpp
new file mode 100644
index 0000000..889fd69
--- /dev/null
+++ b/libwifi_system/hostapd_manager.cpp
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+#include "wifi_system/hostapd_manager.h"
+
+#include <iomanip>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <cutils/properties.h>
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+#include <private/android_filesystem_config.h>
+
+#include "wifi_system/wifi.h"
+
+using android::base::StringPrintf;
+using android::base::WriteStringToFile;
+using std::string;
+using std::vector;
+using std::stringstream;
+
+namespace android {
+namespace wifi_system {
+namespace {
+
+const int kDefaultApChannel = 6;
+const char kHostapdServiceName[] = "hostapd";
+const char kHostapdConfigFilePath[] = "/data/misc/wifi/hostapd.conf";
+
+string GeneratePsk(const vector<uint8_t>& ssid,
+                   const vector<uint8_t>& passphrase) {
+  string result;
+  unsigned char psk[SHA256_DIGEST_LENGTH];
+
+  // Use the PKCS#5 PBKDF2 with 4096 iterations
+  if (PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(passphrase.data()),
+                             passphrase.size(),
+                             ssid.data(), ssid.size(),
+                             4096, sizeof(psk), psk) != 1) {
+    LOG(ERROR) << "Cannot generate PSK using PKCS#5 PBKDF2";
+    return result;
+  }
+
+  stringstream ss;
+  ss << std::hex;
+  ss << std::setfill('0');
+  for (int j = 0; j < SHA256_DIGEST_LENGTH; j++) {
+    ss << std::setw(2) << static_cast<unsigned int>(psk[j]);
+  }
+  result = ss.str();
+
+  return result;
+}
+
+}  // namespace
+
+bool HostapdManager::StartHostapd() {
+  if (hostapd_is_running_) {
+    LOG(ERROR) << "SoftAP is already running";
+    return false;
+  }
+
+  if (ensure_entropy_file_exists() < 0) {
+    LOG(WARNING) << "Wi-Fi entropy file was not created";
+  }
+
+  if (property_set("ctl.start", kHostapdServiceName) != 0) {
+    LOG(ERROR) << "Failed to start SoftAP";
+    return false;
+  }
+
+  LOG(DEBUG) << "SoftAP started successfully";
+  hostapd_is_running_ = true;
+  return true;
+}
+
+bool HostapdManager::IsHostapdRunning() {
+  return hostapd_is_running_;
+}
+
+bool HostapdManager::StopHostapd() {
+  if (!hostapd_is_running_) {
+    LOG(DEBUG) << "SoftAP is not running";
+    return true;  // Not really an error, hostapd is already stopped.
+  }
+
+  LOG(DEBUG) << "Stopping the SoftAP service...";
+
+  if (property_set("ctl.stop", kHostapdServiceName) < 0) {
+    LOG(ERROR) << "Failed to stop hostapd service!";
+    return false;
+  }
+
+  LOG(DEBUG) << "SoftAP stopped successfully";
+  hostapd_is_running_ = false;
+  return true;
+}
+
+bool HostapdManager::WriteHostapdConfig(const string& config) {
+  if (!WriteStringToFile(config, kHostapdConfigFilePath,
+                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+                         AID_SYSTEM, AID_WIFI)) {
+    int error = errno;
+    LOG(ERROR) << "Cannot write hostapd config to \""
+               << kHostapdConfigFilePath << "\": " << strerror(error);
+    return false;
+  }
+  return true;
+}
+
+string HostapdManager::CreateHostapdConfig(
+    const string& interface_name,
+    const vector<uint8_t> ssid,
+    bool is_hidden,
+    int channel,
+    EncryptionType encryption_type,
+    const vector<uint8_t> passphrase) {
+  string result;
+
+  if (channel < 0) {
+    channel = kDefaultApChannel;
+  }
+
+  if (ssid.size() > 32) {
+    LOG(ERROR) << "SSIDs must be <= 32 bytes long";
+    return result;
+  }
+
+  stringstream ss;
+  ss << std::hex;
+  ss << std::setfill('0');
+  for (uint8_t b : ssid) {
+    ss << std::setw(2) << static_cast<unsigned int>(b);
+  }
+  const string ssid_as_string  = ss.str();
+
+  string encryption_config;
+  if (encryption_type != EncryptionType::kOpen) {
+    string psk = GeneratePsk(ssid, passphrase);
+    if (psk.empty()) {
+      return result;
+    }
+    if (encryption_type == EncryptionType::kWpa) {
+      encryption_config = StringPrintf("wpa=3\n"
+                                       "wpa_pairwise=TKIP CCMP\n"
+                                       "wpa_psk=%s\n", psk.c_str());
+    } else if (encryption_type == EncryptionType::kWpa2) {
+      encryption_config = StringPrintf("wpa=2\n"
+                                       "rsn_pairwise=CCMP\n"
+                                       "wpa_psk=%s\n", psk.c_str());
+    } else {
+      using encryption_t = std::underlying_type<EncryptionType>::type;
+      LOG(ERROR) << "Unknown encryption type ("
+                 << static_cast<encryption_t>(encryption_type)
+                 << ")";
+      return result;
+    }
+  }
+
+  result = StringPrintf(
+      "interface=%s\n"
+      "driver=nl80211\n"
+      "ctrl_interface=/data/misc/wifi/hostapd\n"
+      // ssid2 signals to hostapd that the value is not a literal value
+      // for use as a SSID.  In this case, we're giving it a hex string
+      // and hostapd needs to expect that.
+      "ssid2=%s\n"
+      "channel=%d\n"
+      "ieee80211n=1\n"
+      "hw_mode=%c\n"
+      "ignore_broadcast_ssid=%d\n"
+      "wowlan_triggers=any\n"
+      "%s",
+      interface_name.c_str(),
+      ssid_as_string.c_str(),
+      channel,
+      (channel <= 14) ? 'g' : 'a',
+      (is_hidden) ? 1 : 0,
+      encryption_config.c_str());
+  return result;
+}
+
+}  // namespace wifi_system
+}  // namespace android
diff --git a/libwifi_system/include/wifi_system/hal_tool.h b/libwifi_system/include/wifi_system/hal_tool.h
new file mode 100644
index 0000000..b25893e
--- /dev/null
+++ b/libwifi_system/include/wifi_system/hal_tool.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_WIFI_SYSTEM_HAL_TOOL_H
+#define ANDROID_WIFI_SYSTEM_HAL_TOOL_H
+
+#include <hardware_legacy/wifi_hal.h>
+
+namespace android {
+namespace wifi_system {
+
+// Utilities for interacting with the HAL.
+class HalTool {
+ public:
+  HalTool() = default;
+  virtual ~HalTool() = default;
+
+  virtual bool InitFunctionTable(wifi_hal_fn* hal_fn);
+
+  virtual bool CanGetValidChannels(wifi_hal_fn* hal_fn);
+};  // class HalTool
+
+}  // namespace wifi_system
+}  // namespace android
+
+#endif  // ANDROID_WIFI_SYSTEM_HAL_TOOL_H
diff --git a/libwifi_system/include/wifi_system/hostapd_manager.h b/libwifi_system/include/wifi_system/hostapd_manager.h
new file mode 100644
index 0000000..2bffde4
--- /dev/null
+++ b/libwifi_system/include/wifi_system/hostapd_manager.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_WIFI_SYSTEM_HOSTAPD_MANAGER_H
+#define ANDROID_WIFI_SYSTEM_HOSTAPD_MANAGER_H
+
+#include <string>
+#include <vector>
+
+#include <android-base/macros.h>
+
+namespace android {
+namespace wifi_system {
+
+class HostapdManager {
+ public:
+  enum class EncryptionType {
+    kOpen,
+    kWpa,
+    kWpa2,  // Strongly prefer this if at all possible.
+  };
+
+  HostapdManager() = default;
+  virtual ~HostapdManager() = default;
+
+  // Request that hostapd be started.
+  // Returns true on success.
+  virtual bool StartHostapd();
+
+  // Returns true if hostapd is currently running.
+  virtual bool IsHostapdRunning();
+
+  // Request that a running instance of hostapd be stopped.
+  // Returns true on success.
+  virtual bool StopHostapd();
+
+  // Create a string suitable for writing to the hostapd configuration file.
+  // |interface_name| is a network interface name (e.g. "wlan0").
+  // |ssid| is the SSID used by the configurated network.
+  // |is_hidden| is true iff hostapd should not broadcast the SSID.
+  // |channel| is the WiFi channel (e.g. 6) or <0 for a default value.
+  // |encryption_type| defines the encryption of the configured network.
+  // |passphrase| is ignored for kOpen networks.
+  //
+  // Returns an empty string on failure.
+  virtual std::string CreateHostapdConfig(
+      const std::string& interface_name,
+      const std::vector<uint8_t> ssid,
+      bool is_hidden,
+      int channel,
+      EncryptionType encryption,
+      const std::vector<uint8_t> passphrase);
+
+  // Write out a hostapd configuration file created via CreateHostapdConfig().
+  // Future instances of hostapd will use this new configuration.
+  // Returns true if the configuration file is successfully written.
+  virtual bool WriteHostapdConfig(const std::string& config_file);
+
+ private:
+  bool hostapd_is_running_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(HostapdManager);
+};  // class HostapdManager
+
+}  // namespace wifi_system
+}  // namespace android
+
+#endif  // ANDROID_WIFI_SYSTEM_HOSTAPD_MANAGER_H
diff --git a/libwifi_system/include/wifi_system/interface_tool.h b/libwifi_system/include/wifi_system/interface_tool.h
new file mode 100644
index 0000000..2e58379
--- /dev/null
+++ b/libwifi_system/include/wifi_system/interface_tool.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_WIFI_SYSTEM_INTERFACE_TOOL_H
+#define ANDROID_WIFI_SYSTEM_INTERFACE_TOOL_H
+
+namespace android {
+namespace wifi_system {
+
+class InterfaceTool {
+ public:
+  InterfaceTool() = default;
+  virtual ~InterfaceTool() = default;
+
+  // Set the interface named by |if_name| up or down.
+  // Returns true on success, false otherwise.
+  virtual bool SetUpState(const char* if_name, bool request_up);
+
+  // A helpful alias for SetUpState() that assumes there is a single system
+  // WiFi interface.  Prefer this form if you're hardcoding "wlan0" to help us
+  // identify all the places we are hardcoding the name of the wifi interface.
+  virtual bool SetWifiUpState(bool request_up);
+
+};  // class InterfaceTool
+
+}  // namespace wifi_system
+}  // namespace android
+
+#endif  // ANDROID_WIFI_SYSTEM_INTERFACE_TOOL_H
diff --git a/libwifi_system/include/wifi_system/wifi.h b/libwifi_system/include/wifi_system/wifi.h
new file mode 100644
index 0000000..3e662a1
--- /dev/null
+++ b/libwifi_system/include/wifi_system/wifi.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_WIFI_SYSTEM_WIFI_H
+#define ANDROID_WIFI_SYSTEM_WIFI_H
+
+#include <cstddef>
+
+namespace android {
+namespace wifi_system {
+
+extern const char kWiFiEntropyFile[];
+
+/**
+ * Start supplicant.
+ *
+ * @return 0 on success, < 0 on failure.
+ */
+int wifi_start_supplicant(int p2pSupported);
+
+/**
+ * Stop supplicant.
+ *
+ * @return 0 on success, < 0 on failure.
+ */
+int wifi_stop_supplicant(int p2pSupported);
+
+/**
+ * Open a connection to supplicant
+ *
+ * @return 0 on success, < 0 on failure.
+ */
+int wifi_connect_to_supplicant();
+
+/**
+ * Close connection to supplicant
+ *
+ * @return 0 on success, < 0 on failure.
+ */
+void wifi_close_supplicant_connection();
+
+/**
+ * wifi_wait_for_event() performs a blocking call to
+ * get a Wi-Fi event and returns a string representing
+ * a Wi-Fi event when it occurs.
+ *
+ * @param buf is the buffer that receives the event
+ * @param len is the maximum length of the buffer
+ *
+ * @returns number of bytes in buffer, 0 if no
+ * event (for instance, no connection), and less than 0
+ * if there is an error.
+ */
+int wifi_wait_for_event(char* buf, size_t len);
+
+/**
+ * wifi_command() issues a command to the Wi-Fi driver.
+ *
+ * Android extends the standard commands listed at
+ * /link http://hostap.epitest.fi/wpa_supplicant/devel/ctrl_iface_page.html
+ * to include support for sending commands to the driver:
+ *
+ * See wifi/java/android/net/wifi/WifiNative.java for the details of
+ * driver commands that are supported
+ *
+ * @param command is the string command (preallocated with 32 bytes)
+ * @param commandlen is command buffer length
+ * @param reply is a buffer to receive a reply string
+ * @param reply_len on entry, this is the maximum length of
+ *        the reply buffer. On exit, the number of
+ *        bytes in the reply buffer.
+ *
+ * @return 0 if successful, < 0 if an error.
+ */
+int wifi_command(const char* command, char* reply, size_t* reply_len);
+
+/**
+ * Check and create if necessary initial entropy file
+ */
+int ensure_entropy_file_exists();
+
+}  // namespace wifi_system
+}  // namespace android
+
+#endif  // ANDROID_WIFI_SYSTEM_WIFI_H
diff --git a/libwifi_system/interface_tool.cpp b/libwifi_system/interface_tool.cpp
new file mode 100644
index 0000000..ed0b9f7
--- /dev/null
+++ b/libwifi_system/interface_tool.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#include "wifi_system/interface_tool.h"
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+/* We need linux/if.h for flags like IFF_UP.  Sadly, it forward declares
+   struct sockaddr and must be included after sys/socket.h. */
+#include <linux/if.h>
+
+#include <android-base/unique_fd.h>
+#include <log/log.h>
+
+namespace android {
+namespace wifi_system {
+namespace {
+
+const char kWlan0InterfaceName[] = "wlan0";
+
+}  // namespace
+
+bool InterfaceTool::SetUpState(const char* if_name, bool request_up) {
+  base::unique_fd sock(socket(PF_INET, SOCK_DGRAM, 0));
+  if (sock.get() < 0) {
+    ALOGE("Bad socket: %d, errno: %d\n", sock.get(), errno);
+    return false;
+  }
+
+  struct ifreq ifr;
+  memset(&ifr, 0, sizeof(ifr));
+  if (strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)) >=
+      sizeof(ifr.ifr_name)) {
+    ALOGE("Interface name is too long: %s\n", if_name);
+    return false;
+  }
+
+  if (TEMP_FAILURE_RETRY(ioctl(sock.get(), SIOCGIFFLAGS, &ifr)) != 0) {
+    ALOGE("Could not read interface %s errno: %d\n", if_name, errno);
+    return false;
+  }
+
+  const bool currently_up = ifr.ifr_flags & IFF_UP;
+  if (currently_up == request_up) {
+    return true;
+  }
+
+  if (request_up) {
+    ifr.ifr_flags |= IFF_UP;
+  } else {
+    ifr.ifr_flags &= ~IFF_UP;
+  }
+
+  if (TEMP_FAILURE_RETRY(ioctl(sock.get(), SIOCSIFFLAGS, &ifr)) != 0) {
+    ALOGE("Could not set interface %s flags: %d\n", if_name, errno);
+    return false;
+  }
+
+  return true;
+}
+
+bool InterfaceTool::SetWifiUpState(bool request_up) {
+  return SetUpState(kWlan0InterfaceName, request_up);
+}
+
+}  // namespace wifi_system
+}  // namespace android
diff --git a/libwifi_system/testlib/include/wifi_system_test/mock_hal_tool.h b/libwifi_system/testlib/include/wifi_system_test/mock_hal_tool.h
new file mode 100644
index 0000000..312428f
--- /dev/null
+++ b/libwifi_system/testlib/include/wifi_system_test/mock_hal_tool.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_WIFI_SYSTEM_TEST_MOCK_HAL_TOOL_H
+#define ANDROID_WIFI_SYSTEM_TEST_MOCK_HAL_TOOL_H
+
+#include <wifi_system/hal_tool.h>
+
+namespace android {
+namespace wifi_system {
+
+class MockHalTool : public HalTool {
+ public:
+  ~MockHalTool() override = default;
+
+  MOCK_METHOD1(InitFunctionTable, bool(wifi_hal_fn*));
+  MOCK_METHOD1(CanGetValidChannels, bool(wifi_hal_fn*));
+
+};  // class MockHalTool
+
+}  // namespace wifi_system
+}  // namespace android
+
+#endif  // ANDROID_WIFI_SYSTEM_TEST_MOCK_HAL_TOOL_H
diff --git a/libwifi_system/testlib/include/wifi_system_test/mock_interface_tool.h b/libwifi_system/testlib/include/wifi_system_test/mock_interface_tool.h
new file mode 100644
index 0000000..13e6780
--- /dev/null
+++ b/libwifi_system/testlib/include/wifi_system_test/mock_interface_tool.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_WIFI_SYSTEM_TEST_MOCK_INTERFACE_TOOL_H
+#define ANDROID_WIFI_SYSTEM_TEST_MOCK_INTERFACE_TOOL_H
+
+#include <wifi_system/interface_tool.h>
+
+namespace android {
+namespace wifi_system {
+
+class MockInterfaceTool : public InterfaceTool {
+ public:
+  ~MockInterfaceTool() override = default;
+
+  MOCK_METHOD2(SetUpState, bool(const char* if_name, bool request_up));
+  MOCK_METHOD1(SetWifiUpState, bool(bool request_up));
+
+};  // class MockInterfaceTool
+
+}  // namespace wifi_system
+}  // namespace android
+
+#endif  // ANDROID_WIFI_SYSTEM_TEST_MOCK_INTERFACE_TOOL_H
diff --git a/libwifi_system/tests/hostapd_manager_unittest.cpp b/libwifi_system/tests/hostapd_manager_unittest.cpp
new file mode 100644
index 0000000..f8ebd99
--- /dev/null
+++ b/libwifi_system/tests/hostapd_manager_unittest.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <string>
+#include <vector>
+
+#include "wifi_system/hostapd_manager.h"
+
+using std::string;
+using std::vector;
+
+namespace android {
+namespace wifi_system {
+namespace {
+
+const char kTestInterfaceName[] = "foobar0";
+const char kTestSsidStr[] = "helloisitme";
+const char kTestPassphraseStr[] = "yourelookingfor";
+const int kTestChannel = 2;
+
+#define CONFIG_COMMON_PREFIX \
+    "interface=foobar0\n" \
+    "driver=nl80211\n" \
+    "ctrl_interface=/data/misc/wifi/hostapd\n" \
+    "ssid2=68656c6c6f" "6973" "6974" "6d65\n" \
+    "channel=2\n" \
+    "ieee80211n=1\n" \
+    "hw_mode=g\n"
+
+// If you generate your config file with both the test ssid
+// and the test passphrase, you'll get this line in the config.
+#define CONFIG_PSK_LINE \
+    "wpa_psk=dffa36815281e5a6eca1910f254717fa2528681335e3bbec5966d2aa9221a66e\n"
+
+#define CONFIG_WPA_SUFFIX \
+    "wpa=3\n" \
+    "wpa_pairwise=TKIP CCMP\n" \
+    CONFIG_PSK_LINE
+
+#define CONFIG_WPA2_SUFFIX \
+    "wpa=2\n" \
+    "rsn_pairwise=CCMP\n" \
+    CONFIG_PSK_LINE
+
+const char kExpectedOpenConfig[] =
+  CONFIG_COMMON_PREFIX
+  "ignore_broadcast_ssid=0\n"
+  "wowlan_triggers=any\n";
+
+const char kExpectedWpaConfig[] =
+    CONFIG_COMMON_PREFIX
+    "ignore_broadcast_ssid=0\n"
+    "wowlan_triggers=any\n"
+    CONFIG_WPA_SUFFIX;
+
+const char kExpectedWpa2Config[] =
+    CONFIG_COMMON_PREFIX
+    "ignore_broadcast_ssid=0\n"
+    "wowlan_triggers=any\n"
+    CONFIG_WPA2_SUFFIX;
+
+class HostapdManagerTest : public ::testing::Test {
+ protected:
+  string GetConfigForEncryptionType(
+      HostapdManager::EncryptionType encryption_type) {
+    return HostapdManager().CreateHostapdConfig(
+        kTestInterfaceName,
+        cstr2vector(kTestSsidStr),
+        false,  // not hidden
+        kTestChannel,
+        encryption_type,
+        cstr2vector(kTestPassphraseStr));
+  }
+
+  vector<uint8_t> cstr2vector(const char* data) {
+    return vector<uint8_t>(data, data + strlen(data));
+  }
+};  // class HostapdManagerTest
+
+}  // namespace
+
+TEST_F(HostapdManagerTest, GeneratesCorrectOpenConfig) {
+  string config = GetConfigForEncryptionType(
+      HostapdManager::EncryptionType::kOpen);
+  EXPECT_FALSE(config.empty());
+  EXPECT_EQ(kExpectedOpenConfig, config);
+}
+
+TEST_F(HostapdManagerTest, GeneratesCorrectWpaConfig) {
+  string config = GetConfigForEncryptionType(
+      HostapdManager::EncryptionType::kWpa);
+  EXPECT_FALSE(config.empty());
+  EXPECT_EQ(kExpectedWpaConfig, config);
+}
+
+TEST_F(HostapdManagerTest, GeneratesCorrectWpa2Config) {
+  string config = GetConfigForEncryptionType(
+      HostapdManager::EncryptionType::kWpa2);
+  EXPECT_FALSE(config.empty());
+  EXPECT_EQ(kExpectedWpa2Config, config);
+}
+
+TEST_F(HostapdManagerTest, RespectsHiddenSetting) {
+  string config = HostapdManager().CreateHostapdConfig(
+        kTestInterfaceName,
+        cstr2vector(kTestSsidStr),
+        true,
+        kTestChannel,
+        HostapdManager::EncryptionType::kOpen,
+        vector<uint8_t>());
+  EXPECT_FALSE(config.find("ignore_broadcast_ssid=1\n") == string::npos);
+  EXPECT_TRUE(config.find("ignore_broadcast_ssid=0\n") == string::npos);
+}
+
+TEST_F(HostapdManagerTest, CorrectlyInfersHwMode) {
+  string config = HostapdManager().CreateHostapdConfig(
+        kTestInterfaceName,
+        cstr2vector(kTestSsidStr),
+        true,
+        44,
+        HostapdManager::EncryptionType::kOpen,
+        vector<uint8_t>());
+  EXPECT_FALSE(config.find("hw_mode=a\n") == string::npos);
+  EXPECT_TRUE(config.find("hw_mode=g\n") == string::npos);
+}
+
+
+}  // namespace wifi_system
+}  // namespace android
diff --git a/libwifi_system/tests/main.cpp b/libwifi_system/tests/main.cpp
new file mode 100644
index 0000000..51e8dad
--- /dev/null
+++ b/libwifi_system/tests/main.cpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  // Force ourselves to always log to stderr
+  android::base::InitLogging(argv, android::base::StderrLogger);
+  return RUN_ALL_TESTS();
+}
+
diff --git a/libwifi_system/wifi.cpp b/libwifi_system/wifi.cpp
new file mode 100644
index 0000000..3b08cf1
--- /dev/null
+++ b/libwifi_system/wifi.cpp
@@ -0,0 +1,566 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wifi_system/wifi.h"
+#define LOG_TAG "WifiHW"
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <cutils/log.h>
+#include <cutils/memory.h>
+#include <cutils/misc.h>
+#include <cutils/properties.h>
+#include <private/android_filesystem_config.h>
+
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h>
+
+#ifdef LIBWPA_CLIENT_EXISTS
+#include <libwpa_client/wpa_ctrl.h>
+#else
+#define WPA_EVENT_TERMINATING "CTRL-EVENT-TERMINATING "
+struct wpa_ctrl {};
+void wpa_ctrl_cleanup(void) {}
+struct wpa_ctrl* wpa_ctrl_open(const char* ctrl_path) {
+  return NULL;
+}
+void wpa_ctrl_close(struct wpa_ctrl* ctrl) {}
+int wpa_ctrl_request(struct wpa_ctrl* ctrl, const char* cmd, size_t cmd_len,
+                     char* reply, size_t* reply_len,
+                     void (*msg_cb)(char* msg, size_t len)) {
+  return 0;
+}
+int wpa_ctrl_attach(struct wpa_ctrl* ctrl) { return 0; }
+int wpa_ctrl_detach(struct wpa_ctrl* ctrl) { return 0; }
+int wpa_ctrl_recv(struct wpa_ctrl* ctrl, char* reply, size_t* reply_len) {
+  return 0;
+}
+int wpa_ctrl_get_fd(struct wpa_ctrl* ctrl) { return 0; }
+#endif  // defined LIBWPA_CLIENT_EXISTS
+
+namespace android {
+namespace wifi_system {
+namespace {
+
+/* socket pair used to exit from a blocking read */
+int exit_sockets[2];
+struct wpa_ctrl* ctrl_conn;
+struct wpa_ctrl* monitor_conn;
+
+static char primary_iface[PROPERTY_VALUE_MAX];
+// TODO: use new ANDROID_SOCKET mechanism, once support for multiple
+// sockets is in
+
+#define WIFI_TEST_INTERFACE "sta"
+
+#define WIFI_DRIVER_LOADER_DELAY 1000000
+
+const char IFACE_DIR[] = "/data/system/wpa_supplicant";
+const char SUPPLICANT_NAME[] = "wpa_supplicant";
+const char SUPP_PROP_NAME[] = "init.svc.wpa_supplicant";
+const char P2P_SUPPLICANT_NAME[] = "p2p_supplicant";
+const char P2P_PROP_NAME[] = "init.svc.p2p_supplicant";
+const char SUPP_CONFIG_TEMPLATE[] = "/system/etc/wifi/wpa_supplicant.conf";
+const char SUPP_CONFIG_FILE[] = "/data/misc/wifi/wpa_supplicant.conf";
+const char P2P_CONFIG_FILE[] = "/data/misc/wifi/p2p_supplicant.conf";
+
+const char IFNAME[] = "IFNAME=";
+#define IFNAMELEN (sizeof(IFNAME) - 1)
+const char WPA_EVENT_IGNORE[] = "CTRL-EVENT-IGNORE ";
+
+unsigned char dummy_key[21] = {0x02, 0x11, 0xbe, 0x33, 0x43, 0x35, 0x68,
+                               0x47, 0x84, 0x99, 0xa9, 0x2b, 0x1c, 0xd3,
+                               0xee, 0xff, 0xf1, 0xe2, 0xf3, 0xf4, 0xf5};
+
+/* Is either SUPPLICANT_NAME or P2P_SUPPLICANT_NAME */
+char supplicant_name[PROPERTY_VALUE_MAX];
+/* Is either SUPP_PROP_NAME or P2P_PROP_NAME */
+char supplicant_prop_name[PROPERTY_KEY_MAX];
+
+void wifi_close_sockets() {
+  if (ctrl_conn != NULL) {
+    wpa_ctrl_close(ctrl_conn);
+    ctrl_conn = NULL;
+  }
+
+  if (monitor_conn != NULL) {
+    wpa_ctrl_close(monitor_conn);
+    monitor_conn = NULL;
+  }
+
+  if (exit_sockets[0] >= 0) {
+    close(exit_sockets[0]);
+    exit_sockets[0] = -1;
+  }
+
+  if (exit_sockets[1] >= 0) {
+    close(exit_sockets[1]);
+    exit_sockets[1] = -1;
+  }
+}
+
+int ensure_config_file_exists(const char* config_file) {
+  char buf[2048];
+  int srcfd, destfd;
+  int nread;
+  int ret;
+
+  ret = access(config_file, R_OK | W_OK);
+  if ((ret == 0) || (errno == EACCES)) {
+    if ((ret != 0) &&
+        (chmod(config_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) != 0)) {
+      ALOGE("Cannot set RW to \"%s\": %s", config_file, strerror(errno));
+      return -1;
+    }
+    return 0;
+  } else if (errno != ENOENT) {
+    ALOGE("Cannot access \"%s\": %s", config_file, strerror(errno));
+    return -1;
+  }
+
+  srcfd = TEMP_FAILURE_RETRY(open(SUPP_CONFIG_TEMPLATE, O_RDONLY));
+  if (srcfd < 0) {
+    ALOGE("Cannot open \"%s\": %s", SUPP_CONFIG_TEMPLATE, strerror(errno));
+    return -1;
+  }
+
+  destfd = TEMP_FAILURE_RETRY(open(config_file, O_CREAT | O_RDWR, 0660));
+  if (destfd < 0) {
+    close(srcfd);
+    ALOGE("Cannot create \"%s\": %s", config_file, strerror(errno));
+    return -1;
+  }
+
+  while ((nread = TEMP_FAILURE_RETRY(read(srcfd, buf, sizeof(buf)))) != 0) {
+    if (nread < 0) {
+      ALOGE("Error reading \"%s\": %s", SUPP_CONFIG_TEMPLATE, strerror(errno));
+      close(srcfd);
+      close(destfd);
+      unlink(config_file);
+      return -1;
+    }
+    TEMP_FAILURE_RETRY(write(destfd, buf, nread));
+  }
+
+  close(destfd);
+  close(srcfd);
+
+  /* chmod is needed because open() didn't set permisions properly */
+  if (chmod(config_file, 0660) < 0) {
+    ALOGE("Error changing permissions of %s to 0660: %s", config_file,
+          strerror(errno));
+    unlink(config_file);
+    return -1;
+  }
+
+  if (chown(config_file, AID_SYSTEM, AID_WIFI) < 0) {
+    ALOGE("Error changing group ownership of %s to %d: %s", config_file,
+          AID_WIFI, strerror(errno));
+    unlink(config_file);
+    return -1;
+  }
+  return 0;
+}
+
+}  // namespace
+
+const char kWiFiEntropyFile[] = "/data/misc/wifi/entropy.bin";
+
+int wifi_start_supplicant(int p2p_supported) {
+  char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
+  int count = 200; /* wait at most 20 seconds for completion */
+  const prop_info* pi;
+  unsigned serial = 0;
+
+  if (p2p_supported) {
+    strcpy(supplicant_name, P2P_SUPPLICANT_NAME);
+    strcpy(supplicant_prop_name, P2P_PROP_NAME);
+
+    /* Ensure p2p config file is created */
+    if (ensure_config_file_exists(P2P_CONFIG_FILE) < 0) {
+      ALOGE("Failed to create a p2p config file");
+      return -1;
+    }
+
+  } else {
+    strcpy(supplicant_name, SUPPLICANT_NAME);
+    strcpy(supplicant_prop_name, SUPP_PROP_NAME);
+  }
+
+  /* Check whether already running */
+  if (property_get(supplicant_prop_name, supp_status, NULL) &&
+      strcmp(supp_status, "running") == 0) {
+    return 0;
+  }
+
+  /* Before starting the daemon, make sure its config file exists */
+  if (ensure_config_file_exists(SUPP_CONFIG_FILE) < 0) {
+    ALOGE("Wi-Fi will not be enabled");
+    return -1;
+  }
+
+  if (ensure_entropy_file_exists() < 0) {
+    ALOGE("Wi-Fi entropy file was not created");
+  }
+
+  /* Clear out any stale socket files that might be left over. */
+  wpa_ctrl_cleanup();
+
+  /* Reset sockets used for exiting from hung state */
+  exit_sockets[0] = exit_sockets[1] = -1;
+
+  /*
+   * Get a reference to the status property, so we can distinguish
+   * the case where it goes stopped => running => stopped (i.e.,
+   * it start up, but fails right away) from the case in which
+   * it starts in the stopped state and never manages to start
+   * running at all.
+   */
+  pi = __system_property_find(supplicant_prop_name);
+  if (pi != NULL) {
+    serial = __system_property_serial(pi);
+  }
+  property_get("wifi.interface", primary_iface, WIFI_TEST_INTERFACE);
+
+  property_set("ctl.start", supplicant_name);
+  sched_yield();
+
+  while (count-- > 0) {
+    if (pi == NULL) {
+      pi = __system_property_find(supplicant_prop_name);
+    }
+    if (pi != NULL) {
+      /*
+       * property serial updated means that init process is scheduled
+       * after we sched_yield, further property status checking is based on this
+       */
+      if (__system_property_serial(pi) != serial) {
+        __system_property_read(pi, NULL, supp_status);
+        if (strcmp(supp_status, "running") == 0) {
+          return 0;
+        } else if (strcmp(supp_status, "stopped") == 0) {
+          return -1;
+        }
+      }
+    }
+    usleep(100000);
+  }
+  return -1;
+}
+
+int wifi_stop_supplicant(int p2p_supported) {
+  char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
+  int count = 50; /* wait at most 5 seconds for completion */
+
+  if (p2p_supported) {
+    strcpy(supplicant_name, P2P_SUPPLICANT_NAME);
+    strcpy(supplicant_prop_name, P2P_PROP_NAME);
+  } else {
+    strcpy(supplicant_name, SUPPLICANT_NAME);
+    strcpy(supplicant_prop_name, SUPP_PROP_NAME);
+  }
+
+  /* Check whether supplicant already stopped */
+  if (property_get(supplicant_prop_name, supp_status, NULL) &&
+      strcmp(supp_status, "stopped") == 0) {
+    return 0;
+  }
+
+  property_set("ctl.stop", supplicant_name);
+  sched_yield();
+
+  while (count-- > 0) {
+    if (property_get(supplicant_prop_name, supp_status, NULL)) {
+      if (strcmp(supp_status, "stopped") == 0) return 0;
+    }
+    usleep(100000);
+  }
+  ALOGE("Failed to stop supplicant");
+  return -1;
+}
+
+namespace {
+
+int wifi_connect_on_socket_path(const char* path) {
+  char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
+
+  /* Make sure supplicant is running */
+  if (!property_get(supplicant_prop_name, supp_status, NULL) ||
+      strcmp(supp_status, "running") != 0) {
+    ALOGE("Supplicant not running, cannot connect");
+    return -1;
+  }
+
+  ctrl_conn = wpa_ctrl_open(path);
+  if (ctrl_conn == NULL) {
+    ALOGE("Unable to open connection to supplicant on \"%s\": %s", path,
+          strerror(errno));
+    return -1;
+  }
+  monitor_conn = wpa_ctrl_open(path);
+  if (monitor_conn == NULL) {
+    wpa_ctrl_close(ctrl_conn);
+    ctrl_conn = NULL;
+    return -1;
+  }
+  if (wpa_ctrl_attach(monitor_conn) != 0) {
+    wpa_ctrl_close(monitor_conn);
+    wpa_ctrl_close(ctrl_conn);
+    ctrl_conn = monitor_conn = NULL;
+    return -1;
+  }
+
+  if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) {
+    wpa_ctrl_close(monitor_conn);
+    wpa_ctrl_close(ctrl_conn);
+    ctrl_conn = monitor_conn = NULL;
+    return -1;
+  }
+
+  return 0;
+}
+
+int wifi_send_command(const char* cmd, char* reply, size_t* reply_len) {
+  int ret;
+  if (ctrl_conn == NULL) {
+    ALOGV("Not connected to wpa_supplicant - \"%s\" command dropped.\n", cmd);
+    return -1;
+  }
+  ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), reply, reply_len, NULL);
+  if (ret == -2) {
+    ALOGD("'%s' command timed out.\n", cmd);
+    /* unblocks the monitor receive socket for termination */
+    TEMP_FAILURE_RETRY(write(exit_sockets[0], "T", 1));
+    return -2;
+  } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) {
+    return -1;
+  }
+  if (strncmp(cmd, "PING", 4) == 0) {
+    reply[*reply_len] = '\0';
+  }
+  return 0;
+}
+
+int wifi_supplicant_connection_active() {
+  char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
+
+  if (property_get(supplicant_prop_name, supp_status, NULL)) {
+    if (strcmp(supp_status, "stopped") == 0) return -1;
+  }
+
+  return 0;
+}
+
+int wifi_ctrl_recv(char* reply, size_t* reply_len) {
+  int res;
+  int ctrlfd = wpa_ctrl_get_fd(monitor_conn);
+  struct pollfd rfds[2];
+
+  memset(rfds, 0, 2 * sizeof(struct pollfd));
+  rfds[0].fd = ctrlfd;
+  rfds[0].events |= POLLIN;
+  rfds[1].fd = exit_sockets[1];
+  rfds[1].events |= POLLIN;
+  do {
+    res = TEMP_FAILURE_RETRY(poll(rfds, 2, 30000));
+    if (res < 0) {
+      ALOGE("Error poll = %d", res);
+      return res;
+    } else if (res == 0) {
+      /* timed out, check if supplicant is active
+       * or not ..
+       */
+      res = wifi_supplicant_connection_active();
+      if (res < 0) return -2;
+    }
+  } while (res == 0);
+
+  if (rfds[0].revents & POLLIN) {
+    return wpa_ctrl_recv(monitor_conn, reply, reply_len);
+  }
+
+  /* it is not rfds[0], then it must be rfts[1] (i.e. the exit socket)
+   * or we timed out. In either case, this call has failed ..
+   */
+  return -2;
+}
+
+int wifi_wait_on_socket(char* buf, size_t buflen) {
+  size_t nread = buflen - 1;
+  int result;
+  char* match;
+  char* match2;
+
+  if (monitor_conn == NULL) {
+    return snprintf(buf, buflen, "IFNAME=%s %s - connection closed",
+                    primary_iface, WPA_EVENT_TERMINATING);
+  }
+
+  result = wifi_ctrl_recv(buf, &nread);
+
+  /* Terminate reception on exit socket */
+  if (result == -2) {
+    return snprintf(buf, buflen, "IFNAME=%s %s - connection closed",
+                    primary_iface, WPA_EVENT_TERMINATING);
+  }
+
+  if (result < 0) {
+    ALOGD("wifi_ctrl_recv failed: %s\n", strerror(errno));
+    return snprintf(buf, buflen, "IFNAME=%s %s - recv error", primary_iface,
+                    WPA_EVENT_TERMINATING);
+  }
+  buf[nread] = '\0';
+  /* Check for EOF on the socket */
+  if (result == 0 && nread == 0) {
+    /* Fabricate an event to pass up */
+    ALOGD("Received EOF on supplicant socket\n");
+    return snprintf(buf, buflen, "IFNAME=%s %s - signal 0 received",
+                    primary_iface, WPA_EVENT_TERMINATING);
+  }
+  /*
+   * Events strings are in the format
+   *
+   *     IFNAME=iface <N>CTRL-EVENT-XXX
+   *        or
+   *     <N>CTRL-EVENT-XXX
+   *
+   * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG,
+   * etc.) and XXX is the event name. The level information is not useful
+   * to us, so strip it off.
+   */
+
+  if (strncmp(buf, IFNAME, IFNAMELEN) == 0) {
+    match = strchr(buf, ' ');
+    if (match != NULL) {
+      if (match[1] == '<') {
+        match2 = strchr(match + 2, '>');
+        if (match2 != NULL) {
+          nread -= (match2 - match);
+          memmove(match + 1, match2 + 1, nread - (match - buf) + 1);
+        }
+      }
+    } else {
+      return snprintf(buf, buflen, "%s", WPA_EVENT_IGNORE);
+    }
+  } else if (buf[0] == '<') {
+    match = strchr(buf, '>');
+    if (match != NULL) {
+      nread -= (match + 1 - buf);
+      memmove(buf, match + 1, nread + 1);
+      ALOGV("supplicant generated event without interface - %s\n", buf);
+    }
+  } else {
+    /* let the event go as is! */
+    ALOGW(
+        "supplicant generated event without interface and without message "
+        "level - %s\n",
+        buf);
+  }
+
+  return nread;
+}
+
+}  // namespace
+
+/* Establishes the control and monitor socket connections on the interface */
+int wifi_connect_to_supplicant() {
+  static char path[PATH_MAX];
+
+  if (access(IFACE_DIR, F_OK) == 0) {
+    snprintf(path, sizeof(path), "%s/%s", IFACE_DIR, primary_iface);
+  } else {
+    snprintf(path, sizeof(path), "@android:wpa_%s", primary_iface);
+  }
+  return wifi_connect_on_socket_path(path);
+}
+
+void wifi_close_supplicant_connection() {
+  char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
+  int count =
+      50; /* wait at most 5 seconds to ensure init has stopped stupplicant */
+
+  wifi_close_sockets();
+
+  while (count-- > 0) {
+    if (property_get(supplicant_prop_name, supp_status, NULL)) {
+      if (strcmp(supp_status, "stopped") == 0) return;
+    }
+    usleep(100000);
+  }
+}
+
+int wifi_wait_for_event(char* buf, size_t buflen) {
+  return wifi_wait_on_socket(buf, buflen);
+}
+
+int wifi_command(const char* command, char* reply, size_t* reply_len) {
+  return wifi_send_command(command, reply, reply_len);
+}
+
+int ensure_entropy_file_exists() {
+  int ret;
+  int destfd;
+
+  ret = access(kWiFiEntropyFile, R_OK | W_OK);
+  if ((ret == 0) || (errno == EACCES)) {
+    if ((ret != 0) &&
+        (chmod(kWiFiEntropyFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) != 0)) {
+      ALOGE("Cannot set RW to \"%s\": %s", kWiFiEntropyFile, strerror(errno));
+      return -1;
+    }
+    return 0;
+  }
+  destfd = TEMP_FAILURE_RETRY(open(kWiFiEntropyFile, O_CREAT | O_RDWR, 0660));
+  if (destfd < 0) {
+    ALOGE("Cannot create \"%s\": %s", kWiFiEntropyFile, strerror(errno));
+    return -1;
+  }
+
+  if (TEMP_FAILURE_RETRY(write(destfd, dummy_key, sizeof(dummy_key))) !=
+      sizeof(dummy_key)) {
+    ALOGE("Error writing \"%s\": %s", kWiFiEntropyFile, strerror(errno));
+    close(destfd);
+    return -1;
+  }
+  close(destfd);
+
+  /* chmod is needed because open() didn't set permisions properly */
+  if (chmod(kWiFiEntropyFile, 0660) < 0) {
+    ALOGE("Error changing permissions of %s to 0660: %s", kWiFiEntropyFile,
+          strerror(errno));
+    unlink(kWiFiEntropyFile);
+    return -1;
+  }
+
+  if (chown(kWiFiEntropyFile, AID_SYSTEM, AID_WIFI) < 0) {
+    ALOGE("Error changing group ownership of %s to %d: %s", kWiFiEntropyFile,
+          AID_WIFI, strerror(errno));
+    unlink(kWiFiEntropyFile);
+    return -1;
+  }
+  return 0;
+}
+
+}  // namespace wifi_system
+}  // namespace android
diff --git a/service/Android.mk b/service/Android.mk
index 5c6c839..d949ea4 100644
--- a/service/Android.mk
+++ b/service/Android.mk
@@ -16,79 +16,15 @@
 
 ifneq ($(TARGET_BUILD_PDK), true)
 
-# Make HAL stub library 1
-# ============================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_REQUIRED_MODULES :=
-
-LOCAL_CFLAGS += -Wall -Werror -Wextra -Wno-unused-parameter -Wno-unused-function \
-                -Wunused-variable -Winit-self -Wwrite-strings -Wshadow
-
-LOCAL_C_INCLUDES += \
-	external/libnl-headers \
-	$(call include-path-for, libhardware_legacy)/hardware_legacy
-
-LOCAL_SRC_FILES := \
-	lib/wifi_hal.cpp
-
-LOCAL_MODULE := libwifi-hal
-
-include $(BUILD_STATIC_LIBRARY)
-
-# Make HAL stub library 2
-# ============================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_REQUIRED_MODULES :=
-
-LOCAL_CFLAGS += -Wall -Werror -Wextra -Wno-unused-parameter -Wno-unused-function \
-                -Wunused-variable -Winit-self -Wwrite-strings -Wshadow
-
-LOCAL_C_INCLUDES += \
-	$(LOCAL_PATH)/jni \
-	external/libnl-headers \
-	$(call include-path-for, libhardware_legacy)/hardware_legacy
-
-LOCAL_SRC_FILES := \
-	lib/wifi_hal_stub.cpp
-
-LOCAL_MODULE := libwifi-hal-stub
-
-include $(BUILD_STATIC_LIBRARY)
-
-# set correct hal library path
-# ============================================================
-LIB_WIFI_HAL := libwifi-hal
-
-ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
-  LIB_WIFI_HAL := libwifi-hal-bcm
-else ifeq ($(BOARD_WLAN_DEVICE), qcwcn)
-  LIB_WIFI_HAL := libwifi-hal-qcom
-else ifeq ($(BOARD_WLAN_DEVICE), mrvl)
-  # this is commented because none of the nexus devices
-  # that sport Marvell's wifi have support for HAL
-  # LIB_WIFI_HAL := libwifi-hal-mrvl
-else ifeq ($(BOARD_WLAN_DEVICE), MediaTek)
-  # support MTK WIFI HAL
-  LIB_WIFI_HAL := libwifi-hal-mt66xx
-endif
-
 # Make the JNI part
 # ============================================================
 include $(CLEAR_VARS)
 
-LOCAL_REQUIRED_MODULES := libhardware_legacy
-
 LOCAL_CFLAGS += -Wall -Werror -Wextra -Wno-unused-parameter -Wno-unused-function \
                 -Wunused-variable -Winit-self -Wwrite-strings -Wshadow
 
 LOCAL_C_INCLUDES += \
 	$(JNI_H_INCLUDE) \
-	$(call include-path-for, libhardware)/hardware \
-	$(call include-path-for, libhardware_legacy)/hardware_legacy \
 	libcore/include
 
 LOCAL_SHARED_LIBRARIES += \
@@ -96,19 +32,15 @@
 	libnativehelper \
 	libcutils \
 	libutils \
-	libhardware \
-	libhardware_legacy \
-	libnl \
-	libdl
-
-LOCAL_STATIC_LIBRARIES += libwifi-hal-stub
-LOCAL_STATIC_LIBRARIES += $(LIB_WIFI_HAL)
+	libdl \
+	libwifi-hal \
+	libwifi-system
 
 LOCAL_SRC_FILES := \
 	jni/com_android_server_wifi_WifiNative.cpp \
 	jni/jni_helper.cpp
 
-ifdef INCLUDE_NAN_FEATURE
+ifeq ($(BOARD_HAS_NAN), true)
 LOCAL_SRC_FILES += \
 	jni/com_android_server_wifi_nan_WifiNanNative.cpp
 endif
@@ -120,15 +52,19 @@
 # Build the java code
 # ============================================================
 
+wificond_aidl_path := system/connectivity/wificond/aidl
+wificond_aidl_rel_path := ../../../../../$(wificond_aidl_path)
+
 include $(CLEAR_VARS)
 
-LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/java
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/java $(wificond_aidl_path)
 LOCAL_SRC_FILES := $(call all-java-files-under, java) \
 	$(call all-Iaidl-files-under, java) \
+	$(call all-Iaidl-files-under, $(wificond_aidl_rel_path)) \
 	$(call all-logtags-files-under, java) \
 	$(call all-proto-files-under, proto)
 
-ifndef INCLUDE_NAN_FEATURE
+ifneq ($(BOARD_HAS_NAN), true)
 LOCAL_SRC_FILES := $(filter-out $(call all-java-files-under, \
           java/com/android/server/wifi/nan),$(LOCAL_SRC_FILES))
 endif
diff --git a/service/java/com/android/server/wifi/Clock.java b/service/java/com/android/server/wifi/Clock.java
index df0df6d..bb2f21e 100644
--- a/service/java/com/android/server/wifi/Clock.java
+++ b/service/java/com/android/server/wifi/Clock.java
@@ -27,7 +27,7 @@
      *
      * @return Current time in milliseconds.
      */
-    public long currentTimeMillis() {
+    public long getWallClockMillis() {
         return System.currentTimeMillis();
     }
 
@@ -36,26 +36,26 @@
      *
      * @return Current time since boot in milliseconds.
      */
-    public long elapsedRealtime() {
+    public long getElapsedSinceBootMillis() {
         return SystemClock.elapsedRealtime();
     }
 
-    /**
-     * Returns the current timestamp of the most precise timer available on the local system, in
-     * nanoseconds.
-     *
-     * @return Current time in nanoseconds.
-     */
-    public long nanoTime() {
-        return System.nanoTime();
-    }
-
-    /**
+   /**
      * Returns nanoseconds since boot, including time spent in sleep.
      *
      * @return Current time since boot in nanoseconds.
      */
-    public long elapsedRealtimeNanos() {
+    public long getElapsedSinceBootNanos() {
         return SystemClock.elapsedRealtimeNanos();
     }
+
+    /**
+     * Returns milliseconds since boot, not counting time spent in deep sleep.
+     *
+     * @return Milliseconds of non-sleep uptime since boot.
+     */
+    public long getUptimeSinceBootMillis() {
+        return SystemClock.uptimeMillis();
+    }
+
 }
diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java
index cb03f7a..b273731 100644
--- a/service/java/com/android/server/wifi/FrameworkFacade.java
+++ b/service/java/com/android/server/wifi/FrameworkFacade.java
@@ -20,14 +20,13 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
-import android.net.ConnectivityManager;
+import android.content.pm.PackageManager;
 import android.net.TrafficStats;
 import android.net.ip.IpManager;
 import android.net.wifi.IWifiScanner;
 import android.net.wifi.WifiScanner;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -36,8 +35,6 @@
 import android.security.KeyStore;
 import android.telephony.CarrierConfigManager;
 
-import java.util.ArrayList;
-
 /**
  * This class allows overriding objects with mocks to write unit tests
  */
@@ -128,28 +125,6 @@
     }
 
     /**
-     * Create a SoftApManager.
-     * @param context current context
-     * @param looper current thread looper
-     * @param wifiNative reference to WifiNative
-     * @param nmService reference to NetworkManagementService
-     * @param cm reference to ConnectivityManager
-     * @param countryCode Country code
-     * @param allowed2GChannels list of allowed 2G channels
-     * @param listener listener for SoftApManager
-     * @return an instance of SoftApManager
-     */
-    public SoftApManager makeSoftApManager(
-            Context context, Looper looper, WifiNative wifiNative,
-            INetworkManagementService nmService, ConnectivityManager cm,
-            String countryCode, ArrayList<Integer> allowed2GChannels,
-            SoftApManager.Listener listener) {
-        return new SoftApManager(
-                looper, wifiNative, nmService, countryCode,
-                allowed2GChannels, listener);
-    }
-
-    /**
      * Checks whether the given uid has been granted the given permission.
      * @param permName the permission to check
      * @param uid The uid to check
diff --git a/service/java/com/android/server/wifi/NetworkUpdateResult.java b/service/java/com/android/server/wifi/NetworkUpdateResult.java
index 63cc33f..22c8e22 100644
--- a/service/java/com/android/server/wifi/NetworkUpdateResult.java
+++ b/service/java/com/android/server/wifi/NetworkUpdateResult.java
@@ -67,4 +67,9 @@
     public void setIsNewNetwork(boolean isNew) {
         isNewNetwork = isNew;
     }
+
+    public boolean isSuccess() {
+        return netId != INVALID_NETWORK_ID;
+    }
+
 }
diff --git a/service/java/com/android/server/wifi/README.txt b/service/java/com/android/server/wifi/README.txt
index 0d74da1..2ab4d8b 100644
--- a/service/java/com/android/server/wifi/README.txt
+++ b/service/java/com/android/server/wifi/README.txt
@@ -1,10 +1,26 @@
-This code has moved from 
+Path history for this code:
 
-frameworks/base/services/java/com/android/server/wifi: gitk <SHA1 to be filled in later>
+commit date: 2013-12-18 to 2014-01-07
+commit hash: a07c419913bfae2a896fbc29e8f269ee08c4d910 (add)
+commit hash: 4a3f9cf099bbbe52dc0edb2a7e1d1c976bc335a3 (delete)
+dst:         frameworks/opt/net/wifi/service
+src:         frameworks/base/services/core/java/com/android/server/wifi
 
-Prior to that it was at
+commit date: 2013-12-19
+commit hash: 9158825f9c41869689d6b1786d7c7aa8bdd524ce (many more files)
+commit hash: 19c662b3df3b35756a92282bb6cc767e6407cb8a (a few files)
+dst:         frameworks/base/services/core/java/com/android/server/wifi
+src:         frameworks/base/services/java/com/android/server/wifi
 
-frameworks/base/wifi/java/android/net/wifi: gitk ffadfb9ffdced62db215319d3edc7717802088fb
+commit date: 2013-12-11
+commit hash: ffadfb9ffdced62db215319d3edc7717802088fb
+dst:         frameworks/base/services/java/com/android/server/wifi
+src:         frameworks/base/wifi/java/android/net/wifi
+
+commit date: 2008-10-21
+commit hash: 54b6cfa9a9e5b861a9930af873580d6dc20f773c
+dst:         frameworks/base/wifi/java/android/net/wifi
+src:         initial aosp import?
 
 ////////////////////////////////////////////////////////////////
 
diff --git a/service/java/com/android/server/wifi/ScanDetail.java b/service/java/com/android/server/wifi/ScanDetail.java
index dc87a5b..23e52db 100644
--- a/service/java/com/android/server/wifi/ScanDetail.java
+++ b/service/java/com/android/server/wifi/ScanDetail.java
@@ -83,40 +83,9 @@
         mScanResult = scanResult;
         mNetworkDetail = networkDetail;
         mMatches = matches;
-        mSeen = mScanResult.seen;
-    }
-
-    /**
-     * Update the data stored in the scan result with the provided information.
-     *
-     * @param networkDetail NetworkDetail
-     * @param level int
-     * @param wssid WifiSsid
-     * @param ssid String
-     * @param flags String
-     * @param freq int
-     * @param tsf long
-     */
-    public void updateResults(NetworkDetail networkDetail, int level, WifiSsid wssid, String ssid,
-                              String flags, int freq, long tsf) {
-        mScanResult.level = level;
-        mScanResult.wifiSsid = wssid;
-        // Keep existing API
-        mScanResult.SSID = ssid;
-        mScanResult.capabilities = flags;
-        mScanResult.frequency = freq;
-        mScanResult.timestamp = tsf;
-        mSeen = System.currentTimeMillis();
-        //mScanResult.seen = mSeen;
-        mScanResult.channelWidth = networkDetail.getChannelWidth();
-        mScanResult.centerFreq0 = networkDetail.getCenterfreq0();
-        mScanResult.centerFreq1 = networkDetail.getCenterfreq1();
-        if (networkDetail.is80211McResponderSupport()) {
-            mScanResult.setFlag(ScanResult.FLAG_80211mc_RESPONDER);
-        }
-        if (networkDetail.isInterworking()) {
-            mScanResult.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK);
-        }
+        // Only inherit |mScanResult.seen| if it was previously set. This ensures that |mSeen|
+        // will always contain a valid timestamp.
+        mSeen = (mScanResult.seen == 0) ? System.currentTimeMillis() : mScanResult.seen;
     }
 
     /**
diff --git a/service/java/com/android/server/wifi/ScanDetailCache.java b/service/java/com/android/server/wifi/ScanDetailCache.java
index cb44e2a..ede9a6e 100644
--- a/service/java/com/android/server/wifi/ScanDetailCache.java
+++ b/service/java/com/android/server/wifi/ScanDetailCache.java
@@ -29,8 +29,8 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.Iterator;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Maps BSSIDs to their individual ScanDetails for a given WifiConfiguration.
@@ -40,14 +40,29 @@
     private static final String TAG = "ScanDetailCache";
     private static final boolean DBG = false;
 
-    private WifiConfiguration mConfig;
-    private ConcurrentHashMap<String, ScanDetail> mMap;
-    private ConcurrentHashMap<String, PasspointMatchInfo> mPasspointMatches;
+    private final WifiConfiguration mConfig;
+    private final int mMaxSize;
+    private final int mTrimSize;
+    private final HashMap<String, ScanDetail> mMap;
+    private final HashMap<String, PasspointMatchInfo> mPasspointMatches;
 
-    ScanDetailCache(WifiConfiguration config) {
+    /**
+     * Scan Detail cache associated with each configured network.
+     *
+     * The cache size is trimmed down to |trimSize| once it crosses the provided |maxSize|.
+     * Since this operation is relatively expensive, ensure that |maxSize| and |trimSize| are not
+     * too close to each other. |trimSize| should always be <= |maxSize|.
+     *
+     * @param config   WifiConfiguration object corresponding to the network.
+     * @param maxSize  Max size desired for the cache.
+     * @param trimSize Size to trim the cache down to once it reaches |maxSize|.
+     */
+    ScanDetailCache(WifiConfiguration config, int maxSize, int trimSize) {
         mConfig = config;
-        mMap = new ConcurrentHashMap(16, 0.75f, 2);
-        mPasspointMatches = new ConcurrentHashMap(16, 0.75f, 2);
+        mMaxSize = maxSize;
+        mTrimSize = trimSize;
+        mMap = new HashMap(16, 0.75f);
+        mPasspointMatches = new HashMap(16, 0.75f);
     }
 
     void put(ScanDetail scanDetail) {
@@ -55,6 +70,10 @@
     }
 
     void put(ScanDetail scanDetail, PasspointMatch match, HomeSP homeSp) {
+        // First check if we have reached |maxSize|. if yes, trim it down to |trimSize|.
+        if (mMap.size() >= mMaxSize) {
+            trim();
+        }
 
         mMap.put(scanDetail.getBSSIDString(), scanDetail);
 
@@ -75,6 +94,7 @@
 
     void remove(String bssid) {
         mMap.remove(bssid);
+        mPasspointMatches.remove(bssid);
     }
 
     int size() {
@@ -94,13 +114,12 @@
     }
 
     /**
-     * Method to reduce the cache to the given size by removing the oldest entries.
-     *
-     * @param num int target cache size
+     * Method to reduce the cache to |mTrimSize| size by removing the oldest entries.
+     * TODO: Investigate if this method can be further optimized.
      */
-    public void trim(int num) {
+    private void trim() {
         int currentSize = mMap.size();
-        if (currentSize <= num) {
+        if (currentSize < mTrimSize) {
             return; // Nothing to trim
         }
         ArrayList<ScanDetail> list = new ArrayList<ScanDetail>(mMap.values());
@@ -120,7 +139,7 @@
                 }
             });
         }
-        for (int i = 0; i < currentSize - num; i++) {
+        for (int i = 0; i < currentSize - mTrimSize; i++) {
             // Remove oldest results from scan cache
             ScanDetail result = list.get(i);
             mMap.remove(result.getBSSIDString());
@@ -288,7 +307,6 @@
     }
 
 
-
     @Override
     public String toString() {
         StringBuilder sbuf = new StringBuilder();
diff --git a/service/java/com/android/server/wifi/SoftApManager.java b/service/java/com/android/server/wifi/SoftApManager.java
index 2dfb754..266234b 100644
--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -20,13 +20,14 @@
 import static com.android.server.wifi.util.ApConfigUtil.ERROR_NO_CHANNEL;
 import static com.android.server.wifi.util.ApConfigUtil.SUCCESS;
 
-import android.content.Context;
-import android.net.ConnectivityManager;
+import android.net.wifi.IApInterface;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
+import android.os.IBinder.DeathRecipient;
 import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
+import android.os.RemoteException;
 import android.util.Log;
 
 import com.android.internal.util.State;
@@ -72,8 +73,9 @@
                          INetworkManagementService nmService,
                          String countryCode,
                          ArrayList<Integer> allowed2GChannels,
-                         Listener listener) {
-        mStateMachine = new SoftApStateMachine(looper);
+                         Listener listener,
+                         IApInterface apInterface) {
+        mStateMachine = new SoftApStateMachine(looper, apInterface);
 
         mNmService = nmService;
         mWifiNative = wifiNative;
@@ -174,15 +176,29 @@
         /* Commands for the state machine. */
         public static final int CMD_START = 0;
         public static final int CMD_STOP = 1;
+        public static final int CMD_AP_INTERFACE_BINDER_DEATH = 2;
+
+        private final IApInterface mApInterface;
 
         private final State mIdleState = new IdleState();
         private final State mStartedState = new StartedState();
 
-        SoftApStateMachine(Looper looper) {
+        private ApInterfaceDeathRecipient mDeathRecipient;
+
+        private class ApInterfaceDeathRecipient implements DeathRecipient {
+            @Override
+            public void binderDied() {
+                SoftApStateMachine.this.sendMessage(CMD_AP_INTERFACE_BINDER_DEATH);
+            }
+        }
+
+
+        SoftApStateMachine(Looper looper, IApInterface apInterface) {
             super(TAG, looper);
+            mApInterface = apInterface;
 
             addState(mIdleState);
-            addState(mStartedState, mIdleState);
+            addState(mStartedState);
 
             setInitialState(mIdleState);
             start();
@@ -190,11 +206,31 @@
 
         private class IdleState extends State {
             @Override
+            public void enter() {
+                if (mDeathRecipient != null) {
+                    mApInterface.asBinder().unlinkToDeath(mDeathRecipient, 0);
+                    mDeathRecipient = null;
+                }
+            }
+
+            @Override
             public boolean processMessage(Message message) {
                 switch (message.what) {
                     case CMD_START:
+                        int result = SUCCESS;
                         updateApState(WifiManager.WIFI_AP_STATE_ENABLING, 0);
-                        int result = startSoftAp((WifiConfiguration) message.obj);
+                        mDeathRecipient = new ApInterfaceDeathRecipient();
+                        try {
+                            mApInterface.asBinder().linkToDeath(mDeathRecipient, 0);
+                        } catch (RemoteException e) {
+                            // The remote has already died.
+                            result = ERROR_GENERIC;
+                            break;
+                        }
+
+                        if (result == SUCCESS) {
+                            result = startSoftAp((WifiConfiguration) message.obj);
+                        }
                         if (result == SUCCESS) {
                             updateApState(WifiManager.WIFI_AP_STATE_ENABLED, 0);
                             transitionTo(mStartedState);
@@ -204,12 +240,17 @@
                                 reason = WifiManager.SAP_START_FAILURE_NO_CHANNEL;
                             }
                             updateApState(WifiManager.WIFI_AP_STATE_FAILED, reason);
+                            if (mDeathRecipient != null) {
+                                mApInterface.asBinder().unlinkToDeath(mDeathRecipient, 0);
+                                mDeathRecipient = null;
+                            }
                         }
                         break;
                     default:
                         /* Ignore all other commands. */
                         break;
                 }
+
                 return HANDLED;
             }
         }
@@ -221,10 +262,16 @@
                     case CMD_START:
                         /* Already started, ignore this command. */
                         break;
+                    case CMD_AP_INTERFACE_BINDER_DEATH:
                     case CMD_STOP:
                         updateApState(WifiManager.WIFI_AP_STATE_DISABLING, 0);
                         stopSoftAp();
-                        updateApState(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+                        if (message.what == CMD_AP_INTERFACE_BINDER_DEATH) {
+                            updateApState(WifiManager.WIFI_AP_STATE_FAILED,
+                                    WifiManager.SAP_START_FAILURE_GENERAL);
+                        } else {
+                            updateApState(WifiManager.WIFI_AP_STATE_DISABLED, 0);
+                        }
                         transitionTo(mIdleState);
                         break;
                     default:
diff --git a/service/java/com/android/server/wifi/WifiBackupRestore.java b/service/java/com/android/server/wifi/WifiBackupRestore.java
new file mode 100644
index 0000000..c83e063
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiBackupRestore.java
@@ -0,0 +1,749 @@
+/*
+ * 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 com.android.server.wifi;
+
+import android.net.IpConfiguration;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
+import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
+import android.util.Xml;
+
+import com.android.internal.util.FastXmlSerializer;
+import com.android.server.net.IpConfigStore;
+import com.android.server.wifi.util.XmlUtil;
+import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
+import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayReader;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class used to backup/restore data using the SettingsBackupAgent.
+ * There are 2 symmetric API's exposed here:
+ * 1. retrieveBackupDataFromConfigurations: Retrieve the configuration data to be backed up.
+ * 2. retrieveConfigurationsFromBackupData: Restore the configuration using the provided data.
+ * The byte stream to be backed up is XML encoded and versioned to migrate the data easily across
+ * revisions.
+ */
+public class WifiBackupRestore {
+    private static final String TAG = "WifiBackupRestore";
+
+    /**
+     * Current backup data version. This will be incremented for any additions.
+     */
+    private static final int CURRENT_BACKUP_DATA_VERSION = 1;
+
+    /** This list of older versions will be used to restore data from older backups. */
+    /**
+     * First version of the backup data format.
+     */
+    private static final int INITIAL_BACKUP_DATA_VERSION = 1;
+
+    /**
+     * List of XML section header tags in the backed up data
+     */
+    private static final String XML_TAG_DOCUMENT_HEADER = "WifiBackupData";
+    private static final String XML_TAG_VERSION = "Version";
+    private static final String XML_TAG_SECTION_HEADER_NETWORK_LIST = "NetworkList";
+    private static final String XML_TAG_SECTION_HEADER_NETWORK = "Network";
+    private static final String XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION = "WifiConfiguration";
+    private static final String XML_TAG_SECTION_HEADER_IP_CONFIGURATION = "IpConfiguration";
+
+    /**
+     * Regex to mask out passwords in backup data dump.
+     */
+    private static final String PSK_MASK_LINE_MATCH_PATTERN =
+            "<.*" + WifiConfigurationXmlUtil.XML_TAG_PRE_SHARED_KEY + ".*>.*<.*>";
+    private static final String PSK_MASK_SEARCH_PATTERN =
+            "(<.*" + WifiConfigurationXmlUtil.XML_TAG_PRE_SHARED_KEY + ".*>)(.*)(<.*>)";
+    private static final String PSK_MASK_REPLACE_PATTERN = "$1*$3";
+
+    private static final String WEP_KEYS_MASK_LINE_START_MATCH_PATTERN =
+            "<string-array.*" + WifiConfigurationXmlUtil.XML_TAG_WEP_KEYS + ".*num=\"[0-9]\">";
+    private static final String WEP_KEYS_MASK_LINE_END_MATCH_PATTERN = "</string-array>";
+    private static final String WEP_KEYS_MASK_SEARCH_PATTERN = "(<.*=)(.*)(/>)";
+    private static final String WEP_KEYS_MASK_REPLACE_PATTERN = "$1*$3";
+
+    /**
+     * Verbose logging flag.
+     */
+    private boolean mVerboseLoggingEnabled = false;
+
+    /**
+     * Store the dump of the backup/restore data for debugging. This is only stored when verbose
+     * logging is enabled in developer options.
+     */
+    private byte[] mDebugLastBackupDataRetrieved;
+    private byte[] mDebugLastBackupDataRestored;
+    private byte[] mDebugLastSupplicantBackupDataRestored;
+
+    /**
+     * Retrieve an XML byte stream representing the data that needs to be backed up from the
+     * provided configurations.
+     *
+     * @param configurations list of currently saved networks that needs to be backed up.
+     * @return Raw byte stream of XML that needs to be backed up.
+     */
+    public byte[] retrieveBackupDataFromConfigurations(List<WifiConfiguration> configurations) {
+        if (configurations == null) {
+            Log.e(TAG, "Invalid configuration list received");
+            return null;
+        }
+
+        try {
+            final XmlSerializer out = new FastXmlSerializer();
+            final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+
+            // Start writing the XML stream.
+            XmlUtil.writeDocumentStart(out, XML_TAG_DOCUMENT_HEADER);
+
+            XmlUtil.writeNextValue(out, XML_TAG_VERSION, CURRENT_BACKUP_DATA_VERSION);
+
+            writeNetworkConfigurationsToXml(out, configurations);
+
+            XmlUtil.writeDocumentEnd(out, XML_TAG_DOCUMENT_HEADER);
+
+            byte[] data = outputStream.toByteArray();
+
+            if (mVerboseLoggingEnabled) {
+                mDebugLastBackupDataRetrieved = data;
+            }
+
+            return data;
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "Error retrieving the backup data: " + e);
+        } catch (IOException e) {
+            Log.e(TAG, "Error retrieving the backup data: " + e);
+        }
+        return null;
+    }
+
+    /**
+     * Write the list of configurations to the XML stream.
+     */
+    private void writeNetworkConfigurationsToXml(
+            XmlSerializer out, List<WifiConfiguration> configurations)
+            throws XmlPullParserException, IOException {
+        XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK_LIST);
+        for (WifiConfiguration configuration : configurations) {
+            // We don't want to backup/restore enterprise/passpoint configurations.
+            if (configuration.isEnterprise() || configuration.isPasspoint()) {
+                Log.d(TAG, "Skipping enterprise network for backup: " + configuration.configKey());
+                continue;
+            }
+            // Write this configuration data now.
+            XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK);
+            writeNetworkConfigurationToXml(out, configuration);
+            XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK);
+        }
+        XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK_LIST);
+    }
+
+    /**
+     * Write the configuration data elements from the provided Configuration to the XML stream.
+     * Uses XmlUtils to write the values of each element.
+     */
+    private void writeNetworkConfigurationToXml(XmlSerializer out, WifiConfiguration configuration)
+            throws XmlPullParserException, IOException {
+        XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
+        WifiConfigurationXmlUtil.writeToXmlForBackup(out, configuration);
+        XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
+        XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_IP_CONFIGURATION);
+        IpConfigurationXmlUtil.writeToXml(out, configuration.getIpConfiguration());
+        XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_IP_CONFIGURATION);
+    }
+
+    /**
+     * Parse out the configurations from the back up data.
+     *
+     * @param data raw byte stream representing the XML data.
+     * @return list of networks retrieved from the backed up data.
+     */
+    public List<WifiConfiguration> retrieveConfigurationsFromBackupData(byte[] data) {
+        if (data == null || data.length == 0) {
+            Log.e(TAG, "Invalid backup data received");
+            return null;
+        }
+
+        try {
+            if (mVerboseLoggingEnabled) {
+                mDebugLastBackupDataRestored = data;
+            }
+
+            final XmlPullParser in = Xml.newPullParser();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
+            in.setInput(inputStream, StandardCharsets.UTF_8.name());
+
+            // Start parsing the XML stream.
+            XmlUtil.gotoDocumentStart(in, XML_TAG_DOCUMENT_HEADER);
+            int rootTagDepth = in.getDepth();
+
+            int version = (int) XmlUtil.readNextValueWithName(in, XML_TAG_VERSION);
+            if (version < INITIAL_BACKUP_DATA_VERSION || version > CURRENT_BACKUP_DATA_VERSION) {
+                Log.e(TAG, "Invalid version of data: " + version);
+                return null;
+            }
+
+            return parseNetworkConfigurationsFromXml(in, rootTagDepth, version);
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "Error parsing the backup data: " + e);
+        } catch (IOException e) {
+            Log.e(TAG, "Error parsing the backup data: " + e);
+        }
+        return null;
+    }
+
+    /**
+     * Parses the list of configurations from the provided XML stream.
+     *
+     * @param in            XmlPullParser instance pointing to the XML stream.
+     * @param outerTagDepth depth of the outer tag in the XML document.
+     * @param dataVersion   version number parsed from incoming data.
+     * @return List<WifiConfiguration> object if parsing is successful, null otherwise.
+     */
+    private List<WifiConfiguration> parseNetworkConfigurationsFromXml(
+            XmlPullParser in, int outerTagDepth, int dataVersion)
+            throws XmlPullParserException, IOException {
+        // Find the configuration list section.
+        XmlUtil.gotoNextSectionWithName(in, XML_TAG_SECTION_HEADER_NETWORK_LIST, outerTagDepth);
+        // Find all the configurations within the configuration list section.
+        int networkListTagDepth = outerTagDepth + 1;
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        while (XmlUtil.gotoNextSectionWithNameOrEnd(
+                in, XML_TAG_SECTION_HEADER_NETWORK, networkListTagDepth)) {
+            WifiConfiguration configuration =
+                    parseNetworkConfigurationFromXml(in, dataVersion, networkListTagDepth);
+            if (configuration != null) {
+                Log.v(TAG, "Parsed Configuration: " + configuration.configKey());
+                configurations.add(configuration);
+            }
+        }
+        return configurations;
+    }
+
+    /**
+     * Helper method to parse the WifiConfiguration object and validate the configKey parsed.
+     */
+    private WifiConfiguration parseWifiConfigurationFromXmlAndValidateConfigKey(
+            XmlPullParser in, int outerTagDepth)
+            throws XmlPullParserException, IOException {
+        Pair<String, WifiConfiguration> parsedConfig =
+                WifiConfigurationXmlUtil.parseFromXml(in, outerTagDepth);
+        if (parsedConfig == null || parsedConfig.first == null || parsedConfig.second == null) {
+            return null;
+        }
+        String configKeyParsed = parsedConfig.first;
+        WifiConfiguration configuration = parsedConfig.second;
+        String configKeyCalculated = configuration.configKey();
+        if (!configKeyParsed.equals(configKeyCalculated)) {
+            String configKeyMismatchLog =
+                    "Configuration key does not match. Retrieved: " + configKeyParsed
+                            + ", Calculated: " + configKeyCalculated;
+            if (configuration.shared) {
+                Log.e(TAG, configKeyMismatchLog);
+                return null;
+            } else {
+                // ConfigKey mismatches are expected for private networks because the
+                // UID is not preserved across backup/restore.
+                Log.w(TAG, configKeyMismatchLog);
+            }
+        }
+       return configuration;
+    }
+
+    /**
+     * Parses the configuration data elements from the provided XML stream to a Configuration.
+     *
+     * @param in            XmlPullParser instance pointing to the XML stream.
+     * @param outerTagDepth depth of the outer tag in the XML document.
+     * @param dataVersion   version number parsed from incoming data.
+     * @return WifiConfiguration object if parsing is successful, null otherwise.
+     */
+    private WifiConfiguration parseNetworkConfigurationFromXml(XmlPullParser in, int dataVersion,
+            int outerTagDepth)
+            throws XmlPullParserException, IOException {
+        // Any version migration needs to be handled here in future.
+        if (dataVersion == INITIAL_BACKUP_DATA_VERSION) {
+            WifiConfiguration configuration = null;
+            int networkTagDepth = outerTagDepth + 1;
+            // Retrieve WifiConfiguration object first.
+            XmlUtil.gotoNextSectionWithName(
+                    in, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION, networkTagDepth);
+            int configTagDepth = networkTagDepth + 1;
+            configuration = parseWifiConfigurationFromXmlAndValidateConfigKey(in, configTagDepth);
+            if (configuration == null) {
+                return null;
+            }
+            // Now retrieve any IP configuration info.
+            XmlUtil.gotoNextSectionWithName(
+                    in, XML_TAG_SECTION_HEADER_IP_CONFIGURATION, networkTagDepth);
+            IpConfiguration ipConfiguration =
+                    IpConfigurationXmlUtil.parseFromXml(in, configTagDepth);
+            configuration.setIpConfiguration(ipConfiguration);
+            return configuration;
+        }
+        return null;
+    }
+
+    /**
+     * Create log dump of the backup data in XML format with the preShared & WEP key masked.
+     *
+     * PSK keys are written in the following format in XML:
+     * <string name="PreSharedKey">WifiBackupRestorePsk</string>
+     *
+     * WEP Keys are written in following format in XML:
+     * <string-array name="WEPKeys" num="4">
+     *  <item value="WifiBackupRestoreWep1" />
+     *  <item value="WifiBackupRestoreWep2" />
+     *  <item value="WifiBackupRestoreWep3" />
+     *  <item value="WifiBackupRestoreWep3" />
+     * </string-array>
+     */
+    private String createLogFromBackupData(byte[] data) {
+        StringBuilder sb = new StringBuilder();
+        try {
+            String xmlString = new String(data, StandardCharsets.UTF_8.name());
+            boolean wepKeysLine = false;
+            for (String line : xmlString.split("\n")) {
+                if (line.matches(PSK_MASK_LINE_MATCH_PATTERN)) {
+                    line = line.replaceAll(PSK_MASK_SEARCH_PATTERN, PSK_MASK_REPLACE_PATTERN);
+                }
+                if (line.matches(WEP_KEYS_MASK_LINE_START_MATCH_PATTERN)) {
+                    wepKeysLine = true;
+                } else if (line.matches(WEP_KEYS_MASK_LINE_END_MATCH_PATTERN)) {
+                    wepKeysLine = false;
+                } else if (wepKeysLine) {
+                    line = line.replaceAll(
+                            WEP_KEYS_MASK_SEARCH_PATTERN, WEP_KEYS_MASK_REPLACE_PATTERN);
+                }
+                sb.append(line).append("\n");
+            }
+        } catch (UnsupportedEncodingException e) {
+            return "";
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Restore state from the older supplicant back up data.
+     * The old backup data was essentially a backup of wpa_supplicant.conf & ipconfig.txt file.
+     *
+     * @param supplicantData Raw byte stream of wpa_supplicant.conf
+     * @param ipConfigData   Raw byte stream of ipconfig.txt
+     * @return list of networks retrieved from the backed up data.
+     */
+    public List<WifiConfiguration> retrieveConfigurationsFromSupplicantBackupData(
+            byte[] supplicantData, byte[] ipConfigData) {
+        if (supplicantData == null || supplicantData.length == 0) {
+            Log.e(TAG, "Invalid supplicant backup data received");
+            return null;
+        }
+
+        if (mVerboseLoggingEnabled) {
+            mDebugLastSupplicantBackupDataRestored = supplicantData;
+        }
+
+        SupplicantBackupMigration.SupplicantNetworks supplicantNetworks =
+                new SupplicantBackupMigration.SupplicantNetworks();
+        // Incorporate the networks present in the backup data.
+        char[] restoredAsChars = new char[supplicantData.length];
+        for (int i = 0; i < supplicantData.length; i++) {
+            restoredAsChars[i] = (char) supplicantData[i];
+        }
+
+        BufferedReader in = new BufferedReader(new CharArrayReader(restoredAsChars));
+        supplicantNetworks.readNetworksFromStream(in);
+
+        // Retrieve corresponding WifiConfiguration objects.
+        List<WifiConfiguration> configurations = supplicantNetworks.retrieveWifiConfigurations();
+
+        // Now retrieve all the IpConfiguration objects and set in the corresponding
+        // WifiConfiguration objects if ipconfig data is present.
+        if (ipConfigData != null && ipConfigData.length != 0) {
+            SparseArray<IpConfiguration> networks =
+                    IpConfigStore.readIpAndProxyConfigurations(
+                            new ByteArrayInputStream(ipConfigData));
+            if (networks != null) {
+                for (int i = 0; i < networks.size(); i++) {
+                    int id = networks.keyAt(i);
+                    for (WifiConfiguration configuration : configurations) {
+                        // This is a dangerous lookup, but that's how it is currently written.
+                        if (configuration.configKey().hashCode() == id) {
+                            configuration.setIpConfiguration(networks.valueAt(i));
+                        }
+                    }
+                }
+            } else {
+                Log.e(TAG, "Failed to parse ipconfig data");
+            }
+        } else {
+            Log.e(TAG, "Invalid ipconfig backup data received");
+        }
+        return configurations;
+    }
+
+    /**
+     * Enable verbose logging.
+     *
+     * @param verbose verbosity level.
+     */
+    public void enableVerboseLogging(int verbose) {
+        mVerboseLoggingEnabled = (verbose > 0);
+        if (!mVerboseLoggingEnabled) {
+            mDebugLastBackupDataRetrieved = null;
+            mDebugLastBackupDataRestored = null;
+            mDebugLastSupplicantBackupDataRestored = null;
+        }
+    }
+
+    /**
+     * Dump out the last backup/restore data if verbose logging is enabled.
+     *
+     * @param fd   unused
+     * @param pw   PrintWriter for writing dump to
+     * @param args unused
+     */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Dump of WifiBackupRestore");
+        if (mDebugLastBackupDataRetrieved != null) {
+            pw.println("Last backup data retrieved: "
+                    + createLogFromBackupData(mDebugLastBackupDataRetrieved));
+        }
+        if (mDebugLastBackupDataRestored != null) {
+            pw.println("Last backup data restored: "
+                    + createLogFromBackupData(mDebugLastBackupDataRestored));
+        }
+        if (mDebugLastSupplicantBackupDataRestored != null) {
+            pw.println("Last old backup data restored: "
+                    + SupplicantBackupMigration.createLogFromBackupData(
+                            mDebugLastSupplicantBackupDataRestored));
+        }
+    }
+
+    /**
+     * These sub classes contain the logic to parse older backups and restore wifi state from it.
+     * Most of the code here has been migrated over from BackupSettingsAgent.
+     * This is kind of ugly text parsing, but it is needed to support the migration of this data.
+     */
+    public static class SupplicantBackupMigration {
+        /**
+         * List of keys to look out for in wpa_supplicant.conf parsing.
+         * These key values are declared in different parts of the wifi codebase today.
+         */
+        public static final String SUPPLICANT_KEY_SSID = WifiConfiguration.ssidVarName;
+        public static final String SUPPLICANT_KEY_HIDDEN = WifiConfiguration.hiddenSSIDVarName;
+        public static final String SUPPLICANT_KEY_KEY_MGMT = WifiConfiguration.KeyMgmt.varName;
+        public static final String SUPPLICANT_KEY_CLIENT_CERT =
+                WifiEnterpriseConfig.CLIENT_CERT_KEY;
+        public static final String SUPPLICANT_KEY_CA_CERT = WifiEnterpriseConfig.CA_CERT_KEY;
+        public static final String SUPPLICANT_KEY_CA_PATH = WifiEnterpriseConfig.CA_PATH_KEY;
+        public static final String SUPPLICANT_KEY_EAP = WifiEnterpriseConfig.EAP_KEY;
+        public static final String SUPPLICANT_KEY_PSK = WifiConfiguration.pskVarName;
+        public static final String SUPPLICANT_KEY_WEP_KEY0 = WifiConfiguration.wepKeyVarNames[0];
+        public static final String SUPPLICANT_KEY_WEP_KEY1 = WifiConfiguration.wepKeyVarNames[1];
+        public static final String SUPPLICANT_KEY_WEP_KEY2 = WifiConfiguration.wepKeyVarNames[2];
+        public static final String SUPPLICANT_KEY_WEP_KEY3 = WifiConfiguration.wepKeyVarNames[3];
+        public static final String SUPPLICANT_KEY_WEP_KEY_IDX =
+                WifiConfiguration.wepTxKeyIdxVarName;
+        public static final String SUPPLICANT_KEY_ID_STR = WifiSupplicantControl.ID_STRING_VAR_NAME;
+
+        /**
+         * Regex to mask out passwords in backup data dump.
+         */
+        private static final String PSK_MASK_LINE_MATCH_PATTERN =
+                ".*" + SUPPLICANT_KEY_PSK + ".*=.*";
+        private static final String PSK_MASK_SEARCH_PATTERN =
+                "(.*" + SUPPLICANT_KEY_PSK + ".*=)(.*)";
+        private static final String PSK_MASK_REPLACE_PATTERN = "$1*";
+
+        private static final String WEP_KEYS_MASK_LINE_MATCH_PATTERN =
+                ".*" + SUPPLICANT_KEY_WEP_KEY0.replace("0", "") + ".*=.*";
+        private static final String WEP_KEYS_MASK_SEARCH_PATTERN =
+                "(.*" + SUPPLICANT_KEY_WEP_KEY0.replace("0", "") + ".*=)(.*)";
+        private static final String WEP_KEYS_MASK_REPLACE_PATTERN = "$1*";
+
+        /**
+         * Create log dump of the backup data in wpa_supplicant.conf format with the preShared &
+         * WEP key masked.
+         *
+         * PSK keys are written in the following format in wpa_supplicant.conf:
+         *  psk=WifiBackupRestorePsk
+         *
+         * WEP Keys are written in following format in wpa_supplicant.conf:
+         *  wep_keys0=WifiBackupRestoreWep0
+         *  wep_keys1=WifiBackupRestoreWep1
+         *  wep_keys2=WifiBackupRestoreWep2
+         *  wep_keys3=WifiBackupRestoreWep3
+         */
+        public static String createLogFromBackupData(byte[] data) {
+            StringBuilder sb = new StringBuilder();
+            try {
+                String supplicantConfString = new String(data, StandardCharsets.UTF_8.name());
+                for (String line : supplicantConfString.split("\n")) {
+                    if (line.matches(PSK_MASK_LINE_MATCH_PATTERN)) {
+                        line = line.replaceAll(PSK_MASK_SEARCH_PATTERN, PSK_MASK_REPLACE_PATTERN);
+                    }
+                    if (line.matches(WEP_KEYS_MASK_LINE_MATCH_PATTERN)) {
+                        line = line.replaceAll(
+                                WEP_KEYS_MASK_SEARCH_PATTERN, WEP_KEYS_MASK_REPLACE_PATTERN);
+                    }
+                    sb.append(line).append("\n");
+                }
+            } catch (UnsupportedEncodingException e) {
+                return "";
+            }
+            return sb.toString();
+        }
+
+        /**
+         * Class for capturing a network definition from the wifi supplicant config file.
+         */
+        static class SupplicantNetwork {
+            private String mParsedSSIDLine;
+            private String mParsedHiddenLine;
+            private String mParsedKeyMgmtLine;
+            private String mParsedPskLine;
+            private String[] mParsedWepKeyLines = new String[4];
+            private String mParsedWepTxKeyIdxLine;
+            private String mParsedIdStrLine;
+            public boolean certUsed = false;
+            public boolean isEap = false;
+
+            /**
+             * Read lines from wpa_supplicant.conf stream for this network.
+             */
+            public static SupplicantNetwork readNetworkFromStream(BufferedReader in) {
+                final SupplicantNetwork n = new SupplicantNetwork();
+                String line;
+                try {
+                    while (in.ready()) {
+                        line = in.readLine();
+                        if (line == null || line.startsWith("}")) {
+                            break;
+                        }
+                        n.parseLine(line);
+                    }
+                } catch (IOException e) {
+                    return null;
+                }
+                return n;
+            }
+
+            /**
+             * Parse a line from wpa_supplicant.conf stream for this network.
+             */
+            void parseLine(String line) {
+                // Can't rely on particular whitespace patterns so strip leading/trailing.
+                line = line.trim();
+                if (line.isEmpty()) return; // only whitespace; drop the line.
+
+                // Now parse the network block within wpa_supplicant.conf and store the important
+                // lines for procesing later.
+                if (line.startsWith(SUPPLICANT_KEY_SSID)) {
+                    mParsedSSIDLine = line;
+                } else if (line.startsWith(SUPPLICANT_KEY_HIDDEN)) {
+                    mParsedHiddenLine = line;
+                } else if (line.startsWith(SUPPLICANT_KEY_KEY_MGMT)) {
+                    mParsedKeyMgmtLine = line;
+                    if (line.contains("EAP")) {
+                        isEap = true;
+                    }
+                } else if (line.startsWith(SUPPLICANT_KEY_CLIENT_CERT)) {
+                    certUsed = true;
+                } else if (line.startsWith(SUPPLICANT_KEY_CA_CERT)) {
+                    certUsed = true;
+                } else if (line.startsWith(SUPPLICANT_KEY_CA_PATH)) {
+                    certUsed = true;
+                } else if (line.startsWith(SUPPLICANT_KEY_EAP)) {
+                    isEap = true;
+                } else if (line.startsWith(SUPPLICANT_KEY_PSK)) {
+                    mParsedPskLine = line;
+                } else if (line.startsWith(SUPPLICANT_KEY_WEP_KEY0)) {
+                    mParsedWepKeyLines[0] = line;
+                } else if (line.startsWith(SUPPLICANT_KEY_WEP_KEY1)) {
+                    mParsedWepKeyLines[1] = line;
+                } else if (line.startsWith(SUPPLICANT_KEY_WEP_KEY2)) {
+                    mParsedWepKeyLines[2] = line;
+                } else if (line.startsWith(SUPPLICANT_KEY_WEP_KEY3)) {
+                    mParsedWepKeyLines[3] = line;
+                } else if (line.startsWith(SUPPLICANT_KEY_WEP_KEY_IDX)) {
+                    mParsedWepTxKeyIdxLine = line;
+                } else if (line.startsWith(SUPPLICANT_KEY_ID_STR)) {
+                    mParsedIdStrLine = line;
+                }
+            }
+
+            /**
+             * Create WifiConfiguration object from the parsed data for this network.
+             */
+            public WifiConfiguration createWifiConfiguration() {
+                if (mParsedSSIDLine == null) {
+                    // No SSID => malformed network definition
+                    return null;
+                }
+                WifiConfiguration configuration = new WifiConfiguration();
+                configuration.SSID = mParsedSSIDLine.substring(mParsedSSIDLine.indexOf('=') + 1);
+
+                if (mParsedHiddenLine != null) {
+                    // Can't use Boolean.valueOf() because it works only for true/false.
+                    configuration.hiddenSSID =
+                            Integer.parseInt(mParsedHiddenLine.substring(
+                                    mParsedHiddenLine.indexOf('=') + 1)) != 0;
+                }
+                if (mParsedKeyMgmtLine == null) {
+                    // no key_mgmt line specified; this is defined as equivalent to
+                    // "WPA-PSK WPA-EAP".
+                    configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+                    configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+                } else {
+                    // Need to parse the mParsedKeyMgmtLine line
+                    final String bareKeyMgmt =
+                            mParsedKeyMgmtLine.substring(mParsedKeyMgmtLine.indexOf('=') + 1);
+                    String[] typeStrings = bareKeyMgmt.split("\\s+");
+
+                    // Parse out all the key management regimes permitted for this network.
+                    // The literal strings here are the standard values permitted in
+                    // wpa_supplicant.conf.
+                    for (int i = 0; i < typeStrings.length; i++) {
+                        final String ktype = typeStrings[i];
+                        if (ktype.equals("NONE")) {
+                            configuration.allowedKeyManagement.set(
+                                    WifiConfiguration.KeyMgmt.NONE);
+                        } else if (ktype.equals("WPA-PSK")) {
+                            configuration.allowedKeyManagement.set(
+                                    WifiConfiguration.KeyMgmt.WPA_PSK);
+                        } else if (ktype.equals("WPA-EAP")) {
+                            configuration.allowedKeyManagement.set(
+                                    WifiConfiguration.KeyMgmt.WPA_EAP);
+                        } else if (ktype.equals("IEEE8021X")) {
+                            configuration.allowedKeyManagement.set(
+                                    WifiConfiguration.KeyMgmt.IEEE8021X);
+                        }
+                    }
+                }
+                if (mParsedPskLine != null) {
+                    configuration.preSharedKey =
+                            mParsedPskLine.substring(mParsedPskLine.indexOf('=') + 1);
+                }
+                if (mParsedWepKeyLines[0] != null) {
+                    configuration.wepKeys[0] =
+                            mParsedWepKeyLines[0].substring(mParsedWepKeyLines[0].indexOf('=') + 1);
+                }
+                if (mParsedWepKeyLines[1] != null) {
+                    configuration.wepKeys[1] =
+                            mParsedWepKeyLines[1].substring(mParsedWepKeyLines[1].indexOf('=') + 1);
+                }
+                if (mParsedWepKeyLines[2] != null) {
+                    configuration.wepKeys[2] =
+                            mParsedWepKeyLines[2].substring(mParsedWepKeyLines[2].indexOf('=') + 1);
+                }
+                if (mParsedWepKeyLines[3] != null) {
+                    configuration.wepKeys[3] =
+                            mParsedWepKeyLines[3].substring(mParsedWepKeyLines[3].indexOf('=') + 1);
+                }
+                if (mParsedWepTxKeyIdxLine != null) {
+                    configuration.wepTxKeyIndex =
+                            Integer.valueOf(mParsedWepTxKeyIdxLine.substring(
+                                    mParsedWepTxKeyIdxLine.indexOf('=') + 1));
+                }
+                if (mParsedIdStrLine != null) {
+                    String idString =
+                            mParsedIdStrLine.substring(mParsedIdStrLine.indexOf('=') + 1);
+                    Map<String, String> extras = WifiNative.parseNetworkExtra(idString);
+                    String configKey = extras.get(WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY);
+                    if (!configKey.equals(configuration.configKey())) {
+                        // ConfigKey mismatches are expected for private networks because the
+                        // UID is not preserved across backup/restore.
+                        Log.w(TAG, "Configuration key does not match. Retrieved: " + configKey
+                                + ", Calculated: " + configuration.configKey());
+                    }
+                }
+                return configuration;
+            }
+        }
+
+        /**
+         * Ingest multiple wifi config fragments from wpa_supplicant.conf, looking for network={}
+         * blocks and eliminating duplicates
+         */
+        static class SupplicantNetworks {
+            final ArrayList<SupplicantNetwork> mNetworks = new ArrayList<>(8);
+
+            /**
+             * Parse the wpa_supplicant.conf file stream and add networks.
+             */
+            public void readNetworksFromStream(BufferedReader in) {
+                try {
+                    String line;
+                    while (in.ready()) {
+                        line = in.readLine();
+                        if (line != null) {
+                            if (line.startsWith("network")) {
+                                SupplicantNetwork net = SupplicantNetwork.readNetworkFromStream(in);
+                                // Networks that use certificates for authentication can't be
+                                // restored because the certificates they need don't get restored
+                                // (because they are stored in keystore, and can't be restored).
+                                // Similarly, omit EAP network definitions to avoid propagating
+                                // controlled enterprise network definitions.
+                                if (net.isEap || net.certUsed) {
+                                    Log.d(TAG, "Skipping enterprise network for restore: "
+                                            + net.mParsedSSIDLine + " / " + net.mParsedKeyMgmtLine);
+                                    continue;
+                                }
+                                mNetworks.add(net);
+                            }
+                        }
+                    }
+                } catch (IOException e) {
+                    // whatever happened, we're done now
+                }
+            }
+
+            /**
+             * Retrieve a list of WifiConfiguration objects parsed from wpa_supplicant.conf
+             */
+            public List<WifiConfiguration> retrieveWifiConfigurations() {
+                ArrayList<WifiConfiguration> wifiConfigurations = new ArrayList<>();
+                for (SupplicantNetwork net : mNetworks) {
+                    WifiConfiguration wifiConfiguration = net.createWifiConfiguration();
+                    if (wifiConfiguration != null) {
+                        Log.v(TAG, "Parsed Configuration: " + wifiConfiguration.configKey());
+                        wifiConfigurations.add(wifiConfiguration);
+                    }
+                }
+                return wifiConfigurations;
+            }
+        }
+    }
+}
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index c1a334a..1e288ef 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -45,7 +45,6 @@
 import android.net.wifi.WpsResult;
 import android.os.Environment;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -151,8 +150,6 @@
  *
  */
 public class WifiConfigManager {
-    private static boolean sVDBG = false;
-    private static boolean sVVDBG = false;
     public static final String TAG = "WifiConfigManager";
     public static final int MAX_TX_PACKET_FOR_FULL_SCANS = 8;
     public static final int MAX_RX_PACKET_FOR_FULL_SCANS = 16;
@@ -185,6 +182,11 @@
     private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
 
     /**
+     * Maximum age of scan results that can be used for averaging out RSSI value.
+     */
+    private static final int SCAN_RESULT_MAXIMUM_AGE_MS = 40000;
+
+    /**
      * The threshold for each kind of error. If a network continuously encounter the same error more
      * than the threshold times, this network will be disabled. -1 means unavailable.
      */
@@ -195,10 +197,12 @@
             5,  //  threshold for DISABLED_AUTHENTICATION_FAILURE
             5,  //  threshold for DISABLED_DHCP_FAILURE
             5,  //  threshold for DISABLED_DNS_FAILURE
+            1,  //  threshold for DISABLED_WPS_START
             6,  //  threshold for DISABLED_TLS_VERSION_MISMATCH
             1,  //  threshold for DISABLED_AUTHENTICATION_NO_CREDENTIALS
             1,  //  threshold for DISABLED_NO_INTERNET
-            1   //  threshold for DISABLED_BY_WIFI_MANAGER
+            1,  //  threshold for DISABLED_BY_WIFI_MANAGER
+            1   //  threshold for DISABLED_BY_USER_SWITCH
     };
 
     /**
@@ -211,10 +215,12 @@
             5,                  // threshold for DISABLED_AUTHENTICATION_FAILURE
             5,                  // threshold for DISABLED_DHCP_FAILURE
             5,                  // threshold for DISABLED_DNS_FAILURE
+            0,                  // threshold for DISABLED_WPS_START
             Integer.MAX_VALUE,  // threshold for DISABLED_TLS_VERSION
             Integer.MAX_VALUE,  // threshold for DISABLED_AUTHENTICATION_NO_CREDENTIALS
             Integer.MAX_VALUE,  // threshold for DISABLED_NO_INTERNET
-            Integer.MAX_VALUE   // threshold for DISABLED_BY_WIFI_MANAGER
+            Integer.MAX_VALUE,  // threshold for DISABLED_BY_WIFI_MANAGER
+            Integer.MAX_VALUE   // threshold for DISABLED_BY_USER_SWITCH
     };
 
     public final AtomicBoolean mEnableAutoJoinWhenAssociated = new AtomicBoolean();
@@ -222,7 +228,6 @@
     public final AtomicBoolean mEnableRssiPollWhenAssociated = new AtomicBoolean(true);
     public final AtomicInteger mThresholdSaturatedRssi5 = new AtomicInteger();
     public final AtomicInteger mThresholdQualifiedRssi24 = new AtomicInteger();
-    public final AtomicInteger mEnableVerboseLogging = new AtomicInteger(0);
     public final AtomicInteger mAlwaysEnableScansWhileAssociated = new AtomicInteger(0);
     public final AtomicInteger mMaxNumActiveChannelsForPartialScans = new AtomicInteger();
 
@@ -255,6 +260,10 @@
      * The SSIDs are encoded in a String as per definition of WifiConfiguration.SSID field.
      */
     public Set<String> mDeletedEphemeralSSIDs = new HashSet<String>();
+    /**
+     * List of blacklisted BSSIDs.
+     */
+    private final HashSet<String> mBssidBlacklist = new HashSet<String>();
 
     /* configured networks with network id as the key */
     private final ConfigurationMap mConfiguredNetworks;
@@ -262,7 +271,8 @@
     private final LocalLog mLocalLog;
     private final KeyStore mKeyStore;
     private final WifiNetworkHistory mWifiNetworkHistory;
-    private final WifiConfigStore mWifiConfigStore;
+    private final WifiSupplicantControl mWifiSupplicantControl;
+    private final WifiKeyStore mWifiKeyStore;
     private final AnqpCache mAnqpCache;
     private final SupplicantBridge mSupplicantBridge;
     private final SupplicantBridgeCallbacks mSupplicantBridgeCallbacks;
@@ -270,15 +280,15 @@
     private final boolean mEnableOsuQueries;
     private final SIMAccessor mSIMAccessor;
     private final UserManager mUserManager;
-    private final Object mActiveScanDetailLock = new Object();
+    private final BackupManagerProxy mBackupManagerProxy;
 
+    private boolean mVerboseLoggingEnabled = false;
     private Context mContext;
     private FrameworkFacade mFacade;
     private Clock mClock;
     private IpConfigStore mIpconfigStore;
     private DelayedDiskWrite mWriter;
     private boolean mOnlyLinkSameCredentialConfigurations;
-    private boolean mShowNetworks = false;
     private int mCurrentUserId = UserHandle.USER_SYSTEM;
 
     /* Stores a map of NetworkId to ScanCache */
@@ -304,7 +314,8 @@
      */
     private HashSet<String> mLostConfigsDbg = new HashSet<String>();
 
-    private ScanDetail mActiveScanDetail;   // ScanDetail associated with active network
+    // NetworkDetail associated with the last selected Passpoint network.
+    private NetworkDetail mSelectedPasspointNetwork;
 
     private class SupplicantBridgeCallbacks implements SupplicantBridge.SupplicantBridgeCallbacks {
         @Override
@@ -339,12 +350,7 @@
         mClock = clock;
         mKeyStore = keyStore;
         mUserManager = userManager;
-
-        if (mShowNetworks) {
-            mLocalLog = wifiNative.getLocalLog();
-        } else {
-            mLocalLog = null;
-        }
+        mLocalLog = wifiNative.getLocalLog();
 
         mOnlyLinkSameCredentialConfigurations = mContext.getResources().getBoolean(
                 R.bool.config_wifi_only_link_same_credential_configurations);
@@ -396,28 +402,27 @@
         mSIMAccessor = new SIMAccessor(mContext);
         mWriter = new DelayedDiskWrite();
         mIpconfigStore = new IpConfigStore(mWriter);
-        mWifiNetworkHistory = new WifiNetworkHistory(context, mLocalLog, mWriter);
-        mWifiConfigStore =
-                new WifiConfigStore(context, wifiNative, mKeyStore, mLocalLog, mShowNetworks, true);
+        mWifiNetworkHistory = new WifiNetworkHistory(mContext, mLocalLog, mWriter);
+        mWifiSupplicantControl = new WifiSupplicantControl(mContext, wifiNative, mLocalLog);
+        mWifiKeyStore = new WifiKeyStore(keyStore);
+        mBackupManagerProxy = new BackupManagerProxy();
     }
 
     public void trimANQPCache(boolean all) {
         mAnqpCache.clear(all, DBG);
     }
 
+    /**
+     * Enable verbose logging.
+     */
     void enableVerboseLogging(int verbose) {
-        mEnableVerboseLogging.set(verbose);
         if (verbose > 0) {
-            sVDBG = true;
-            mShowNetworks = true;
+            mVerboseLoggingEnabled = true;
         } else {
-            sVDBG = false;
+            mVerboseLoggingEnabled = false;
         }
-        if (verbose > 1) {
-            sVVDBG = true;
-        } else {
-            sVVDBG = false;
-        }
+        mWifiSupplicantControl.enableVerboseLogging(mVerboseLoggingEnabled);
+        mWifiKeyStore.enableVerboseLogging(mVerboseLoggingEnabled);
     }
 
     /**
@@ -543,50 +548,6 @@
     }
 
     /**
-     * Fetch the list of currently saved networks (i.e. all configured networks, excluding
-     * ephemeral networks) that were recently seen.
-     *
-     * @param scanResultAgeMs The maximum age (in ms) of scan results for which we calculate the
-     * RSSI values
-     * @param copy If true, the returned list will contain copies of the configurations for the
-     * saved networks. Otherwise, the returned list will contain references to these
-     * configurations.
-     * @return List of networks
-     */
-    List<WifiConfiguration> getRecentSavedNetworks(int scanResultAgeMs, boolean copy) {
-        List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
-
-        for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) {
-            if (config.ephemeral) {
-                // Do not enumerate and return this configuration to anyone (e.g. WiFi Picker);
-                // treat it as unknown instead. This configuration can still be retrieved
-                // directly by its key or networkId.
-                continue;
-            }
-
-            // Calculate the RSSI for scan results that are more recent than scanResultAgeMs.
-            ScanDetailCache cache = getScanDetailCache(config);
-            if (cache == null) {
-                continue;
-            }
-            config.setVisibility(cache.getVisibility(scanResultAgeMs));
-            if (config.visibility == null) {
-                continue;
-            }
-            if (config.visibility.rssi5 == WifiConfiguration.INVALID_RSSI
-                    && config.visibility.rssi24 == WifiConfiguration.INVALID_RSSI) {
-                continue;
-            }
-            if (copy) {
-                networks.add(new WifiConfiguration(config));
-            } else {
-                networks.add(config);
-            }
-        }
-        return networks;
-    }
-
-    /**
      *  Update the configuration and BSSID with latest RSSI value.
      */
     void updateConfiguration(WifiInfo info) {
@@ -603,9 +564,8 @@
                 result.level = info.getRssi();
 
                 // Average the RSSI value
-                result.averageRssi(previousRssi, previousSeen,
-                        WifiQualifiedNetworkSelector.SCAN_RESULT_MAXIMUNM_AGE);
-                if (sVDBG) {
+                result.averageRssi(previousRssi, previousSeen, SCAN_RESULT_MAXIMUM_AGE_MS);
+                if (mVerboseLoggingEnabled) {
                     logd("updateConfiguration freq=" + result.frequency
                             + " BSSID=" + result.BSSID
                             + " RSSI=" + result.level
@@ -655,11 +615,11 @@
     }
 
     private boolean setNetworkPriorityNative(WifiConfiguration config, int priority) {
-        return mWifiConfigStore.setNetworkPriority(config, priority);
+        return mWifiSupplicantControl.setNetworkPriority(config, priority);
     }
 
     private boolean setSSIDNative(WifiConfiguration config, String ssid) {
-        return mWifiConfigStore.setNetworkSSID(config, ssid);
+        return mWifiSupplicantControl.setNetworkSSID(config, ssid);
     }
 
     public boolean updateLastConnectUid(WifiConfiguration config, int uid) {
@@ -686,7 +646,7 @@
      * @return false if the network id is invalid
      */
     boolean selectNetwork(WifiConfiguration config, boolean updatePriorities, int uid) {
-        if (sVDBG) localLogNetwork("selectNetwork", config.networkId);
+        if (mVerboseLoggingEnabled) localLogNetwork("selectNetwork", config.networkId);
         if (config.networkId == INVALID_NETWORK_ID) return false;
         if (!WifiConfigurationUtil.isVisibleToAnyProfile(config,
                 mUserManager.getProfiles(mCurrentUserId))) {
@@ -712,6 +672,7 @@
             setNetworkPriorityNative(config, ++mLastPriority);
         }
 
+        NetworkDetail selectedPasspointNetwork = null;
         if (config.isPasspoint()) {
             // Set the SSID for the underlying WPA supplicant network entry corresponding to this
             // Passpoint profile to the SSID of the BSS selected by QNS. |config.SSID| is set by
@@ -720,9 +681,18 @@
             logd("Setting SSID for WPA supplicant network " + config.networkId + " to "
                     + config.SSID);
             setSSIDNative(config, config.SSID);
+            String selectedPasspointNetworkBssid = mWifiSupplicantControl.getNetworkBSSID(config);
+            if (selectedPasspointNetworkBssid != null) {
+                ScanDetail result =
+                        getScanDetailCache(config).getScanDetail(selectedPasspointNetworkBssid);
+                if (result != null) {
+                    selectedPasspointNetwork = result.getNetworkDetail();
+                }
+            }
         }
+        mSelectedPasspointNetwork = selectedPasspointNetwork;
 
-        mWifiConfigStore.enableHS20(config.isPasspoint());
+        mWifiSupplicantControl.enableHS20(config.isPasspoint());
 
         if (updatePriorities) {
             saveConfig();
@@ -759,8 +729,10 @@
             return new NetworkUpdateResult(INVALID_NETWORK_ID);
         }
 
-        if (sVDBG) localLogNetwork("WifiConfigManager: saveNetwork netId", config.networkId);
-        if (sVDBG) {
+        if (mVerboseLoggingEnabled) {
+            localLogNetwork("WifiConfigManager: saveNetwork netId", config.networkId);
+        }
+        if (mVerboseLoggingEnabled) {
             logd("WifiConfigManager saveNetwork,"
                     + " size=" + Integer.toString(mConfiguredNetworks.sizeForAllUsers())
                     + " (for all users)"
@@ -770,7 +742,7 @@
         }
 
         if (mDeletedEphemeralSSIDs.remove(config.SSID)) {
-            if (sVDBG) {
+            if (mVerboseLoggingEnabled) {
                 logd("WifiConfigManager: removed from ephemeral blacklist: " + config.SSID);
             }
             // NOTE: This will be flushed to disk as part of the addOrUpdateNetworkNative call
@@ -781,18 +753,22 @@
         NetworkUpdateResult result = addOrUpdateNetworkNative(config, uid);
         int netId = result.getNetworkId();
 
-        if (sVDBG) localLogNetwork("WifiConfigManager: saveNetwork got it back netId=", netId);
+        if (mVerboseLoggingEnabled) {
+            localLogNetwork("WifiConfigManager: saveNetwork got it back netId=", netId);
+        }
 
         conf = mConfiguredNetworks.getForCurrentUser(netId);
         if (conf != null) {
             if (!conf.getNetworkSelectionStatus().isNetworkEnabled()) {
-                if (sVDBG) localLog("WifiConfigManager: re-enabling: " + conf.SSID);
+                if (mVerboseLoggingEnabled) {
+                    localLog("WifiConfigManager: re-enabling: " + conf.SSID);
+                }
 
                 // reenable autojoin, since new information has been provided
                 updateNetworkSelectionStatus(netId,
                         WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
             }
-            if (sVDBG) {
+            if (mVerboseLoggingEnabled) {
                 logd("WifiConfigManager: saveNetwork got config back netId="
                         + Integer.toString(netId)
                         + " uid=" + Integer.toString(config.creatorUid));
@@ -810,7 +786,7 @@
 
     void noteRoamingFailure(WifiConfiguration config, int reason) {
         if (config == null) return;
-        config.lastRoamingFailure = mClock.currentTimeMillis();
+        config.lastRoamingFailure = mClock.getWallClockMillis();
         config.roamingFailureBlackListTimeMilli =
                 2 * (config.roamingFailureBlackListTimeMilli + 1000);
         if (config.roamingFailureBlackListTimeMilli > mNetworkSwitchingBlackListPeriodMs) {
@@ -820,7 +796,7 @@
     }
 
     void saveWifiConfigBSSID(WifiConfiguration config, String bssid) {
-        mWifiConfigStore.setNetworkBSSID(config, bssid);
+        mWifiSupplicantControl.setNetworkBSSID(config, bssid);
     }
 
 
@@ -836,6 +812,7 @@
                             WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
                     break;
                 case DISCONNECTED:
+                    mSelectedPasspointNetwork = null;
                     //If network is already disabled, keep the status
                     if (config.status == Status.CURRENT) {
                         config.status = Status.ENABLED;
@@ -885,7 +862,7 @@
      * @return {@code true} if it succeeds, {@code false} otherwise
      */
     boolean forgetNetwork(int netId) {
-        if (mShowNetworks) localLogNetwork("forgetNetwork", netId);
+        if (mVerboseLoggingEnabled) localLogNetwork("forgetNetwork", netId);
         if (!removeNetwork(netId)) {
             loge("Failed to forget network " + netId);
             return false;
@@ -910,7 +887,7 @@
             return WifiConfiguration.INVALID_NETWORK_ID;
         }
 
-        if (mShowNetworks) localLogNetwork("addOrUpdateNetwork id=", config.networkId);
+        if (mVerboseLoggingEnabled) localLogNetwork("addOrUpdateNetwork id=", config.networkId);
         if (config.isPasspoint()) {
             /* create a temporary SSID with providerFriendlyName */
             Long csum = getChecksum(config.FQDN);
@@ -955,11 +932,8 @@
     }
 
     public int matchProviderWithCurrentNetwork(String fqdn) {
-        ScanDetail scanDetail = null;
-        synchronized (mActiveScanDetailLock) {
-            scanDetail = mActiveScanDetail;
-        }
-        if (scanDetail == null) {
+        NetworkDetail selectedPasspointNetwork = mSelectedPasspointNetwork;
+        if (selectedPasspointNetwork == null) {
             return PasspointMatch.None.ordinal();
         }
         HomeSP homeSP = mMOManager.getHomeSP(fqdn);
@@ -967,12 +941,15 @@
             return PasspointMatch.None.ordinal();
         }
 
-        ANQPData anqpData = mAnqpCache.getEntry(scanDetail.getNetworkDetail());
+        Map<Constants.ANQPElementType, ANQPElement> anqpElements
+                = selectedPasspointNetwork.getANQPElements();
 
-        Map<Constants.ANQPElementType, ANQPElement> anqpElements =
-                anqpData != null ? anqpData.getANQPElements() : null;
+        if (anqpElements == null || anqpElements.isEmpty()) {
+            ANQPData anqpData = mAnqpCache.getEntry(selectedPasspointNetwork);
+            anqpElements = anqpData != null ? anqpData.getANQPElements() : null;
+        }
 
-        return homeSP.match(scanDetail.getNetworkDetail(), anqpElements, mSIMAccessor).ordinal();
+        return homeSP.match(selectedPasspointNetwork, anqpElements, mSIMAccessor).ordinal();
     }
 
     /**
@@ -1149,7 +1126,7 @@
      * @return {@code true} if it succeeds, {@code false} otherwise
      */
     boolean removeNetwork(int netId) {
-        if (mShowNetworks) localLogNetwork("removeNetwork", netId);
+        if (mVerboseLoggingEnabled) localLogNetwork("removeNetwork", netId);
         WifiConfiguration config = mConfiguredNetworks.getForCurrentUser(netId);
         if (!removeConfigAndSendBroadcastIfNeeded(config)) {
             return false;
@@ -1170,7 +1147,7 @@
         if (config == null) {
             return false;
         }
-        if (!mWifiConfigStore.removeNetwork(config)) {
+        if (!removeNetworkNative(config)) {
             loge("Failed to remove network " + config.networkId);
             return false;
         }
@@ -1187,7 +1164,7 @@
             return false;
         }
         String key = config.configKey();
-        if (sVDBG) {
+        if (mVerboseLoggingEnabled) {
             logd("removeNetwork " + " key=" + key + " config.id=" + config.networkId);
         }
         writeIpAndProxyConfigurations();
@@ -1238,7 +1215,7 @@
             if (app.uid != config.creatorUid || !app.packageName.equals(config.creatorName)) {
                 continue;
             }
-            if (mShowNetworks) {
+            if (mVerboseLoggingEnabled) {
                 localLog("Removing network " + config.SSID
                          + ", application \"" + app.packageName + "\" uninstalled"
                          + " from user " + UserHandle.getUserId(app.uid));
@@ -1261,7 +1238,7 @@
                 continue;
             }
             success &= removeNetwork(config.networkId);
-            if (mShowNetworks) {
+            if (mVerboseLoggingEnabled) {
                 localLog("Removing network " + config.SSID
                         + ", user " + userId + " removed");
             }
@@ -1283,54 +1260,61 @@
         if (config == null) {
             return false;
         }
-
         updateNetworkSelectionStatus(
                 config, WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
         setLatestUserSelectedConfiguration(config);
         boolean ret = true;
         if (disableOthers) {
             ret = selectNetworkWithoutBroadcast(config.networkId);
-            if (sVDBG) {
-                localLogNetwork("enableNetwork(disableOthers=true, uid=" + uid + ") ",
-                        config.networkId);
+            if (ret) {
+                if (mVerboseLoggingEnabled) {
+                    localLogNetwork("enableNetwork(disableOthers=true, uid=" + uid + ") ",
+                            config.networkId);
+                }
+                markAllNetworksDisabledExcept(config.networkId,
+                        WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER);
+                updateLastConnectUid(config, uid);
+                writeKnownNetworkHistory();
+                sendConfiguredNetworksChangedBroadcast();
             }
-            updateLastConnectUid(config, uid);
-            writeKnownNetworkHistory();
-            sendConfiguredNetworksChangedBroadcast();
         } else {
-            if (sVDBG) localLogNetwork("enableNetwork(disableOthers=false) ", config.networkId);
+            if (mVerboseLoggingEnabled) {
+                localLogNetwork("enableNetwork(disableOthers=false) ", config.networkId);
+            }
             sendConfiguredNetworksChangedBroadcast(config, WifiManager.CHANGE_REASON_CONFIG_CHANGE);
         }
         return ret;
     }
 
     boolean selectNetworkWithoutBroadcast(int netId) {
-        return mWifiConfigStore.selectNetwork(
-                mConfiguredNetworks.getForCurrentUser(netId),
-                mConfiguredNetworks.valuesForCurrentUser());
+        return mWifiSupplicantControl.selectNetwork(mConfiguredNetworks.getForCurrentUser(netId));
     }
 
     /**
      * Disable a network in wpa_supplicant.
      */
     boolean disableNetworkNative(WifiConfiguration config) {
-        return mWifiConfigStore.disableNetwork(config);
+        return mWifiSupplicantControl.disableNetwork(config);
     }
 
     /**
      * Disable all networks in wpa_supplicant.
      */
     void disableAllNetworksNative() {
-        mWifiConfigStore.disableAllNetworks(mConfiguredNetworks.valuesForCurrentUser());
+        mWifiSupplicantControl.disableAllNetworks(mConfiguredNetworks.valuesForCurrentUser());
     }
 
-    /**
-     * Disable a network. Note that there is no saveConfig operation.
-     * @param netId network to be disabled
-     * @return {@code true} if it succeeds, {@code false} otherwise
-     */
-    boolean disableNetwork(int netId) {
-        return mWifiConfigStore.disableNetwork(mConfiguredNetworks.getForCurrentUser(netId));
+    /* Mark all networks except specified netId as disabled */
+    private void markAllNetworksDisabledExcept(int netId, int disableReason) {
+        for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) {
+            if (config != null && config.networkId != netId) {
+                updateNetworkSelectionStatus(config, disableReason);
+            }
+        }
+    }
+
+    private void markAllNetworksDisabled(int disableReason) {
+        markAllNetworksDisabledExcept(WifiConfiguration.INVALID_NETWORK_ID, disableReason);
     }
 
     /**
@@ -1381,11 +1365,13 @@
     }
 
     /**
-     * Check the config. If it is temporarily disabled, check the disable time is expired or not, If
-     * expired, enabled it again for qualified network selection.
+     * Attempt to re-enable a network for qualified network selection, if this network was either:
+     *      a) Previously temporarily disabled, but its disable timeout has expired, or
+     *      b) Previously disabled because of a user switch, but is now visible to the current
+     *         user.
      * @param networkId the id of the network to be checked for possible unblock (due to timeout)
-     * @return true if network status has been changed
-     *         false network status is not changed
+     * @return true if the network identified by {@param networkId} was re-enabled for qualified
+     *         network selection, false otherwise.
      */
     public boolean tryEnableQualifiedNetwork(int networkId) {
         WifiConfiguration config = getWifiConfiguration(networkId);
@@ -1397,25 +1383,33 @@
     }
 
     /**
-     * Check the config. If it is temporarily disabled, check the disable is expired or not, If
-     * expired, enabled it again for qualified network selection.
-     * @param config network to be checked for possible unblock (due to timeout)
-     * @return true if network status has been changed
-     *         false network status is not changed
+     * Attempt to re-enable a network for qualified network selection, if this network was either:
+     *      a) Previously temporarily disabled, but its disable timeout has expired, or
+     *      b) Previously disabled because of a user switch, but is now visible to the current
+     *         user.
+     * @param config configuration for the network to be re-enabled for network selection. The
+     *               network corresponding to the config must be visible to the current user.
+     * @return true if the network identified by {@param config} was re-enabled for qualified
+     *         network selection, false otherwise.
      */
     private boolean tryEnableQualifiedNetwork(WifiConfiguration config) {
         WifiConfiguration.NetworkSelectionStatus networkStatus = config.getNetworkSelectionStatus();
         if (networkStatus.isNetworkTemporaryDisabled()) {
             //time difference in minutes
             long timeDifference =
-                    (mClock.elapsedRealtime() - networkStatus.getDisableTime()) / 1000 / 60;
+                    (mClock.getElapsedSinceBootMillis() - networkStatus.getDisableTime()) / 1000 / 60;
             if (timeDifference < 0 || timeDifference
                     >= NETWORK_SELECTION_DISABLE_TIMEOUT[
                     networkStatus.getNetworkSelectionDisableReason()]) {
                 updateNetworkSelectionStatus(config.networkId,
-                        networkStatus.NETWORK_SELECTION_ENABLE);
+                        WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
                 return true;
             }
+        } else if (networkStatus.isDisabledByReason(
+                WifiConfiguration.NetworkSelectionStatus.DISABLED_DUE_TO_USER_SWITCH)) {
+            updateNetworkSelectionStatus(config.networkId,
+                    WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
+            return true;
         }
         return false;
     }
@@ -1436,15 +1430,14 @@
         WifiConfiguration.NetworkSelectionStatus networkStatus = config.getNetworkSelectionStatus();
         if (reason < 0 || reason >= WifiConfiguration.NetworkSelectionStatus
                 .NETWORK_SELECTION_DISABLED_MAX) {
-            localLog("Invalid Network disable reason:" + reason);
+            localLog("Invalid Network disable reason: " + reason);
             return false;
         }
 
         if (reason == WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) {
             if (networkStatus.isNetworkEnabled()) {
                 if (DBG) {
-                    localLog("Need not change Qualified network Selection status since"
-                            + " already enabled");
+                    localLog("Do nothing. Network is already enabled!");
                 }
                 return false;
             }
@@ -1455,17 +1448,13 @@
                     WifiConfiguration.NetworkSelectionStatus
                     .INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP);
             networkStatus.clearDisableReasonCounter();
-            String disableTime = DateFormat.getDateTimeInstance().format(new Date());
-            if (DBG) {
-                localLog("Re-enable network: " + config.SSID + " at " + disableTime);
-            }
+            config.status = Status.ENABLED;
             sendConfiguredNetworksChangedBroadcast(config, WifiManager.CHANGE_REASON_CONFIG_CHANGE);
         } else {
             //disable the network
             if (networkStatus.isNetworkPermanentlyDisabled()) {
-                //alreay permanent disable
                 if (DBG) {
-                    localLog("Do nothing. Alreay permanent disabled! "
+                    localLog("Do nothing. Network is already permanently disabled! Disable reason: "
                             + WifiConfiguration.NetworkSelectionStatus
                             .getNetworkDisableReasonString(reason));
                 }
@@ -1473,38 +1462,32 @@
             } else if (networkStatus.isNetworkTemporaryDisabled()
                     && reason < WifiConfiguration.NetworkSelectionStatus
                     .DISABLED_TLS_VERSION_MISMATCH) {
-                //alreay temporarily disable
                 if (DBG) {
-                    localLog("Do nothing. Already temporarily disabled! "
+                    localLog("Do nothing. Network is already temporarily disabled! Disable reason: "
                             + WifiConfiguration.NetworkSelectionStatus
                             .getNetworkDisableReasonString(reason));
                 }
                 return false;
             }
-
-            if (networkStatus.isNetworkEnabled()) {
-                disableNetworkNative(config);
-                sendConfiguredNetworksChangedBroadcast(config,
-                        WifiManager.CHANGE_REASON_CONFIG_CHANGE);
-                localLog("Disable network " + config.SSID + " reason:"
-                        + WifiConfiguration.NetworkSelectionStatus
-                        .getNetworkDisableReasonString(reason));
-            }
+            disableNetworkNative(config);
             if (reason < WifiConfiguration.NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) {
                 networkStatus.setNetworkSelectionStatus(WifiConfiguration.NetworkSelectionStatus
                         .NETWORK_SELECTION_TEMPORARY_DISABLED);
-                networkStatus.setDisableTime(mClock.elapsedRealtime());
+                networkStatus.setDisableTime(mClock.getElapsedSinceBootMillis());
             } else {
                 networkStatus.setNetworkSelectionStatus(WifiConfiguration.NetworkSelectionStatus
                         .NETWORK_SELECTION_PERMANENTLY_DISABLED);
+                config.status = Status.DISABLED;
+                sendConfiguredNetworksChangedBroadcast(
+                        config, WifiManager.CHANGE_REASON_CONFIG_CHANGE);
             }
             networkStatus.setNetworkSelectionDisableReason(reason);
-            if (DBG) {
-                String disableTime = DateFormat.getDateTimeInstance().format(new Date());
-                localLog("Network:" + config.SSID + "Configure new status:"
-                        + networkStatus.getNetworkStatusString() + " with reason:"
-                        + networkStatus.getNetworkDisableReasonString() + " at: " + disableTime);
-            }
+        }
+        if (DBG) {
+            String time = DateFormat.getDateTimeInstance().format(new Date());
+            localLog("Network: " + config.SSID + " Configure new status: "
+                    + networkStatus.getNetworkStatusString() + " with reason: "
+                    + networkStatus.getNetworkDisableReasonString() + " at: " + time);
         }
         return true;
     }
@@ -1514,7 +1497,7 @@
      * @return {@code true} if it succeeds, {@code false} otherwise
      */
     boolean saveConfig() {
-        return mWifiConfigStore.saveConfig();
+        return mWifiSupplicantControl.saveConfig();
     }
 
     /**
@@ -1524,8 +1507,12 @@
      * @return Wps result containing status and pin
      */
     WpsResult startWpsWithPinFromAccessPoint(WpsInfo config) {
-        return mWifiConfigStore.startWpsWithPinFromAccessPoint(
-                config, mConfiguredNetworks.valuesForCurrentUser());
+        WpsResult result = mWifiSupplicantControl.startWpsWithPinFromAccessPoint(config);
+        /* WPS leaves all networks disabled */
+        if (result.status == WpsResult.Status.SUCCESS) {
+            markAllNetworksDisabled(WifiConfiguration.NetworkSelectionStatus.DISABLED_WPS_START);
+        }
+        return result;
     }
 
     /**
@@ -1534,8 +1521,12 @@
      * @return WpsResult indicating status and pin
      */
     WpsResult startWpsWithPinFromDevice(WpsInfo config) {
-        return mWifiConfigStore.startWpsWithPinFromDevice(
-            config, mConfiguredNetworks.valuesForCurrentUser());
+        WpsResult result = mWifiSupplicantControl.startWpsWithPinFromDevice(config);
+        /* WPS leaves all networks disabled */
+        if (result.status == WpsResult.Status.SUCCESS) {
+            markAllNetworksDisabled(WifiConfiguration.NetworkSelectionStatus.DISABLED_WPS_START);
+        }
+        return result;
     }
 
     /**
@@ -1544,8 +1535,12 @@
      * @return WpsResult indicating status and pin
      */
     WpsResult startWpsPbc(WpsInfo config) {
-        return mWifiConfigStore.startWpsPbc(
-            config, mConfiguredNetworks.valuesForCurrentUser());
+        WpsResult result = mWifiSupplicantControl.startWpsPbc(config);
+        /* WPS leaves all networks disabled */
+        if (result.status == WpsResult.Status.SUCCESS) {
+            markAllNetworksDisabled(WifiConfiguration.NetworkSelectionStatus.DISABLED_WPS_START);
+        }
+        return result;
     }
 
     /**
@@ -1647,7 +1642,7 @@
 
         final Map<String, WifiConfiguration> configs = new HashMap<>();
         final SparseArray<Map<String, String>> networkExtras = new SparseArray<>();
-        mLastPriority = mWifiConfigStore.loadNetworks(configs, networkExtras);
+        mLastPriority = mWifiSupplicantControl.loadNetworks(configs, networkExtras);
 
         readNetworkHistory(configs);
         readPasspointConfig(configs, networkExtras);
@@ -1658,15 +1653,16 @@
         // 2) mConfiguredNetworks caches a Passpoint network's FQDN the moment the network is added.
         //    Thus, we had to load the FQDNs first.
         mConfiguredNetworks.clear();
+        mScanDetailCaches.clear();
         for (Map.Entry<String, WifiConfiguration> entry : configs.entrySet()) {
             final String configKey = entry.getKey();
             final WifiConfiguration config = entry.getValue();
             if (!configKey.equals(config.configKey())) {
-                if (mShowNetworks) {
+                if (mVerboseLoggingEnabled) {
                     log("Ignoring network " + config.networkId + " because the configKey loaded "
                             + "from wpa_supplicant.conf is not valid.");
                 }
-                mWifiConfigStore.removeNetwork(config);
+                removeNetworkNative(config);
                 continue;
             }
             mConfiguredNetworks.put(config);
@@ -1676,7 +1672,7 @@
 
         sendConfiguredNetworksChangedBroadcast();
 
-        if (mShowNetworks) {
+        if (mVerboseLoggingEnabled) {
             localLog("loadConfiguredNetworks loaded " + mConfiguredNetworks.sizeForAllUsers()
                     + " networks (for all users)");
         }
@@ -1684,8 +1680,8 @@
         if (mConfiguredNetworks.sizeForAllUsers() == 0) {
             // no networks? Lets log if the file contents
             logKernelTime();
-            logContents(WifiConfigStore.SUPPLICANT_CONFIG_FILE);
-            logContents(WifiConfigStore.SUPPLICANT_CONFIG_FILE_BACKUP);
+            logContents(WifiSupplicantControl.SUPPLICANT_CONFIG_FILE);
+            logContents(WifiSupplicantControl.SUPPLICANT_CONFIG_FILE_BACKUP);
             logContents(WifiNetworkHistory.NETWORK_HISTORY_CONFIG_FILE);
         }
     }
@@ -1717,15 +1713,16 @@
     }
 
     private Map<String, String> readNetworkVariablesFromSupplicantFile(String key) {
-        return mWifiConfigStore.readNetworkVariablesFromSupplicantFile(key);
+        return mWifiSupplicantControl.readNetworkVariablesFromSupplicantFile(key);
     }
 
     private String readNetworkVariableFromSupplicantFile(String configKey, String key) {
-        long start = SystemClock.elapsedRealtimeNanos();
-        Map<String, String> data = mWifiConfigStore.readNetworkVariablesFromSupplicantFile(key);
-        long end = SystemClock.elapsedRealtimeNanos();
+        long start = mClock.getElapsedSinceBootNanos();
+        Map<String, String> data =
+                mWifiSupplicantControl.readNetworkVariablesFromSupplicantFile(key);
+        long end = mClock.getElapsedSinceBootNanos();
 
-        if (sVDBG) {
+        if (mVerboseLoggingEnabled) {
             localLog("readNetworkVariableFromSupplicantFile configKey=[" + configKey + "] key="
                     + key + " duration=" + (long) (end - start));
         }
@@ -1743,7 +1740,7 @@
             if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP)
                     && config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
 
-                if (needsSoftwareBackedKeyStore(config.enterpriseConfig)) {
+                if (mWifiKeyStore.needsSoftwareBackedKeyStore(config.enterpriseConfig)) {
                     return true;
                 }
             }
@@ -1773,7 +1770,8 @@
                     continue;
                 }
                 final String configFqdn =
-                        networkExtras.get(config.networkId).get(WifiConfigStore.ID_STRING_KEY_FQDN);
+                        networkExtras.get(config.networkId)
+                                .get(WifiSupplicantControl.ID_STRING_KEY_FQDN);
                 if (configFqdn != null && configFqdn.equals(fqdn)) {
                     Log.d(TAG, "Matched " + configFqdn + " with " + config.networkId);
                     ++matchedConfigs;
@@ -1838,7 +1836,7 @@
     }
 
     public void setAndEnableLastSelectedConfiguration(int netId) {
-        if (sVDBG) {
+        if (mVerboseLoggingEnabled) {
             logd("setLastSelectedConfiguration " + Integer.toString(netId));
         }
         if (netId == WifiConfiguration.INVALID_NETWORK_ID) {
@@ -1851,10 +1849,10 @@
                 mLastSelectedTimeStamp = -1;
             } else {
                 mLastSelectedConfiguration = selected.configKey();
-                mLastSelectedTimeStamp = mClock.elapsedRealtime();
+                mLastSelectedTimeStamp = mClock.getElapsedSinceBootMillis();
                 updateNetworkSelectionStatus(netId,
                         WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
-                if (sVDBG) {
+                if (mVerboseLoggingEnabled) {
                     logd("setLastSelectedConfiguration now: " + mLastSelectedConfiguration);
                 }
             }
@@ -1864,7 +1862,7 @@
     public void setLatestUserSelectedConfiguration(WifiConfiguration network) {
         if (network != null) {
             mLastSelectedConfiguration = network.configKey();
-            mLastSelectedTimeStamp = mClock.elapsedRealtime();
+            mLastSelectedTimeStamp = mClock.getElapsedSinceBootMillis();
         }
     }
 
@@ -1923,7 +1921,9 @@
          * refer to an existing configuration.
          */
 
-        if (sVDBG) localLog("addOrUpdateNetworkNative " + config.getPrintableSsid());
+        if (mVerboseLoggingEnabled) {
+            localLog("addOrUpdateNetworkNative " + config.getPrintableSsid());
+        }
         if (config.isPasspoint() && !mMOManager.isEnabled()) {
             Log.e(TAG, "Passpoint is not enabled");
             return new NetworkUpdateResult(INVALID_NETWORK_ID);
@@ -1955,9 +1955,19 @@
         // HasEverConnected to be set to false.
         WifiConfiguration originalConfig = new WifiConfiguration(currentConfig);
 
-        if (!mWifiConfigStore.addOrUpdateNetwork(config, currentConfig)) {
+        if (!mWifiSupplicantControl.addOrUpdateNetwork(config)) {
             return new NetworkUpdateResult(INVALID_NETWORK_ID);
         }
+        // Update the keys for enterprise networks and save the enterprise parameters to
+        // wpa_supplicant.
+        if (config.enterpriseConfig != null
+                && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
+            if (!(mWifiKeyStore.updateNetworkKeys(config, currentConfig)
+                    && mWifiSupplicantControl.saveEnterpriseConfiguration(config))) {
+                removeNetworkNative(config);
+                return new NetworkUpdateResult(INVALID_NETWORK_ID);
+            }
+        }
         int netId = config.networkId;
         String savedConfigKey = config.configKey();
 
@@ -2044,21 +2054,18 @@
         StringBuilder sb = new StringBuilder();
         sb.append("time=");
         Calendar c = Calendar.getInstance();
-        c.setTimeInMillis(mClock.currentTimeMillis());
+        c.setTimeInMillis(mClock.getWallClockMillis());
         sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c));
 
         if (newNetwork) {
+            // New networks start out disabled according to public API.
+            updateNetworkSelectionStatus(currentConfig,
+                    WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER);
             currentConfig.creationTime = sb.toString();
         } else {
             currentConfig.updateTime = sb.toString();
         }
 
-        if (currentConfig.status == WifiConfiguration.Status.ENABLED) {
-            // Make sure autojoin remain in sync with user modifying the configuration
-            updateNetworkSelectionStatus(currentConfig.networkId,
-                    WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
-        }
-
         if (currentConfig.configKey().equals(getLastSelectedConfiguration())
                 && currentConfig.ephemeral) {
             // Make the config non-ephemeral since the user just explicitly clicked it.
@@ -2069,15 +2076,17 @@
             }
         }
 
-        if (sVDBG) log("will read network variables netId=" + Integer.toString(netId));
+        if (mVerboseLoggingEnabled) {
+            log("will read network variables netId=" + Integer.toString(netId));
+        }
 
         readNetworkVariables(currentConfig);
         // When we read back the config from wpa_supplicant, some of the default values are set
         // which could change the configKey.
         if (!savedConfigKey.equals(currentConfig.configKey())) {
-            if (!mWifiConfigStore.saveNetworkMetadata(currentConfig)) {
+            if (!mWifiSupplicantControl.saveNetworkMetadata(currentConfig)) {
                 loge("Failed to set network metadata. Removing config " + config.networkId);
-                mWifiConfigStore.removeNetwork(config);
+                removeNetworkNative(config);
                 return new NetworkUpdateResult(INVALID_NETWORK_ID);
             }
         }
@@ -2113,10 +2122,25 @@
 
         saveConfig();
         writeKnownNetworkHistory();
-
+        // Stage the backup of the SettingsProvider package which backs this up.
+        mBackupManagerProxy.notifyDataChanged();
         return result;
     }
 
+    private boolean removeNetworkNative(WifiConfiguration config) {
+        if (!mWifiSupplicantControl.removeNetwork(config)) {
+            return false;
+        }
+        // Remove any associated keys.
+        if (config.enterpriseConfig != null
+                && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
+            mWifiKeyStore.removeKeys(config.enterpriseConfig);
+        }
+        // Stage the backup of the SettingsProvider package which backs this up.
+        mBackupManagerProxy.notifyDataChanged();
+        return true;
+    }
+
     private boolean wasBitSetUpdated(BitSet originalBitSet, BitSet currentBitSet) {
         if (originalBitSet != null && currentBitSet != null) {
             // both configs have values set, check if they are different
@@ -2249,7 +2273,9 @@
         if (config == null) return null;
         ScanDetailCache cache = mScanDetailCaches.get(config.networkId);
         if (cache == null && config.networkId != WifiConfiguration.INVALID_NETWORK_ID) {
-            cache = new ScanDetailCache(config);
+            cache =
+                    new ScanDetailCache(
+                            config, MAX_NUM_SCAN_CACHE_ENTRIES + 64, MAX_NUM_SCAN_CACHE_ENTRIES);
             mScanDetailCaches.put(config.networkId, cache);
         }
         return cache;
@@ -2301,7 +2327,7 @@
             if (config.defaultGwMacAddress != null && link.defaultGwMacAddress != null) {
                 // If both default GW are known, link only if they are equal
                 if (config.defaultGwMacAddress.equals(link.defaultGwMacAddress)) {
-                    if (sVDBG) {
+                    if (mVerboseLoggingEnabled) {
                         logd("linkConfiguration link due to same gw " + link.SSID
                                 + " and " + config.SSID + " GW " + config.defaultGwMacAddress);
                     }
@@ -2317,7 +2343,7 @@
 
                     for (String abssid : getScanDetailCache(config).keySet()) {
                         for (String bbssid : linkedScanDetailCache.keySet()) {
-                            if (sVVDBG) {
+                            if (mVerboseLoggingEnabled) {
                                 logd("linkConfiguration try to link due to DBDC BSSID match "
                                         + link.SSID + " and " + config.SSID + " bssida " + abssid
                                         + " bssidb " + bbssid);
@@ -2346,7 +2372,7 @@
             }
 
             if (doLink) {
-                if (sVDBG) {
+                if (mVerboseLoggingEnabled) {
                     logd("linkConfiguration: will link " + link.configKey()
                             + " and " + config.configKey());
                 }
@@ -2365,7 +2391,7 @@
             } else {
                 if (link.linkedConfigurations != null
                         && (link.linkedConfigurations.get(config.configKey()) != null)) {
-                    if (sVDBG) {
+                    if (mVerboseLoggingEnabled) {
                         logd("linkConfiguration: un-link " + config.configKey()
                                 + " from " + link.configKey());
                     }
@@ -2373,7 +2399,7 @@
                 }
                 if (config.linkedConfigurations != null
                         && (config.linkedConfigurations.get(link.configKey()) != null)) {
-                    if (sVDBG) {
+                    if (mVerboseLoggingEnabled) {
                         logd("linkConfiguration: un-link " + link.configKey()
                                 + " from " + config.configKey());
                     }
@@ -2387,7 +2413,7 @@
         if (config == null) {
             return null;
         }
-        long now_ms = mClock.currentTimeMillis();
+        long now_ms = mClock.getWallClockMillis();
 
         HashSet<Integer> channels = new HashSet<Integer>();
 
@@ -2396,7 +2422,7 @@
             return null;
         }
 
-        if (sVDBG) {
+        if (mVerboseLoggingEnabled) {
             StringBuilder dbg = new StringBuilder();
             dbg.append("makeChannelList age=" + Integer.toString(age)
                     + " for " + config.configKey()
@@ -2418,7 +2444,7 @@
                 if (numChannels > mMaxNumActiveChannelsForPartialScans.get()) {
                     break;
                 }
-                if (sVDBG) {
+                if (mVerboseLoggingEnabled) {
                     boolean test = (now_ms - result.seen) < age;
                     logd("has " + result.BSSID + " freq=" + Integer.toString(result.frequency)
                             + " age=" + Long.toString(now_ms - result.seen) + " ?=" + test);
@@ -2442,7 +2468,7 @@
                 }
                 for (ScanDetail scanDetail : getScanDetailCache(linked).values()) {
                     ScanResult result = scanDetail.getScanResult();
-                    if (sVDBG) {
+                    if (mVerboseLoggingEnabled) {
                         logd("has link: " + result.BSSID
                                 + " freq=" + Integer.toString(result.frequency)
                                 + " age=" + Long.toString(now_ms - result.seen));
@@ -2629,30 +2655,6 @@
             scanResult.untrusted = true;
         }
 
-        if (scanDetailCache.size() > (MAX_NUM_SCAN_CACHE_ENTRIES + 64)) {
-            long now_dbg = 0;
-            if (sVVDBG) {
-                logd(" Will trim config " + config.configKey()
-                        + " size " + scanDetailCache.size());
-
-                for (ScanDetail sd : scanDetailCache.values()) {
-                    logd("     " + sd.getBSSIDString() + " " + sd.getSeen());
-                }
-                now_dbg = SystemClock.elapsedRealtimeNanos();
-            }
-            // Trim the scan result cache to MAX_NUM_SCAN_CACHE_ENTRIES entries max
-            // Since this operation is expensive, make sure it is not performed
-            // until the cache has grown significantly above the trim treshold
-            scanDetailCache.trim(MAX_NUM_SCAN_CACHE_ENTRIES);
-            if (sVVDBG) {
-                long diff = SystemClock.elapsedRealtimeNanos() - now_dbg;
-                logd(" Finished trimming config, time(ns) " + diff);
-                for (ScanDetail sd : scanDetailCache.values()) {
-                    logd("     " + sd.getBSSIDString() + " " + sd.getSeen());
-                }
-            }
-        }
-
         // Add the scan result to this WifiConfiguration
         if (passpointMatch != null) {
             scanDetailCache.put(scanDetail, passpointMatch, getHomeSPForConfig(config));
@@ -2796,7 +2798,8 @@
         final List<WifiConfiguration> hiddenConfigurations =
                 mConfiguredNetworks.handleUserSwitch(mCurrentUserId);
         for (WifiConfiguration network : hiddenConfigurations) {
-            disableNetworkNative(network);
+            updateNetworkSelectionStatus(
+                    network, WifiConfiguration.NetworkSelectionStatus.DISABLED_DUE_TO_USER_SWITCH);
         }
         enableAllNetworks();
 
@@ -2895,7 +2898,7 @@
         }
 
         if (ipChanged || proxyChanged || isNewNetwork) {
-            if (sVDBG) {
+            if (mVerboseLoggingEnabled) {
                 logd("writeIpAndProxyConfigurationsOnChange: " + currentConfig.SSID + " -> "
                         + newConfig.SSID + " path: " + IP_CONFIG_FILE);
             }
@@ -2911,7 +2914,7 @@
      * @param config the {@link WifiConfiguration} object to be filled in.
      */
     private void readNetworkVariables(WifiConfiguration config) {
-        mWifiConfigStore.readNetworkVariables(config);
+        mWifiSupplicantControl.readNetworkVariables(config);
     }
 
     /* return the allowed key management based on a scan result */
@@ -2922,7 +2925,7 @@
 
         config.SSID = "\"" + result.SSID + "\"";
 
-        if (sVDBG) {
+        if (mVerboseLoggingEnabled) {
             logd("WifiConfiguration from scan results "
                     + config.SSID + " cap " + result.capabilities);
         }
@@ -3051,68 +3054,11 @@
         }
     }
 
-    static boolean needsSoftwareBackedKeyStore(WifiEnterpriseConfig config) {
-        String client = config.getClientCertificateAlias();
-        if (!TextUtils.isEmpty(client)) {
-            // a valid client certificate is configured
-
-            // BUGBUG: keyStore.get() never returns certBytes; because it is not
-            // taking WIFI_UID as a parameter. It always looks for certificate
-            // with SYSTEM_UID, and never finds any Wifi certificates. Assuming that
-            // all certificates need software keystore until we get the get() API
-            // fixed.
-
-            return true;
-        }
-
-        /*
-        try {
-
-            if (DBG) Slog.d(TAG, "Loading client certificate " + Credentials
-                    .USER_CERTIFICATE + client);
-
-            CertificateFactory factory = CertificateFactory.getInstance("X.509");
-            if (factory == null) {
-                Slog.e(TAG, "Error getting certificate factory");
-                return;
-            }
-
-            byte[] certBytes = keyStore.get(Credentials.USER_CERTIFICATE + client);
-            if (certBytes != null) {
-                Certificate cert = (X509Certificate) factory.generateCertificate(
-                        new ByteArrayInputStream(certBytes));
-
-                if (cert != null) {
-                    mNeedsSoftwareKeystore = hasHardwareBackedKey(cert);
-
-                    if (DBG) Slog.d(TAG, "Loaded client certificate " + Credentials
-                            .USER_CERTIFICATE + client);
-                    if (DBG) Slog.d(TAG, "It " + (mNeedsSoftwareKeystore ? "needs" :
-                            "does not need" ) + " software key store");
-                } else {
-                    Slog.d(TAG, "could not generate certificate");
-                }
-            } else {
-                Slog.e(TAG, "Could not load client certificate " + Credentials
-                        .USER_CERTIFICATE + client);
-                mNeedsSoftwareKeystore = true;
-            }
-
-        } catch(CertificateException e) {
-            Slog.e(TAG, "Could not read certificates");
-            mCaCert = null;
-            mClientCertificate = null;
-        }
-        */
-
-        return false;
-    }
-
     /**
      * Resets all sim networks from the network list.
      */
     public void resetSimNetworks() {
-        mWifiConfigStore.resetSimNetworks(mConfiguredNetworks.valuesForCurrentUser());
+        mWifiSupplicantControl.resetSimNetworks(mConfiguredNetworks.valuesForCurrentUser());
     }
 
     boolean isNetworkConfigured(WifiConfiguration config) {
@@ -3242,7 +3188,7 @@
             }
         }
         // Record last time Connectivity Service switched us away from WiFi and onto Cell
-        mLastUnwantedNetworkDisconnectTimestamp = mClock.currentTimeMillis();
+        mLastUnwantedNetworkDisconnectTimestamp = mClock.getWallClockMillis();
     }
 
     int getMaxDhcpRetries() {
@@ -3251,16 +3197,36 @@
                 DEFAULT_MAX_DHCP_RETRIES);
     }
 
+    /**
+     * Clear BSSID blacklist in wpa_supplicant & HAL.
+     */
     void clearBssidBlacklist() {
-        mWifiConfigStore.clearBssidBlacklist();
+        mBssidBlacklist.clear();
+        mWifiSupplicantControl.clearBssidBlacklist();
     }
 
+    /**
+     * Add a BSSID to the blacklist.
+     *
+     * @param bssid to be added.
+     */
     void blackListBssid(String bssid) {
-        mWifiConfigStore.blackListBssid(bssid);
+        if (TextUtils.isEmpty(bssid)) {
+            return;
+        }
+        mBssidBlacklist.add(bssid);
+        mWifiSupplicantControl.blackListBssid(bssid,
+                mBssidBlacklist.toArray(new String[mBssidBlacklist.size()]));
     }
 
+    /**
+     * Checks if the provided bssid is blacklisted or not.
+     *
+     * @param bssid bssid to be checked.
+     * @return true if present, false otherwise.
+     */
     public boolean isBssidBlacklisted(String bssid) {
-        return mWifiConfigStore.isBssidBlacklisted(bssid);
+        return mBssidBlacklist.contains(bssid);
     }
 
     public boolean getEnableAutoJoinWhenAssociated() {
@@ -3271,12 +3237,6 @@
         mEnableAutoJoinWhenAssociated.set(enabled);
     }
 
-    public void setActiveScanDetail(ScanDetail activeScanDetail) {
-        synchronized (mActiveScanDetailLock) {
-            mActiveScanDetail = activeScanDetail;
-        }
-    }
-
     /**
      * Check if the provided ephemeral network was deleted by the user or not.
      * @param ssid ssid of the network
diff --git a/service/java/com/android/server/wifi/WifiConfigManagerNew.java b/service/java/com/android/server/wifi/WifiConfigManagerNew.java
new file mode 100644
index 0000000..41e66bd
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiConfigManagerNew.java
@@ -0,0 +1,1341 @@
+/*
+ * 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 com.android.server.wifi;
+
+import android.app.ActivityManager;
+import android.app.admin.DeviceAdminInfo;
+import android.app.admin.DevicePolicyManagerInternal;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.IpConfiguration;
+import android.net.ProxyInfo;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
+import android.net.wifi.WifiEnterpriseConfig;
+import android.net.wifi.WifiManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.LocalLog;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
+import com.android.server.wifi.util.ScanResultUtil;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This class provides the APIs to manage configured Wi-Fi networks.
+ * It deals with the following:
+ * - Maintaining a list of configured networks for quick access.
+ * - Persisting the configurations to store when required.
+ * - Supporting WifiManager Public API calls:
+ *   > addOrUpdateNetwork()
+ *   > removeNetwork()
+ *   > enableNetwork()
+ *   > disableNetwork()
+ * - Handle user switching on multi-user devices.
+ *
+ * All network configurations retrieved from this class are copies of the original configuration
+ * stored in the internal database. So, any updates to the retrieved configuration object are
+ * meaningless and will not be reflected in the original database.
+ * This is done on purpose to ensure that only WifiConfigManager can modify configurations stored
+ * in the internal database. Any configuration updates should be triggered with appropriate helper
+ * methods of this class using the configuration's unique networkId.
+ *
+ * NOTE: These API's are not thread safe and should only be used from WifiStateMachine thread.
+ */
+public class WifiConfigManagerNew {
+    /**
+     * String used to mask passwords to public interface.
+     */
+    @VisibleForTesting
+    public static final String PASSWORD_MASK = "*";
+    /**
+     * Network Selection disable reason thresholds. These numbers are used to debounce network
+     * failures before we disable them.
+     * These are indexed using the disable reason constants defined in
+     * {@link android.net.wifi.WifiConfiguration.NetworkSelectionStatus}.
+     */
+    @VisibleForTesting
+    public static final int[] NETWORK_SELECTION_DISABLE_THRESHOLD = {
+            -1, //  threshold for NETWORK_SELECTION_ENABLE
+            1,  //  threshold for DISABLED_BAD_LINK
+            5,  //  threshold for DISABLED_ASSOCIATION_REJECTION
+            5,  //  threshold for DISABLED_AUTHENTICATION_FAILURE
+            5,  //  threshold for DISABLED_DHCP_FAILURE
+            5,  //  threshold for DISABLED_DNS_FAILURE
+            1,  //  threshold for DISABLED_WPS_START
+            6,  //  threshold for DISABLED_TLS_VERSION_MISMATCH
+            1,  //  threshold for DISABLED_AUTHENTICATION_NO_CREDENTIALS
+            1,  //  threshold for DISABLED_NO_INTERNET
+            1,  //  threshold for DISABLED_BY_WIFI_MANAGER
+            1   //  threshold for DISABLED_BY_USER_SWITCH
+    };
+    /**
+     * Network Selection disable timeout for each kind of error. After the timeout milliseconds,
+     * enable the network again.
+     * These are indexed using the disable reason constants defined in
+     * {@link android.net.wifi.WifiConfiguration.NetworkSelectionStatus}.
+     */
+    @VisibleForTesting
+    public static final int[] NETWORK_SELECTION_DISABLE_TIMEOUT_MS = {
+            Integer.MAX_VALUE,  // threshold for NETWORK_SELECTION_ENABLE
+            15 * 60 * 1000,     // threshold for DISABLED_BAD_LINK
+            5 * 60 * 1000,      // threshold for DISABLED_ASSOCIATION_REJECTION
+            5 * 60 * 1000,      // threshold for DISABLED_AUTHENTICATION_FAILURE
+            5 * 60 * 1000,      // threshold for DISABLED_DHCP_FAILURE
+            5 * 60 * 1000,      // threshold for DISABLED_DNS_FAILURE
+            0 * 60 * 1000,      // threshold for DISABLED_WPS_START
+            Integer.MAX_VALUE,  // threshold for DISABLED_TLS_VERSION
+            Integer.MAX_VALUE,  // threshold for DISABLED_AUTHENTICATION_NO_CREDENTIALS
+            Integer.MAX_VALUE,  // threshold for DISABLED_NO_INTERNET
+            Integer.MAX_VALUE,  // threshold for DISABLED_BY_WIFI_MANAGER
+            Integer.MAX_VALUE   // threshold for DISABLED_BY_USER_SWITCH
+    };
+    /**
+     * Max size of scan details to cache in {@link #mScanDetailCaches}.
+     */
+    @VisibleForTesting
+    public static final int SCAN_CACHE_ENTRIES_MAX_SIZE = 192;
+    /**
+     * Once the size of the scan details in the cache {@link #mScanDetailCaches} exceeds
+     * {@link #SCAN_CACHE_ENTRIES_MAX_SIZE}, trim it down to this value so that we have some
+     * buffer time before the next eviction.
+     */
+    @VisibleForTesting
+    public static final int SCAN_CACHE_ENTRIES_TRIM_SIZE = 128;
+    /**
+     * Flags to be passed in for |canModifyNetwork| to decide if the change is minor and can
+     * bypass the lockdown checks.
+     */
+    private static final boolean ALLOW_LOCKDOWN_CHECK_BYPASS = true;
+    private static final boolean DISALLOW_LOCKDOWN_CHECK_BYPASS = false;
+    /**
+     * Log tag for this class.
+     */
+    private static final String TAG = "WifiConfigManagerNew";
+    /**
+     * List of external dependencies for WifiConfigManager.
+     */
+    private final Context mContext;
+    private final FrameworkFacade mFacade;
+    private final Clock mClock;
+    private final UserManager mUserManager;
+    private final BackupManagerProxy mBackupManagerProxy;
+    private final WifiConfigStoreNew mWifiConfigStore;
+    private final WifiKeyStore mWifiKeyStore;
+    /**
+     * Local log used for debugging any WifiConfigManager issues.
+     */
+    private final LocalLog mLocalLog =
+            new LocalLog(ActivityManager.isLowRamDeviceStatic() ? 128 : 256);
+    /**
+     * Map of configured networks with network id as the key.
+     */
+    private final ConfigurationMap mConfiguredNetworks;
+    /**
+     * Stores a map of NetworkId to ScanDetailCache.
+     */
+    private final ConcurrentHashMap<Integer, ScanDetailCache> mScanDetailCaches;
+    /**
+     * Framework keeps a list of ephemeral SSIDs that where deleted by user,
+     * so as, framework knows not to autoconnect again those SSIDs based on scorer input.
+     * The list is never cleared up.
+     * The SSIDs are encoded in a String as per definition of WifiConfiguration.SSID field.
+     */
+    private final Set<String> mDeletedEphemeralSSIDs;
+
+    /**
+     * Verbose logging flag. Toggled by developer options.
+     */
+    private boolean mVerboseLoggingEnabled = false;
+    /**
+     * Current logged in user ID.
+     */
+    private int mCurrentUserId = UserHandle.USER_SYSTEM;
+    /**
+     * This is keeping track of the last network ID assigned. Any new networks will be assigned
+     * |mLastNetworkId + 1| as network ID.
+     */
+    private int mLastNetworkId;
+
+    /**
+     * Create new instance of WifiConfigManager.
+     */
+    WifiConfigManagerNew(
+            Context context, FrameworkFacade facade, Clock clock, UserManager userManager,
+            WifiKeyStore wifiKeyStore, WifiConfigStoreNew wifiConfigStore) {
+        mContext = context;
+        mFacade = facade;
+        mClock = clock;
+        mUserManager = userManager;
+        mBackupManagerProxy = new BackupManagerProxy();
+        mWifiConfigStore = wifiConfigStore;
+        mWifiKeyStore = wifiKeyStore;
+
+        mConfiguredNetworks = new ConfigurationMap(userManager);
+        mScanDetailCaches = new ConcurrentHashMap<>(16, 0.75f, 2);
+        mDeletedEphemeralSSIDs = new HashSet<String>();
+    }
+
+    /**
+     * Construct the string to be put in the |creationTime| & |updateTime| elements of
+     * WifiConfiguration from the provided wall clock millis.
+     *
+     * @param wallClockMillis Time in milliseconds to be converted to string.
+     */
+    @VisibleForTesting
+    public static String createDebugTimeStampString(long wallClockMillis) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("time=");
+        Calendar c = Calendar.getInstance();
+        c.setTimeInMillis(wallClockMillis);
+        sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c));
+        return sb.toString();
+    }
+
+    /**
+     * Enable/disable verbose logging in WifiConfigManager & its helper classes.
+     */
+    public void enableVerboseLogging(int verbose) {
+        if (verbose > 0) {
+            mVerboseLoggingEnabled = true;
+        } else {
+            mVerboseLoggingEnabled = false;
+        }
+        mWifiConfigStore.enableVerboseLogging(mVerboseLoggingEnabled);
+        mWifiKeyStore.enableVerboseLogging(mVerboseLoggingEnabled);
+    }
+
+    /**
+     * Helper method to mask all passwords/keys from the provided WifiConfiguration object. This
+     * is needed when the network configurations are being requested via the public WifiManager
+     * API's.
+     * This currently masks the following elements: psk, wepKeys & enterprise config password.
+     */
+    private void maskPasswordsInWifiConfiguration(WifiConfiguration configuration) {
+        if (!TextUtils.isEmpty(configuration.preSharedKey)) {
+            configuration.preSharedKey = PASSWORD_MASK;
+        }
+        if (configuration.wepKeys != null) {
+            for (int i = 0; i < configuration.wepKeys.length; i++) {
+                if (!TextUtils.isEmpty(configuration.wepKeys[i])) {
+                    configuration.wepKeys[i] = PASSWORD_MASK;
+                }
+            }
+        }
+        if (!TextUtils.isEmpty(configuration.enterpriseConfig.getPassword())) {
+            configuration.enterpriseConfig.setPassword(PASSWORD_MASK);
+        }
+    }
+
+    /**
+     * Fetch the list of currently configured networks maintained in WifiConfigManager.
+     *
+     * This retrieves a copy of the internal configurations maintained by WifiConfigManager and
+     * should be used for any public interfaces.
+     *
+     * @param savedOnly     Retrieve only saved networks.
+     * @param maskPasswords Mask passwords or not.
+     * @return List of WifiConfiguration objects representing the networks.
+     */
+    private List<WifiConfiguration> getConfiguredNetworks(
+            boolean savedOnly, boolean maskPasswords) {
+        List<WifiConfiguration> networks = new ArrayList<>();
+        for (WifiConfiguration config : getInternalConfiguredNetworks()) {
+            if (savedOnly && config.ephemeral) {
+                continue;
+            }
+            WifiConfiguration newConfig = new WifiConfiguration(config);
+            if (maskPasswords) {
+                maskPasswordsInWifiConfiguration(newConfig);
+            }
+            networks.add(newConfig);
+        }
+        return networks;
+    }
+
+    /**
+     * Retrieves the list of all configured networks with passwords masked.
+     *
+     * @return List of WifiConfiguration objects representing the networks.
+     */
+    public List<WifiConfiguration> getConfiguredNetworks() {
+        return getConfiguredNetworks(false, true);
+    }
+
+    /**
+     * Retrieves the list of all configured networks with the passwords in plaintext.
+     *
+     * WARNING: Don't use this to pass network configurations to external apps. Should only be
+     * sent to system apps/wifi stack, when there is a need for passwords in plaintext.
+     * TODO: Need to understand the current use case of this API.
+     *
+     * @return List of WifiConfiguration objects representing the networks.
+     */
+    public List<WifiConfiguration> getConfiguredNetworksWithPasswords() {
+        return getConfiguredNetworks(false, false);
+    }
+
+    /**
+     * Retrieves the list of all configured networks with the passwords masked.
+     *
+     * @return List of WifiConfiguration objects representing the networks.
+     */
+    public List<WifiConfiguration> getSavedNetworks() {
+        return getConfiguredNetworks(true, true);
+    }
+
+    /**
+     * Retrieves the configured network corresponding to the provided networkId with password
+     * masked.
+     *
+     * @param networkId networkId of the requested network.
+     * @return WifiConfiguration object if found, null otherwise.
+     */
+    public WifiConfiguration getConfiguredNetwork(int networkId) {
+        WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+        if (config == null) {
+            return null;
+        }
+        // Create a new configuration object with the passwords masked to send out to the external
+        // world.
+        WifiConfiguration network = new WifiConfiguration(config);
+        maskPasswordsInWifiConfiguration(network);
+        return network;
+    }
+
+    /**
+     * Retrieves the configured network corresponding to the provided networkId with password
+     * in plaintext.
+     *
+     * WARNING: Don't use this to pass network configurations to external apps. Should only be
+     * sent to system apps/wifi stack, when there is a need for passwords in plaintext.
+     *
+     * @param networkId networkId of the requested network.
+     * @return WifiConfiguration object if found, null otherwise.
+     */
+    public WifiConfiguration getConfiguredNetworkWithPassword(int networkId) {
+        WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+        if (config == null) {
+            return null;
+        }
+        // Create a new configuration object without the passwords masked to send out to the
+        // external world.
+        WifiConfiguration network = new WifiConfiguration(config);
+        return network;
+    }
+
+    /**
+     * Helper method to retrieve all the internal WifiConfiguration objects corresponding to all
+     * the networks in our database.
+     */
+    private Collection<WifiConfiguration> getInternalConfiguredNetworks() {
+        return mConfiguredNetworks.valuesForCurrentUser();
+    }
+
+    /**
+     * Helper method to retrieve the internal WifiConfiguration object corresponding to the
+     * provided configuration in our database.
+     * This first attempts to find the network using the provided network ID in configuration,
+     * else it attempts to find a matching configuration using the configKey.
+     */
+    private WifiConfiguration getInternalConfiguredNetwork(WifiConfiguration config) {
+        WifiConfiguration internalConfig = mConfiguredNetworks.getForCurrentUser(config.networkId);
+        if (internalConfig != null) {
+            return internalConfig;
+        }
+        return mConfiguredNetworks.getByConfigKeyForCurrentUser(config.configKey());
+    }
+
+    /**
+     * Helper method to retrieve the internal WifiConfiguration object corresponding to the
+     * provided network ID in our database.
+     */
+    private WifiConfiguration getInternalConfiguredNetwork(int networkId) {
+        return mConfiguredNetworks.getForCurrentUser(networkId);
+    }
+
+    /**
+     * Helper method to check if the network is already configured internally or not.
+     */
+    private boolean isNetworkConfiguredInternally(WifiConfiguration config) {
+        return getInternalConfiguredNetwork(config) != null;
+    }
+
+    /**
+     * Helper method to check if the network is already configured internally or not.
+     */
+    private boolean isNetworkConfiguredInternally(int networkId) {
+        return getInternalConfiguredNetwork(networkId) != null;
+    }
+
+    /**
+     * Method to send out the configured networks change broadcast when a single network
+     * configuration is changed.
+     *
+     * @param network WifiConfiguration corresponding to the network that was changed.
+     * @param reason  The reason for the change, should be one of WifiManager.CHANGE_REASON_ADDED,
+     *                WifiManager.CHANGE_REASON_REMOVED, or WifiManager.CHANGE_REASON_CHANGE.
+     */
+    private void sendConfiguredNetworkChangedBroadcast(
+            WifiConfiguration network, int reason) {
+        Intent intent = new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+        intent.putExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, false);
+        // Create a new WifiConfiguration with passwords masked before we send it out.
+        WifiConfiguration broadcastNetwork = new WifiConfiguration(network);
+        maskPasswordsInWifiConfiguration(broadcastNetwork);
+        intent.putExtra(WifiManager.EXTRA_WIFI_CONFIGURATION, broadcastNetwork);
+        intent.putExtra(WifiManager.EXTRA_CHANGE_REASON, reason);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+    }
+
+    /**
+     * Method to send out the configured networks change broadcast when multiple network
+     * configurations are changed.
+     */
+    private void sendConfiguredNetworksChangedBroadcast() {
+        Intent intent = new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+        intent.putExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, true);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+    }
+
+    /**
+     * Checks if the app has the permission to override Wi-Fi network configuration or not.
+     *
+     * @param uid uid of the app.
+     * @return true if the app does have the permission, false otherwise.
+     */
+    private boolean checkConfigOverridePermission(int uid) {
+        try {
+            int permission =
+                    mFacade.checkUidPermission(
+                            android.Manifest.permission.OVERRIDE_WIFI_CONFIG, uid);
+            return (permission == PackageManager.PERMISSION_GRANTED);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error checking for permission " + e);
+            return false;
+        }
+    }
+
+    /**
+     * Checks if |uid| has permission to modify the provided configuration.
+     *
+     * @param config         WifiConfiguration object corresponding to the network to be modified.
+     * @param uid            UID of the app requesting the modification.
+     * @param ignoreLockdown Ignore the configuration lockdown checks for debug data updates.
+     */
+    private boolean canModifyNetwork(WifiConfiguration config, int uid, boolean ignoreLockdown) {
+        final DevicePolicyManagerInternal dpmi = LocalServices.getService(
+                DevicePolicyManagerInternal.class);
+
+        final boolean isUidDeviceOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(uid,
+                DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+
+        // If |uid| corresponds to the device owner, allow all modifications.
+        if (isUidDeviceOwner) {
+            return true;
+        }
+
+        final boolean isCreator = (config.creatorUid == uid);
+
+        // Check if the |uid| is either the creator of the network or holds the
+        // |OVERRIDE_CONFIG_WIFI| permission if the caller asks us to bypass the lockdown checks.
+        if (ignoreLockdown) {
+            return isCreator || checkConfigOverridePermission(uid);
+        }
+
+        // Check if device has DPM capability. If it has and |dpmi| is still null, then we
+        // treat this case with suspicion and bail out.
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)
+                && dpmi == null) {
+            Log.w(TAG, "Error retrieving DPMI service.");
+            return false;
+        }
+
+        // WiFi config lockdown related logic. At this point we know uid is NOT a Device Owner.
+
+        final boolean isConfigEligibleForLockdown = dpmi != null && dpmi.isActiveAdminWithPolicy(
+                config.creatorUid, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+        if (!isConfigEligibleForLockdown) {
+            return isCreator || checkConfigOverridePermission(uid);
+        }
+
+        final ContentResolver resolver = mContext.getContentResolver();
+        final boolean isLockdownFeatureEnabled = Settings.Global.getInt(resolver,
+                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0) != 0;
+        return !isLockdownFeatureEnabled && checkConfigOverridePermission(uid);
+    }
+
+    /**
+     * Copy over public elements from an external WifiConfiguration object to the internal
+     * configuration object if element has been set in the provided external WifiConfiguration.
+     * The only exception is the hidden |IpConfiguration| parameters, these need to be copied over
+     * for every update.
+     *
+     * This method updates all elements that are common to both network addition & update.
+     * The following fields of {@link WifiConfiguration} are not copied from external configs:
+     *  > networkId - These are allocated by Wi-Fi stack internally for any new configurations.
+     *  > status - The status needs to be explicitly updated using
+     *             {@link WifiManager#enableNetwork(int, boolean)} or
+     *             {@link WifiManager#disableNetwork(int)}.
+     *
+     * @param externalConfig WifiConfiguration object provided from the external API.
+     * @param internalConfig WifiConfiguration object in our internal map.
+     */
+    private void mergeWithInternalWifiConfiguration(
+            WifiConfiguration externalConfig, WifiConfiguration internalConfig) {
+        if (externalConfig.SSID != null) {
+            internalConfig.SSID = externalConfig.SSID;
+        }
+        if (externalConfig.BSSID != null) {
+            internalConfig.BSSID = externalConfig.BSSID;
+        }
+        internalConfig.hiddenSSID = externalConfig.hiddenSSID;
+        if (externalConfig.preSharedKey != null) {
+            internalConfig.preSharedKey = externalConfig.preSharedKey;
+        }
+        // Modify only wep keys are present in the provided configuration. This is a little tricky
+        // because there is no easy way to tell if the app is actually trying to null out the
+        // existing keys or not.
+        if (externalConfig.wepKeys != null) {
+            boolean hasWepKey = false;
+            for (int i = 0; i < internalConfig.wepKeys.length; i++) {
+                if (externalConfig.wepKeys[i] != null) {
+                    internalConfig.wepKeys[i] = externalConfig.wepKeys[i];
+                    hasWepKey = true;
+                }
+            }
+            if (hasWepKey) {
+                internalConfig.wepTxKeyIndex = externalConfig.wepTxKeyIndex;
+            }
+        }
+        if (externalConfig.FQDN != null) {
+            internalConfig.FQDN = externalConfig.FQDN;
+        }
+        if (externalConfig.providerFriendlyName != null) {
+            internalConfig.providerFriendlyName = externalConfig.providerFriendlyName;
+        }
+        if (externalConfig.roamingConsortiumIds != null) {
+            internalConfig.roamingConsortiumIds = externalConfig.roamingConsortiumIds;
+        }
+
+        // Copy over all the auth/protocol/key mgmt parameters if set.
+        if (externalConfig.allowedAuthAlgorithms != null
+                && !externalConfig.allowedAuthAlgorithms.isEmpty()) {
+            internalConfig.allowedAuthAlgorithms = externalConfig.allowedAuthAlgorithms;
+        }
+        if (externalConfig.allowedProtocols != null
+                && !externalConfig.allowedProtocols.isEmpty()) {
+            internalConfig.allowedProtocols = externalConfig.allowedProtocols;
+        }
+        if (externalConfig.allowedKeyManagement != null
+                && !externalConfig.allowedKeyManagement.isEmpty()) {
+            internalConfig.allowedKeyManagement = externalConfig.allowedKeyManagement;
+        }
+        if (externalConfig.allowedPairwiseCiphers != null
+                && !externalConfig.allowedPairwiseCiphers.isEmpty()) {
+            internalConfig.allowedPairwiseCiphers = externalConfig.allowedPairwiseCiphers;
+        }
+        if (externalConfig.allowedGroupCiphers != null
+                && !externalConfig.allowedGroupCiphers.isEmpty()) {
+            internalConfig.allowedGroupCiphers = externalConfig.allowedGroupCiphers;
+        }
+
+        // Copy over the |IpConfiguration| parameters if set.
+        if (externalConfig.getIpConfiguration() != null) {
+            if (externalConfig.getIpAssignment() != IpConfiguration.IpAssignment.UNASSIGNED) {
+                internalConfig.setIpAssignment(externalConfig.getIpAssignment());
+                internalConfig.setStaticIpConfiguration(externalConfig.getStaticIpConfiguration());
+            }
+            if (externalConfig.getProxySettings() != IpConfiguration.ProxySettings.UNASSIGNED) {
+                internalConfig.setProxySettings(externalConfig.getProxySettings());
+                internalConfig.setHttpProxy(externalConfig.getHttpProxy());
+            }
+        }
+
+        // Copy over the |WifiEnterpriseConfig| parameters if set.
+        if (externalConfig.enterpriseConfig != null) {
+            internalConfig.enterpriseConfig =
+                    new WifiEnterpriseConfig(externalConfig.enterpriseConfig);
+        }
+    }
+
+    /**
+     * Set all the exposed defaults in the newly created WifiConfiguration object.
+     * These fields have a default value advertised in our public documentation. The only exception
+     * is the hidden |IpConfiguration| parameters, these have a default value even though they're
+     * hidden.
+     *
+     * @param configuration provided WifiConfiguration object.
+     */
+    private void setDefaultsInWifiConfiguration(WifiConfiguration configuration) {
+        configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+        configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
+
+        configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+        configuration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
+
+        configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+
+        configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+        configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
+
+        configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+        configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+        configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
+        configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
+
+        configuration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
+        configuration.setProxySettings(IpConfiguration.ProxySettings.NONE);
+    }
+
+    /**
+     * Create a new WifiConfiguration object by copying over parameters from the provided
+     * external configuration and set defaults for the appropriate parameters.
+     *
+     * @param config provided external WifiConfiguration object.
+     * @return New WifiConfiguration object with parameters merged from the provided external
+     * configuration.
+     */
+    private WifiConfiguration createNewInternalWifiConfigurationFromExternal(
+            WifiConfiguration config, int uid) {
+        WifiConfiguration newConfig = new WifiConfiguration();
+
+        // First allocate a new network ID for the configuration.
+        newConfig.networkId = mLastNetworkId++;
+
+        // First set defaults in the new configuration created.
+        setDefaultsInWifiConfiguration(newConfig);
+
+        // Copy over all the public elements from the provided configuration.
+        mergeWithInternalWifiConfiguration(config, newConfig);
+
+        // Copy over the hidden configuration parameters. These are the only parameters used by
+        // system apps to indicate some property about the network being added.
+        // These are only copied over for network additions and ignored for network updates.
+        newConfig.requirePMF = config.requirePMF;
+        newConfig.noInternetAccessExpected = config.noInternetAccessExpected;
+        newConfig.ephemeral = config.ephemeral;
+        newConfig.meteredHint = config.meteredHint;
+        newConfig.useExternalScores = config.useExternalScores;
+        newConfig.shared = config.shared;
+
+        // Add debug information for network addition.
+        newConfig.creatorUid = newConfig.lastUpdateUid = uid;
+        newConfig.creatorName = newConfig.lastUpdateName =
+                mContext.getPackageManager().getNameForUid(uid);
+        newConfig.creationTime = newConfig.updateTime =
+                createDebugTimeStampString(mClock.getWallClockMillis());
+
+        return newConfig;
+    }
+
+    /**
+     * Merges the provided external WifiConfiguration object with the existing internal
+     * WifiConfiguration object.
+     *
+     * @param config provided external WifiConfiguration object.
+     * @return Existing WifiConfiguration object with parameters merged from the provided
+     * configuration.
+     */
+    private WifiConfiguration updateExistingInternalWifiConfigurationFromExternal(
+            WifiConfiguration config, int uid) {
+        WifiConfiguration existingConfig = getInternalConfiguredNetwork(config);
+
+        // Copy over all the public elements from the provided configuration.
+        mergeWithInternalWifiConfiguration(config, existingConfig);
+
+        // Add debug information for network update.
+        existingConfig.lastUpdateUid = uid;
+        existingConfig.lastUpdateName = mContext.getPackageManager().getNameForUid(uid);
+        existingConfig.updateTime = createDebugTimeStampString(mClock.getWallClockMillis());
+
+        return existingConfig;
+    }
+
+    /**
+     * Compare existing and new IpConfiguration and return if IP assignment has changed or not.
+     *
+     * @param existingConfig Existing config corresponding to the network already stored in our
+     *                       database.
+     * @param newConfig      New updated config object in our database.
+     * @return true if IP assignment have changed, false otherwise.
+     */
+    private boolean hasIpChanged(WifiConfiguration existingConfig, WifiConfiguration newConfig) {
+        switch (newConfig.getIpAssignment()) {
+            case STATIC:
+                if (existingConfig.getIpAssignment() != newConfig.getIpAssignment()) {
+                    return true;
+                } else {
+                    return !Objects.equals(
+                            existingConfig.getStaticIpConfiguration(),
+                            newConfig.getStaticIpConfiguration());
+                }
+            case DHCP:
+                return (existingConfig.getIpAssignment() != newConfig.getIpAssignment());
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Compare existing and new IpConfiguration and return if Proxy settings has changed or not.
+     *
+     * @param existingConfig Existing config corresponding to the network already stored in our
+     *                       database.
+     * @param newConfig      New updated config object in our database.
+     * @return true if proxy settings have changed, false otherwise.
+     */
+    private boolean hasProxyChanged(WifiConfiguration existingConfig, WifiConfiguration newConfig) {
+        switch (newConfig.getProxySettings()) {
+            case STATIC:
+            case PAC:
+                ProxyInfo newHttpProxy = newConfig.getHttpProxy();
+                ProxyInfo currentHttpProxy = existingConfig.getHttpProxy();
+                if (newHttpProxy != null) {
+                    return !newHttpProxy.equals(currentHttpProxy);
+                } else {
+                    return (currentHttpProxy != null);
+                }
+            case NONE:
+                return (existingConfig.getProxySettings() != newConfig.getProxySettings());
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Add a network or update a network configuration to our database.
+     * If the supplied networkId is INVALID_NETWORK_ID, we create a new empty
+     * network configuration. Otherwise, the networkId should refer to an existing configuration.
+     *
+     * @param config provided WifiConfiguration object.
+     * @param uid    UID of the app requesting the network addition/deletion.
+     * @return NetworkUpdateResult object representing status of the update.
+     */
+    private NetworkUpdateResult addOrUpdateNetworkInternal(WifiConfiguration config, int uid) {
+        if (mVerboseLoggingEnabled) {
+            Log.v(TAG, "Adding/Updating network " + config.getPrintableSsid());
+        }
+        boolean newNetwork;
+        WifiConfiguration existingInternalConfig;
+        WifiConfiguration newInternalConfig;
+
+        if (!isNetworkConfiguredInternally(config)) {
+            newNetwork = true;
+            existingInternalConfig = null;
+            newInternalConfig = createNewInternalWifiConfigurationFromExternal(config, uid);
+        } else {
+            newNetwork = false;
+            existingInternalConfig =
+                    new WifiConfiguration(getInternalConfiguredNetwork(config));
+            // Check for the app's permission before we let it update this network.
+            if (!canModifyNetwork(existingInternalConfig, uid, DISALLOW_LOCKDOWN_CHECK_BYPASS)) {
+                Log.e(TAG, "UID " + uid + " does not have permission to update configuration "
+                        + config.configKey());
+                return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
+            }
+            newInternalConfig = updateExistingInternalWifiConfigurationFromExternal(config, uid);
+        }
+
+        // Update the keys for enterprise networks.
+        if (config.enterpriseConfig != null
+                && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
+            if (!(mWifiKeyStore.updateNetworkKeys(config, existingInternalConfig))) {
+                return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
+            }
+        }
+
+        // Add it our internal map.
+        mConfiguredNetworks.put(newInternalConfig);
+
+        // Stage the backup of the SettingsProvider package which backs this up.
+        mBackupManagerProxy.notifyDataChanged();
+
+        // This is needed to inform IpManager about any IP configuration changes.
+        boolean hasIpChanged =
+                newNetwork || hasIpChanged(existingInternalConfig, newInternalConfig);
+        boolean hasProxyChanged =
+                newNetwork || hasProxyChanged(existingInternalConfig, newInternalConfig);
+        NetworkUpdateResult result = new NetworkUpdateResult(hasIpChanged, hasProxyChanged);
+        result.setIsNewNetwork(newNetwork);
+        result.setNetworkId(newInternalConfig.networkId);
+
+        localLog("addOrUpdateNetworkInternal: added/updated config."
+                + " netId=" + newInternalConfig.networkId
+                + " configKey=" + newInternalConfig.configKey()
+                + " uid=" + Integer.toString(newInternalConfig.creatorUid)
+                + " name=" + newInternalConfig.creatorName);
+        return result;
+    }
+
+    /**
+     * Add a network or update a network configuration to our database.
+     * If the supplied networkId is INVALID_NETWORK_ID, we create a new empty
+     * network configuration. Otherwise, the networkId should refer to an existing configuration.
+     *
+     * @param config provided WifiConfiguration object.
+     * @param uid    UID of the app requesting the network addition/deletion.
+     * @return NetworkUpdateResult object representing status of the update.
+     */
+    public NetworkUpdateResult addOrUpdateNetwork(WifiConfiguration config, int uid) {
+        if (config == null) {
+            Log.e(TAG, "Cannot add/update network with null config");
+            return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID);
+        }
+        NetworkUpdateResult result = addOrUpdateNetworkInternal(config, uid);
+        if (!result.isSuccess()) {
+            Log.e(TAG, "Failed to add/update network " + config.getPrintableSsid());
+            return result;
+        }
+        WifiConfiguration newConfig = getInternalConfiguredNetwork(result.getNetworkId());
+        sendConfiguredNetworkChangedBroadcast(
+                newConfig,
+                result.isNewNetwork()
+                        ? WifiManager.CHANGE_REASON_ADDED
+                        : WifiManager.CHANGE_REASON_CONFIG_CHANGE);
+        // External modification, persist it immediately.
+        saveToStore(true);
+        return result;
+    }
+
+    /**
+     * Removes the specified network configuration from our database.
+     *
+     * @param config provided WifiConfiguration object.
+     * @return true if successful, false otherwise.
+     */
+    private boolean removeNetworkInternal(WifiConfiguration config) {
+        if (mVerboseLoggingEnabled) {
+            Log.v(TAG, "Removing network " + config.getPrintableSsid());
+        }
+        // Remove any associated enterprise keys.
+        if (config.enterpriseConfig != null
+                && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
+            mWifiKeyStore.removeKeys(config.enterpriseConfig);
+        }
+
+        mConfiguredNetworks.remove(config.networkId);
+        mScanDetailCaches.remove(config.networkId);
+        // Stage the backup of the SettingsProvider package which backs this up.
+        mBackupManagerProxy.notifyDataChanged();
+
+        localLog("removeNetworkInternal: removed config."
+                + " netId=" + config.networkId
+                + " configKey=" + config.configKey());
+        return true;
+    }
+
+    /**
+     * Removes the specified network configuration from our database.
+     *
+     * @param networkId network ID of the provided network.
+     * @return true if successful, false otherwise.
+     */
+    public boolean removeNetwork(int networkId) {
+        WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+        if (config == null) {
+            Log.e(TAG, "Cannot find network with networkId " + networkId);
+            return false;
+        }
+        if (!removeNetworkInternal(config)) {
+            Log.e(TAG, "Failed to remove network " + config.getPrintableSsid());
+            return false;
+        }
+        sendConfiguredNetworkChangedBroadcast(config, WifiManager.CHANGE_REASON_REMOVED);
+        // External modification, persist it immediately.
+        saveToStore(true);
+        return true;
+    }
+
+    /**
+     * Helper method to mark a network enabled for network selection.
+     */
+    private void setNetworkSelectionEnabled(NetworkSelectionStatus status) {
+        status.setNetworkSelectionStatus(
+                NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
+        status.setDisableTime(
+                NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP);
+        status.setNetworkSelectionDisableReason(NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
+
+        // Clear out all the disable reason counters.
+        status.clearDisableReasonCounter();
+    }
+
+    /**
+     * Helper method to mark a network temporarily disabled for network selection.
+     */
+    private void setNetworkSelectionTemporarilyDisabled(
+            NetworkSelectionStatus status, int disableReason) {
+        status.setNetworkSelectionStatus(
+                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
+        // Only need a valid time filled in for temporarily disabled networks.
+        status.setDisableTime(mClock.getElapsedSinceBootMillis());
+        status.setNetworkSelectionDisableReason(disableReason);
+    }
+
+    /**
+     * Helper method to mark a network permanently disabled for network selection.
+     */
+    private void setNetworkSelectionPermanentlyDisabled(
+            NetworkSelectionStatus status, int disableReason) {
+        status.setNetworkSelectionStatus(
+                NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
+        status.setDisableTime(
+                NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP);
+        status.setNetworkSelectionDisableReason(disableReason);
+    }
+
+    /**
+     * Helper method to set the publicly exposed status for the network and send out the network
+     * status change broadcast.
+     */
+    private void setNetworkStatus(WifiConfiguration config, int status) {
+        config.status = status;
+        sendConfiguredNetworkChangedBroadcast(config, WifiManager.CHANGE_REASON_CONFIG_CHANGE);
+    }
+
+    /**
+     * Sets a network's status (both internal and public) according to the update reason and
+     * its current state.
+     *
+     * This updates the network's {@link WifiConfiguration#mNetworkSelectionStatus} field and the
+     * public {@link WifiConfiguration#status} field if the network is either enabled or
+     * permanently disabled.
+     *
+     * @param config network to be updated.
+     * @param reason reason code for update.
+     * @return true if the input configuration has been updated, false otherwise.
+     */
+    private boolean setNetworkSelectionStatus(WifiConfiguration config, int reason) {
+        NetworkSelectionStatus networkStatus = config.getNetworkSelectionStatus();
+        if (reason < 0 || reason >= NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX) {
+            Log.e(TAG, "Invalid Network disable reason " + reason);
+            return false;
+        }
+        if (reason == NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) {
+            setNetworkSelectionEnabled(networkStatus);
+            setNetworkStatus(config, WifiConfiguration.Status.ENABLED);
+        } else if (reason < NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) {
+            setNetworkSelectionTemporarilyDisabled(networkStatus, reason);
+        } else {
+            setNetworkSelectionPermanentlyDisabled(networkStatus, reason);
+            setNetworkStatus(config, WifiConfiguration.Status.DISABLED);
+        }
+        localLog("setNetworkSelectionStatus: configKey=" + config.configKey()
+                + " networkStatus=" + networkStatus.getNetworkStatusString() + " disableReason="
+                + networkStatus.getNetworkDisableReasonString() + " at="
+                + createDebugTimeStampString(mClock.getWallClockMillis()));
+        return true;
+    }
+
+    /**
+     * Update a network's status (both internal and public) according to the update reason and
+     * its current state.
+     *
+     * @param config network to be updated.
+     * @param reason reason code for update.
+     * @return true if the input configuration has been updated, false otherwise.
+     */
+    private boolean updateNetworkSelectionStatus(WifiConfiguration config, int reason) {
+        NetworkSelectionStatus networkStatus = config.getNetworkSelectionStatus();
+        if (reason != NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) {
+            networkStatus.incrementDisableReasonCounter(reason);
+            // For network disable reasons, we should only update the status if we cross the
+            // threshold.
+            int disableReasonCounter = networkStatus.getDisableReasonCounter(reason);
+            int disableReasonThreshold = NETWORK_SELECTION_DISABLE_THRESHOLD[reason];
+            if (disableReasonCounter < disableReasonThreshold) {
+                if (mVerboseLoggingEnabled) {
+                    Log.v(TAG, "Disable counter for network " + config.getPrintableSsid()
+                            + " for reason "
+                            + NetworkSelectionStatus.getNetworkDisableReasonString(reason) + " is "
+                            + networkStatus.getDisableReasonCounter(reason) + " and threshold is "
+                            + disableReasonThreshold);
+                }
+                return true;
+            }
+        }
+        return setNetworkSelectionStatus(config, reason);
+    }
+
+    /**
+     * Update a network's status (both internal and public) according to the update reason and
+     * its current state.
+     *
+     * Each network has 2 status:
+     * 1. NetworkSelectionStatus: This is internal selection status of the network. This is used
+     * for temporarily disabling a network for QNS.
+     * 2. Status: This is the exposed status for a network. This is mostly set by
+     * the public API's {@link WifiManager#enableNetwork(int, boolean)} &
+     * {@link WifiManager#disableNetwork(int)}.
+     *
+     * @param networkId network ID of the network that needs the update.
+     * @param reason    reason to update the network.
+     * @return true if the input configuration has been updated, false otherwise.
+     */
+    public boolean updateNetworkSelectionStatus(int networkId, int reason) {
+        WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+        if (config == null) {
+            Log.e(TAG, "Cannot find network with networkId " + networkId);
+            return false;
+        }
+        return updateNetworkSelectionStatus(config, reason);
+    }
+
+    /**
+     * Attempt to re-enable a network for network selection, if this network was either:
+     * a) Previously temporarily disabled, but its disable timeout has expired, or
+     * b) Previously disabled because of a user switch, but is now visible to the current
+     * user.
+     *
+     * @param config configuration for the network to be re-enabled for network selection. The
+     *               network corresponding to the config must be visible to the current user.
+     * @return true if the network identified by {@param config} was re-enabled for qualified
+     * network selection, false otherwise.
+     */
+    private boolean tryEnableNetwork(WifiConfiguration config) {
+        NetworkSelectionStatus networkStatus = config.getNetworkSelectionStatus();
+        if (networkStatus.isNetworkTemporaryDisabled()) {
+            long timeDifferenceMs =
+                    mClock.getElapsedSinceBootMillis() - networkStatus.getDisableTime();
+            int disableReason = networkStatus.getNetworkSelectionDisableReason();
+            long disableTimeoutMs = NETWORK_SELECTION_DISABLE_TIMEOUT_MS[disableReason];
+            if (timeDifferenceMs >= disableTimeoutMs) {
+                return updateNetworkSelectionStatus(
+                        config, NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
+            }
+        } else if (networkStatus.isDisabledByReason(
+                NetworkSelectionStatus.DISABLED_DUE_TO_USER_SWITCH)) {
+            return updateNetworkSelectionStatus(
+                    config, NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
+        }
+        return false;
+    }
+
+    /**
+     * Attempt to re-enable a network for network selection, if this network was either:
+     * a) Previously temporarily disabled, but its disable timeout has expired, or
+     * b) Previously disabled because of a user switch, but is now visible to the current
+     * user.
+     *
+     * @param networkId the id of the network to be checked for possible unblock (due to timeout)
+     * @return true if the network identified by {@param networkId} was re-enabled for qualified
+     * network selection, false otherwise.
+     */
+    public boolean tryEnableNetwork(int networkId) {
+        WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+        if (config == null) {
+            Log.e(TAG, "Cannot find network with networkId " + networkId);
+            return false;
+        }
+        return tryEnableNetwork(config);
+    }
+
+    /**
+     * Enable a network using the public {@link WifiManager#enableNetwork(int, boolean)} API.
+     *
+     * @param networkId network ID of the network that needs the update.
+     * @param uid       uid of the app requesting the update.
+     * @return {@code true} if it succeeds, {@code false} otherwise
+     */
+    public boolean enableNetwork(int networkId, int uid) {
+        WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+        if (config == null) {
+            Log.e(TAG, "Cannot find network with networkId " + networkId);
+            return false;
+        }
+        if (!canModifyNetwork(config, uid, DISALLOW_LOCKDOWN_CHECK_BYPASS)) {
+            Log.e(TAG, "UID " + uid + " does not have permission to update configuration "
+                    + config.configKey());
+            return false;
+        }
+        return updateNetworkSelectionStatus(
+                networkId, WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
+    }
+
+    /**
+     * Disable a network using the public {@link WifiManager#disableNetwork(int)} API.
+     *
+     * @param networkId network ID of the network that needs the update.
+     * @param uid       uid of the app requesting the update.
+     * @return {@code true} if it succeeds, {@code false} otherwise
+     */
+    public boolean disableNetwork(int networkId, int uid) {
+        WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+        if (config == null) {
+            Log.e(TAG, "Cannot find network with networkId " + networkId);
+            return false;
+        }
+        if (!canModifyNetwork(config, uid, DISALLOW_LOCKDOWN_CHECK_BYPASS)) {
+            Log.e(TAG, "UID " + uid + " does not have permission to update configuration "
+                    + config.configKey());
+            return false;
+        }
+        return updateNetworkSelectionStatus(
+                networkId, NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER);
+    }
+
+    /**
+     * Checks if the |uid| has the necessary permission to override wifi config and updates the last
+     * connected UID for the provided configuration.
+     *
+     * @param networkId network ID corresponding to the network.
+     * @param uid       uid of the app requesting the connection.
+     * @return {@code true} if |uid| has the necessary permission to trigger connection to the
+     * network, {@code false} otherwise.
+     */
+    public boolean checkAndUpdateLastConnectUid(int networkId, int uid) {
+        WifiConfiguration config = getInternalConfiguredNetwork(networkId);
+        if (config == null) {
+            Log.e(TAG, "Cannot find network with networkId " + networkId);
+            return false;
+        }
+        if (!canModifyNetwork(config, uid, ALLOW_LOCKDOWN_CHECK_BYPASS)) {
+            Log.e(TAG, "UID " + uid + " does not have permission to update configuration "
+                    + config.configKey());
+            return false;
+        }
+        config.lastConnectUid = uid;
+        return true;
+    }
+
+    /**
+     * Helper method to get the scan detail cache entry {@link #mScanDetailCaches} for the provided
+     * network.
+     *
+     * @param networkId network ID corresponding to the network.
+     * @return existing {@link ScanDetailCache} entry if one exists or null.
+     */
+    @VisibleForTesting
+    public ScanDetailCache getScanDetailCacheForNetwork(int networkId) {
+        return mScanDetailCaches.get(networkId);
+    }
+
+    /**
+     * Helper method to get or create a scan detail cache entry {@link #mScanDetailCaches} for
+     * the provided network.
+     *
+     * @param config configuration corresponding to the the network.
+     * @return existing {@link ScanDetailCache} entry if one exists or a new instance created for
+     * this network.
+     */
+    private ScanDetailCache getOrCreateScanDetailCacheForNetwork(WifiConfiguration config) {
+        if (config == null) return null;
+        ScanDetailCache cache = getScanDetailCacheForNetwork(config.networkId);
+        if (cache == null && config.networkId != WifiConfiguration.INVALID_NETWORK_ID) {
+            cache =
+                    new ScanDetailCache(
+                            config, SCAN_CACHE_ENTRIES_MAX_SIZE, SCAN_CACHE_ENTRIES_TRIM_SIZE);
+            mScanDetailCaches.put(config.networkId, cache);
+        }
+        return cache;
+    }
+
+    /**
+     * Saves the provided ScanDetail into the corresponding scan detail cache entry
+     * {@link #mScanDetailCaches} for the provided network.
+     *
+     * @param config     configuration corresponding to the the network.
+     * @param scanDetail new scan detail instance to be saved into the cache.
+     */
+    private void saveToScanDetailCacheForNetwork(
+            WifiConfiguration config, ScanDetail scanDetail) {
+        ScanResult scanResult = scanDetail.getScanResult();
+
+        ScanDetailCache scanDetailCache = getOrCreateScanDetailCacheForNetwork(config);
+        if (scanDetailCache == null) {
+            Log.e(TAG, "Could not allocate scan cache for " + config.getPrintableSsid());
+            return;
+        }
+
+        // Adding a new BSSID
+        ScanResult result = scanDetailCache.get(scanResult.BSSID);
+        if (result != null) {
+            // transfer the black list status
+            scanResult.blackListTimestamp = result.blackListTimestamp;
+            scanResult.numIpConfigFailures = result.numIpConfigFailures;
+            scanResult.numConnection = result.numConnection;
+            scanResult.isAutoJoinCandidate = result.isAutoJoinCandidate;
+        }
+        if (config.ephemeral) {
+            // For an ephemeral Wi-Fi config, the ScanResult should be considered
+            // untrusted.
+            scanResult.untrusted = true;
+        }
+
+        // Add the scan detail to this network's scan detail cache.
+        scanDetailCache.put(scanDetail);
+
+        // Since we added a scan result to this configuration, re-attempt linking
+        // TODO: linkConfiguration(config);
+    }
+
+    /**
+     * Retrieves a saved network corresponding to the provided scan detail if one exists.
+     *
+     * @param scanDetail ScanDetail instance  to use for looking up the network.
+     * @return WifiConfiguration object representing the network corresponding to the scanDetail,
+     * null if none exists.
+     */
+    private WifiConfiguration getSavedNetworkForScanDetail(ScanDetail scanDetail) {
+        ScanResult scanResult = scanDetail.getScanResult();
+        if (scanResult == null) {
+            Log.e(TAG, "No scan result found in scan detail");
+            return null;
+        }
+        // Add the double quotes to the scan result SSID for comparison with the network configs.
+        String ssidToCompare = "\"" + scanResult.SSID + "\"";
+        for (WifiConfiguration config : getInternalConfiguredNetworks()) {
+            if (config.SSID == null || !config.SSID.equals(ssidToCompare)) {
+                continue;
+            }
+            if (ScanResultUtil.doesScanResultEncryptionMatchWithNetwork(scanResult, config)) {
+                localLog("getSavedNetworkFromScanDetail: Found " + config.configKey()
+                        + " for " + scanResult.SSID + "[" + scanResult.capabilities + "]");
+                return config;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Retrieves a saved network corresponding to the provided scan detail if one exists and caches
+     * the provided |scanDetail| into the corresponding scan detail cache entry
+     * {@link #mScanDetailCaches} for the retrieved network.
+     *
+     * @param scanDetail input a scanDetail from the scan result
+     * @return WifiConfiguration object representing the network corresponding to the scanDetail,
+     * null if none exists.
+     */
+    public WifiConfiguration getSavedNetworkForScanDetailAndCache(ScanDetail scanDetail) {
+        WifiConfiguration network = getSavedNetworkForScanDetail(scanDetail);
+        if (network == null) {
+            return null;
+        }
+        saveToScanDetailCacheForNetwork(network, scanDetail);
+        return getConfiguredNetworkWithPassword(network.networkId);
+    }
+
+    /**
+     * Read the config store and load the in-memory lists from the store data retrieved.
+     * This reads all the network configurations from:
+     * 1. Shared WifiConfigStore.xml
+     * 2. User WifiConfigStore.xml
+     * 3. PerProviderSubscription.conf
+     */
+    private void loadFromStore() {
+        WifiConfigStoreData storeData;
+
+        long readStartTime = mClock.getElapsedSinceBootMillis();
+        try {
+            storeData = mWifiConfigStore.read();
+        } catch (Exception e) {
+            Log.wtf(TAG, "Reading from new store failed " + e + ". All saved networks are lost!");
+            return;
+        }
+        long readTime = mClock.getElapsedSinceBootMillis() - readStartTime;
+        Log.d(TAG, "Loading from store completed in " + readTime + " ms.");
+
+        // Clear out all the existing in-memory lists and load the lists from what was retrieved
+        // from the config store.
+        mConfiguredNetworks.clear();
+        mDeletedEphemeralSSIDs.clear();
+        mScanDetailCaches.clear();
+        for (WifiConfiguration configuration : storeData.configurations) {
+            configuration.networkId = mLastNetworkId++;
+            if (mVerboseLoggingEnabled) {
+                Log.v(TAG, "Adding network from store " + configuration.configKey());
+            }
+            mConfiguredNetworks.put(configuration);
+        }
+        for (String ssid : storeData.deletedEphemeralSSIDs) {
+            mDeletedEphemeralSSIDs.add(ssid);
+        }
+        if (mConfiguredNetworks.sizeForAllUsers() == 0) {
+            Log.w(TAG, "No stored networks found.");
+        }
+    }
+
+    /**
+     * Save the current snapshot of the in-memory lists to the config store.
+     *
+     * @param forceWrite Whether the write needs to be forced or not.
+     * @return Whether the write was successful or not, this is applicable only for force writes.
+     */
+    private boolean saveToStore(boolean forceWrite) {
+        ArrayList<WifiConfiguration> configurations = new ArrayList<>();
+        // Don't persist ephemeral networks to store.
+        for (WifiConfiguration config : mConfiguredNetworks.valuesForCurrentUser()) {
+            if (!config.ephemeral) {
+                configurations.add(config);
+            }
+        }
+        WifiConfigStoreData storeData =
+                new WifiConfigStoreData(configurations, mDeletedEphemeralSSIDs);
+
+        long writeStartTime = mClock.getElapsedSinceBootMillis();
+        try {
+            mWifiConfigStore.write(forceWrite, storeData);
+        } catch (Exception e) {
+            Log.wtf(TAG, "Writing to store failed " + e + ". Saved networks maybe lost!");
+            return false;
+        }
+        long writeTime = mClock.getElapsedSinceBootMillis() - writeStartTime;
+        Log.d(TAG, "Writing to store completed in " + writeTime + " ms.");
+        return true;
+    }
+
+    /**
+     * Helper method for logging into local log buffer.
+     */
+    private void localLog(String s) {
+        if (mLocalLog != null) {
+            mLocalLog.log(s);
+        }
+    }
+
+    /**
+     * Dump the local log buffer.
+     */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Dump of WifiConfigManager");
+        pw.println("WifiConfigManager - Log Begin ----");
+        mLocalLog.dump(fd, pw, args);
+        pw.println("WifiConfigManager - Log End ----");
+    }
+}
diff --git a/service/java/com/android/server/wifi/WifiConfigStoreData.java b/service/java/com/android/server/wifi/WifiConfigStoreData.java
new file mode 100644
index 0000000..4d1802f
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiConfigStoreData.java
@@ -0,0 +1,521 @@
+/*
+ * 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 com.android.server.wifi;
+
+import android.net.IpConfiguration;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
+import android.net.wifi.WifiEnterpriseConfig;
+import android.util.Pair;
+import android.util.Xml;
+
+import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.XmlUtil;
+import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
+import com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil;
+import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
+import com.android.server.wifi.util.XmlUtil.WifiEnterpriseConfigXmlUtil;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Class to encapsulate all the data to be stored across all the stores. This is a snapshot
+ * of all the settings passed from {@link WifiConfigManager} to persistent store.
+ * Instances of this class are passed from/to WifiConfigManager and WifiConfigStore for
+ * writing/parsing data to/from the store files.
+ *
+ * Note: Nesting of objects during serialization makes it hard to deserialize data especially
+ * when we have elements added to the parent object in future revisions. So, when we serialize
+ * {@link WifiConfiguration} objects (representing saved networks), we add separate sections in the
+ * XML for each nested object (such as {@link IpConfiguration} and {@link NetworkSelectionStatus})
+ * within WifiConfiguration object.
+ */
+public class WifiConfigStoreData {
+    /**
+     * Current config store data version. This will be incremented for any additions.
+     */
+    private static final int CURRENT_CONFIG_STORE_DATA_VERSION = 1;
+    /** This list of older versions will be used to restore data from older config store. */
+    /**
+     * First version of the config store data format.
+     */
+    private static final int INITIAL_CONFIG_STORE_DATA_VERSION = 1;
+    /**
+     * List of XML section header tags in the config store data.
+     */
+    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_NETWORK_LIST = "NetworkList";
+    private static final String XML_TAG_SECTION_HEADER_NETWORK = "Network";
+    private static final String XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION = "WifiConfiguration";
+    private static final String XML_TAG_SECTION_HEADER_NETWORK_STATUS = "NetworkStatus";
+    private static final String XML_TAG_SECTION_HEADER_IP_CONFIGURATION = "IpConfiguration";
+    private static final String XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION =
+            "WifiEnterpriseConfiguration";
+    private static final String XML_TAG_SECTION_HEADER_DELETED_EPHEMERAL_SSID_LIST =
+            "DeletedEphemeralSSIDList";
+    /**
+     * List of saved networks visible to the current user to be stored (includes shared & private).
+     */
+    public List<WifiConfiguration> configurations;
+    /**
+     * List of deleted ephemeral ssids to be stored.
+     */
+    public Set<String> deletedEphemeralSSIDs;
+
+    /**
+     * Create a new instance of store data to be written to the store files.
+     *
+     * @param configurations        list of saved networks to be stored.
+     *                              See {@link WifiConfigManager#mConfiguredNetworks}.
+     * @param deletedEphemeralSSIDs list of deleted ephemeral ssids to be stored.
+     *                              See {@link WifiConfigManager#mDeletedEphemeralSSIDs}
+     */
+    public WifiConfigStoreData(
+            List<WifiConfiguration> configurations, Set<String> deletedEphemeralSSIDs) {
+        this.configurations = configurations;
+        this.deletedEphemeralSSIDs = deletedEphemeralSSIDs;
+    }
+
+    /**
+     * Create a new instance of the store data parsed from the store file data.
+     *
+     * Note: If any of the raw data is null or empty, will create an empty corresponding store data.
+     * This is to handle fresh install devices where these stores are not yet created.
+     *
+     * @param sharedDataBytes raw data retrieved from the shared store file.
+     * @param userDataBytes   raw data retrieved from the user store file.
+     * @return new instance of store data.
+     */
+    public static WifiConfigStoreData parseRawData(byte[] sharedDataBytes, byte[] userDataBytes)
+            throws XmlPullParserException, IOException {
+        SharedData sharedData;
+        UserData userData;
+        try {
+            if (sharedDataBytes != null && sharedDataBytes.length > 0) {
+                sharedData = SharedData.parseRawData(sharedDataBytes);
+            } else {
+                sharedData = new SharedData(new ArrayList<WifiConfiguration>());
+            }
+            if (userDataBytes != null && userDataBytes.length > 0) {
+                userData = UserData.parseRawData(userDataBytes);
+            } else {
+                userData = new UserData(new ArrayList<WifiConfiguration>(), new HashSet<String>());
+            }
+            return getStoreData(sharedData, userData);
+        } catch (ClassCastException e) {
+            throw new XmlPullParserException("Wrong value type parsed: " + e);
+        }
+    }
+
+    /**
+     * Create a WifiConfigStoreData instance from the retrieved UserData & SharedData instance.
+     */
+    private static WifiConfigStoreData getStoreData(SharedData sharedData, UserData userData) {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.addAll(sharedData.configurations);
+        configurations.addAll(userData.configurations);
+        return new WifiConfigStoreData(configurations, userData.deletedEphemeralSSIDs);
+
+    }
+
+    /**
+     * Write the list of networks to the XML stream.
+     *
+     * @param out            XmlSerializer instance pointing to the XML stream.
+     * @param configurations list of WifiConfiguration objects corresponding to the networks.
+     */
+    private static void writeNetworksToXml(
+            XmlSerializer out, List<WifiConfiguration> configurations)
+            throws XmlPullParserException, IOException {
+        XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK_LIST);
+        for (WifiConfiguration configuration : configurations) {
+            // Write this configuration data now.
+            XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK);
+            writeNetworkToXml(out, configuration);
+            XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK);
+        }
+        XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK_LIST);
+    }
+
+    /**
+     * Write a network to the XML stream.
+     * Nested objects within the provided WifiConfiguration object are written into separate XML
+     * sections.
+     *
+     * @param out           XmlSerializer instance pointing to the XML stream.
+     * @param configuration WifiConfiguration object corresponding to the network.
+     */
+    private static void writeNetworkToXml(
+            XmlSerializer out, WifiConfiguration configuration)
+            throws XmlPullParserException, IOException {
+        XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
+        WifiConfigurationXmlUtil.writeToXmlForConfigStore(out, configuration);
+        XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
+
+        XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK_STATUS);
+        NetworkSelectionStatusXmlUtil.writeToXml(out, configuration.getNetworkSelectionStatus());
+        XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK_STATUS);
+
+        XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_IP_CONFIGURATION);
+        IpConfigurationXmlUtil.writeToXml(out, configuration.getIpConfiguration());
+        XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_IP_CONFIGURATION);
+
+        // Store the enterprise configuration for enterprise networks.
+        if (configuration.isEnterprise()) {
+            XmlUtil.writeNextSectionStart(
+                    out, XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
+            WifiEnterpriseConfigXmlUtil.writeToXml(out, configuration.enterpriseConfig);
+            XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
+        }
+    }
+
+    /**
+     * Parses the list of networks from the provided XML stream.
+     *
+     * @param in            XmlPullParser instance pointing to the XML stream.
+     * @param outerTagDepth depth of the outer tag in the XML document.
+     * @param dataVersion   version number parsed from incoming data.
+     * @return list of WifiConfiguration objects corresponding to the networks if parsing is
+     * successful, null otherwise.
+     */
+    private static List<WifiConfiguration> parseNetworksFromXml(
+            XmlPullParser in, int outerTagDepth, int dataVersion)
+            throws XmlPullParserException, IOException {
+        // Find the configuration list section.
+        XmlUtil.gotoNextSectionWithName(in, XML_TAG_SECTION_HEADER_NETWORK_LIST, outerTagDepth);
+        // Find all the configurations within the configuration list section.
+        int networkListTagDepth = outerTagDepth + 1;
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        while (XmlUtil.gotoNextSectionWithNameOrEnd(
+                in, XML_TAG_SECTION_HEADER_NETWORK, networkListTagDepth)) {
+            WifiConfiguration configuration =
+                    parseNetworkFromXml(in, networkListTagDepth, dataVersion);
+            if (configuration != null) {
+                configurations.add(configuration);
+            }
+        }
+        return configurations;
+    }
+
+    /**
+     * Helper method to parse the WifiConfiguration object and validate the configKey parsed.
+     */
+    private static WifiConfiguration parseWifiConfigurationFromXmlAndValidateConfigKey(
+            XmlPullParser in, int outerTagDepth)
+            throws XmlPullParserException, IOException {
+        Pair<String, WifiConfiguration> parsedConfig =
+                WifiConfigurationXmlUtil.parseFromXml(in, outerTagDepth);
+        if (parsedConfig == null || parsedConfig.first == null || parsedConfig.second == null) {
+            throw new XmlPullParserException("XML parsing of wifi configuration failed");
+        }
+        String configKeyParsed = parsedConfig.first;
+        WifiConfiguration configuration = parsedConfig.second;
+        String configKeyCalculated = configuration.configKey();
+        if (!configKeyParsed.equals(configKeyCalculated)) {
+            throw new XmlPullParserException(
+                    "Configuration key does not match. Retrieved: " + configKeyParsed
+                            + ", Calculated: " + configKeyCalculated);
+        }
+        return configuration;
+    }
+
+    /**
+     * Parses a network from the provided XML stream.
+     *
+     * @param in            XmlPullParser instance pointing to the XML stream.
+     * @param outerTagDepth depth of the outer tag in the XML document.
+     * @param dataVersion   version number parsed from incoming data.
+     * @return WifiConfiguration object corresponding to the network if parsing is successful,
+     * null otherwise.
+     */
+    private static WifiConfiguration parseNetworkFromXml(
+            XmlPullParser in, int outerTagDepth, int dataVersion)
+            throws XmlPullParserException, IOException {
+        // Any version migration needs to be handled here in future.
+        if (dataVersion == INITIAL_CONFIG_STORE_DATA_VERSION) {
+            WifiConfiguration configuration = null;
+
+            int networkTagDepth = outerTagDepth + 1;
+            XmlUtil.gotoNextSectionWithName(
+                    in, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION, networkTagDepth);
+            int configTagDepth = networkTagDepth + 1;
+            configuration = parseWifiConfigurationFromXmlAndValidateConfigKey(in, configTagDepth);
+
+            XmlUtil.gotoNextSectionWithName(
+                    in, XML_TAG_SECTION_HEADER_NETWORK_STATUS, networkTagDepth);
+            NetworkSelectionStatus status =
+                    NetworkSelectionStatusXmlUtil.parseFromXml(in, configTagDepth);
+            configuration.setNetworkSelectionStatus(status);
+
+            XmlUtil.gotoNextSectionWithName(
+                    in, XML_TAG_SECTION_HEADER_IP_CONFIGURATION, networkTagDepth);
+            IpConfiguration ipConfiguration =
+                    IpConfigurationXmlUtil.parseFromXml(in, configTagDepth);
+            configuration.setIpConfiguration(ipConfiguration);
+
+            // Check if there is an enterprise configuration section.
+            if (XmlUtil.gotoNextSectionWithNameOrEnd(
+                    in, XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION, networkTagDepth)) {
+                WifiEnterpriseConfig enterpriseConfig =
+                        WifiEnterpriseConfigXmlUtil.parseFromXml(in, configTagDepth);
+                configuration.enterpriseConfig = enterpriseConfig;
+            }
+
+            return configuration;
+        }
+        return null;
+    }
+
+    /**
+     * Write the document start and version to the XML stream.
+     * This is used for both the shared and user config store data.
+     *
+     * @param out XmlSerializer instance pointing to the XML stream.
+     */
+    private static void writeDocumentStartAndVersionToXml(XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        XmlUtil.writeDocumentStart(out, XML_TAG_DOCUMENT_HEADER);
+        XmlUtil.writeNextValue(out, XML_TAG_VERSION, CURRENT_CONFIG_STORE_DATA_VERSION);
+    }
+
+    /**
+     * Parse the document start and version from the XML stream.
+     * This is used for both the shared and user config store data.
+     *
+     * @param in XmlPullParser instance pointing to the XML stream.
+     * @return version number retrieved from the Xml stream.
+     */
+    private static int parseDocumentStartAndVersionFromXml(XmlPullParser in)
+            throws XmlPullParserException, IOException {
+        XmlUtil.gotoDocumentStart(in, XML_TAG_DOCUMENT_HEADER);
+        int version = (int) XmlUtil.readNextValueWithName(in, XML_TAG_VERSION);
+        if (version < INITIAL_CONFIG_STORE_DATA_VERSION
+                || version > CURRENT_CONFIG_STORE_DATA_VERSION) {
+            throw new XmlPullParserException("Invalid version of data: " + version);
+        }
+        return version;
+    }
+
+    /**
+     * Create raw byte array to be stored in the share store file.
+     * This method serializes the data to a byte array in XML format.
+     *
+     * @return byte array with the serialized output.
+     */
+    public byte[] createSharedRawData() throws XmlPullParserException, IOException {
+        SharedData sharedData = getSharedData();
+        return sharedData.createRawData();
+    }
+
+    /**
+     * Create raw byte array to be stored in the user store file.
+     * This method serializes the data to a byte array in XML format.
+     *
+     * @return byte array with the serialized output.
+     */
+    public byte[] createUserRawData() throws XmlPullParserException, IOException {
+        UserData userData = getUserData();
+        return userData.createRawData();
+    }
+
+    /**
+     * Retrieve the shared data to be stored in the shared config store file.
+     *
+     * @return SharedData instance.
+     */
+    private SharedData getSharedData() {
+        List<WifiConfiguration> sharedConfigurations = new ArrayList<>();
+        for (WifiConfiguration configuration : configurations) {
+            if (configuration.shared) {
+                sharedConfigurations.add(configuration);
+            }
+        }
+        return new SharedData(sharedConfigurations);
+    }
+
+    /**
+     * Retrieve the user specific data to be stored in the user config store file.
+     *
+     * @return UserData instance.
+     */
+    private UserData getUserData() {
+        List<WifiConfiguration> userConfigurations = new ArrayList<>();
+        for (WifiConfiguration configuration : configurations) {
+            if (!configuration.shared) {
+                userConfigurations.add(configuration);
+            }
+        }
+        return new UserData(userConfigurations, deletedEphemeralSSIDs);
+    }
+
+    /**
+     * Class to encapsulate all the data to be stored in the shared store.
+     */
+    public static class SharedData {
+        public List<WifiConfiguration> configurations;
+
+        /**
+         * Create a new instance of shared store data to be written to the store files.
+         *
+         * @param configurations list of shared saved networks to be stored.
+         */
+        public SharedData(List<WifiConfiguration> configurations) {
+            this.configurations = configurations;
+        }
+
+        /**
+         * Create a new instance of the shared store data parsed from the store file.
+         * This method deserializes the provided byte array in XML format to a new SharedData
+         * instance.
+         *
+         * @param sharedDataBytes raw data retrieved from the shared store file.
+         * @return new instance of store data.
+         */
+        public static SharedData parseRawData(byte[] sharedDataBytes)
+                throws XmlPullParserException, IOException{
+            final XmlPullParser in = Xml.newPullParser();
+            final ByteArrayInputStream inputStream = new ByteArrayInputStream(sharedDataBytes);
+            in.setInput(inputStream, StandardCharsets.UTF_8.name());
+
+            // Start parsing the XML stream.
+            int rootTagDepth = in.getDepth() + 1;
+            int version = parseDocumentStartAndVersionFromXml(in);
+
+            List<WifiConfiguration> configurations =
+                    parseNetworksFromXml(in, rootTagDepth, version);
+
+            return new SharedData(configurations);
+        }
+
+        /**
+         * Create raw byte array to be stored in the store file.
+         * This method serializes the data to a byte array in XML format.
+         *
+         * @return byte array with the serialized output.
+         */
+        public byte[] createRawData() throws XmlPullParserException, IOException  {
+            final XmlSerializer out = new FastXmlSerializer();
+            final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+
+            // Start writing the XML stream.
+            writeDocumentStartAndVersionToXml(out);
+
+            // Write all the shared network configurations.
+            writeNetworksToXml(out, configurations);
+
+            XmlUtil.writeDocumentEnd(out, XML_TAG_DOCUMENT_HEADER);
+
+            byte[] data = outputStream.toByteArray();
+
+            return data;
+        }
+    }
+
+    /**
+     * Class to encapsulate all the data to be stored in the user specific store.
+     */
+    public static class UserData {
+        private static final String XML_TAG_SSID_LIST = "SSIDList";
+
+        public List<WifiConfiguration> configurations;
+        public Set<String> deletedEphemeralSSIDs;
+
+        /**
+         * Create a new instance of user specific store data to be written to the store files.
+         *
+         * @param configurations        list of user specific saved networks to be stored.
+         * @param deletedEphemeralSSIDs list of deleted ephemeral ssids to be stored.
+         */
+        public UserData(List<WifiConfiguration> configurations, Set<String> deletedEphemeralSSIDs) {
+            this.configurations = configurations;
+            this.deletedEphemeralSSIDs = deletedEphemeralSSIDs;
+        }
+
+        /**
+         * Create a new instance of the user store data parsed from the store file.
+         * This method deserializes the provided byte array in XML format to a new UserData
+         * instance.
+         *
+         * @param userDataBytes raw data retrieved from the user store file.
+         * @return new instance of store data.
+         */
+        public static UserData parseRawData(byte[] userDataBytes)
+            throws XmlPullParserException, IOException {
+            final XmlPullParser in = Xml.newPullParser();
+            final ByteArrayInputStream inputStream = new ByteArrayInputStream(userDataBytes);
+            in.setInput(inputStream, StandardCharsets.UTF_8.name());
+
+            // Start parsing the XML stream.
+            int rootTagDepth = in.getDepth() + 1;
+            int version = parseDocumentStartAndVersionFromXml(in);
+
+            List<WifiConfiguration> configurations =
+                    parseNetworksFromXml(in, rootTagDepth, version);
+
+            XmlUtil.gotoNextSectionWithName(
+                    in, XML_TAG_SECTION_HEADER_DELETED_EPHEMERAL_SSID_LIST, rootTagDepth);
+            Set<String> deletedEphemralList =
+                    (Set<String>) XmlUtil.readNextValueWithName(in, XML_TAG_SSID_LIST);
+
+            return new UserData(configurations, deletedEphemralList);
+        }
+
+        /**
+         * Create raw byte array to be stored in the store file.
+         * This method serializes the data to a byte array in XML format.
+         *
+         * @return byte array with the serialized output.
+         */
+        public byte[] createRawData() throws XmlPullParserException, IOException {
+            final XmlSerializer out = new FastXmlSerializer();
+            final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+
+            // Start writing the XML stream.
+            writeDocumentStartAndVersionToXml(out);
+
+            // Write all the user network configurations.
+            writeNetworksToXml(out, configurations);
+
+            XmlUtil.writeNextSectionStart(
+                    out, XML_TAG_SECTION_HEADER_DELETED_EPHEMERAL_SSID_LIST);
+            XmlUtil.writeNextValue(out, XML_TAG_SSID_LIST, deletedEphemeralSSIDs);
+            XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_DELETED_EPHEMERAL_SSID_LIST);
+
+            XmlUtil.writeDocumentEnd(out, XML_TAG_DOCUMENT_HEADER);
+
+            byte[] data = outputStream.toByteArray();
+
+            return data;
+        }
+    }
+}
+
+
diff --git a/service/java/com/android/server/wifi/WifiConfigStoreNew.java b/service/java/com/android/server/wifi/WifiConfigStoreNew.java
new file mode 100644
index 0000000..cd0e1d2
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiConfigStoreNew.java
@@ -0,0 +1,329 @@
+/*
+ * 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 com.android.server.wifi;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.AtomicFile;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * This class provides the API's to save/load/modify network configurations from a persistent
+ * store. Uses keystore for certificate/key management operations.
+ * NOTE: This class should only be used from WifiConfigManager and is not thread-safe!
+ */
+public class WifiConfigStoreNew {
+    /**
+     * Alarm tag to use for starting alarms for buffering file writes.
+     */
+    @VisibleForTesting
+    public static final String BUFFERED_WRITE_ALARM_TAG = "WriteBufferAlarm";
+    /**
+     * Log tag.
+     */
+    private static final String TAG = "WifiConfigStoreNew";
+    /**
+     * Config store file name for both shared & user specific stores.
+     */
+    private static final String STORE_FILE_NAME = "WifiConfigStore.xml";
+    /**
+     * Directory to store the shared config store file.
+     */
+    private static final String SHARED_STORE_DIRECTORY =
+            new File(Environment.getDataDirectory(), "misc/wifi").getAbsolutePath();
+    /**
+     * Time interval for buffering file writes for non-forced writes
+     */
+    private static final int BUFFERED_WRITE_ALARM_INTERVAL_MS = 10 * 1000;
+    /**
+     * Handler instance to post alarm timeouts to
+     */
+    private final Handler mEventHandler;
+    /**
+     * Alarm manager instance to start buffer timeout alarms.
+     */
+    private final AlarmManager mAlarmManager;
+    /**
+     * Clock instance to retrieve timestamps for alarms.
+     */
+    private final Clock mClock;
+    /**
+     * Shared config store file instance.
+     */
+    private StoreFile mSharedStore;
+    /**
+     * User specific store file instance.
+     */
+    private StoreFile mUserStore;
+    /**
+     * Verbose logging flag.
+     */
+    private boolean mVerboseLoggingEnabled = false;
+    /**
+     * Flag to indicate if there is a buffered write pending.
+     */
+    private boolean mBufferedWritePending = false;
+    /**
+     * Alarm listener for flushing out any buffered writes.
+     */
+    private final AlarmManager.OnAlarmListener mBufferedWriteListener =
+            new AlarmManager.OnAlarmListener() {
+                public void onAlarm() {
+                    try {
+                        writeBufferedData();
+                    } catch (IOException e) {
+                        Log.wtf(TAG, "Buffered write failed");
+                    }
+
+                }
+            };
+
+    /**
+     * Create a new instance of WifiConfigStore.
+     * Note: The store file instances have been made inputs to this class to ease unit-testing.
+     *
+     * @param context     context to use for retrieving the alarm manager.
+     * @param looper      looper instance to post alarm timeouts to.
+     * @param clock       clock instance to retrieve timestamps for alarms.
+     * @param sharedStore StoreFile instance pointing to the shared store file. This should
+     *                    be retrieved using {@link #createSharedFile()} method.
+     * @param userStore   StoreFile instance pointing to the user specific store file. This should
+     *                    be retrieved using {@link #createUserFile(int)} method.
+     */
+    public WifiConfigStoreNew(Context context, Looper looper, Clock clock,
+            StoreFile sharedStore, StoreFile userStore) {
+
+        mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+        mEventHandler = new Handler(looper);
+        mClock = clock;
+
+        // Initialize the store files.
+        mSharedStore = sharedStore;
+        mUserStore = userStore;
+    }
+
+    /**
+     * Create a new instance of the shared store file.
+     *
+     * @return new instance of the store file.
+     */
+    public static StoreFile createSharedFile() {
+        return new StoreFile(new File(SHARED_STORE_DIRECTORY, STORE_FILE_NAME));
+    }
+
+    /**
+     * Create a new instance of the user specific store file.
+     * The user store file is inside the user's encrypted data directory.
+     *
+     * @param userId userId corresponding to the currently logged-in user.
+     * @return new instance of the store file.
+     */
+    public static StoreFile createUserFile(int userId) {
+        final String userDir = Environment.getDataSystemCeDirectory(userId).getAbsolutePath();
+        return new StoreFile(new File(userDir, STORE_FILE_NAME));
+    }
+
+    /**
+     * Enable verbose logging.
+     */
+    public void enableVerboseLogging(boolean verbose) {
+        mVerboseLoggingEnabled = verbose;
+    }
+
+    /**
+     * API to write the provided store data to config stores.
+     * The method writes the user specific configurations to user specific config store and the
+     * shared configurations to shared config store.
+     *
+     * @param forceSync boolean to force write the config stores now. if false, the writes are
+     *                  buffered and written after the configured interval.
+     * @param storeData The entire data to be stored across all the config store files.
+     */
+    public void write(boolean forceSync, WifiConfigStoreData storeData)
+            throws XmlPullParserException, IOException {
+        // Serialize the provided data and send it to the respective stores. The actual write will
+        // be performed later depending on the |forceSync| flag .
+        byte[] sharedDataBytes = storeData.createSharedRawData();
+        byte[] userDataBytes = storeData.createUserRawData();
+
+        mSharedStore.storeRawDataToWrite(sharedDataBytes);
+        mUserStore.storeRawDataToWrite(userDataBytes);
+
+        // Every write provides a new snapshot to be persisted, so |forceSync| flag overrides any
+        // pending buffer writes.
+        if (forceSync) {
+            writeBufferedData();
+        } else {
+            startBufferedWriteAlarm();
+        }
+    }
+
+    /**
+     * Helper method to start a buffered write alarm if one doesn't already exist.
+     */
+    private void startBufferedWriteAlarm() {
+        if (!mBufferedWritePending) {
+            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                    mClock.getElapsedSinceBootMillis() + BUFFERED_WRITE_ALARM_INTERVAL_MS,
+                    BUFFERED_WRITE_ALARM_TAG, mBufferedWriteListener, mEventHandler);
+            mBufferedWritePending = true;
+        }
+    }
+
+    /**
+     * Helper method to stop a buffered write alarm if one exists.
+     */
+    private void stopBufferedWriteAlarm() {
+        if (mBufferedWritePending) {
+            mAlarmManager.cancel(mBufferedWriteListener);
+            mBufferedWritePending = false;
+        }
+    }
+
+    /**
+     * Helper method to actually perform the writes to the file. This flushes out any write data
+     * being buffered in the respective stores and cancels any pending buffer write alarms.
+     */
+    private void writeBufferedData() throws IOException {
+        stopBufferedWriteAlarm();
+        mSharedStore.writeBufferedRawData();
+        mUserStore.writeBufferedRawData();
+    }
+
+    /**
+     * API to read the store data from the config stores.
+     * The method reads the user specific configurations from user specific config store and the
+     * shared configurations from the shared config store.
+     *
+     * @return storeData The entire data retrieved across all the config store files.
+     */
+    public WifiConfigStoreData read() throws XmlPullParserException, IOException {
+        byte[] sharedDataBytes = mSharedStore.readRawData();
+        byte[] userDataBytes = mUserStore.readRawData();
+
+        return WifiConfigStoreData.parseRawData(sharedDataBytes, userDataBytes);
+    }
+
+    /**
+     * Handle a user switch. This changes the user specific store.
+     *
+     * @param userStore StoreFile instance pointing to the user specific store file. This should
+     *                  be retrieved using {@link #createUserFile(int)} method.
+     */
+    public void handleUserSwitch(StoreFile userStore) throws IOException {
+        // Flush out any stored data if present before switching the user stores.
+        writeBufferedData();
+        mUserStore = userStore;
+    }
+
+    /**
+     * Class to encapsulate all file writes. This is a wrapper over {@link AtomicFile} to write/read
+     * raw data from the persistent file. This class provides helper methods to read/write the
+     * entire file into a byte array.
+     * This helps to separate out the processing/parsing from the actual file writing.
+     */
+    public static class StoreFile {
+        /**
+         * File permissions to lock down the file.
+         */
+        private static final int FILE_MODE = 0600;
+        /**
+         * The store file to be written to.
+         */
+        private final AtomicFile mAtomicFile;
+        /**
+         * This is an intermediate buffer to store the data to be written.
+         */
+        private byte[] mWriteData;
+        /**
+         * Store the file name for setting the file permissions/logging purposes.
+         */
+        private String mFileName;
+
+        public StoreFile(File file) {
+            mAtomicFile = new AtomicFile(file);
+            mFileName = mAtomicFile.getBaseFile().getAbsolutePath();
+        }
+
+        /**
+         * Read the entire raw data from the store file and return in a byte array.
+         *
+         * @return raw data read from the file or null if the file is not found.
+         * @throws IOException if an error occurs. The input stream is always closed by the method
+         * even when an exception is encountered.
+         */
+        public byte[] readRawData() throws IOException {
+            try {
+                return mAtomicFile.readFully();
+            } catch (FileNotFoundException e) {
+                return null;
+            }
+        }
+
+        /**
+         * Store the provided byte array to be written when {@link #writeBufferedRawData()} method
+         * is invoked.
+         * This intermediate step is needed to help in buffering file writes.
+         *
+         * @param data raw data to be written to the file.
+         */
+        public void storeRawDataToWrite(byte[] data) {
+            mWriteData = data;
+        }
+
+        /**
+         * Write the stored raw data to the store file.
+         * After the write to file, the mWriteData member is reset.
+         * @throws IOException if an error occurs. The output stream is always closed by the method
+         * even when an exception is encountered.
+         */
+        public void writeBufferedRawData() throws IOException {
+            if (mWriteData == null) {
+                Log.w(TAG, "No data stored for writing to file: " + mFileName);
+                return;
+            }
+            // Write the data to the atomic file.
+            FileOutputStream out = null;
+            try {
+                out = mAtomicFile.startWrite();
+                FileUtils.setPermissions(mFileName, FILE_MODE, -1, -1);
+                out.write(mWriteData);
+                mAtomicFile.finishWrite(out);
+            } catch (IOException e) {
+                if (out != null) {
+                    mAtomicFile.failWrite(out);
+                }
+                throw e;
+            }
+            // Reset the pending write data after write.
+            mWriteData = null;
+        }
+    }
+}
diff --git a/service/java/com/android/server/wifi/WifiConfigurationUtil.java b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
index 7d0fb3c..9059c45 100644
--- a/service/java/com/android/server/wifi/WifiConfigurationUtil.java
+++ b/service/java/com/android/server/wifi/WifiConfigurationUtil.java
@@ -23,14 +23,17 @@
 import java.util.List;
 
 /**
- * Helper for working with {@link android.net.wifi.WifiConfiguration} objects.
+ * WifiConfiguration utility for any {@link android.net.wifi.WifiConfiguration} related operations.
+ * Currently contains:
+ *   > Helper method to check if the WifiConfiguration object is visible to the provided users.
+ *   > Helper methods to identify the encryption of a WifiConfiguration object.
  */
 public class WifiConfigurationUtil {
     /**
      * Check whether a network configuration is visible to a user or any of its managed profiles.
      * @param config the network configuration whose visibility should be checked
      * @param profiles the user IDs of the user itself and all its managed profiles (can be obtained
-     *         via {@link android.os.UserManager.getProfiles})
+     *         via {@link android.os.UserManager#getProfiles})
      * @return whether the network configuration is visible to the user or any of its managed
      *         profiles
      */
@@ -46,4 +49,48 @@
         }
         return false;
     }
+
+    /**
+     * Checks if the provided |wepKeys| array contains any non-null value;
+     */
+    public static boolean hasAnyValidWepKey(String[] wepKeys) {
+        for (int i = 0; i < wepKeys.length; i++) {
+            if (wepKeys[i] != null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Helper method to check if the provided |config| corresponds to a PSK network or not.
+     */
+    public static boolean isConfigForPskNetwork(WifiConfiguration config) {
+        return config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK);
+    }
+
+    /**
+     * Helper method to check if the provided |config| corresponds to a EAP network or not.
+     */
+    public static boolean isConfigForEapNetwork(WifiConfiguration config) {
+        return (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)
+                || config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
+    }
+
+    /**
+     * Helper method to check if the provided |config| corresponds to a WEP network or not.
+     */
+    public static boolean isConfigForWepNetwork(WifiConfiguration config) {
+        return (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)
+                && hasAnyValidWepKey(config.wepKeys));
+    }
+
+    /**
+     * Helper method to check if the provided |config| corresponds to an open network or not.
+     */
+    public static boolean isConfigForOpenNetwork(WifiConfiguration config) {
+        return !(isConfigForWepNetwork(config) || isConfigForPskNetwork(config)
+                || isConfigForEapNetwork(config));
+    }
+
 }
diff --git a/service/java/com/android/server/wifi/WifiConnectivityManager.java b/service/java/com/android/server/wifi/WifiConnectivityManager.java
index 7f3d5d7..b73d149 100644
--- a/service/java/com/android/server/wifi/WifiConnectivityManager.java
+++ b/service/java/com/android/server/wifi/WifiConnectivityManager.java
@@ -36,7 +36,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.wifi.util.ScanDetailUtil;
+import com.android.server.wifi.util.ScanResultUtil;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -220,10 +220,9 @@
         localLog(listenerName + " onResults: start QNS");
         WifiConfiguration candidate =
                 mQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                mUntrustedConnectionAllowed, scanDetails,
-                mStateMachine.isLinkDebouncing(), mStateMachine.isConnected(),
-                mStateMachine.isDisconnected(),
-                mStateMachine.isSupplicantTransientState());
+                mUntrustedConnectionAllowed, mStateMachine.isLinkDebouncing(),
+                mStateMachine.isConnected(), mStateMachine.isDisconnected(),
+                mStateMachine.isSupplicantTransientState(), scanDetails);
         mWifiLastResortWatchdog.updateAvailableNetworks(
                 mQualifiedNetworkSelector.getFilteredScanDetails());
         if (candidate != null) {
@@ -286,7 +285,7 @@
                             + fullScanResult.capabilities);
             }
 
-            mScanDetails.add(ScanDetailUtil.toScanDetail(fullScanResult));
+            mScanDetails.add(ScanResultUtil.toScanDetail(fullScanResult));
         }
     }
 
@@ -355,7 +354,7 @@
                             + fullScanResult.capabilities);
             }
 
-            mScanDetails.add(ScanDetailUtil.toScanDetail(fullScanResult));
+            mScanDetails.add(ScanResultUtil.toScanDetail(fullScanResult));
         }
     }
 
@@ -479,7 +478,7 @@
             localLog("PnoScanListener: onPnoNetworkFound: results len = " + results.length);
 
             for (ScanResult result: results) {
-                mScanDetails.add(ScanDetailUtil.toScanDetail(result));
+                mScanDetails.add(ScanResultUtil.toScanDetail(result));
             }
 
             boolean wasConnectAttempted;
@@ -615,7 +614,7 @@
             return;
         }
 
-        Long elapsedTimeMillis = mClock.elapsedRealtime();
+        Long elapsedTimeMillis = mClock.getElapsedSinceBootMillis();
         if (!mScreenOn && shouldSkipConnectionAttempt(elapsedTimeMillis)) {
             localLog("connectToNetwork: Too many connection attempts. Skipping this attempt!");
             mTotalConnectivityAttemptsRateLimited++;
@@ -705,7 +704,7 @@
 
     // Start a single scan and set up the interval for next single scan.
     private void startPeriodicSingleScan() {
-        long currentTimeStamp = mClock.elapsedRealtime();
+        long currentTimeStamp = mClock.getElapsedSinceBootMillis();
 
         if (mLastPeriodicSingleScanTimeStamp != RESET_TIME_STAMP) {
             long msSinceLastScan = currentTimeStamp - mLastPeriodicSingleScanTimeStamp;
@@ -923,7 +922,7 @@
         Log.i(TAG, "scheduleWatchdogTimer");
 
         mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            mClock.elapsedRealtime() + WATCHDOG_INTERVAL_MS,
+                            mClock.getElapsedSinceBootMillis() + WATCHDOG_INTERVAL_MS,
                             WATCHDOG_TIMER_TAG,
                             mWatchdogListener, mEventHandler);
     }
@@ -931,7 +930,7 @@
     // Set up periodic scan timer
     private void schedulePeriodicScanTimer(int intervalMs) {
         mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            mClock.elapsedRealtime() + intervalMs,
+                            mClock.getElapsedSinceBootMillis() + intervalMs,
                             PERIODIC_SCAN_TIMER_TAG,
                             mPeriodicScanTimerListener, mEventHandler);
         mPeriodicScanTimerSet = true;
@@ -952,7 +951,7 @@
         RestartSingleScanListener restartSingleScanListener =
                 new RestartSingleScanListener(isFullBandScan);
         mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            mClock.elapsedRealtime() + RESTART_SCAN_DELAY_MS,
+                            mClock.getElapsedSinceBootMillis() + RESTART_SCAN_DELAY_MS,
                             RESTART_SINGLE_SCAN_TIMER_TAG,
                             restartSingleScanListener, mEventHandler);
     }
@@ -962,7 +961,7 @@
         localLog("scheduleDelayedConnectivityScan");
 
         mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            mClock.elapsedRealtime() + msFromNow,
+                            mClock.getElapsedSinceBootMillis() + msFromNow,
                             RESTART_CONNECTIVITY_SCAN_TIMER_TAG,
                             mRestartScanListener, mEventHandler);
 
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 6939d45..cc117da 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -16,34 +16,170 @@
 
 package com.android.server.wifi;
 
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.wifi.IApInterface;
+import android.net.wifi.IWificond;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.INetworkManagementService;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.os.UserManager;
+import android.provider.Settings;
 import android.security.KeyStore;
 
+import com.android.internal.R;
+import com.android.server.am.BatteryStatsService;
+
+import java.util.ArrayList;
+
 /**
- *  WiFi dependency injector using thread-safe lazy singleton pattern. To be used for accessing
- *  various wifi class instances and as a handle for mock injection.
+ *  WiFi dependency injector. To be used for accessing various WiFi class instances and as a
+ *  handle for mock injection.
+ *
+ *  Some WiFi class instances currently depend on having a Looper from a HandlerThread that has
+ *  been started. To accommodate this, we have a two-phased approach to initialize and retrieve
+ *  an instance of the WifiInjector.
  */
 public class WifiInjector {
-    // see: https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom
-    private static class LazyHolder {
-        public static final WifiInjector sInstance = new WifiInjector();
-    }
+    private static final String BOOT_DEFAULT_WIFI_COUNTRY_CODE = "ro.boot.wificountrycode";
+    private static final String WIFICOND_SERVICE_NAME = "wificond";
 
-    public static WifiInjector getInstance() {
-        return LazyHolder.sInstance;
-    }
+    static WifiInjector sWifiInjector = null;
 
+    private final Context mContext;
+    private final FrameworkFacade mFrameworkFacade = new FrameworkFacade();
+    private final HandlerThread mWifiServiceHandlerThread;
+    private final HandlerThread mWifiStateMachineHandlerThread;
+    private final WifiTrafficPoller mTrafficPoller;
+    private final WifiCountryCode mCountryCode;
+    private final BackupManagerProxy mBackupManagerProxy = new BackupManagerProxy();
+    private final WifiStateMachine mWifiStateMachine;
+    private final WifiSettingsStore mSettingsStore;
+    private final WifiCertManager mCertManager;
+    private final WifiNotificationController mNotificationController;
+    private final WifiLockManager mLockManager;
+    private final WifiController mWifiController;
     private final Clock mClock = new Clock();
     private final WifiMetrics mWifiMetrics = new WifiMetrics(mClock);
-    private final WifiLastResortWatchdog mWifiLastResortWatchdog =
-            new WifiLastResortWatchdog(mWifiMetrics);
+    private final WifiLastResortWatchdog mWifiLastResortWatchdog;
     private final PropertyService mPropertyService = new SystemPropertyService();
     private final BuildProperties mBuildProperties = new SystemBuildProperties();
     private final KeyStore mKeyStore = KeyStore.getInstance();
+    private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore();
+    private final WifiMulticastLockManager mWifiMulticastLockManager;
+
+    public WifiInjector(Context context) {
+        if (context == null) {
+            throw new IllegalStateException(
+                    "WifiInjector should not be initialized with a null Context.");
+        }
+
+        if (sWifiInjector != null) {
+            throw new IllegalStateException(
+                    "WifiInjector was already created, use getInstance instead.");
+        }
+
+        sWifiInjector = this;
+
+        mContext = context;
+        // Now create and start handler threads
+        mWifiServiceHandlerThread = new HandlerThread("WifiService");
+        mWifiServiceHandlerThread.start();
+        mWifiStateMachineHandlerThread = new HandlerThread("WifiStateMachine");
+        mWifiStateMachineHandlerThread.start();
+
+        // Now get instances of all the objects that depend on the HandlerThreads
+        mTrafficPoller =  new WifiTrafficPoller(mContext, mWifiServiceHandlerThread.getLooper(),
+                WifiNative.getWlanNativeInterface().getInterfaceName());
+        mCountryCode = new WifiCountryCode(WifiNative.getWlanNativeInterface(),
+                SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
+                mFrameworkFacade.getStringSetting(mContext, Settings.Global.WIFI_COUNTRY_CODE),
+                mContext.getResources()
+                        .getBoolean(R.bool.config_wifi_revert_country_code_on_cellular_loss));
+        mWifiStateMachine = new WifiStateMachine(mContext, mFrameworkFacade,
+                mWifiStateMachineHandlerThread.getLooper(), UserManager.get(mContext),
+                this, mBackupManagerProxy, mCountryCode);
+        mSettingsStore = new WifiSettingsStore(mContext);
+        mCertManager = new WifiCertManager(mContext);
+        mNotificationController = new WifiNotificationController(mContext,
+                mWifiServiceHandlerThread.getLooper(), mWifiStateMachine,
+                mFrameworkFacade, null);
+        mLockManager = new WifiLockManager(mContext, BatteryStatsService.getService());
+        mWifiController = new WifiController(mContext, mWifiStateMachine, mSettingsStore,
+                mLockManager, mWifiServiceHandlerThread.getLooper(), mFrameworkFacade);
+        mWifiLastResortWatchdog = new WifiLastResortWatchdog(mWifiController, mWifiMetrics);
+        mWifiMulticastLockManager = new WifiMulticastLockManager(mWifiStateMachine,
+                BatteryStatsService.getService());
+    }
+
+    /**
+     *  Obtain an instance of the WifiInjector class.
+     *
+     *  This is the generic method to get an instance of the class. The first instance should be
+     *  retrieved using the getInstanceWithContext method.
+     */
+    public static WifiInjector getInstance() {
+        if (sWifiInjector == null) {
+            throw new IllegalStateException(
+                    "Attempted to retrieve a WifiInjector instance before constructor was called.");
+        }
+        return sWifiInjector;
+    }
 
     public WifiMetrics getWifiMetrics() {
         return mWifiMetrics;
     }
 
+    public BackupManagerProxy getBackupManagerProxy() {
+        return mBackupManagerProxy;
+    }
+
+    public FrameworkFacade getFrameworkFacade() {
+        return mFrameworkFacade;
+    }
+
+    public HandlerThread getWifiServiceHandlerThread() {
+        return mWifiServiceHandlerThread;
+    }
+
+    public HandlerThread getWifiStateMachineHandlerThread() {
+        return mWifiStateMachineHandlerThread;
+    }
+
+    public WifiTrafficPoller getWifiTrafficPoller() {
+        return mTrafficPoller;
+    }
+
+    public WifiCountryCode getWifiCountryCode() {
+        return mCountryCode;
+    }
+
+    public WifiStateMachine getWifiStateMachine() {
+        return mWifiStateMachine;
+    }
+
+    public WifiSettingsStore getWifiSettingsStore() {
+        return mSettingsStore;
+    }
+
+    public WifiCertManager getWifiCertManager() {
+        return mCertManager;
+    }
+
+    public WifiNotificationController getWifiNotificationController() {
+        return mNotificationController;
+    }
+
+    public WifiLockManager getWifiLockManager() {
+        return mLockManager;
+    }
+
+    public WifiController getWifiController() {
+        return mWifiController;
+    }
+
     public WifiLastResortWatchdog getWifiLastResortWatchdog() {
         return mWifiLastResortWatchdog;
     }
@@ -56,9 +192,47 @@
         return mPropertyService;
     }
 
-    public BuildProperties getBuildProperties() { return mBuildProperties; }
+    public BuildProperties getBuildProperties() {
+        return mBuildProperties;
+    }
 
     public KeyStore getKeyStore() {
         return mKeyStore;
     }
+
+    public WifiBackupRestore getWifiBackupRestore() {
+        return mWifiBackupRestore;
+    }
+
+    public WifiMulticastLockManager getWifiMulticastLockManager() {
+        return mWifiMulticastLockManager;
+    }
+
+    public IWificond makeWificond() {
+        // We depend on being able to refresh our binder in WifiStateMachine, so don't cache it.
+        IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME);
+        return IWificond.Stub.asInterface(binder);
+    }
+
+    /**
+     * Create a SoftApManager.
+     * @param wifiNative reference to WifiNative
+     * @param nmService reference to NetworkManagementService
+     * @param cm reference to ConnectivityManager
+     * @param countryCode Country code
+     * @param allowed2GChannels list of allowed 2G channels
+     * @param listener listener for SoftApManager
+     * @param apInterface network interface to start hostapd against
+     * @return an instance of SoftApManager
+     */
+    public SoftApManager makeSoftApManager(
+            WifiNative wifiNative,
+            INetworkManagementService nmService, ConnectivityManager cm,
+            String countryCode, ArrayList<Integer> allowed2GChannels,
+            SoftApManager.Listener listener, IApInterface apInterface) {
+        return new SoftApManager(
+                mWifiServiceHandlerThread.getLooper(),
+                wifiNative, nmService, countryCode,
+                allowed2GChannels, listener, apInterface);
+    }
 }
diff --git a/service/java/com/android/server/wifi/WifiKeyStore.java b/service/java/com/android/server/wifi/WifiKeyStore.java
new file mode 100644
index 0000000..f921988
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiKeyStore.java
@@ -0,0 +1,249 @@
+/*
+ * 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 com.android.server.wifi;
+
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
+import android.os.Process;
+import android.security.Credentials;
+import android.security.KeyChain;
+import android.security.KeyStore;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.io.IOException;
+import java.security.Key;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class provides the methods to access keystore for certificate management.
+ *
+ * NOTE: This class should only be used from WifiConfigManager!
+ */
+public class WifiKeyStore {
+    private static final String TAG = "WifiKeyStore";
+
+    private boolean mVerboseLoggingEnabled = false;
+
+    private final KeyStore mKeyStore;
+
+    WifiKeyStore(KeyStore keyStore) {
+        mKeyStore = keyStore;
+    }
+
+    /**
+     * Enable verbose logging.
+     */
+    void enableVerboseLogging(boolean verbose) {
+        mVerboseLoggingEnabled = verbose;
+    }
+
+    // Certificate and private key management for EnterpriseConfig
+    private static boolean needsKeyStore(WifiEnterpriseConfig config) {
+        return (config.getClientCertificate() != null || config.getCaCertificate() != null);
+    }
+
+    private static boolean isHardwareBackedKey(Key key) {
+        return KeyChain.isBoundKeyAlgorithm(key.getAlgorithm());
+    }
+
+    private static boolean hasHardwareBackedKey(Certificate certificate) {
+        return isHardwareBackedKey(certificate.getPublicKey());
+    }
+
+    /**
+     * Install keys for given enterprise network.
+     *
+     * @param existingConfig Existing config corresponding to the network already stored in our
+     *                       database. This maybe null if it's a new network.
+     * @param config         Config corresponding to the network.
+     * @return true if successful, false otherwise.
+     */
+    private boolean installKeys(WifiEnterpriseConfig existingConfig, WifiEnterpriseConfig config,
+            String name) {
+        boolean ret = true;
+        String privKeyName = Credentials.USER_PRIVATE_KEY + name;
+        String userCertName = Credentials.USER_CERTIFICATE + name;
+        if (config.getClientCertificate() != null) {
+            byte[] privKeyData = config.getClientPrivateKey().getEncoded();
+            if (mVerboseLoggingEnabled) {
+                if (isHardwareBackedKey(config.getClientPrivateKey())) {
+                    Log.d(TAG, "importing keys " + name + " in hardware backed store");
+                } else {
+                    Log.d(TAG, "importing keys " + name + " in software backed store");
+                }
+            }
+            ret = mKeyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
+                    KeyStore.FLAG_NONE);
+
+            if (!ret) {
+                return ret;
+            }
+
+            ret = putCertInKeyStore(userCertName, config.getClientCertificate());
+            if (!ret) {
+                // Remove private key installed
+                mKeyStore.delete(privKeyName, Process.WIFI_UID);
+                return ret;
+            }
+        }
+
+        X509Certificate[] caCertificates = config.getCaCertificates();
+        Set<String> oldCaCertificatesToRemove = new ArraySet<>();
+        if (existingConfig != null && existingConfig.getCaCertificateAliases() != null) {
+            oldCaCertificatesToRemove.addAll(
+                    Arrays.asList(existingConfig.getCaCertificateAliases()));
+        }
+        List<String> caCertificateAliases = null;
+        if (caCertificates != null) {
+            caCertificateAliases = new ArrayList<>();
+            for (int i = 0; i < caCertificates.length; i++) {
+                String alias = caCertificates.length == 1 ? name
+                        : String.format("%s_%d", name, i);
+
+                oldCaCertificatesToRemove.remove(alias);
+                ret = putCertInKeyStore(Credentials.CA_CERTIFICATE + alias, caCertificates[i]);
+                if (!ret) {
+                    // Remove client key+cert
+                    if (config.getClientCertificate() != null) {
+                        mKeyStore.delete(privKeyName, Process.WIFI_UID);
+                        mKeyStore.delete(userCertName, Process.WIFI_UID);
+                    }
+                    // Remove added CA certs.
+                    for (String addedAlias : caCertificateAliases) {
+                        mKeyStore.delete(Credentials.CA_CERTIFICATE + addedAlias, Process.WIFI_UID);
+                    }
+                    return ret;
+                } else {
+                    caCertificateAliases.add(alias);
+                }
+            }
+        }
+        // Remove old CA certs.
+        for (String oldAlias : oldCaCertificatesToRemove) {
+            mKeyStore.delete(Credentials.CA_CERTIFICATE + oldAlias, Process.WIFI_UID);
+        }
+        // Set alias names
+        if (config.getClientCertificate() != null) {
+            config.setClientCertificateAlias(name);
+            config.resetClientKeyEntry();
+        }
+
+        if (caCertificates != null) {
+            config.setCaCertificateAliases(
+                    caCertificateAliases.toArray(new String[caCertificateAliases.size()]));
+            config.resetCaCertificate();
+        }
+        return ret;
+    }
+
+    private boolean putCertInKeyStore(String name, Certificate cert) {
+        try {
+            byte[] certData = Credentials.convertToPem(cert);
+            if (mVerboseLoggingEnabled) Log.d(TAG, "putting certificate " + name + " in keystore");
+            return mKeyStore.put(name, certData, Process.WIFI_UID, KeyStore.FLAG_NONE);
+        } catch (IOException e1) {
+            return false;
+        } catch (CertificateException e2) {
+            return false;
+        }
+    }
+
+    /**
+     * Remove enterprise keys from the network config.
+     *
+     * @param config Config corresponding to the network.
+     */
+    public void removeKeys(WifiEnterpriseConfig config) {
+        String client = config.getClientCertificateAlias();
+        // a valid client certificate is configured
+        if (!TextUtils.isEmpty(client)) {
+            if (mVerboseLoggingEnabled) Log.d(TAG, "removing client private key and user cert");
+            mKeyStore.delete(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID);
+            mKeyStore.delete(Credentials.USER_CERTIFICATE + client, Process.WIFI_UID);
+        }
+
+        String[] aliases = config.getCaCertificateAliases();
+        // a valid ca certificate is configured
+        if (aliases != null) {
+            for (String ca : aliases) {
+                if (!TextUtils.isEmpty(ca)) {
+                    if (mVerboseLoggingEnabled) Log.d(TAG, "removing CA cert: " + ca);
+                    mKeyStore.delete(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID);
+                }
+            }
+        }
+    }
+
+    /**
+     * Update/Install keys for given enterprise network.
+     *
+     * @param config         Config corresponding to the network.
+     * @param existingConfig Existing config corresponding to the network already stored in our
+     *                       database. This maybe null if it's a new network.
+     * @return true if successful, false otherwise.
+     */
+    public boolean updateNetworkKeys(WifiConfiguration config, WifiConfiguration existingConfig) {
+        WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig;
+        if (needsKeyStore(enterpriseConfig)) {
+            try {
+                /* config passed may include only fields being updated.
+                 * In order to generate the key id, fetch uninitialized
+                 * fields from the currently tracked configuration
+                 */
+                String keyId = config.getKeyIdForCredentials(existingConfig);
+                if (!installKeys(existingConfig != null
+                        ? existingConfig.enterpriseConfig : null, enterpriseConfig, keyId)) {
+                    Log.e(TAG, config.SSID + ": failed to install keys");
+                    return false;
+                }
+            } catch (IllegalStateException e) {
+                Log.e(TAG, config.SSID + " invalid config for key installation: " + e.getMessage());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Checks whether the configuration requires a software backed keystore or not.
+     * @param config WifiEnterprise config instance pointing to the enterprise configuration of the
+     *               network.
+     */
+    public static boolean needsSoftwareBackedKeyStore(WifiEnterpriseConfig config) {
+        String client = config.getClientCertificateAlias();
+        if (!TextUtils.isEmpty(client)) {
+            // a valid client certificate is configured
+
+            // BUGBUG(b/29578316): keyStore.get() never returns certBytes; because it is not
+            // taking WIFI_UID as a parameter. It always looks for certificate
+            // with SYSTEM_UID, and never finds any Wifi certificates. Assuming that
+            // all certificates need software keystore until we get the get() API
+            // fixed.
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
index 558b50e..6fb2050 100644
--- a/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
+++ b/service/java/com/android/server/wifi/WifiLastResortWatchdog.java
@@ -34,8 +34,7 @@
  */
 public class WifiLastResortWatchdog {
     private static final String TAG = "WifiLastResortWatchdog";
-    private static final boolean VDBG = false;
-    private static final boolean DBG = true;
+    private boolean mVerboseLoggingEnabled = false;
     /**
      * Association Failure code
      */
@@ -80,9 +79,10 @@
 
     private WifiMetrics mWifiMetrics;
 
-    private WifiController mWifiController = null;
+    private WifiController mWifiController;
 
-    WifiLastResortWatchdog(WifiMetrics wifiMetrics) {
+    WifiLastResortWatchdog(WifiController wifiController, WifiMetrics wifiMetrics) {
+        mWifiController = wifiController;
         mWifiMetrics = wifiMetrics;
     }
 
@@ -95,7 +95,9 @@
      */
     public void updateAvailableNetworks(
             List<Pair<ScanDetail, WifiConfiguration>> availableNetworks) {
-        if (VDBG) Log.v(TAG, "updateAvailableNetworks: size = " + availableNetworks.size());
+        if (mVerboseLoggingEnabled) {
+            Log.v(TAG, "updateAvailableNetworks: size = " + availableNetworks.size());
+        }
         // Add new networks to mRecentAvailableNetworks
         if (availableNetworks != null) {
             for (Pair<ScanDetail, WifiConfiguration> pair : availableNetworks) {
@@ -105,7 +107,9 @@
                 if (scanResult == null) continue;
                 String bssid = scanResult.BSSID;
                 String ssid = "\"" + scanDetail.getSSID() + "\"";
-                if (VDBG) Log.v(TAG, " " + bssid + ": " + scanDetail.getSSID());
+                if (mVerboseLoggingEnabled) {
+                    Log.v(TAG, " " + bssid + ": " + scanDetail.getSSID());
+                }
                 // Cache the scanResult & WifiConfig
                 AvailableNetworkFailureCount availableNetworkFailureCount =
                         mRecentAvailableNetworks.get(bssid);
@@ -161,15 +165,12 @@
                         mSsidFailureCount.remove(ssid);
                     }
                 } else {
-                    if (DBG) {
-                        Log.d(TAG, "updateAvailableNetworks: SSID to AP count mismatch for "
-                                + ssid);
-                    }
+                    Log.d(TAG, "updateAvailableNetworks: SSID to AP count mismatch for " + ssid);
                 }
                 it.remove();
             }
         }
-        if (VDBG) Log.v(TAG, toString());
+        if (mVerboseLoggingEnabled) Log.v(TAG, toString());
     }
 
     /**
@@ -180,7 +181,7 @@
      * @return true if watchdog triggers, returned for test visibility
      */
     public boolean noteConnectionFailureAndTriggerIfNeeded(String ssid, String bssid, int reason) {
-        if (VDBG) {
+        if (mVerboseLoggingEnabled) {
             Log.v(TAG, "noteConnectionFailureAndTriggerIfNeeded: [" + ssid + ", " + bssid + ", "
                     + reason + "]");
         }
@@ -189,7 +190,9 @@
 
         // Have we met conditions to trigger the Watchdog Wifi restart?
         boolean isRestartNeeded = checkTriggerCondition();
-        if (VDBG) Log.v(TAG, "isRestartNeeded = " + isRestartNeeded);
+        if (mVerboseLoggingEnabled) {
+            Log.v(TAG, "isRestartNeeded = " + isRestartNeeded);
+        }
         if (isRestartNeeded) {
             // Stop the watchdog from triggering until re-enabled
             setWatchdogTriggerEnabled(false);
@@ -207,7 +210,9 @@
      * @param isEntering true if called from ConnectedState.enter(), false for exit()
      */
     public void connectedStateTransition(boolean isEntering) {
-        if (VDBG) Log.v(TAG, "connectedStateTransition: isEntering = " + isEntering);
+        if (mVerboseLoggingEnabled) {
+            Log.v(TAG, "connectedStateTransition: isEntering = " + isEntering);
+        }
         mWifiIsConnected = isEntering;
         if (isEntering) {
             // We connected to something! Reset failure counts for everything
@@ -228,7 +233,7 @@
      * @param reason Message id from WifiStateMachine for this failure
      */
     private void updateFailureCountForNetwork(String ssid, String bssid, int reason) {
-        if (VDBG) {
+        if (mVerboseLoggingEnabled) {
             Log.v(TAG, "updateFailureCountForNetwork: [" + ssid + ", " + bssid + ", "
                     + reason + "]");
         }
@@ -249,9 +254,7 @@
     private void incrementSsidFailureCount(String ssid, int reason) {
         Pair<AvailableNetworkFailureCount, Integer> ssidFails = mSsidFailureCount.get(ssid);
         if (ssidFails == null) {
-            if (DBG) {
-                Log.v(TAG, "updateFailureCountForNetwork: No networks for ssid = " + ssid);
-            }
+            Log.d(TAG, "updateFailureCountForNetwork: No networks for ssid = " + ssid);
             return;
         }
         AvailableNetworkFailureCount failureCount = ssidFails.first;
@@ -267,22 +270,18 @@
         AvailableNetworkFailureCount availableNetworkFailureCount =
                 mRecentAvailableNetworks.get(bssid);
         if (availableNetworkFailureCount == null) {
-            if (DBG) {
-                Log.d(TAG, "updateFailureCountForNetwork: Unable to find Network [" + ssid
-                        + ", " + bssid + "]");
-            }
+            Log.d(TAG, "updateFailureCountForNetwork: Unable to find Network [" + ssid
+                    + ", " + bssid + "]");
             return;
         }
         if (!availableNetworkFailureCount.ssid.equals(ssid)) {
-            if (DBG) {
-                Log.d(TAG, "updateFailureCountForNetwork: Failed connection attempt has"
-                        + " wrong ssid. Failed [" + ssid + ", " + bssid + "], buffered ["
-                        + availableNetworkFailureCount.ssid + ", " + bssid + "]");
-            }
+            Log.d(TAG, "updateFailureCountForNetwork: Failed connection attempt has"
+                    + " wrong ssid. Failed [" + ssid + ", " + bssid + "], buffered ["
+                    + availableNetworkFailureCount.ssid + ", " + bssid + "]");
             return;
         }
         if (availableNetworkFailureCount.config == null) {
-            if (VDBG) {
+            if (mVerboseLoggingEnabled) {
                 Log.v(TAG, "updateFailureCountForNetwork: network has no config ["
                         + ssid + ", " + bssid + "]");
             }
@@ -297,7 +296,7 @@
      * @return is the trigger condition true
      */
     private boolean checkTriggerCondition() {
-        if (VDBG) Log.v(TAG, "checkTriggerCondition.");
+        if (mVerboseLoggingEnabled) Log.v(TAG, "checkTriggerCondition.");
         // Don't check Watchdog trigger if wifi is in a connected state
         // (This should not occur, but we want to protect against any race conditions)
         if (mWifiIsConnected) return false;
@@ -319,7 +318,7 @@
         }
         // We have met the failure count for every available network & there is at-least one network
         // we have previously connected to present.
-        if (VDBG) {
+        if (mVerboseLoggingEnabled) {
             Log.v(TAG, "checkTriggerCondition: return = " + atleastOneNetworkHasEverConnected);
         }
         return atleastOneNetworkHasEverConnected;
@@ -329,7 +328,7 @@
      * Trigger a restart of the wifi stack.
      */
     private void restartWifiStack() {
-        if (VDBG) Log.v(TAG, "restartWifiStack.");
+        if (mVerboseLoggingEnabled) Log.v(TAG, "restartWifiStack.");
 
         // First verify that we can send the trigger message.
         if (mWifiController == null) {
@@ -337,17 +336,15 @@
             return;
         }
 
-        if (DBG) Log.d(TAG, toString());
-
         mWifiController.sendMessage(WifiController.CMD_RESTART_WIFI);
-        Log.i(TAG, "Triggered WiFi stack restart.");
+        Log.i(TAG, "Triggered WiFi stack restart.\n" + toString());
     }
 
     /**
      * Update WifiMetrics with various Watchdog stats (trigger counts, failed network counts)
      */
     private void incrementWifiMetricsTriggerCounts() {
-        if (VDBG) Log.v(TAG, "incrementWifiMetricsTriggerCounts.");
+        if (mVerboseLoggingEnabled) Log.v(TAG, "incrementWifiMetricsTriggerCounts.");
         mWifiMetrics.incrementNumLastResortWatchdogTriggers();
         mWifiMetrics.addCountToNumLastResortWatchdogAvailableNetworksTotal(
                 mSsidFailureCount.size());
@@ -379,7 +376,7 @@
      * Clear failure counts for each network in recentAvailableNetworks
      */
     private void clearAllFailureCounts() {
-        if (VDBG) Log.v(TAG, "clearAllFailureCounts.");
+        if (mVerboseLoggingEnabled) Log.v(TAG, "clearAllFailureCounts.");
         for (Map.Entry<String, AvailableNetworkFailureCount> entry
                 : mRecentAvailableNetworks.entrySet()) {
             final AvailableNetworkFailureCount failureCount = entry.getValue();
@@ -403,7 +400,7 @@
      * @param enable true to enable the Watchdog trigger, false to disable it
      */
     private void setWatchdogTriggerEnabled(boolean enable) {
-        if (VDBG) Log.v(TAG, "setWatchdogTriggerEnabled: enable = " + enable);
+        if (mVerboseLoggingEnabled) Log.v(TAG, "setWatchdogTriggerEnabled: enable = " + enable);
         mWatchdogAllowedToTrigger = enable;
     }
 
@@ -417,14 +414,15 @@
         sb.append("\nmRecentAvailableNetworks: ").append(mRecentAvailableNetworks.size());
         for (Map.Entry<String, AvailableNetworkFailureCount> entry
                 : mRecentAvailableNetworks.entrySet()) {
-            sb.append("\n ").append(entry.getKey()).append(": ").append(entry.getValue());
+            sb.append("\n ").append(entry.getKey()).append(": ").append(entry.getValue())
+                .append(", Age: ").append(entry.getValue().age);
         }
         sb.append("\nmSsidFailureCount:");
         for (Map.Entry<String, Pair<AvailableNetworkFailureCount, Integer>> entry :
                 mSsidFailureCount.entrySet()) {
             final AvailableNetworkFailureCount failureCount = entry.getValue().first;
             final Integer apCount = entry.getValue().second;
-            sb.append("\n").append(entry.getKey()).append(": ").append(apCount).append(", ")
+            sb.append("\n").append(entry.getKey()).append(": ").append(apCount).append(",")
                     .append(failureCount.toString());
         }
         return sb.toString();
@@ -457,9 +455,7 @@
         String ssid = availableNetworkFailureCount.ssid;
         Pair<AvailableNetworkFailureCount, Integer> ssidFails = mSsidFailureCount.get(ssid);
         if (ssidFails == null) {
-            if (DBG) {
-                Log.d(TAG, "getFailureCount: Could not find SSID count for " + ssid);
-            }
+            Log.d(TAG, "getFailureCount: Could not find SSID count for " + ssid);
             return 0;
         }
         final AvailableNetworkFailureCount failCount = ssidFails.first;
@@ -475,6 +471,14 @@
         }
     }
 
+    protected void enableVerboseLogging(int verbose) {
+        if (verbose > 0) {
+            mVerboseLoggingEnabled = true;
+        } else {
+            mVerboseLoggingEnabled = false;
+        }
+    }
+
     /**
      * This class holds the failure counts for an 'available network' (one of the potential
      * candidates for connection, as determined by framework).
@@ -537,24 +541,13 @@
         }
 
         public String toString() {
-            return  ssid + ", HasEverConnected: " + ((config != null)
+            return  ssid + " HasEverConnected: " + ((config != null)
                     ? config.getNetworkSelectionStatus().getHasEverConnected() : "null_config")
                     + ", Failures: {"
                     + "Assoc: " + associationRejection
                     + ", Auth: " + authenticationFailure
                     + ", Dhcp: " + dhcpFailure
-                    + "}"
-                    + ", Age: " + age;
+                    + "}";
         }
     }
-
-    /**
-     * Method used to set the WifiController for the this watchdog.
-     *
-     * The WifiController is used to send the restart wifi command to carry out the wifi restart.
-     * @param wifiController WifiController instance that will be sent the CMD_RESTART_WIFI message.
-     */
-    public void setWifiController(WifiController wifiController) {
-        mWifiController = wifiController;
-    }
 }
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 0dc5ccf..0eaf029 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -77,7 +77,7 @@
      */
     private final SparseIntArray mWifiSystemStateEntries = new SparseIntArray();
     /**
-     * Records the elapsedRealtime (in seconds) that represents the beginning of data
+     * Records the getElapsedSinceBootMillis (in seconds) that represents the beginning of data
      * capture for for this WifiMetricsProto
      */
     private final SparseIntArray mRssiPollCounts = new SparseIntArray();
@@ -313,7 +313,7 @@
         mCurrentConnectionEvent = null;
         mScreenOn = true;
         mWifiState = WifiMetricsProto.WifiLog.WIFI_DISABLED;
-        mRecordStartTimeSec = mClock.elapsedRealtime() / 1000;
+        mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000;
     }
 
     // Values used for indexing SystemStateEntries
@@ -356,12 +356,12 @@
             }
             mCurrentConnectionEvent = new ConnectionEvent();
             mCurrentConnectionEvent.mConnectionEvent.startTimeMillis =
-                    mClock.currentTimeMillis();
+                    mClock.getWallClockMillis();
             mCurrentConnectionEvent.mConfigBssid = targetBSSID;
             mCurrentConnectionEvent.mConnectionEvent.roamType = roamType;
             mCurrentConnectionEvent.mRouterFingerPrint.updateFromWifiConfiguration(config);
             mCurrentConnectionEvent.mConfigBssid = "any";
-            mCurrentConnectionEvent.mRealStartTime = mClock.elapsedRealtime();
+            mCurrentConnectionEvent.mRealStartTime = mClock.getElapsedSinceBootMillis();
             mCurrentConnectionEvent.mWifiState = mWifiState;
             mCurrentConnectionEvent.mScreenOn = mScreenOn;
             mConnectionEventList.add(mCurrentConnectionEvent);
@@ -414,7 +414,7 @@
                 boolean result = (level2FailureCode == 1)
                         && (connectivityFailureCode == WifiMetricsProto.ConnectionEvent.HLF_NONE);
                 mCurrentConnectionEvent.mConnectionEvent.connectionResult = result ? 1 : 0;
-                mCurrentConnectionEvent.mRealEndTime = mClock.elapsedRealtime();
+                mCurrentConnectionEvent.mRealEndTime = mClock.getElapsedSinceBootMillis();
                 mCurrentConnectionEvent.mConnectionEvent.durationTakenToConnectMillis = (int)
                         (mCurrentConnectionEvent.mRealEndTime
                         - mCurrentConnectionEvent.mRealStartTime);
@@ -922,7 +922,7 @@
                 pw.println("mWifiLogProto.numLastResortWatchdogTriggersWithBadOther="
                         + mWifiLogProto.numLastResortWatchdogTriggersWithBadOther);
                 pw.println("mWifiLogProto.recordDurationSec="
-                        + ((mClock.elapsedRealtime() / 1000) - mRecordStartTimeSec));
+                        + ((mClock.getElapsedSinceBootMillis() / 1000) - mRecordStartTimeSec));
                 pw.println("mWifiLogProto.rssiPollRssiCount: Printing counts for [" + MIN_RSSI_POLL
                         + ", " + MAX_RSSI_POLL + "]");
                 StringBuilder sb = new StringBuilder();
@@ -986,7 +986,7 @@
                 mWifiLogProto.wifiSystemStateEntries[i].isScreenOn =
                         (mWifiSystemStateEntries.keyAt(i) % 2) > 0;
             }
-            mWifiLogProto.recordDurationSec = (int) ((mClock.elapsedRealtime() / 1000)
+            mWifiLogProto.recordDurationSec = (int) ((mClock.getElapsedSinceBootMillis() / 1000)
                     - mRecordStartTimeSec);
 
             /**
@@ -1014,7 +1014,7 @@
             }
             mScanReturnEntries.clear();
             mWifiSystemStateEntries.clear();
-            mRecordStartTimeSec = mClock.elapsedRealtime() / 1000;
+            mRecordStartTimeSec = mClock.getElapsedSinceBootMillis() / 1000;
             mRssiPollCounts.clear();
             mWifiLogProto.clear();
         }
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index 1f2b397..8c0d36a 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -59,8 +59,7 @@
  */
 public class WifiMonitor {
 
-    private static boolean DBG = false;
-    private static final boolean VDBG = false;
+    private static final boolean DBG = false;
     private static final String TAG = "WifiMonitor";
 
     /** Events we receive from the supplicant daemon */
@@ -536,12 +535,13 @@
     }
 
     private int mRecvErrors = 0;
+    private boolean mVerboseLoggingEnabled = false;
 
     void enableVerboseLogging(int verbose) {
         if (verbose > 0) {
-            DBG = true;
+            mVerboseLoggingEnabled = true;
         } else {
-            DBG = false;
+            mVerboseLoggingEnabled = false;
         }
     }
 
@@ -589,7 +589,7 @@
             return true;
         }
 
-        if (DBG) Log.d(TAG, "connecting to supplicant");
+        if (mVerboseLoggingEnabled) Log.d(TAG, "connecting to supplicant");
         int connectTries = 0;
         while (true) {
             if (mWifiNative.connectToSupplicant()) {
@@ -625,7 +625,7 @@
     }
 
     public synchronized void stopMonitoring(String iface) {
-        if (DBG) Log.d(TAG, "stopMonitoring(" + iface + ")");
+        if (mVerboseLoggingEnabled) Log.d(TAG, "stopMonitoring(" + iface + ")");
         setMonitoring(iface, true);
         sendMessage(iface, SUP_DISCONNECTION_EVENT);
         setMonitoring(iface, false);
@@ -693,10 +693,14 @@
                     }
                 }
             } else {
-                if (DBG) Log.d(TAG, "Dropping event because (" + iface + ") is stopped");
+                if (mVerboseLoggingEnabled) {
+                    Log.d(TAG, "Dropping event because (" + iface + ") is stopped");
+                }
             }
         } else {
-            if (DBG) Log.d(TAG, "Sending to all monitors because there's no matching iface");
+            if (mVerboseLoggingEnabled) {
+                Log.d(TAG, "Sending to all monitors because there's no matching iface");
+            }
             boolean firstHandler = true;
             for (Map.Entry<String, SparseArray<Set<Handler>>> entry : mHandlerMap.entrySet()) {
                 if (isMonitoring(entry.getKey())) {
@@ -731,25 +735,29 @@
         }
 
         public void run() {
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 Log.d(TAG, "MonitorThread start with mConnected=" + mConnected);
             }
             //noinspection InfiniteLoopStatement
             for (;;) {
                 if (!mConnected) {
-                    if (DBG) Log.d(TAG, "MonitorThread exit because mConnected is false");
+                    if (mVerboseLoggingEnabled) {
+                        Log.d(TAG, "MonitorThread exit because mConnected is false");
+                    }
                     break;
                 }
                 String eventStr = mWifiNative.waitForEvent();
 
                 // Skip logging the common but mostly uninteresting events
                 if (!eventStr.contains(BSS_ADDED_STR) && !eventStr.contains(BSS_REMOVED_STR)) {
-                    if (DBG) Log.d(TAG, "Event [" + eventStr + "]");
+                    if (mVerboseLoggingEnabled) Log.d(TAG, "Event [" + eventStr + "]");
                     mLocalLog.log("Event [" + eventStr + "]");
                 }
 
                 if (dispatchEvent(eventStr)) {
-                    if (DBG) Log.d(TAG, "Disconnecting from the supplicant, no more events");
+                    if (mVerboseLoggingEnabled) {
+                        Log.d(TAG, "Disconnecting from the supplicant, no more events");
+                    }
                     break;
                 }
             }
@@ -782,7 +790,7 @@
             iface = "p2p0";
         }
 
-        if (VDBG) Log.d(TAG, "Dispatching event to interface: " + iface);
+        if (DBG) Log.d(TAG, "Dispatching event to interface: " + iface);
 
         if (dispatchEvent(eventStr, iface)) {
             mConnected = false;
@@ -803,7 +811,7 @@
 
     /* @return true if the event was supplicant disconnection */
     private boolean dispatchEvent(String eventStr, String iface) {
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             // Dont log CTRL-EVENT-BSS-ADDED which are too verbose and not handled
             if (eventStr != null && !eventStr.contains("CTRL-EVENT-BSS-ADDED")) {
                 Log.d(TAG, iface + " cnt=" + Integer.toString(eventLogCounter)
@@ -856,7 +864,9 @@
                     eventStr.endsWith(AUTH_TIMEOUT_STR)) {
                 sendMessage(iface, AUTHENTICATION_FAILURE_EVENT);
             } else {
-                if (DBG) Log.w(TAG, "couldn't identify event type - " + eventStr);
+                if (mVerboseLoggingEnabled) {
+                    Log.w(TAG, "couldn't identify event type - " + eventStr);
+                }
             }
             eventLogCounter++;
             return false;
@@ -867,7 +877,9 @@
         if (nameEnd != -1)
             eventName = eventName.substring(0, nameEnd);
         if (eventName.length() == 0) {
-            if (DBG) Log.i(TAG, "Received wpa_supplicant event with empty event name");
+            if (mVerboseLoggingEnabled) {
+                Log.i(TAG, "Received wpa_supplicant event with empty event name");
+            }
             eventLogCounter++;
             return false;
         }
@@ -978,7 +990,7 @@
              */
             if (eventData.startsWith(WPA_RECV_ERROR_STR)) {
                 if (++mRecvErrors > MAX_RECV_ERRORS) {
-                    if (DBG) {
+                    if (mVerboseLoggingEnabled) {
                         Log.d(TAG, "too many recv errors, closing connection");
                     }
                 } else {
@@ -999,7 +1011,9 @@
             String BSSID = "";
             int status = -1;
             if (!match.find()) {
-                if (DBG) Log.d(TAG, "Assoc Reject: Could not parse assoc reject string");
+                if (mVerboseLoggingEnabled) {
+                    Log.d(TAG, "Assoc Reject: Could not parse assoc reject string");
+                }
             } else {
                 int groupNumber = match.groupCount();
                 int statusGroupNumber = -1;
@@ -1018,9 +1032,9 @@
                 }
             }
             sendMessage(iface, ASSOCIATION_REJECTION_EVENT, eventLogCounter, status, BSSID);
-        } else if (event == BSS_ADDED && !VDBG) {
+        } else if (event == BSS_ADDED && !DBG) {
             // Ignore that event - it is not handled, and dont log it as it is too verbose
-        } else if (event == BSS_REMOVED && !VDBG) {
+        } else if (event == BSS_REMOVED && !DBG) {
             // Ignore that event - it is not handled, and dont log it as it is too verbose
         }  else {
             handleEvent(event, eventData, iface);
@@ -1046,7 +1060,7 @@
      * event name and &quot;&#8195;&#8212;&#8195;&quot;
      */
     private void handleEvent(int event, String remainder, String iface) {
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             Log.d(TAG, "handleEvent " + Integer.toString(event) + " " + remainder);
         }
         switch (event) {
@@ -1067,7 +1081,7 @@
                 break;
 
             case UNKNOWN:
-                if (DBG) {
+                if (mVerboseLoggingEnabled) {
                     Log.w(TAG, "handleEvent unknown: " + Integer.toString(event) + " " + remainder);
                 }
                 break;
@@ -1345,7 +1359,9 @@
             }
 
         } else {
-            if (DBG) Log.w(TAG, "couldn't identify request type - " + dataString);
+            if (mVerboseLoggingEnabled) {
+                Log.w(TAG, "couldn't identify request type - " + dataString);
+            }
         }
     }
 
@@ -1418,7 +1434,9 @@
         if (newState == NetworkInfo.DetailedState.CONNECTED) {
             match = mConnectedEventPattern.matcher(data);
             if (!match.find()) {
-               if (DBG) Log.d(TAG, "handleNetworkStateChange: Couldnt find BSSID in event string");
+                if (mVerboseLoggingEnabled) {
+                    Log.d(TAG, "handleNetworkStateChange: Couldnt find BSSID in event string");
+                }
             } else {
                 BSSID = match.group(1);
                 try {
@@ -1431,7 +1449,9 @@
         } else if (newState == NetworkInfo.DetailedState.DISCONNECTED) {
             match = mDisconnectedEventPattern.matcher(data);
             if (!match.find()) {
-               if (DBG) Log.d(TAG, "handleNetworkStateChange: Could not parse disconnect string");
+                if (mVerboseLoggingEnabled) {
+                    Log.d(TAG, "handleNetworkStateChange: Could not parse disconnect string");
+                }
             } else {
                 BSSID = match.group(1);
                 try {
@@ -1445,9 +1465,10 @@
                     local = -1;
                 }
             }
-            if (DBG) Log.d(TAG, "WifiMonitor notify network disconnect: "
-                    + BSSID
-                    + " reason=" + Integer.toString(reason));
+            if (mVerboseLoggingEnabled) {
+                Log.d(TAG, "WifiMonitor notify network disconnect: " + BSSID
+                        + " reason=" + Integer.toString(reason));
+            }
             sendMessage(iface, NETWORK_DISCONNECTION_EVENT, local, reason, BSSID);
         }
     }
diff --git a/service/java/com/android/server/wifi/WifiMulticastLockManager.java b/service/java/com/android/server/wifi/WifiMulticastLockManager.java
new file mode 100644
index 0000000..40b259d
--- /dev/null
+++ b/service/java/com/android/server/wifi/WifiMulticastLockManager.java
@@ -0,0 +1,195 @@
+/*
+ * 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 com.android.server.wifi;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.app.IBatteryStats;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * WifiMulticastLockManager tracks holders of multicast locks and
+ * triggers enabling and disabling of filtering.
+ *
+ * @hide
+ */
+public class WifiMulticastLockManager {
+    private static final String TAG = "WifiMulticastLockManager";
+    private final List<Multicaster> mMulticasters = new ArrayList<>();
+    private int mMulticastEnabled = 0;
+    private int mMulticastDisabled = 0;
+    private boolean mVerboseLoggingEnabled = false;
+    private final IBatteryStats mBatteryStats;
+    private final FilterController mFilterController;
+
+    /** Delegate for handling state change events for multicast filtering. */
+    public interface FilterController {
+        /** Called when multicast filtering should be enabled */
+        void startFilteringMulticastPackets();
+
+        /** Called when multicast filtering should be disabled */
+        void stopFilteringMulticastPackets();
+    }
+
+    public WifiMulticastLockManager(FilterController filterController, IBatteryStats batteryStats) {
+        mBatteryStats = batteryStats;
+        mFilterController = filterController;
+    }
+
+    private class Multicaster implements IBinder.DeathRecipient {
+        String mTag;
+        int mUid;
+        IBinder mBinder;
+
+        Multicaster(String tag, IBinder binder) {
+            mTag = tag;
+            mUid = Binder.getCallingUid();
+            mBinder = binder;
+            try {
+                mBinder.linkToDeath(this, 0);
+            } catch (RemoteException e) {
+                binderDied();
+            }
+        }
+
+        @Override
+        public void binderDied() {
+            Slog.e(TAG, "Multicaster binderDied");
+            synchronized (mMulticasters) {
+                int i = mMulticasters.indexOf(this);
+                if (i != -1) {
+                    removeMulticasterLocked(i, mUid);
+                }
+            }
+        }
+
+        void unlinkDeathRecipient() {
+            mBinder.unlinkToDeath(this, 0);
+        }
+
+        public int getUid() {
+            return mUid;
+        }
+
+        public String toString() {
+            return "Multicaster{" + mTag + " uid=" + mUid  + "}";
+        }
+    }
+
+    protected void dump(PrintWriter pw) {
+        pw.println("mMulticastEnabled " + mMulticastEnabled);
+        pw.println("mMulticastDisabled " + mMulticastDisabled);
+        pw.println("Multicast Locks held:");
+        for (Multicaster l : mMulticasters) {
+            pw.print("    ");
+            pw.println(l);
+        }
+    }
+
+    protected void enableVerboseLogging(int verbose) {
+        if (verbose > 0) {
+            mVerboseLoggingEnabled = true;
+        } else {
+            mVerboseLoggingEnabled = false;
+        }
+    }
+
+    /** Start filtering if  no multicasters exist. */
+    public void initializeFiltering() {
+        synchronized (mMulticasters) {
+            // if anybody had requested filters be off, leave off
+            if (mMulticasters.size() != 0) {
+                return;
+            } else {
+                mFilterController.startFilteringMulticastPackets();
+            }
+        }
+    }
+
+    /**
+     * Acquire a multicast lock.
+     * @param binder a binder used to ensure caller is still alive
+     * @param tag string name of the caller.
+     */
+    public void acquireLock(IBinder binder, String tag) {
+        synchronized (mMulticasters) {
+            mMulticastEnabled++;
+            mMulticasters.add(new Multicaster(tag, binder));
+            // Note that we could call stopFilteringMulticastPackets only when
+            // our new size == 1 (first call), but this function won't
+            // be called often and by making the stopPacket call each
+            // time we're less fragile and self-healing.
+            mFilterController.stopFilteringMulticastPackets();
+        }
+
+        int uid = Binder.getCallingUid();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mBatteryStats.noteWifiMulticastEnabled(uid);
+        } catch (RemoteException e) {
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    /** Releases a multicast lock */
+    public void releaseLock() {
+        int uid = Binder.getCallingUid();
+        synchronized (mMulticasters) {
+            mMulticastDisabled++;
+            int size = mMulticasters.size();
+            for (int i = size - 1; i >= 0; i--) {
+                Multicaster m = mMulticasters.get(i);
+                if ((m != null) && (m.getUid() == uid)) {
+                    removeMulticasterLocked(i, uid);
+                }
+            }
+        }
+    }
+
+    private void removeMulticasterLocked(int i, int uid) {
+        Multicaster removed = mMulticasters.remove(i);
+
+        if (removed != null) {
+            removed.unlinkDeathRecipient();
+        }
+        if (mMulticasters.size() == 0) {
+            mFilterController.startFilteringMulticastPackets();
+        }
+
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mBatteryStats.noteWifiMulticastDisabled(uid);
+        } catch (RemoteException e) {
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    /** Returns whether multicast should be allowed (filterning disabled). */
+    public boolean isMulticastEnabled() {
+        synchronized (mMulticasters) {
+            return (mMulticasters.size() > 0);
+        }
+    }
+}
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 73765ee..75f5915 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -18,12 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.net.apf.ApfCapabilities;
 import android.net.wifi.RttManager;
 import android.net.wifi.RttManager.ResponderConfig;
@@ -46,6 +41,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.Immutable;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.HexDump;
 import com.android.server.connectivity.KeepalivePacketData;
 import com.android.server.wifi.hotspot2.NetworkDetail;
@@ -339,24 +335,6 @@
     }
 
     /**
-     * Create a comma separate string from integer set.
-     * @param values List of integers.
-     * @return comma separated string.
-     */
-    private static String createCSVStringFromIntegerSet(Set<Integer> values) {
-        StringBuilder list = new StringBuilder();
-        boolean first = true;
-        for (Integer value : values) {
-            if (!first) {
-                list.append(",");
-            }
-            list.append(value);
-            first = false;
-        }
-        return list.toString();
-    }
-
-    /**
      * Start a scan using wpa_supplicant for the given frequencies.
      * @param freqs list of frequencies to scan for, if null scan all supported channels.
      * @param hiddenNetworkIds List of hidden networks to be scanned for.
@@ -365,10 +343,10 @@
         String freqList = null;
         String hiddenNetworkIdList = null;
         if (freqs != null && freqs.size() != 0) {
-            freqList = createCSVStringFromIntegerSet(freqs);
+            freqList = TextUtils.join(",", freqs);
         }
         if (hiddenNetworkIds != null && hiddenNetworkIds.size() != 0) {
-            hiddenNetworkIdList = createCSVStringFromIntegerSet(hiddenNetworkIds);
+            hiddenNetworkIdList = TextUtils.join(",", hiddenNetworkIds);
         }
         return scanWithParams(freqList, hiddenNetworkIdList);
     }
@@ -408,17 +386,26 @@
     }
 
     public boolean setNetworkExtra(int netId, String name, Map<String, String> values) {
+        String encoded = createNetworkExtra(values);
+        if (encoded == null) {
+            return false;
+        }
+        return setNetworkVariable(netId, name, "\"" + encoded + "\"");
+    }
+
+    @VisibleForTesting
+    public static String createNetworkExtra(Map<String, String> values) {
         final String encoded;
         try {
             encoded = URLEncoder.encode(new JSONObject(values).toString(), "UTF-8");
         } catch (NullPointerException e) {
             Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
-            return false;
+            return null;
         } catch (UnsupportedEncodingException e) {
             Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
-            return false;
+            return null;
         }
-        return setNetworkVariable(netId, name, "\"" + encoded + "\"");
+        return encoded;
     }
 
     public boolean setNetworkVariable(int netId, String name, String value) {
@@ -432,12 +419,16 @@
     }
 
     public Map<String, String> getNetworkExtra(int netId, String name) {
-        final String wrapped = getNetworkVariable(netId, name);
-        if (wrapped == null || !wrapped.startsWith("\"") || !wrapped.endsWith("\"")) {
+        final String extraString = getNetworkVariable(netId, name);
+        return parseNetworkExtra(extraString);
+    }
+
+    public static Map<String, String> parseNetworkExtra(String extraSting) {
+        if (extraSting == null || !extraSting.startsWith("\"") || !extraSting.endsWith("\"")) {
             return null;
         }
         try {
-            final String encoded = wrapped.substring(1, wrapped.length() - 1);
+            final String encoded = extraSting.substring(1, extraSting.length() - 1);
             // This method reads a JSON dictionary that was written by setNetworkExtra(). However,
             // on devices that upgraded from Marshmallow, it may encounter a legacy value instead -
             // an FQDN stored as a plain string. If such a value is encountered, the JSONObject
@@ -882,7 +873,7 @@
      * some of the low-level scan parameters used by the driver are changed to
      * reduce interference with A2DP streaming.
      *
-     * @param isSet whether to enable or disable this mode
+     * @param setCoexScanMode whether to enable or disable this mode
      * @return {@code true} if the command succeeded, {@code false} otherwise.
      */
     public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
@@ -1557,6 +1548,7 @@
     private static native void waitForHalEventNative();
 
     private static class MonitorThread extends Thread {
+        @Override
         public void run() {
             Log.i(TAG, "Waiting for HAL events mWifiHalHandle=" + Long.toString(sWifiHalHandle));
             waitForHalEventNative();
diff --git a/service/java/com/android/server/wifi/WifiNetworkHistory.java b/service/java/com/android/server/wifi/WifiNetworkHistory.java
index edbc516..06081f5 100644
--- a/service/java/com/android/server/wifi/WifiNetworkHistory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkHistory.java
@@ -633,7 +633,10 @@
         if (config == null || scanDetailCaches == null) return null;
         ScanDetailCache cache = scanDetailCaches.get(config.networkId);
         if (cache == null && config.networkId != WifiConfiguration.INVALID_NETWORK_ID) {
-            cache = new ScanDetailCache(config);
+            cache =
+                    new ScanDetailCache(
+                            config, WifiConfigManager.MAX_NUM_SCAN_CACHE_ENTRIES + 64,
+                            WifiConfigManager.MAX_NUM_SCAN_CACHE_ENTRIES);
             scanDetailCaches.put(config.networkId, cache);
         }
         return cache;
diff --git a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java
index ff8b7f6..1dba35f 100644
--- a/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java
+++ b/service/java/com/android/server/wifi/WifiQualifiedNetworkSelector.java
@@ -45,7 +45,7 @@
 
 /**
  * This class looks at all the connectivity scan results then
- * select an network for the phone to connect/roam to.
+ * selects a network for the phone to connect or roam to.
  */
 public class WifiQualifiedNetworkSelector {
     private WifiConfigManager mWifiConfigManager;
@@ -59,42 +59,44 @@
     private boolean mDbg = FORCE_DEBUG;
     private WifiConfiguration mCurrentConnectedNetwork = null;
     private String mCurrentBssid = null;
-    //buffer most recent scan results
-    private List<ScanDetail> mScanDetails = null;
-    //buffer of filtered scan results (Scan results considered by network selection) & associated
-    //WifiConfiguration (if any)
+
+    // Buffer of filtered scan results (Scan results considered by network selection) & associated
+    // WifiConfiguration (if any).
     private volatile List<Pair<ScanDetail, WifiConfiguration>> mFilteredScanDetails = null;
 
-    //Minimum time gap between last successful Qualified Network Selection and new selection attempt
-    //usable only when current state is connected state   default 10 s
-    private static final int MINIMUM_QUALIFIED_NETWORK_SELECTION_INTERVAL = 10 * 1000;
+    // Minimum time gap between last successful Qualified Network Selection and a new selection
+    // attempt.
+    private static final int MINIMUM_QUALIFIED_NETWORK_SELECTION_INTERVAL_MS = 10 * 1000;
 
-    //if current network is on 2.4GHz band and has a RSSI over this, need not new network selection
+    // A 2.4GHz network with RSSI value above this threshold is considered qualified. No new
+    // selection attempt necessary.
     public static final int QUALIFIED_RSSI_24G_BAND = -73;
-    //if current network is on 5GHz band and has a RSSI over this, need not new network selection
+    // A 5GHz network with RSSI value above this threshold is considered qualified. No new
+    // selection attempt necessary.
     public static final int QUALIFIED_RSSI_5G_BAND = -70;
-    //any RSSI larger than this will benefit the traffic very limited
+    // A RSSI vaule larger than this threshold is considered saturated and switching to a
+    // higher RSSI value network won't benefit the connection much.
     public static final int RSSI_SATURATION_2G_BAND = -60;
     public static final int RSSI_SATURATION_5G_BAND = -57;
-    //Any value below this will be considered not usable
+    // Any RSSI value below this is considered unacceptable, and the network will be filtered out.
     public static final int MINIMUM_2G_ACCEPT_RSSI = -85;
     public static final int MINIMUM_5G_ACCEPT_RSSI = -82;
 
+    // Constants for BSSID scoring formula.
     public static final int RSSI_SCORE_SLOPE = 4;
     public static final int RSSI_SCORE_OFFSET = 85;
-
     public static final int BAND_AWARD_5GHz = 40;
     public static final int SAME_NETWORK_AWARD = 16;
-
     public static final int SAME_BSSID_AWARD = 24;
     public static final int LAST_SELECTION_AWARD = 480;
     public static final int PASSPOINT_SECURITY_AWARD = 40;
     public static final int SECURITY_AWARD = 80;
+
+    // BSSID blacklist parameters.
     public static final int BSSID_BLACKLIST_THRESHOLD = 3;
-    public static final int BSSID_BLACKLIST_EXPIRE_TIME = 5 * 60 * 1000;
+    public static final int BSSID_BLACKLIST_EXPIRE_TIME_MS = 5 * 60 * 1000;
+
     private final int mNoIntnetPenalty;
-    //TODO: check whether we still need this one when we update the scan manager
-    public static final int SCAN_RESULT_MAXIMUNM_AGE = 40000;
     private static final int INVALID_TIME_STAMP = -1;
     private long mLastQualifiedNetworkSelectionTimeStamp = INVALID_TIME_STAMP;
 
@@ -110,10 +112,11 @@
             new HashMap<String, BssidBlacklistStatus>();
 
     /**
-     * class save the blacklist status of a given BSSID
+     * Class that saves the blacklist status of a given BSSID.
      */
     private static class BssidBlacklistStatus {
-        //how many times it is requested to be blacklisted (association rejection trigger this)
+        // Number of times this BSSID has been requested to be blacklisted.
+        // Association rejection triggers such a request.
         int mCounter;
         boolean mIsBlacklisted;
         long mBlacklistedTimeStamp = INVALID_TIME_STAMP;
@@ -152,7 +155,7 @@
     }
 
     /**
-     * set the user selected preferred band
+     * Set the user preferred band.
      *
      * @param band preferred band user selected
      */
@@ -171,8 +174,7 @@
             mNetworkScoreCache = new WifiNetworkScoreCache(context);
             mScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
         } else {
-            localLoge("No network score service: Couldn't register as a WiFi score Manager, type="
-                    + NetworkKey.TYPE_WIFI + " service= " + Context.NETWORK_SCORE_SERVICE);
+            localLoge("Couldn't get NETWORK_SCORE_SERVICE.");
             mNetworkScoreCache = null;
         }
 
@@ -207,50 +209,58 @@
     }
 
     /**
-     * check whether current network is good enough we need not consider any potential switch
+     * Check if the current connected network is already qualified so that network
+     * selection from the new scan results is not necessary.
      *
      * @param currentNetwork -- current connected network
-     * @return true -- qualified and do not consider potential network switch
-     *         false -- not good enough and should try potential network switch
      */
-    private boolean isNetworkQualified(WifiConfiguration currentNetwork) {
-
+    private boolean isCurrentNetworkQualified(WifiConfiguration currentNetwork) {
         if (currentNetwork == null) {
-            localLog("Disconnected");
+            localLog("No current connected network");
             return false;
         } else {
-            localLog("Current network is: " + currentNetwork.SSID + " ,ID is: "
-                    + currentNetwork.networkId);
+            localLog("Current connected network: " + currentNetwork.SSID
+                    + " , ID: " + currentNetwork.networkId);
         }
 
-        //if current connected network is an ephemeral network,we will consider
-        // there is no current network
+        // Ephemeral networks are not qualified.
         if (currentNetwork.ephemeral) {
-            localLog("Current is ephemeral. Start reselect");
+            localLog("Current network is an ephemeral one");
             return false;
         }
 
-        //if current network is open network, not qualified
+        // Open networks are not qualified.
         if (mWifiConfigManager.isOpenNetwork(currentNetwork)) {
-            localLog("Current network is open network");
+            localLog("Current network is a open one");
             return false;
         }
 
-        // Current network band must match with user preference selection
-        if (mWifiInfo.is24GHz() && (mUserPreferedBand != WifiManager.WIFI_FREQUENCY_BAND_2GHZ)) {
-            localLog("Current band dose not match user preference. Start Qualified Network"
-                    + " Selection Current band = " + (mWifiInfo.is24GHz() ? "2.4GHz band"
-                    : "5GHz band") + "UserPreference band = " + mUserPreferedBand);
+        // Does the current network band match the user preference?
+        //
+        // Note, here the check for 2.4GHz band is different from the one for 5GHz band
+        // such that 5GHz band is always favored.
+        // When the current network is 2.4GHz, it is considered as not qualified as long
+        // as the band preference set by user is not 2.4GHz only. This gives QNS an
+        // opportunity to recommend a 5GHz network if one is available.
+        // When the current network is 5GHz, it's considered as not qualified only if
+        // the band preference set by user is 2.4GHz only.
+        if ((mWifiInfo.is24GHz() && (mUserPreferedBand != WifiManager.WIFI_FREQUENCY_BAND_2GHZ))
+                || (mWifiInfo.is5GHz()
+                     && (mUserPreferedBand == WifiManager.WIFI_FREQUENCY_BAND_2GHZ))) {
+            localLog("Current network band does not match user preference: "
+                    + "current network band=" + (mWifiInfo.is24GHz() ? "2.4GHz" : "5GHz")
+                    + ", however user preferred band=" + mUserPreferedBand);
             return false;
         }
 
+        // Is the current network's singnal strength qualified?
         int currentRssi = mWifiInfo.getRssi();
         if ((mWifiInfo.is24GHz()
                         && currentRssi < mWifiConfigManager.mThresholdQualifiedRssi24.get())
                 || (mWifiInfo.is5GHz()
                         && currentRssi < mWifiConfigManager.mThresholdQualifiedRssi5.get())) {
-            localLog("Current band = " + (mWifiInfo.is24GHz() ? "2.4GHz band" : "5GHz band")
-                    + "current RSSI is: " + currentRssi);
+            localLog("Current network band=" + (mWifiInfo.is24GHz() ? "2.4GHz" : "5GHz")
+                    + ", RSSI[" + currentRssi + "]-acceptable but not qualified");
             return false;
         }
 
@@ -258,7 +268,7 @@
     }
 
     /**
-     * check whether QualifiedNetworkSelection is needed or not
+     * Check whether QualifiedNetworkSelection is needed.
      *
      * @param isLinkDebouncing true -- Link layer is under debouncing
      *                         false -- Link layer is not under debouncing
@@ -268,37 +278,31 @@
      *                       false -- WifiStateMachine is not at disconnected state
      * @param isSupplicantTransientState true -- supplicant is in a transient state now
      *                                   false -- supplicant is not in a transient state now
-     * @return true -- need a Qualified Network Selection procedure
-     *         false -- do not need a QualifiedNetworkSelection procedure
      */
     private boolean needQualifiedNetworkSelection(boolean isLinkDebouncing, boolean isConnected,
             boolean isDisconnected, boolean isSupplicantTransientState) {
-        if (mScanDetails.size() == 0) {
-            localLog("empty scan result");
-            return false;
-        }
-
-        // Do not trigger Qualified Network Selection during L2 link debouncing procedure
+        // No Qualified Network Selection during the L2 link debouncing procedure.
         if (isLinkDebouncing) {
-            localLog("Need not Qualified Network Selection during L2 debouncing");
+            localLog("No QNS during L2 debouncing");
             return false;
         }
 
         if (isConnected) {
-            //already connected. Just try to find better candidate
-            //if switch network is not allowed in connected mode, do not trigger Qualified Network
-            //Selection
+            // Already connected. Looking for a better candidate.
+
+            // Is network switching allowed in connected state?
             if (!mWifiConfigManager.getEnableAutoJoinWhenAssociated()) {
-                localLog("Switch network under connection is not allowed");
+                localLog("Switching networks in connected state is not allowed");
                 return false;
             }
 
-            //Do not select again if last selection is within
-            //MINIMUM_QUALIFIED_NETWORK_SELECTION_INTERVAL
+            // Do not select again if last selection is within
+            // MINIMUM_QUALIFIED_NETWORK_SELECTION_INTERVAL_MS.
             if (mLastQualifiedNetworkSelectionTimeStamp != INVALID_TIME_STAMP) {
-                long gap = mClock.elapsedRealtime() - mLastQualifiedNetworkSelectionTimeStamp;
-                if (gap < MINIMUM_QUALIFIED_NETWORK_SELECTION_INTERVAL) {
-                    localLog("Too short to last successful Qualified Network Selection Gap is:"
+                long gap = mClock.getElapsedSinceBootMillis()
+                            - mLastQualifiedNetworkSelectionTimeStamp;
+                if (gap < MINIMUM_QUALIFIED_NETWORK_SELECTION_INTERVAL_MS) {
+                    localLog("Too short from last successful Qualified Network Selection. Gap is:"
                             + gap + " ms!");
                     return false;
                 }
@@ -308,14 +312,15 @@
                     mWifiConfigManager.getWifiConfiguration(mWifiInfo.getNetworkId());
             if (currentNetwork == null) {
                 // WifiStateMachine in connected state but WifiInfo is not. It means there is a race
-                // condition happened. Do not make QNS until WifiStateMachine goes into
-                // disconnected state
+                // condition. Defer QNS until WifiStateMachine enters the disconnected state.
+                //
+                // TODO(b/28249371): Root cause this race condition.
                 return false;
             }
 
-            if (!isNetworkQualified(mCurrentConnectedNetwork)) {
-                //need not trigger Qualified Network Selection if current network is qualified
-                localLog("Current network is not qualified");
+            // Already connected to a qualified network?
+            if (!isCurrentNetworkQualified(mCurrentConnectedNetwork)) {
+                localLog("Current connected network is not qualified");
                 return true;
             } else {
                 return false;
@@ -323,12 +328,13 @@
         } else if (isDisconnected) {
             mCurrentConnectedNetwork = null;
             mCurrentBssid = null;
-            //Do not start Qualified Network Selection if current state is a transient state
+            // Defer Qualified Network Selection if wpa_supplicant is in the transient state.
             if (isSupplicantTransientState) {
                 return false;
             }
         } else {
-            //Do not allow new network selection in other state
+            // Do not allow new network selection if WifiStateMachine is in a state
+            // other than connected or disconnected.
             localLog("WifiStateMachine is not on connected or disconnected state");
             return false;
         }
@@ -341,68 +347,67 @@
             StringBuffer sbuf) {
 
         int score = 0;
-        //calculate the RSSI score
+        // Calculate the RSSI score.
         int rssi = scanResult.level <= mWifiConfigManager.mThresholdSaturatedRssi24.get()
                 ? scanResult.level : mWifiConfigManager.mThresholdSaturatedRssi24.get();
         score += (rssi + mRssiScoreOffset) * mRssiScoreSlope;
-        sbuf.append(" RSSI score: " +  score);
+        sbuf.append("RSSI score: ").append(score);
+
+        // 5GHz band bonus.
         if (scanResult.is5GHz()) {
-            //5GHz band
             score += mWifiConfigManager.mBandAward5Ghz.get();
-            sbuf.append(" 5GHz bonus: " + mWifiConfigManager.mBandAward5Ghz.get());
+            sbuf.append(" 5GHz bonus: ").append(mWifiConfigManager.mBandAward5Ghz.get());
         }
 
-        //last user selection award
+        // Last user selection award.
         if (sameSelect) {
-            long timeDifference = mClock.elapsedRealtime()
+            long timeDifference = mClock.getElapsedSinceBootMillis()
                     - mWifiConfigManager.getLastSelectedTimeStamp();
 
             if (timeDifference > 0) {
                 int bonus = mLastSelectionAward - (int) (timeDifference / 1000 / 60);
                 score += bonus > 0 ? bonus : 0;
-                sbuf.append(" User selected it last time " + (timeDifference / 1000 / 60)
-                        + " minutes ago, bonus:" + bonus);
+                sbuf.append(" User selected it last time ").append(timeDifference / 1000 / 60)
+                        .append(" minutes ago, bonus: ").append(bonus);
             }
         }
 
-        //same network award
+        // Same network award.
         if (network == currentNetwork || network.isLinked(currentNetwork)) {
             score += mWifiConfigManager.mCurrentNetworkBoost.get();
-            sbuf.append(" Same network with current associated. Bonus: "
-                    + mWifiConfigManager.mCurrentNetworkBoost.get());
+            sbuf.append(" Same network as the current one, bonus: ")
+                    .append(mWifiConfigManager.mCurrentNetworkBoost.get());
         }
 
-        //same BSSID award
+        // Same BSSID award.
         if (sameBssid) {
             score += mSameBssidAward;
-            sbuf.append(" Same BSSID with current association. Bonus: " + mSameBssidAward);
+            sbuf.append(" Same BSSID as the current one, bonus: ").append(mSameBssidAward);
         }
 
-        //security award
+        // Security award.
         if (network.isPasspoint()) {
             score += mPasspointSecurityAward;
-            sbuf.append(" Passpoint Bonus:" + mPasspointSecurityAward);
+            sbuf.append(" Passpoint bonus: ").append(mPasspointSecurityAward);
         } else if (!mWifiConfigManager.isOpenNetwork(network)) {
             score += mSecurityAward;
-            sbuf.append(" Secure network Bonus:" + mSecurityAward);
+            sbuf.append(" Secure network bonus: ").append(mSecurityAward);
         }
 
-        //Penalty for no internet network. Make sure if there is any network with Internet,
-        //however, if there is no any other network with internet, this network can be chosen
+        // No internet penalty.
         if (network.numNoInternetAccessReports > 0 && !network.validatedInternetAccess) {
             score -= mNoIntnetPenalty;
-            sbuf.append(" No internet Penalty:-" + mNoIntnetPenalty);
+            sbuf.append(" No internet penalty: -").append(mNoIntnetPenalty);
         }
 
-
-        sbuf.append(" Score for scanResult: " + scanResult +  " and Network ID: "
-                + network.networkId + " final score:" + score + "\n\n");
+        sbuf.append("    -- ScanResult: ").append(scanResult).append(" for network: ")
+                .append(network.networkId).append(" score: ").append(score).append(" --\n");
 
         return score;
     }
 
     /**
-     * This API try to update all the saved networks' network selection status
+     * Update all the saved networks' selection status
      */
     private void updateSavedNetworkSelectionStatus() {
         List<WifiConfiguration> savedNetworks = mWifiConfigManager.getSavedNetworks();
@@ -411,62 +416,65 @@
             return;
         }
 
-        StringBuffer sbuf = new StringBuffer("Saved Network List\n");
+        StringBuffer sbuf = new StringBuffer("Saved Network List: \n");
         for (WifiConfiguration network : savedNetworks) {
             WifiConfiguration config = mWifiConfigManager.getWifiConfiguration(network.networkId);
             WifiConfiguration.NetworkSelectionStatus status =
                     config.getNetworkSelectionStatus();
 
-            //If the configuration is temporarily disabled, try to re-enable it
+            // If a configuration is temporarily disabled, re-enable it before trying
+            // to connect to it.
             if (status.isNetworkTemporaryDisabled()) {
                 mWifiConfigManager.tryEnableQualifiedNetwork(network.networkId);
             }
 
-            //clean the cached candidate, score and seen
+            // Clear the cached candidate, score and seen.
             status.setCandidate(null);
             status.setCandidateScore(Integer.MIN_VALUE);
             status.setSeenInLastQualifiedNetworkSelection(false);
 
-            //print the debug messages
-            sbuf.append("    " + getNetworkString(network) + " " + " User Preferred BSSID:"
-                    + network.BSSID + " FQDN:" + network.FQDN + " "
-                    + status.getNetworkStatusString() + " Disable account: ");
-            for (int index = status.NETWORK_SELECTION_ENABLE;
-                    index < status.NETWORK_SELECTION_DISABLED_MAX; index++) {
-                sbuf.append(status.getDisableReasonCounter(index) + " ");
+            sbuf.append(" ").append(getNetworkString(network)).append(" ")
+                    .append(" User Preferred BSSID: ").append(network.BSSID)
+                    .append(" FQDN: ").append(network.FQDN).append(" ")
+                    .append(status.getNetworkStatusString()).append(" Disable account: ");
+            for (int index = WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE;
+                    index < WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX;
+                    index++) {
+                sbuf.append(status.getDisableReasonCounter(index)).append(" ");
             }
-            sbuf.append("Connect Choice:" + status.getConnectChoice() + " set time:"
-                    + status.getConnectChoiceTimestamp());
-            sbuf.append("\n");
+            sbuf.append("Connect Choice: ").append(status.getConnectChoice())
+                .append(" set time: ").append(status.getConnectChoiceTimestamp())
+                .append("\n");
         }
         localLog(sbuf.toString());
     }
 
     /**
-     * This API is called when user explicitly select a network. Currently, it is used in following
+     * This API is called when user explicitly selects a network. Currently, it is used in following
      * cases:
-     * (1) User explicitly choose to connect to a saved network
-     * (2) User save a network after add a new network
-     * (3) User save a network after modify a saved network
+     * (1) User explicitly chooses to connect to a saved network.
+     * (2) User saves a network after adding a new network.
+     * (3) User saves a network after modifying a saved network.
      * Following actions will be triggered:
-     * 1. if this network is disabled, we need re-enable it again
-     * 2. we considered user prefer this network over all the networks visible in latest network
-     *    selection procedure
+     * 1. If this network is disabled, we need re-enable it again.
+     * 2. This network is favored over all the other networks visible in latest network
+     *    selection procedure.
      *
-     * @param netId new network ID for either the network the user choose or add
-     * @param persist whether user has the authority to overwrite current connect choice
-     * @return true -- There is change made to connection choice of any saved network
-     *         false -- There is no change made to connection choice of any saved network
+     * @param netId  ID for the network chosen by the user
+     * @param persist  whether user has the authority to overwrite current connect choice
+     * @return true -- There is change made to connection choice of any saved network.
+     *         false -- There is no change made to connection choice of any saved network.
      */
     public boolean userSelectNetwork(int netId, boolean persist) {
+        localLog("userSelectNetwork: network ID=" + netId + " persist=" + persist);
+
         WifiConfiguration selected = mWifiConfigManager.getWifiConfiguration(netId);
-        localLog("userSelectNetwork:" + netId + " persist:" + persist);
         if (selected == null || selected.SSID == null) {
-            localLoge("userSelectNetwork: Bad configuration with nid=" + netId);
+            localLoge("userSelectNetwork: Invalid configuration with nid=" + netId);
             return false;
         }
 
-
+        // Enable the network if it is disabled.
         if (!selected.getNetworkSelectionStatus().isNetworkEnabled()) {
             mWifiConfigManager.updateNetworkSelectionStatus(netId,
                     WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
@@ -480,7 +488,7 @@
         boolean change = false;
         String key = selected.configKey();
         // This is only used for setting the connect choice timestamp for debugging purposes.
-        long currentTime = mClock.currentTimeMillis();
+        long currentTime = mClock.getWallClockMillis();
         List<WifiConfiguration> savedNetworks = mWifiConfigManager.getSavedNetworks();
 
         for (WifiConfiguration network : savedNetworks) {
@@ -502,14 +510,15 @@
             if (status.getSeenInLastQualifiedNetworkSelection()
                     && (status.getConnectChoice() == null
                     || !status.getConnectChoice().equals(key))) {
-                localLog("Add key:" + key + " Set Time: " + currentTime + " to "
+                localLog("Add key: " + key + " Set Time: " + currentTime + " to "
                         + getNetworkString(config));
                 status.setConnectChoice(key);
                 status.setConnectChoiceTimestamp(currentTime);
                 change = true;
             }
         }
-        //Write this change to file
+
+        // Persist changes.
         if (change) {
             mWifiConfigManager.writeKnownNetworkHistory();
             return true;
@@ -519,7 +528,7 @@
     }
 
     /**
-     * enable/disable a BSSID for Quality Network Selection
+     * Enable/disable a BSSID for Quality Network Selection
      * When an association rejection event is obtained, Quality Network Selector will disable this
      * BSSID but supplicant still can try to connect to this bssid. If supplicant connect to it
      * successfully later, this bssid can be re-enabled.
@@ -535,7 +544,7 @@
             if (bssid != null) {
                 BssidBlacklistStatus status = mBssidBlacklist.get(bssid);
                 if (status == null) {
-                    //first time
+                    // First time for this BSSID
                     BssidBlacklistStatus newStatus = new BssidBlacklistStatus();
                     newStatus.mCounter++;
                     mBssidBlacklist.put(bssid, newStatus);
@@ -543,7 +552,7 @@
                     status.mCounter++;
                     if (status.mCounter >= BSSID_BLACKLIST_THRESHOLD) {
                         status.mIsBlacklisted = true;
-                        status.mBlacklistedTimeStamp = mClock.elapsedRealtime();
+                        status.mBlacklistedTimeStamp = mClock.getElapsedSinceBootMillis();
                         return true;
                     }
                 }
@@ -553,18 +562,18 @@
     }
 
     /**
-     * update the buffered BSSID blacklist
+     * Update the buffered BSSID blacklist
      *
      * Go through the whole buffered BSSIDs blacklist and check when the BSSIDs is blocked. If they
-     * were blacked before BSSID_BLACKLIST_EXPIRE_TIME, re-enable it again.
+     * have been blacklisted for BSSID_BLACKLIST_EXPIRE_TIME_MS, re-enable them.
      */
     private void updateBssidBlacklist() {
         Iterator<BssidBlacklistStatus> iter = mBssidBlacklist.values().iterator();
         while (iter.hasNext()) {
             BssidBlacklistStatus status = iter.next();
             if (status != null && status.mIsBlacklisted) {
-                if (mClock.elapsedRealtime() - status.mBlacklistedTimeStamp
-                            >= BSSID_BLACKLIST_EXPIRE_TIME) {
+                if (mClock.getElapsedSinceBootMillis() - status.mBlacklistedTimeStamp
+                            >= BSSID_BLACKLIST_EXPIRE_TIME_MS) {
                     iter.remove();
                 }
             }
@@ -574,8 +583,6 @@
     /**
      * Check whether a bssid is disabled
      * @param bssid -- the bssid to check
-     * @return true -- bssid is disabled
-     *         false -- bssid is not disabled
      */
     public boolean isBssidDisabled(String bssid) {
         BssidBlacklistStatus status = mBssidBlacklist.get(bssid);
@@ -583,35 +590,36 @@
     }
 
     /**
-     * ToDo: This should be called in Connectivity Manager when it gets new scan result
-     * check whether a network slection is needed. If need, check all the new scan results and
-     * select a new qualified network/BSSID to connect to
+     * Select the best network candidate from the new scan results for WifiConnectivityManager
+     * to connect/roam to.
      *
-     * @param forceSelectNetwork true -- start a qualified network selection anyway,no matter
-     *                           current network is already qualified or not.
-     *                           false -- if current network is already qualified, do not do new
-     *                           selection
-     * @param isUntrustedConnectionsAllowed true -- user allow to connect to untrusted network
-     *                                      false -- user do not allow to connect to untrusted
-     *                                      network
-     * @param scanDetails latest scan result obtained (should be connectivity scan only)
-     * @param isLinkDebouncing true -- Link layer is under debouncing
-     *                         false -- Link layer is not under debouncing
-     * @param isConnected true -- device is connected to an AP currently
-     *                    false -- device is not connected to an AP currently
-     * @param isDisconnected true -- WifiStateMachine is at disconnected state
-     *                       false -- WifiStateMachine is not at disconnected state
-     * @param isSupplicantTransient true -- supplicant is in a transient state
-     *                              false -- supplicant is not in a transient state
-     * @return the qualified network candidate found. If no available candidate, return null
+     * @param forceSelectNetwork true -- start a qualified network selection anyway, no matter
+     *                                   the current network is already qualified or not.
+     *                           false -- if current network is already qualified, stay connected
+     *                                    to it.
+     * @param isUntrustedConnectionsAllowed connection to untrusted networks is allowed or not
+     * @param isLinkDebouncing Link layer is under debouncing or not
+     * @param isConnected WifiStateMachine is in the Connected state or not
+     * @param isDisconnected WifiStateMachine is in the Disconnected state or not
+     * @param isSupplicantTransient wpa_supplicant is in a transient state or not
+     * @param scanDetails new connectivity scan results
+     * @return Best network candidate identified. Null if no candidate available or we should
+     *         stay connected to the current network.
      */
-    public WifiConfiguration selectQualifiedNetwork(boolean forceSelectNetwork ,
-            boolean isUntrustedConnectionsAllowed, List<ScanDetail>  scanDetails,
-            boolean isLinkDebouncing, boolean isConnected, boolean isDisconnected,
-            boolean isSupplicantTransient) {
+    public WifiConfiguration selectQualifiedNetwork(boolean forceSelectNetwork,
+            boolean isUntrustedConnectionsAllowed, boolean isLinkDebouncing,
+            boolean isConnected, boolean isDisconnected, boolean isSupplicantTransient,
+            List<ScanDetail>  scanDetails) {
         localLog("==========start qualified Network Selection==========");
-        mScanDetails = scanDetails;
-        List<Pair<ScanDetail, WifiConfiguration>>  filteredScanDetails = new ArrayList<>();
+
+        List<Pair<ScanDetail, WifiConfiguration>> filteredScanDetails = new ArrayList<>();
+
+        if (scanDetails.size() == 0) {
+            localLog("Empty connectivity scan result");
+            mFilteredScanDetails = filteredScanDetails;
+            return null;
+        }
+
         if (mCurrentConnectedNetwork == null) {
             mCurrentConnectedNetwork =
                     mWifiConfigManager.getWifiConfiguration(mWifiInfo.getNetworkId());
@@ -623,8 +631,7 @@
 
         if (!forceSelectNetwork && !needQualifiedNetworkSelection(isLinkDebouncing, isConnected,
                 isDisconnected, isSupplicantTransient)) {
-            localLog("Quit qualified Network Selection since it is not forced and current network"
-                    + " is qualified already");
+            localLog("Stay connected to the current qualified network");
             mFilteredScanDetails = filteredScanDetails;
             return null;
         }
@@ -639,8 +646,8 @@
                 mWifiConfigManager.getWifiConfiguration(lastUserSelectedNetWorkKey);
         if (lastUserSelectedNetwork != null) {
             localLog("Last selection is " + lastUserSelectedNetwork.SSID + " Time to now: "
-                    + ((mClock.elapsedRealtime() - mWifiConfigManager.getLastSelectedTimeStamp())
-                            / 1000 / 60 + " minutes"));
+                    + ((mClock.getElapsedSinceBootMillis()
+                    - mWifiConfigManager.getLastSelectedTimeStamp()) / 1000 / 60 + " minutes"));
         }
 
         updateSavedNetworkSelectionStatus();
@@ -649,51 +656,65 @@
         StringBuffer lowSignalScan = new StringBuffer();
         StringBuffer notSavedScan = new StringBuffer();
         StringBuffer noValidSsid = new StringBuffer();
+        StringBuffer unwantedBand = new StringBuffer();
         StringBuffer scoreHistory =  new StringBuffer();
         ArrayList<NetworkKey> unscoredNetworks = new ArrayList<NetworkKey>();
 
-        //iterate all scan results and find the best candidate with the highest score
-        for (ScanDetail scanDetail : mScanDetails) {
+        // Iterate over all scan results to find the best candidate.
+        for (ScanDetail scanDetail : scanDetails) {
             ScanResult scanResult = scanDetail.getScanResult();
-            //skip bad scan result
+            // Skip bad scan result.
             if (scanResult.SSID == null || TextUtils.isEmpty(scanResult.SSID)) {
                 if (mDbg) {
-                    //We should not see this in ePNO
-                    noValidSsid.append(scanResult.BSSID + " / ");
+                    noValidSsid.append(scanResult.BSSID).append(" / ");
                 }
                 continue;
             }
 
             final String scanId = toScanId(scanResult);
-            //check whether this BSSID is blocked or not
+            // Skip blacklisted BSSID.
             if (mWifiConfigManager.isBssidBlacklisted(scanResult.BSSID)
                     || isBssidDisabled(scanResult.BSSID)) {
-                //We should not see this in ePNO
-                Log.e(TAG, scanId + " is in blacklist.");
+                Log.i(TAG, scanId + " is in the blacklist.");
                 continue;
             }
 
-            //skip scan result with too weak signals
+            // Skip network with too weak signals.
             if ((scanResult.is24GHz() && scanResult.level
                     < mWifiConfigManager.mThresholdMinimumRssi24.get())
                     || (scanResult.is5GHz() && scanResult.level
                     < mWifiConfigManager.mThresholdMinimumRssi5.get())) {
                 if (mDbg) {
-                    lowSignalScan.append(scanId + "(" + (scanResult.is24GHz() ? "2.4GHz" : "5GHz")
-                            + ")" + scanResult.level + " / ");
+                    lowSignalScan.append(scanId).append("(")
+                        .append(scanResult.is24GHz() ? "2.4GHz" : "5GHz")
+                        .append(")").append(scanResult.level).append(" / ");
                 }
                 continue;
             }
 
-            //check if there is already a score for this network
+            // Skip network not matching band preference set by user.
+            // WifiConnectivityManager schedules scan according to the user band prefrence. This is
+            // a check for the ScanResults generated from the old settings.
+            if ((scanResult.is24GHz()
+                    && (mUserPreferedBand == WifiManager.WIFI_FREQUENCY_BAND_5GHZ))
+                    || (scanResult.is5GHz()
+                        && (mUserPreferedBand == WifiManager.WIFI_FREQUENCY_BAND_2GHZ))) {
+                if (mDbg) {
+                    unwantedBand.append(scanId).append("(")
+                        .append(scanResult.is24GHz() ? "2.4GHz" : "5GHz")
+                        .append(")").append(" / ");
+                }
+                continue;
+            }
+
+            // Is there a score for this network? If not, request a score.
             if (mNetworkScoreCache != null && !mNetworkScoreCache.isScoredNetwork(scanResult)) {
-                //no score for this network yet.
                 WifiKey wifiKey;
 
                 try {
                     wifiKey = new WifiKey("\"" + scanResult.SSID + "\"", scanResult.BSSID);
                     NetworkKey ntwkKey = new NetworkKey(wifiKey);
-                    //add to the unscoredNetworks list so we can request score later
+                    // Add to the unscoredNetworks list so we can request score later
                     unscoredNetworks.add(ntwkKey);
                 } catch (IllegalArgumentException e) {
                     Log.w(TAG, "Invalid SSID=" + scanResult.SSID + " BSSID=" + scanResult.BSSID
@@ -701,7 +722,7 @@
                 }
             }
 
-            //check whether this scan result belong to a saved network
+            // Is this scan result from an ephemeral network?
             boolean potentiallyEphemeral = false;
             // Stores WifiConfiguration of potential connection candidates for scan result filtering
             WifiConfiguration potentialEphemeralCandidate = null;
@@ -711,10 +732,10 @@
             if (associatedWifiConfigurations == null) {
                 potentiallyEphemeral =  true;
                 if (mDbg) {
-                    notSavedScan.append(scanId + " / ");
+                    notSavedScan.append(scanId).append(" / ");
                 }
             } else if (associatedWifiConfigurations.size() == 1) {
-                //if there are more than 1 associated network, it must be a passpoint network
+                // If there is more than one associated network, it must be a passpoint network.
                 WifiConfiguration network = associatedWifiConfigurations.get(0);
                 if (network.ephemeral) {
                     potentialEphemeralCandidate = network;
@@ -728,7 +749,7 @@
                 if (isUntrustedConnectionsAllowed) {
                     Integer netScore = getNetworkScore(scanResult, false);
                     if (netScore != null
-                        && !mWifiConfigManager.wasEphemeralNetworkDeleted(scanResult.SSID)) {
+                            && !mWifiConfigManager.wasEphemeralNetworkDeleted(scanResult.SSID)) {
                         externalScoreEvaluator.evalUntrustedCandidate(netScore, scanResult);
                         // scanDetail is for available ephemeral network
                         filteredScanDetails.add(Pair.create(scanDetail,
@@ -738,9 +759,9 @@
                 continue;
             }
 
-            // calculate the score of each scanresult whose associated network is not ephemeral. Due
-            // to one scan result can associated with more than 1 network, we need calculate all
-            // the scores and use the highest one as the scanresults score.
+            // Calculate the score of each ScanResult whose associated network is not ephemeral.
+            // One ScanResult can associated with more than one network, hence we calculate all
+            // the scores and use the highest one as the ScanResult's score
             int highestScore = Integer.MIN_VALUE;
             int score;
             WifiConfiguration configurationCandidateForThisScan = null;
@@ -756,9 +777,9 @@
                     continue;
                 } else if (network.BSSID != null && !network.BSSID.equals("any")
                         && !network.BSSID.equals(scanResult.BSSID)) {
-                    //in such scenario, user (APP) has specified the only BSSID to connect for this
-                    // configuration. So only the matched scan result can be candidate
-                    localLog("Network: " + getNetworkString(network) + " has specified" + "BSSID:"
+                    // App has specified the only BSSID to connect for this
+                    // configuration. So only the matching ScanResult can be a candidate.
+                    localLog("Network " + getNetworkString(network) + " has specified BSSID "
                             + network.BSSID + ". Skip " + scanResult.BSSID);
                     continue;
                 }
@@ -780,13 +801,13 @@
                     configurationCandidateForThisScan = network;
                     potentialCandidate = network;
                 }
-                //update the cached candidate
+                // Update the cached candidate.
                 if (score > status.getCandidateScore()) {
                     status.setCandidate(scanResult);
                     status.setCandidateScore(score);
                 }
             }
-            // Create potential filteredScanDetail entry
+            // Create potential filteredScanDetail entry.
             filteredScanDetails.add(Pair.create(scanDetail, potentialCandidate));
 
             if (highestScore > currentHighestScore || (highestScore == currentHighestScore
@@ -800,7 +821,7 @@
 
         mFilteredScanDetails = filteredScanDetails;
 
-        //kick the score manager if there is any unscored network
+        // Kick the score manager if there is any unscored network.
         if (mScoreManager != null && unscoredNetworks.size() != 0) {
             NetworkKey[] unscoredNetworkKeys =
                     unscoredNetworks.toArray(new NetworkKey[unscoredNetworks.size()]);
@@ -808,13 +829,22 @@
         }
 
         if (mDbg) {
-            localLog(lowSignalScan + " skipped due to low signal\n");
-            localLog(notSavedScan + " skipped due to not saved\n ");
-            localLog(noValidSsid + " skipped due to not valid SSID\n");
+            if (lowSignalScan.length() != 0) {
+                localLog(lowSignalScan + " skipped due to low signal");
+            }
+            if (notSavedScan.length() != 0) {
+                localLog(notSavedScan + " skipped due to not saved");
+            }
+            if (noValidSsid.length() != 0) {
+                localLog(noValidSsid + " skipped due to invalid SSID");
+            }
+            if (unwantedBand.length() != 0) {
+                localLog(unwantedBand + " skipped due to user band preference");
+            }
             localLog(scoreHistory.toString());
         }
 
-        //we need traverse the whole user preference to choose the one user like most now
+        // Traverse the whole user preference to choose the one user likes the most.
         if (scanResultCandidate != null) {
             WifiConfiguration tempConfig = networkCandidate;
 
@@ -830,12 +860,12 @@
                         networkCandidate = tempConfig;
                     }
                 } else {
-                    //we should not come here in theory
+                    // We should not come here in theory.
                     localLoge("Connect choice: " + key + " has no corresponding saved config");
                     break;
                 }
             }
-            localLog("After user choice adjust, the final candidate is:"
+            localLog("After user choice adjustment, the final candidate is:"
                     + getNetworkString(networkCandidate) + " : " + scanResultCandidate.BSSID);
         }
 
@@ -857,27 +887,15 @@
         String currentAssociationId = mCurrentConnectedNetwork == null ? "Disconnected" :
                 getNetworkString(mCurrentConnectedNetwork);
         String targetAssociationId = getNetworkString(networkCandidate);
-        //In passpoint, saved configuration has garbage SSID. We need update it with the SSID of
-        //the scan result.
+        // In passpoint, saved configuration is initialized with a fake SSID. Now update it with
+        // the real SSID from the scan result.
         if (networkCandidate.isPasspoint()) {
-            // This will update the passpoint configuration in WifiConfigManager
             networkCandidate.SSID = "\"" + scanResultCandidate.SSID + "\"";
         }
 
-        //For debug purpose only
-        if (scanResultCandidate.BSSID.equals(mCurrentBssid)) {
-            localLog(currentAssociationId + " is already the best choice!");
-        } else if (mCurrentConnectedNetwork != null
-                && (mCurrentConnectedNetwork.networkId == networkCandidate.networkId
-                || mCurrentConnectedNetwork.isLinked(networkCandidate))) {
-            localLog("Roaming from " + currentAssociationId + " to " + targetAssociationId);
-        } else {
-            localLog("reconnect from " + currentAssociationId + " to " + targetAssociationId);
-        }
-
         mCurrentBssid = scanResultCandidate.BSSID;
         mCurrentConnectedNetwork = networkCandidate;
-        mLastQualifiedNetworkSelectionTimeStamp = mClock.elapsedRealtime();
+        mLastQualifiedNetworkSelectionTimeStamp = mClock.getElapsedSinceBootMillis();
         return networkCandidate;
     }
 
@@ -958,7 +976,7 @@
                                   : String.format("%s:%s", scanResult.SSID, scanResult.BSSID);
     }
 
-    //Dump the logs
+    // Dump the logs.
     void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("Dump of WifiQualifiedNetworkSelector");
         pw.println("WifiQualifiedNetworkSelector - Log Begin ----");
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index 50e28bf..dfdf3cd 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -97,12 +97,8 @@
                                                  WifiConfigManager wifiConfigManager,
                                                  NetworkAgent networkAgent,
                                                  WifiScoreReport lastReport,
-                                                 int aggressiveHandover) {
-        boolean debugLogging = false;
-        if (wifiConfigManager.mEnableVerboseLogging.get() > 0) {
-            debugLogging = true;
-        }
-
+                                                 int aggressiveHandover,
+                                                 boolean verboseLogging) {
         StringBuilder sb = new StringBuilder();
 
         int score = STARTING_SCORE;
@@ -258,7 +254,7 @@
                     currentConfiguration.numTicksAtNotHighRSSI));
         }
 
-        if (debugLogging) {
+        if (verboseLogging) {
             String rssiStatus = "";
             if (isBadRSSI) {
                 rssiStatus += " badRSSI ";
@@ -286,7 +282,7 @@
                 wifiInfo.linkStuckCount += 1;
             }
             sb.append(String.format(" ls+=%d", wifiInfo.linkStuckCount));
-            if (debugLogging) {
+            if (verboseLogging) {
                 Log.d(TAG, " bad link -> stuck count ="
                         + Integer.toString(wifiInfo.linkStuckCount));
             }
@@ -295,7 +291,7 @@
                 wifiInfo.linkStuckCount -= 1;
             }
             sb.append(String.format(" ls-=%d", wifiInfo.linkStuckCount));
-            if (debugLogging) {
+            if (verboseLogging) {
                 Log.d(TAG, " good link -> stuck count ="
                         + Integer.toString(wifiInfo.linkStuckCount));
             }
@@ -311,7 +307,7 @@
 
         if (isBadLinkspeed) {
             score -= BAD_LINKSPEED_PENALTY;
-            if (debugLogging) {
+            if (verboseLogging) {
                 Log.d(TAG, " isBadLinkspeed   ---> count=" + badLinkspeedcount
                         + " score=" + Integer.toString(score));
             }
@@ -338,7 +334,7 @@
         score -= wifiInfo.badRssiCount * BAD_RSSI_COUNT_PENALTY + wifiInfo.lowRssiCount;
         sb.append(String.format(",%d", score));
 
-        if (debugLogging) {
+        if (verboseLogging) {
             Log.d(TAG, " badRSSI count" + Integer.toString(wifiInfo.badRssiCount)
                     + " lowRSSI count" + Integer.toString(wifiInfo.lowRssiCount)
                     + " --> score " + Integer.toString(score));
@@ -346,7 +342,7 @@
 
         if (isHighRSSI) {
             score += 5;
-            if (debugLogging) Log.d(TAG, " isHighRSSI       ---> score=" + Integer.toString(score));
+            if (verboseLogging) Log.d(TAG, " isHighRSSI       ---> score=" + score);
         }
         sb.append(String.format(",%d]", score));
 
@@ -362,7 +358,7 @@
 
         //report score
         if (score != wifiInfo.score) {
-            if (debugLogging) {
+            if (verboseLogging) {
                 Log.d(TAG, "calculateWifiScore() report new score " + Integer.toString(score));
             }
             wifiInfo.score = score;
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index be24e49..cb107f5 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -73,7 +73,6 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.WorkSource;
@@ -82,13 +81,10 @@
 import android.util.Log;
 import android.util.Slog;
 
-import com.android.internal.R;
-import com.android.internal.app.IBatteryStats;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.AsyncChannel;
-import com.android.server.am.BatteryStatsService;
 import com.android.server.wifi.configparse.ConfigBuilder;
 
 import org.xml.sax.SAXException;
@@ -123,19 +119,12 @@
     private static final String TAG = "WifiService";
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
-    private static final String BOOT_DEFAULT_WIFI_COUNTRY_CODE = "ro.boot.wificountrycode";
 
     final WifiStateMachine mWifiStateMachine;
 
     private final Context mContext;
     private final FrameworkFacade mFacade;
 
-    private final List<Multicaster> mMulticasters =
-            new ArrayList<Multicaster>();
-    private int mMulticastEnabled;
-    private int mMulticastDisabled;
-
-    private final IBatteryStats mBatteryStats;
     private final PowerManager mPowerManager;
     private final AppOpsManager mAppOps;
     private final UserManager mUserManager;
@@ -155,6 +144,9 @@
     private final WifiCertManager mCertManager;
 
     private final WifiInjector mWifiInjector;
+    /* Backup/Restore Module */
+    private final WifiBackupRestore mWifiBackupRestore;
+
     /**
      * Asynchronous channel to WifiStateMachine
      */
@@ -254,7 +246,7 @@
         }
 
         private void replyFailed(Message msg, int what, int why) {
-            Message reply = msg.obtain();
+            Message reply = Message.obtain();
             reply.what = what;
             reply.arg1 = why;
             try {
@@ -306,48 +298,38 @@
     }
 
     WifiStateMachineHandler mWifiStateMachineHandler;
-
     private WifiController mWifiController;
     private final WifiLockManager mWifiLockManager;
+    private final WifiMulticastLockManager mWifiMulticastLockManager;
 
     public WifiServiceImpl(Context context) {
         mContext = context;
-        mWifiInjector = WifiInjector.getInstance();
-        mFacade = new FrameworkFacade();
-        HandlerThread wifiThread = new HandlerThread("WifiService");
-        wifiThread.start();
+        mWifiInjector = new WifiInjector(context);
+
+        mFacade = mWifiInjector.getFrameworkFacade();
         mWifiMetrics = mWifiInjector.getWifiMetrics();
-        mTrafficPoller = new WifiTrafficPoller(mContext, wifiThread.getLooper(),
-                WifiNative.getWlanNativeInterface().getInterfaceName());
+        mTrafficPoller = mWifiInjector.getWifiTrafficPoller();
         mUserManager = UserManager.get(mContext);
-        HandlerThread wifiStateMachineThread = new HandlerThread("WifiStateMachine");
-        wifiStateMachineThread.start();
-        mCountryCode = new WifiCountryCode(
-                WifiNative.getWlanNativeInterface(),
-                SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
-                mFacade.getStringSetting(mContext, Settings.Global.WIFI_COUNTRY_CODE),
-                mContext.getResources().getBoolean(
-                        R.bool.config_wifi_revert_country_code_on_cellular_loss));
-        mWifiStateMachine = new WifiStateMachine(mContext, mFacade,
-            wifiStateMachineThread.getLooper(), mUserManager, mWifiInjector,
-            new BackupManagerProxy(), mCountryCode);
-        mSettingsStore = new WifiSettingsStore(mContext);
+        mCountryCode = mWifiInjector.getWifiCountryCode();
+        mWifiStateMachine = mWifiInjector.getWifiStateMachine();
         mWifiStateMachine.enableRssiPolling(true);
-        mBatteryStats = BatteryStatsService.getService();
-        mPowerManager = context.getSystemService(PowerManager.class);
-        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
-        mCertManager = new WifiCertManager(mContext);
+        mSettingsStore = mWifiInjector.getWifiSettingsStore();
+        mPowerManager = mContext.getSystemService(PowerManager.class);
+        mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+        mCertManager = mWifiInjector.getWifiCertManager();
 
-        mNotificationController = new WifiNotificationController(mContext,
-                wifiThread.getLooper(), mWifiStateMachine, mFacade, null);
+        mNotificationController = mWifiInjector.getWifiNotificationController();
 
-        mWifiLockManager = new WifiLockManager(mContext, mBatteryStats);
-        mClientHandler = new ClientHandler(wifiThread.getLooper());
-        mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
-        mWifiController = new WifiController(mContext, mWifiStateMachine,
-                mSettingsStore, mWifiLockManager, wifiThread.getLooper(), mFacade);
-        // Set the WifiController for WifiLastResortWatchdog
-        mWifiInjector.getWifiLastResortWatchdog().setWifiController(mWifiController);
+        mWifiLockManager = mWifiInjector.getWifiLockManager();
+        mWifiMulticastLockManager = mWifiInjector.getWifiMulticastLockManager();
+        HandlerThread wifiServiceHandlerThread = mWifiInjector.getWifiServiceHandlerThread();
+        mClientHandler = new ClientHandler(wifiServiceHandlerThread.getLooper());
+        mWifiStateMachineHandler =
+                new WifiStateMachineHandler(wifiServiceHandlerThread.getLooper());
+        mWifiController = mWifiInjector.getWifiController();
+        mWifiBackupRestore = mWifiInjector.getWifiBackupRestore();
+
+        enableVerboseLoggingInternal(getVerboseLoggingLevel());
     }
 
 
@@ -419,6 +401,7 @@
      * see {@link android.net.wifi.WifiManager#pingSupplicant()}
      * @return {@code true} if the operation succeeds, {@code false} otherwise
      */
+    @Override
     public boolean pingSupplicant() {
         enforceAccessPermission();
         if (mWifiStateMachineChannel != null) {
@@ -436,6 +419,7 @@
      * @param settings If null, use default parameter, i.e. full scan.
      * @param workSource If null, all blame is given to the calling uid.
      */
+    @Override
     public void startScan(ScanSettings settings, WorkSource workSource) {
         enforceChangePermission();
         synchronized (this) {
@@ -475,6 +459,7 @@
                 settings, workSource);
     }
 
+    @Override
     public String getWpsNfcConfigurationToken(int netId) {
         enforceConnectivityInternalPermission();
         return mWifiStateMachine.syncGetWpsNfcConfigurationToken(netId);
@@ -547,6 +532,7 @@
      * @return {@code true} if the enable/disable operation was
      *         started or is already in the queue.
      */
+    @Override
     public synchronized boolean setWifiEnabled(boolean enable) {
         enforceChangePermission();
         Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
@@ -579,6 +565,7 @@
      *         {@link WifiManager#WIFI_STATE_ENABLING},
      *         {@link WifiManager#WIFI_STATE_UNKNOWN}
      */
+    @Override
     public int getWifiEnabledState() {
         enforceAccessPermission();
         return mWifiStateMachine.syncGetWifiState();
@@ -590,6 +577,7 @@
      *        part of WifiConfiguration
      * @param enabled true to enable and false to disable
      */
+    @Override
     public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
         enforceChangePermission();
         ConnectivityManager.enforceTetherChangePermission(mContext);
@@ -612,6 +600,7 @@
      *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
      *         {@link WifiManager#WIFI_AP_STATE_FAILED}
      */
+    @Override
     public int getWifiApEnabledState() {
         enforceAccessPermission();
         return mWifiStateMachine.syncGetWifiApState();
@@ -621,6 +610,7 @@
      * see {@link WifiManager#getWifiApConfiguration()}
      * @return soft access point configuration
      */
+    @Override
     public WifiConfiguration getWifiApConfiguration() {
         enforceAccessPermission();
         return mWifiStateMachine.syncGetWifiApConfiguration();
@@ -630,6 +620,7 @@
      * see {@link WifiManager#buildWifiConfig()}
      * @return a WifiConfiguration.
      */
+    @Override
     public WifiConfiguration buildWifiConfig(String uriString, String mimeType, byte[] data) {
         if (mimeType.equals(ConfigBuilder.WifiConfigType)) {
             try {
@@ -649,6 +640,7 @@
      * see {@link WifiManager#setWifiApConfiguration(WifiConfiguration)}
      * @param wifiConfig WifiConfiguration details for soft access point
      */
+    @Override
     public void setWifiApConfiguration(WifiConfiguration wifiConfig) {
         enforceChangePermission();
         if (wifiConfig == null)
@@ -661,10 +653,9 @@
     }
 
     /**
-     * @param enable {@code true} to enable, {@code false} to disable.
-     * @return {@code true} if the enable/disable operation was
-     *         started or is already in the queue.
+     * see {@link android.net.wifi.WifiManager#isScanAlwaysAvailable()}
      */
+    @Override
     public boolean isScanAlwaysAvailable() {
         enforceAccessPermission();
         return mSettingsStore.isScanAlwaysAvailable();
@@ -673,6 +664,7 @@
     /**
      * see {@link android.net.wifi.WifiManager#disconnect()}
      */
+    @Override
     public void disconnect() {
         enforceChangePermission();
         mWifiStateMachine.disconnectCommand();
@@ -681,6 +673,7 @@
     /**
      * see {@link android.net.wifi.WifiManager#reconnect()}
      */
+    @Override
     public void reconnect() {
         enforceChangePermission();
         mWifiStateMachine.reconnectCommand();
@@ -689,6 +682,7 @@
     /**
      * see {@link android.net.wifi.WifiManager#reassociate()}
      */
+    @Override
     public void reassociate() {
         enforceChangePermission();
         mWifiStateMachine.reassociateCommand();
@@ -697,6 +691,7 @@
     /**
      * see {@link android.net.wifi.WifiManager#getSupportedFeatures}
      */
+    @Override
     public int getSupportedFeatures() {
         enforceAccessPermission();
         if (mWifiStateMachineChannel != null) {
@@ -717,6 +712,7 @@
     /**
      * see {@link android.net.wifi.WifiManager#getControllerActivityEnergyInfo(int)}
      */
+    @Override
     public WifiActivityEnergyInfo reportActivityInfo() {
         enforceAccessPermission();
         if ((getSupportedFeatures() & WifiManager.WIFI_FEATURE_LINK_LAYER_STATS) == 0) {
@@ -788,6 +784,7 @@
      * see {@link android.net.wifi.WifiManager#getConfiguredNetworks()}
      * @return the list of configured networks
      */
+    @Override
     public List<WifiConfiguration> getConfiguredNetworks() {
         enforceAccessPermission();
         if (mWifiStateMachineChannel != null) {
@@ -803,6 +800,7 @@
      * see {@link android.net.wifi.WifiManager#getPrivilegedConfiguredNetworks()}
      * @return the list of configured networks with real preSharedKey
      */
+    @Override
     public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
         enforceReadCredentialPermission();
         enforceAccessPermission();
@@ -819,6 +817,7 @@
      * @param scanResult scanResult that represents the BSSID
      * @return {@link WifiConfiguration} that matches this BSSID or null
      */
+    @Override
     public WifiConfiguration getMatchingWifiConfig(ScanResult scanResult) {
         enforceAccessPermission();
         return mWifiStateMachine.syncGetMatchingWifiConfig(scanResult, mWifiStateMachineChannel);
@@ -829,6 +828,7 @@
      * @return the supplicant-assigned identifier for the new or updated
      * network if the operation succeeds, or {@code -1} if it fails
      */
+    @Override
     public int addOrUpdateNetwork(WifiConfiguration config) {
         enforceChangePermission();
         if (isValid(config) && isValidPasspoint(config)) {
@@ -899,6 +899,7 @@
      * to the supplicant
      * @return {@code true} if the operation succeeded
      */
+    @Override
     public boolean removeNetwork(int netId) {
         enforceChangePermission();
 
@@ -917,6 +918,7 @@
      * @param disableOthers if true, disable all other networks.
      * @return {@code true} if the operation succeeded
      */
+    @Override
     public boolean enableNetwork(int netId, boolean disableOthers) {
         enforceChangePermission();
         if (mWifiStateMachineChannel != null) {
@@ -934,6 +936,7 @@
      * to the supplicant
      * @return {@code true} if the operation succeeded
      */
+    @Override
     public boolean disableNetwork(int netId) {
         enforceChangePermission();
         if (mWifiStateMachineChannel != null) {
@@ -948,6 +951,7 @@
      * See {@link android.net.wifi.WifiManager#getConnectionInfo()}
      * @return the Wi-Fi information, contained in {@link WifiInfo}.
      */
+    @Override
     public WifiInfo getConnectionInfo() {
         enforceAccessPermission();
         /*
@@ -962,6 +966,7 @@
      * a list of {@link ScanResult} objects.
      * @return the list of results
      */
+    @Override
     public List<ScanResult> getScanResults(String callingPackage) {
         enforceAccessPermission();
         int userId = UserHandle.getCallingUserId();
@@ -998,6 +1003,7 @@
      * @param mo The MO in XML form
      * @return -1 for failure
      */
+    @Override
     public int addPasspointManagementObject(String mo) {
         return mWifiStateMachine.syncAddPasspointManagementObject(mWifiStateMachineChannel, mo);
     }
@@ -1008,6 +1014,7 @@
      * @param mos A List of MO definitions to be updated
      * @return the number of nodes updated, or -1 for failure
      */
+    @Override
     public int modifyPasspointManagementObject(String fqdn, List<PasspointManagementObjectDefinition> mos) {
         return mWifiStateMachine.syncModifyPasspointManagementObject(mWifiStateMachineChannel, fqdn, mos);
     }
@@ -1017,6 +1024,7 @@
      * @param bssid The BSSID of the AP
      * @param fileName Icon file name
      */
+    @Override
     public void queryPasspointIcon(long bssid, String fileName) {
         mWifiStateMachine.syncQueryPasspointIcon(mWifiStateMachineChannel, bssid, fileName);
     }
@@ -1026,6 +1034,7 @@
      * @param fqdn FQDN of the SP
      * @return ordinal [HomeProvider, RoamingProvider, Incomplete, None, Declined]
      */
+    @Override
     public int matchProviderWithCurrentNetwork(String fqdn) {
         return mWifiStateMachine.matchProviderWithCurrentNetwork(mWifiStateMachineChannel, fqdn);
     }
@@ -1035,6 +1044,7 @@
      * @param holdoff hold off time in milliseconds
      * @param ess set if the hold off pertains to an ESS rather than a BSS
      */
+    @Override
     public void deauthenticateNetwork(long holdoff, boolean ess) {
         mWifiStateMachine.deauthenticateNetwork(mWifiStateMachineChannel, holdoff, ess);
     }
@@ -1088,8 +1098,8 @@
      *
      * TODO: deprecate this
      */
+    @Override
     public boolean saveConfiguration() {
-        boolean result = true;
         enforceChangePermission();
         if (mWifiStateMachineChannel != null) {
             return mWifiStateMachine.syncSaveConfig(mWifiStateMachineChannel);
@@ -1108,6 +1118,7 @@
      * persisted country code on a restart, when the locale information is
      * not available from telephony.
      */
+    @Override
     public void setCountryCode(String countryCode, boolean persist) {
         Slog.i(TAG, "WifiService trying to set country code to " + countryCode +
                 " with persist set to " + persist);
@@ -1129,6 +1140,7 @@
      * Get the country code
      * @return ISO 3166 country code.
      */
+    @Override
     public String getCountryCode() {
         enforceConnectivityInternalPermission();
         String country = mCountryCode.getCurrentCountryCode();
@@ -1143,6 +1155,7 @@
      * @param persist {@code true} if the setting should be remembered.
      *
      */
+    @Override
     public void setFrequencyBand(int band, boolean persist) {
         enforceChangePermission();
         if (!isDualBandSupported()) return;
@@ -1160,11 +1173,13 @@
     /**
      * Get the operational frequency band
      */
+    @Override
     public int getFrequencyBand() {
         enforceAccessPermission();
         return mWifiStateMachine.getFrequencyBand();
     }
 
+    @Override
     public boolean isDualBandSupported() {
         //TODO: Should move towards adding a driver API that checks at runtime
         return mContext.getResources().getBoolean(
@@ -1177,6 +1192,8 @@
      * @return the DHCP information
      * @deprecated
      */
+    @Override
+    @Deprecated
     public DhcpInfo getDhcpInfo() {
         enforceAccessPermission();
         DhcpResults dhcpResults = mWifiStateMachine.syncGetDhcpResults();
@@ -1216,6 +1233,7 @@
      * see {@link android.net.wifi.WifiManager#addToBlacklist}
      *
      */
+    @Override
     public void addToBlacklist(String bssid) {
         enforceChangePermission();
 
@@ -1226,6 +1244,7 @@
      * see {@link android.net.wifi.WifiManager#clearBlacklist}
      *
      */
+    @Override
     public void clearBlacklist() {
         enforceChangePermission();
 
@@ -1306,6 +1325,7 @@
         }
     }
 
+    @Override
     public void enableTdls(String remoteAddress, boolean enable) {
         if (remoteAddress == null) {
           throw new IllegalArgumentException("remoteAddress cannot be null");
@@ -1318,6 +1338,7 @@
     }
 
 
+    @Override
     public void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable) {
         if (remoteMacAddress == null) {
           throw new IllegalArgumentException("remoteMacAddress cannot be null");
@@ -1330,6 +1351,7 @@
      * Get a reference to handler. This is used by a client to establish
      * an AsyncChannel communication with WifiService
      */
+    @Override
     public Messenger getWifiServiceMessenger() {
         enforceAccessPermission();
         enforceChangePermission();
@@ -1339,6 +1361,7 @@
     /**
      * Disable an ephemeral network, i.e. network that is created thru a WiFi Scorer
      */
+    @Override
     public void disableEphemeralNetwork(String SSID) {
         enforceAccessPermission();
         enforceChangePermission();
@@ -1348,6 +1371,7 @@
     /**
      * Get the IP and proxy configuration file
      */
+    @Override
     public String getConfigFile() {
         enforceAccessPermission();
         return mWifiStateMachine.getConfigFile();
@@ -1473,8 +1497,6 @@
             pw.println("Stay-awake conditions: " +
                     Settings.Global.getInt(mContext.getContentResolver(),
                                            Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0));
-            pw.println("mMulticastEnabled " + mMulticastEnabled);
-            pw.println("mMulticastDisabled " + mMulticastDisabled);
             pw.println("mInIdleMode " + mInIdleMode);
             pw.println("mScanPending " + mScanPending);
             mWifiController.dump(fd, pw, args);
@@ -1511,15 +1533,12 @@
             pw.println("Locks held:");
             mWifiLockManager.dump(pw);
             pw.println();
-            pw.println("Multicast Locks held:");
-            for (Multicaster l : mMulticasters) {
-                pw.print("    ");
-                pw.println(l);
-            }
-
+            mWifiMulticastLockManager.dump(pw);
             pw.println();
             mWifiStateMachine.dump(fd, pw, args);
             pw.println();
+            mWifiBackupRestore.dump(fd, pw, args);
+            pw.println();
         }
     }
 
@@ -1546,168 +1565,91 @@
         return false;
     }
 
-    private class Multicaster implements IBinder.DeathRecipient {
-        String mTag;
-        int mUid;
-        IBinder mBinder;
-
-        Multicaster(String tag, IBinder binder) {
-            mTag = tag;
-            mUid = Binder.getCallingUid();
-            mBinder = binder;
-            try {
-                mBinder.linkToDeath(this, 0);
-            } catch (RemoteException e) {
-                binderDied();
-            }
-        }
-
-        @Override
-        public void binderDied() {
-            Slog.e(TAG, "Multicaster binderDied");
-            synchronized (mMulticasters) {
-                int i = mMulticasters.indexOf(this);
-                if (i != -1) {
-                    removeMulticasterLocked(i, mUid);
-                }
-            }
-        }
-
-        void unlinkDeathRecipient() {
-            mBinder.unlinkToDeath(this, 0);
-        }
-
-        public int getUid() {
-            return mUid;
-        }
-
-        public String toString() {
-            return "Multicaster{" + mTag + " uid=" + mUid  + "}";
-        }
-    }
-
+    @Override
     public void initializeMulticastFiltering() {
         enforceMulticastChangePermission();
-
-        synchronized (mMulticasters) {
-            // if anybody had requested filters be off, leave off
-            if (mMulticasters.size() != 0) {
-                return;
-            } else {
-                mWifiStateMachine.startFilteringMulticastPackets();
-            }
-        }
+        mWifiMulticastLockManager.initializeFiltering();
     }
 
+    @Override
     public void acquireMulticastLock(IBinder binder, String tag) {
         enforceMulticastChangePermission();
-
-        synchronized (mMulticasters) {
-            mMulticastEnabled++;
-            mMulticasters.add(new Multicaster(tag, binder));
-            // Note that we could call stopFilteringMulticastPackets only when
-            // our new size == 1 (first call), but this function won't
-            // be called often and by making the stopPacket call each
-            // time we're less fragile and self-healing.
-            mWifiStateMachine.stopFilteringMulticastPackets();
-        }
-
-        int uid = Binder.getCallingUid();
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            mBatteryStats.noteWifiMulticastEnabled(uid);
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
+        mWifiMulticastLockManager.acquireLock(binder, tag);
     }
 
+    @Override
     public void releaseMulticastLock() {
         enforceMulticastChangePermission();
-
-        int uid = Binder.getCallingUid();
-        synchronized (mMulticasters) {
-            mMulticastDisabled++;
-            int size = mMulticasters.size();
-            for (int i = size - 1; i >= 0; i--) {
-                Multicaster m = mMulticasters.get(i);
-                if ((m != null) && (m.getUid() == uid)) {
-                    removeMulticasterLocked(i, uid);
-                }
-            }
-        }
+        mWifiMulticastLockManager.releaseLock();
     }
 
-    private void removeMulticasterLocked(int i, int uid)
-    {
-        Multicaster removed = mMulticasters.remove(i);
-
-        if (removed != null) {
-            removed.unlinkDeathRecipient();
-        }
-        if (mMulticasters.size() == 0) {
-            mWifiStateMachine.startFilteringMulticastPackets();
-        }
-
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            mBatteryStats.noteWifiMulticastDisabled(uid);
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
+    @Override
     public boolean isMulticastEnabled() {
         enforceAccessPermission();
-
-        synchronized (mMulticasters) {
-            return (mMulticasters.size() > 0);
-        }
+        return mWifiMulticastLockManager.isMulticastEnabled();
     }
 
+    @Override
     public void enableVerboseLogging(int verbose) {
         enforceAccessPermission();
+        mFacade.setIntegerSetting(
+                mContext, Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, verbose);
+        enableVerboseLoggingInternal(verbose);
+    }
+
+    private void enableVerboseLoggingInternal(int verbose) {
         mWifiStateMachine.enableVerboseLogging(verbose);
         mWifiLockManager.enableVerboseLogging(verbose);
+        mWifiMulticastLockManager.enableVerboseLogging(verbose);
+        mWifiInjector.getWifiLastResortWatchdog().enableVerboseLogging(verbose);
+        mWifiInjector.getWifiBackupRestore().enableVerboseLogging(verbose);
     }
 
+    @Override
     public int getVerboseLoggingLevel() {
         enforceAccessPermission();
-        return mWifiStateMachine.getVerboseLoggingLevel();
+        return mFacade.getIntegerSetting(
+                mContext, Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0);
     }
 
+    @Override
     public void enableAggressiveHandover(int enabled) {
         enforceAccessPermission();
         mWifiStateMachine.enableAggressiveHandover(enabled);
     }
 
+    @Override
     public int getAggressiveHandover() {
         enforceAccessPermission();
         return mWifiStateMachine.getAggressiveHandover();
     }
 
+    @Override
     public void setAllowScansWithTraffic(int enabled) {
         enforceAccessPermission();
         mWifiStateMachine.setAllowScansWithTraffic(enabled);
     }
 
+    @Override
     public int getAllowScansWithTraffic() {
         enforceAccessPermission();
         return mWifiStateMachine.getAllowScansWithTraffic();
     }
 
+    @Override
     public boolean setEnableAutoJoinWhenAssociated(boolean enabled) {
         enforceChangePermission();
         return mWifiStateMachine.setEnableAutoJoinWhenAssociated(enabled);
     }
 
+    @Override
     public boolean getEnableAutoJoinWhenAssociated() {
         enforceAccessPermission();
         return mWifiStateMachine.getEnableAutoJoinWhenAssociated();
     }
 
     /* Return the Wifi Connection statistics object */
+    @Override
     public WifiConnectionStatistics getConnectionStatistics() {
         enforceAccessPermission();
         enforceReadCredentialPermission();
@@ -1719,6 +1661,7 @@
         }
     }
 
+    @Override
     public void factoryReset() {
         enforceConnectivityInternalPermission();
 
@@ -1807,6 +1750,7 @@
         return null;
     }
 
+    @Override
     public Network getCurrentNetwork() {
         enforceAccessPermission();
         return mWifiStateMachine.getCurrentNetwork();
@@ -1888,8 +1832,96 @@
      *
      * @param enabled true-enable; false-disable
      */
+    @Override
     public void enableWifiConnectivityManager(boolean enabled) {
         enforceConnectivityInternalPermission();
         mWifiStateMachine.enableWifiConnectivityManager(enabled);
     }
+
+    /**
+     * Retrieve the data to be backed to save the current state.
+     *
+     * @return  Raw byte stream of the data to be backed up.
+     */
+    @Override
+    public byte[] retrieveBackupData() {
+        enforceReadCredentialPermission();
+        enforceAccessPermission();
+        if (mWifiStateMachineChannel == null) {
+            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
+            return null;
+        }
+
+        Slog.d(TAG, "Retrieving backup data");
+        List<WifiConfiguration> wifiConfigurations =
+                mWifiStateMachine.syncGetPrivilegedConfiguredNetwork(mWifiStateMachineChannel);
+        byte[] backupData =
+                mWifiBackupRestore.retrieveBackupDataFromConfigurations(wifiConfigurations);
+        Slog.d(TAG, "Retrieved backup data");
+        return backupData;
+    }
+
+    /**
+     * Helper method to restore networks retrieved from backup data.
+     *
+     * @param configurations list of WifiConfiguration objects parsed from the backup data.
+     */
+    private void restoreNetworks(List<WifiConfiguration> configurations) {
+        if (configurations == null) {
+            Slog.e(TAG, "Backup data parse failed");
+            return;
+        }
+        for (WifiConfiguration configuration : configurations) {
+            int networkId = mWifiStateMachine.syncAddOrUpdateNetwork(
+                    mWifiStateMachineChannel, configuration);
+            if (networkId == WifiConfiguration.INVALID_NETWORK_ID) {
+                Slog.e(TAG, "Restore network failed: " + configuration.configKey());
+                continue;
+            }
+            // Enable all networks restored.
+            mWifiStateMachine.syncEnableNetwork(mWifiStateMachineChannel, networkId, false);
+        }
+    }
+
+    /**
+     * Restore state from the backed up data.
+     *
+     * @param data Raw byte stream of the backed up data.
+     */
+    @Override
+    public void restoreBackupData(byte[] data) {
+        enforceChangePermission();
+        if (mWifiStateMachineChannel == null) {
+            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
+            return;
+        }
+
+        Slog.d(TAG, "Restoring backup data");
+        List<WifiConfiguration> wifiConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(data);
+        restoreNetworks(wifiConfigurations);
+        Slog.d(TAG, "Restored backup data");
+    }
+
+    /**
+     * Restore state from the older supplicant back up data.
+     * The old backup data was essentially a backup of wpa_supplicant.conf & ipconfig.txt file.
+     *
+     * @param supplicantData Raw byte stream of wpa_supplicant.conf
+     * @param ipConfigData Raw byte stream of ipconfig.txt
+     */
+    public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) {
+        enforceChangePermission();
+        if (mWifiStateMachineChannel == null) {
+            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
+            return;
+        }
+
+        Slog.d(TAG, "Restoring supplicant backup data");
+        List<WifiConfiguration> wifiConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, ipConfigData);
+        restoreNetworks(wifiConfigurations);
+        Slog.d(TAG, "Restored supplicant backup data");
+    }
 }
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index e3ab3bc..c2e4b93 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -29,7 +29,6 @@
 
 import android.Manifest;
 import android.app.ActivityManager;
-import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
@@ -56,6 +55,8 @@
 import android.net.StaticIpConfiguration;
 import android.net.dhcp.DhcpClient;
 import android.net.ip.IpManager;
+import android.net.wifi.IApInterface;
+import android.net.wifi.IWificond;
 import android.net.wifi.PasspointManagementObjectDefinition;
 import android.net.wifi.RssiPacketCountInfo;
 import android.net.wifi.ScanResult;
@@ -73,6 +74,7 @@
 import android.net.wifi.WpsInfo;
 import android.net.wifi.WpsResult;
 import android.net.wifi.WpsResult.Status;
+import android.net.wifi.nan.WifiNanManager;
 import android.net.wifi.p2p.IWifiP2pManager;
 import android.os.BatteryStats;
 import android.os.Binder;
@@ -85,7 +87,6 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.WorkSource;
@@ -120,12 +121,10 @@
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Calendar;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
-import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -146,22 +145,22 @@
  *
  * @hide
  */
-public class WifiStateMachine extends StateMachine implements WifiNative.WifiRssiEventHandler {
+public class WifiStateMachine extends StateMachine implements WifiNative.WifiRssiEventHandler,
+        WifiMulticastLockManager.FilterController {
 
     private static final String NETWORKTYPE = "WIFI";
     private static final String NETWORKTYPE_UNTRUSTED = "WIFI_UT";
     @VisibleForTesting public static final short NUM_LOG_RECS_NORMAL = 100;
     @VisibleForTesting public static final short NUM_LOG_RECS_VERBOSE_LOW_MEMORY = 200;
     @VisibleForTesting public static final short NUM_LOG_RECS_VERBOSE = 3000;
-    private static boolean DBG = false;
-    private static boolean USE_PAUSE_SCANS = false;
     private static final String TAG = "WifiStateMachine";
 
     private static final int ONE_HOUR_MILLI = 1000 * 60 * 60;
 
     private static final String GOOGLE_OUI = "DA-A1-19";
 
-    private int mVerboseLoggingLevel = 0;
+    private boolean mVerboseLoggingEnabled = false;
+
     /* debug flag, indicating if handling of ASSOCIATION_REJECT ended up blacklisting
      * the corresponding BSSID.
      */
@@ -172,16 +171,18 @@
      *
      * @param s is string log
      */
+    @Override
     protected void loge(String s) {
         Log.e(getName(), s);
     }
+    @Override
     protected void logd(String s) {
         Log.d(getName(), s);
     }
-    protected void log(String s) {;
+    @Override
+    protected void log(String s) {
         Log.d(getName(), s);
     }
-    private WifiLastResortWatchdog mWifiLastResortWatchdog;
     private WifiMetrics mWifiMetrics;
     private WifiInjector mWifiInjector;
     private WifiMonitor mWifiMonitor;
@@ -190,11 +191,13 @@
     private WifiConnectivityManager mWifiConnectivityManager;
     private WifiQualifiedNetworkSelector mWifiQualifiedNetworkSelector;
     private INetworkManagementService mNwService;
+    private IWificond mWificond;
     private ConnectivityManager mCm;
     private BaseWifiLogger mWifiLogger;
     private WifiApConfigStore mWifiApConfigStore;
     private final boolean mP2pSupported;
     private final AtomicBoolean mP2pConnected = new AtomicBoolean(false);
+    private final boolean mNanSupported;
     private boolean mTemporarilyDisconnectWifi = false;
     private final String mPrimaryDeviceType;
     private final Clock mClock;
@@ -213,21 +216,16 @@
 
     private boolean mScreenOn = false;
 
-    /* Chipset supports background scan */
-    private final boolean mBackgroundScanSupported;
-
     private final String mInterfaceName;
-    /* Tethering interface could be separate from wlan interface */
-    private String mTetherInterfaceName;
 
     private int mLastSignalLevel = -1;
     private String mLastBssid;
     private int mLastNetworkId; // The network Id we successfully joined
-    private boolean linkDebouncing = false;
+    private boolean mIsLinkDebouncing = false;
 
     @Override
     public void onRssiThresholdBreached(byte curRssi) {
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             Log.e(TAG, "onRssiThresholdBreach event. Cur Rssi = " + curRssi);
         }
         sendMessage(CMD_RSSI_THRESHOLD_BREACH, curRssi);
@@ -247,7 +245,7 @@
                 // This value of hw has to be believed as this value is averaged and has breached
                 // the rssi thresholds and raised event to host. This would be eggregious if this
                 // value is invalid
-                mWifiInfo.setRssi((int) curRssi);
+                mWifiInfo.setRssi(curRssi);
                 updateCapabilities(getCurrentWifiConfiguration());
                 int ret = startRssiMonitoringOffload(maxRssi, minRssi);
                 Log.d(TAG, "Re-program RSSI thresholds for " + smToString(reason) +
@@ -274,12 +272,8 @@
     private boolean mSendScanResultsBroadcast = false;
 
     private final Queue<Message> mBufferedScanMsg = new LinkedList<Message>();
-    private WorkSource mScanWorkSource = null;
     private static final int UNKNOWN_SCAN_SOURCE = -1;
     private static final int ADD_OR_UPDATE_SOURCE = -3;
-    private static final int SET_ALLOW_UNTRUSTED_SOURCE = -4;
-    private static final int ENABLE_WIFI = -5;
-    public static final int DFS_RESTRICTED_SCAN_REQUEST = -6;
 
     private static final int SCAN_REQUEST_BUFFER_MAX_SIZE = 10;
     private static final String CUSTOMIZED_SCAN_SETTING = "customized_scan_settings";
@@ -322,14 +316,6 @@
     private int mSupplicantStopFailureToken = 0;
 
     /**
-     * Tether state change notification time out
-     */
-    private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000;
-
-    /* Tracks sequence number on a tether notification time out */
-    private int mTetherToken = 0;
-
-    /**
      * Driver start time out.
      */
     private static final int DRIVER_START_TIME_OUT_MSECS = 10000;
@@ -338,12 +324,6 @@
     private int mDriverStartToken = 0;
 
     /**
-     * Don't select new network when previous network selection is
-     * pending connection for this much time
-     */
-    private static final int CONNECT_TIMEOUT_MSEC = 3000;
-
-    /**
      * The link properties of the wifi interface.
      * Do not modify this directly; use updateLinkProperties instead.
      */
@@ -394,9 +374,6 @@
     // Used as debug to indicate which configuration last was removed
     private WifiConfiguration lastForgetConfigurationAttempt = null;
 
-    //Random used by softAP channel Selection
-    private static Random mRandom = new Random(Calendar.getInstance().getTimeInMillis());
-
     boolean isRoaming() {
         return mAutoRoaming;
     }
@@ -417,18 +394,18 @@
         }
         if (!mTargetRoamBSSID.equals("any") && bssid.equals("any")) {
             // Changing to ANY
-            if (!mWifiConfigManager.ROAM_ON_ANY) {
+            if (!WifiConfigManager.ROAM_ON_ANY) {
                 ret = false; // Nothing to do
             }
         }
         if (config.BSSID != null) {
             bssid = config.BSSID;
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 Log.d(TAG, "force BSSID to " + bssid + "due to config");
             }
         }
 
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             logd("autoRoamSetBSSID " + bssid + " key=" + config.configKey());
         }
         mTargetRoamBSSID = bssid;
@@ -450,7 +427,7 @@
 
         if (config.BSSID != null) {
             bssid = config.BSSID;
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 Log.d(TAG, "force BSSID to " + bssid + "due to config");
             }
         }
@@ -462,13 +439,13 @@
         String networkSelectionBSSID = config.getNetworkSelectionStatus()
                 .getNetworkSelectionBSSID();
         if (networkSelectionBSSID != null && networkSelectionBSSID.equals(bssid)) {
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 Log.d(TAG, "Current preferred BSSID is the same as the target one");
             }
             return false;
         }
 
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             Log.d(TAG, "target set to " + config.SSID + ":" + bssid);
         }
         mTargetRoamBSSID = bssid;
@@ -528,9 +505,6 @@
 
     private final IpManager mIpManager;
 
-    private AlarmManager mAlarmManager;
-    private PendingIntent mScanIntent;
-
     /* Tracks current frequency mode */
     private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
 
@@ -538,6 +512,7 @@
     private AsyncChannel mReplyChannel = new AsyncChannel();
 
     private WifiP2pServiceImpl mWifiP2pServiceImpl;
+    private WifiNanManager mWifiNanManager;
 
     // Used to initiate a connection with WifiP2pService
     private AsyncChannel mWifiP2pChannel;
@@ -549,8 +524,6 @@
     private UntrustedWifiNetworkFactory mUntrustedNetworkFactory;
     private WifiNetworkAgent mNetworkAgent;
 
-    private String[] mWhiteListedSsids = null;
-
     private byte[] mRssiRanges;
 
     // Keep track of various statistics, for retrieval by System Apps, i.e. under @SystemApi
@@ -667,8 +640,6 @@
     static final int CMD_SET_FREQUENCY_BAND                             = BASE + 90;
     /* Enable TDLS on a specific MAC address */
     static final int CMD_ENABLE_TDLS                                    = BASE + 92;
-    /* DHCP/IP configuration watchdog */
-    static final int CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER            = BASE + 93;
 
     /**
      * Watchdog for protecting against b/16823537
@@ -708,15 +679,6 @@
     /* try to match a provider with current network */
     static final int CMD_MATCH_PROVIDER_NETWORK                         = BASE + 105;
 
-    /**
-     * Make this timer 40 seconds, which is about the normal DHCP timeout.
-     * In no valid case, the WiFiStateMachine should remain stuck in ObtainingIpAddress
-     * for more than 30 seconds.
-     */
-    static final int OBTAINING_IP_ADDRESS_GUARD_TIMER_MSEC = 40000;
-
-    int obtainingIpWatchdogCount = 0;
-
     /* Commands from/to the SupplicantStateTracker */
     /* Reset the supplicant state tracker */
     static final int CMD_RESET_SUPPLICANT_STATE                         = BASE + 111;
@@ -771,9 +733,6 @@
 
     static final int CMD_ACCEPT_UNVALIDATED                             = BASE + 153;
 
-    /* used to log if PNO was started */
-    static final int CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION              = BASE + 158;
-
     /* used to offload sending IP packet */
     static final int CMD_START_IP_PACKET_OFFLOAD                        = BASE + 160;
 
@@ -846,16 +805,6 @@
     private AtomicBoolean mUserWantsSuspendOpt = new AtomicBoolean(true);
 
     /**
-     * Default framework scan interval in milliseconds. This is used in the scenario in which
-     * wifi chipset does not support background scanning to set up a
-     * periodic wake up scan so that the device can connect to a new access
-     * point on the move. {@link Settings.Global#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can
-     * override this.
-     */
-    private final int mDefaultFrameworkScanIntervalMs;
-
-
-    /**
      * Scan period for the NO_NETWORKS_PERIIDOC_SCAN_FEATURE
      */
     private final int mNoNetworksPeriodicScan;
@@ -948,8 +897,6 @@
      */
     private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED);
 
-    private static final int SCAN_REQUEST = 0;
-
     /**
      * Work source to use to blame usage on the WiFi service
      */
@@ -982,11 +929,6 @@
     // Used for debug and stats gathering
     private static int sScanAlarmIntentCount = 0;
 
-    private static final int sFrameworkMinScanIntervalSaneValue = 10000;
-
-    private long mGScanStartTimeMilli;
-    private long mGScanPeriodMilli;
-
     private FrameworkFacade mFacade;
 
     private final BackupManagerProxy mBackupManagerProxy;
@@ -1000,7 +942,6 @@
         super("WifiStateMachine", looper);
         mWifiInjector = wifiInjector;
         mWifiMetrics = mWifiInjector.getWifiMetrics();
-        mWifiLastResortWatchdog = wifiInjector.getWifiLastResortWatchdog();
         mClock = wifiInjector.getClock();
         mPropertyService = wifiInjector.getPropertyService();
         mBuildProperties = wifiInjector.getBuildProperties();
@@ -1021,6 +962,8 @@
 
         mP2pSupported = mContext.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_WIFI_DIRECT);
+        mNanSupported = mContext.getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_WIFI_NAN);
 
         mWifiConfigManager = mFacade.makeWifiConfigManager(context, mWifiNative, facade,
                 mWifiInjector.getClock(), userManager, mWifiInjector.getKeyStore());
@@ -1047,6 +990,8 @@
         IBinder s1 = mFacade.getService(Context.WIFI_P2P_SERVICE);
         mWifiP2pServiceImpl = (WifiP2pServiceImpl) IWifiP2pManager.Stub.asInterface(s1);
 
+        mWifiNanManager = (WifiNanManager) mContext.getSystemService(Context.WIFI_NAN_SERVICE);
+
         mNetworkInfo.setIsAvailable(false);
         mLastBssid = null;
         mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
@@ -1055,21 +1000,12 @@
         mIpManager = mFacade.makeIpManager(mContext, mInterfaceName, new IpManagerCallback());
         mIpManager.setMulticastFilter(true);
 
-        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-
-        // Make sure the interval is not configured less than 10 seconds
-        int period = mContext.getResources().getInteger(
-                R.integer.config_wifi_framework_scan_interval);
-        if (period < sFrameworkMinScanIntervalSaneValue) {
-            period = sFrameworkMinScanIntervalSaneValue;
-        }
-        mDefaultFrameworkScanIntervalMs = period;
-
         mNoNetworksPeriodicScan = mContext.getResources().getInteger(
                 R.integer.config_wifi_no_network_periodic_scan_interval);
 
-        mBackgroundScanSupported = mContext.getResources().getBoolean(
-                R.bool.config_wifi_background_scan_support);
+        // TODO: remove these settings from the config file since we no longer obey them
+        // mContext.getResources().getInteger(R.integer.config_wifi_framework_scan_interval);
+        // mContext.getResources().getBoolean(R.bool.config_wifi_background_scan_support);
 
         mPrimaryDeviceType = mContext.getResources().getString(
                 R.string.config_wifi_p2p_device_type);
@@ -1210,10 +1146,6 @@
         } catch (PackageManager.NameNotFoundException e) {
             loge("Unable to resolve SystemUI's UID.");
         }
-
-        mVerboseLoggingLevel = mFacade.getIntegerSetting(
-                mContext, Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, 0);
-        updateLoggingLevel();
     }
 
     class IpManagerCallback extends IpManager.Callback {
@@ -1233,8 +1165,8 @@
                 sendMessage(CMD_IPV4_PROVISIONING_SUCCESS, dhcpResults);
             } else {
                 sendMessage(CMD_IPV4_PROVISIONING_FAILURE);
-                mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(getTargetSsid(),
-                        mTargetRoamBSSID,
+                mWifiInjector.getWifiLastResortWatchdog().noteConnectionFailureAndTriggerIfNeeded(
+                        getTargetSsid(), mTargetRoamBSSID,
                         WifiLastResortWatchdog.FAILURE_CODE_DHCP);
             }
         }
@@ -1289,48 +1221,37 @@
         return mFacade.getBroadcast(mContext, requestCode, intent, 0);
     }
 
-    int getVerboseLoggingLevel() {
-        return mVerboseLoggingLevel;
-    }
-
-    void enableVerboseLogging(int verbose) {
-        mVerboseLoggingLevel = verbose;
-        mFacade.setIntegerSetting(
-                mContext, Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED, verbose);
-        updateLoggingLevel();
-    }
-
     /**
      * Set wpa_supplicant log level using |mVerboseLoggingLevel| flag.
      */
     void setSupplicantLogLevel() {
-        if (mVerboseLoggingLevel > 0) {
+        if (mVerboseLoggingEnabled) {
             mWifiNative.setSupplicantLogLevel("DEBUG");
         } else {
             mWifiNative.setSupplicantLogLevel("INFO");
         }
     }
 
-    void updateLoggingLevel() {
-        if (mVerboseLoggingLevel > 0) {
-            DBG = true;
+    void enableVerboseLogging(int verbose) {
+        if (verbose > 0) {
+            mVerboseLoggingEnabled = true;
             setLogRecSize(ActivityManager.isLowRamDeviceStatic()
                     ? NUM_LOG_RECS_VERBOSE_LOW_MEMORY : NUM_LOG_RECS_VERBOSE);
         } else {
-            DBG = false;
+            mVerboseLoggingEnabled = false;
             setLogRecSize(NUM_LOG_RECS_NORMAL);
         }
-        configureVerboseHalLogging(mVerboseLoggingLevel > 0);
+        configureVerboseHalLogging(mVerboseLoggingEnabled);
         setSupplicantLogLevel();
-        mCountryCode.enableVerboseLogging(mVerboseLoggingLevel);
-        mWifiLogger.startLogging(DBG);
-        mWifiMonitor.enableVerboseLogging(mVerboseLoggingLevel);
-        mWifiNative.enableVerboseLogging(mVerboseLoggingLevel);
-        mWifiConfigManager.enableVerboseLogging(mVerboseLoggingLevel);
-        mSupplicantStateTracker.enableVerboseLogging(mVerboseLoggingLevel);
-        mWifiQualifiedNetworkSelector.enableVerboseLogging(mVerboseLoggingLevel);
+        mCountryCode.enableVerboseLogging(verbose);
+        mWifiLogger.startLogging(mVerboseLoggingEnabled);
+        mWifiMonitor.enableVerboseLogging(verbose);
+        mWifiNative.enableVerboseLogging(verbose);
+        mWifiConfigManager.enableVerboseLogging(verbose);
+        mSupplicantStateTracker.enableVerboseLogging(verbose);
+        mWifiQualifiedNetworkSelector.enableVerboseLogging(verbose);
         if (mWifiConnectivityManager != null) {
-            mWifiConnectivityManager.enableVerboseLogging(mVerboseLoggingLevel);
+            mWifiConnectivityManager.enableVerboseLogging(verbose);
         }
     }
 
@@ -1345,15 +1266,6 @@
                 enableVerbose ? LOGD_LEVEL_VERBOSE : LOGD_LEVEL_DEBUG);
     }
 
-    long mLastScanPermissionUpdate = 0;
-    boolean mConnectedModeGScanOffloadStarted = false;
-    // Don't do a G-scan enable/re-enable cycle more than once within 20seconds
-    // The function updateAssociatedScanPermission() can be called quite frequently, hence
-    // we want to throttle the GScan Stop->Start transition
-    static final long SCAN_PERMISSION_UPDATE_THROTTLE_MILLI = 20000;
-    void updateAssociatedScanPermission() {
-    }
-
     private int mAggressiveHandover = 0;
 
     int getAggressiveHandover() {
@@ -1437,7 +1349,7 @@
         Bundle bundle = new Bundle();
         bundle.putParcelable(CUSTOMIZED_SCAN_SETTING, settings);
         bundle.putParcelable(CUSTOMIZED_SCAN_WORKSOURCE, workSource);
-        bundle.putLong(SCAN_REQUEST_TIME, System.currentTimeMillis());
+        bundle.putLong(SCAN_REQUEST_TIME, mClock.getWallClockMillis());
         sendMessage(CMD_START_SCAN, callingUid, scanCounter, bundle);
     }
 
@@ -1477,7 +1389,7 @@
     public long getDisconnectedTimeMilli() {
         if (getCurrentState() == mDisconnectedState
                 && mDisconnectedTimeStamp != 0) {
-            long now_ms = System.currentTimeMillis();
+            long now_ms = mClock.getWallClockMillis();
             return now_ms - mDisconnectedTimeStamp;
         }
         return 0;
@@ -1506,7 +1418,7 @@
     //TODO: this is used only to track connection attempts, however the link state and packet per
     //TODO: second logic should be folded into that
     private boolean checkOrDeferScanAllowed(Message msg) {
-        long now = System.currentTimeMillis();
+        long now = mClock.getWallClockMillis();
         if (lastConnectAttemptTimestamp != 0 && (now - lastConnectAttemptTimestamp) < 10000) {
             Message dmsg = Message.obtain(msg);
             sendMessageDelayed(dmsg, 11000 - (now - lastConnectAttemptTimestamp));
@@ -1529,7 +1441,7 @@
     private long lastLinkLayerStatsUpdate = 0;
 
     String reportOnTime() {
-        long now = System.currentTimeMillis();
+        long now = mClock.getWallClockMillis();
         StringBuilder sb = new StringBuilder();
         // Report stats since last report
         int on = mOnTime - mOnTimeLastReport;
@@ -1548,7 +1460,7 @@
         return sb.toString();
     }
 
-    WifiLinkLayerStats getWifiLinkLayerStats(boolean dbg) {
+    WifiLinkLayerStats getWifiLinkLayerStats() {
         WifiLinkLayerStats stats = null;
         if (mWifiLinkLayerStatsSupported > 0) {
             String name = "wlan0";
@@ -1556,7 +1468,7 @@
             if (name != null && stats == null && mWifiLinkLayerStatsSupported > 0) {
                 mWifiLinkLayerStatsSupported -= 1;
             } else if (stats != null) {
-                lastLinkLayerStatsUpdate = System.currentTimeMillis();
+                lastLinkLayerStatsUpdate = mClock.getWallClockMillis();
                 mOnTime = stats.on_time;
                 mTxTime = stats.tx_time;
                 mRxTime = stats.rx_time;
@@ -1704,16 +1616,21 @@
         }
         WifiScanner.ScanListener nativeScanListener = new WifiScanner.ScanListener() {
                 // ignore all events since WifiStateMachine is registered for the supplicant events
+                @Override
                 public void onSuccess() {
                 }
+                @Override
                 public void onFailure(int reason, String description) {
                     mIsScanOngoing = false;
                     mIsFullScanOngoing = false;
                 }
+                @Override
                 public void onResults(WifiScanner.ScanData[] results) {
                 }
+                @Override
                 public void onFullResult(ScanResult fullScanResult) {
                 }
+                @Override
                 public void onPeriodChanged(int periodInMs) {
                 }
             };
@@ -1817,19 +1734,19 @@
     }
 
     public boolean isSupplicantTransientState() {
-        SupplicantState SupplicantState = mWifiInfo.getSupplicantState();
-        if (SupplicantState == SupplicantState.ASSOCIATING
-                || SupplicantState == SupplicantState.AUTHENTICATING
-                || SupplicantState == SupplicantState.FOUR_WAY_HANDSHAKE
-                || SupplicantState == SupplicantState.GROUP_HANDSHAKE) {
+        SupplicantState supplicantState = mWifiInfo.getSupplicantState();
+        if (supplicantState == SupplicantState.ASSOCIATING
+                || supplicantState == SupplicantState.AUTHENTICATING
+                || supplicantState == SupplicantState.FOUR_WAY_HANDSHAKE
+                || supplicantState == SupplicantState.GROUP_HANDSHAKE) {
 
-            if (DBG) {
-                Log.d(TAG, "Supplicant is under transient state: " + SupplicantState);
+            if (mVerboseLoggingEnabled) {
+                Log.d(TAG, "Supplicant is under transient state: " + supplicantState);
             }
             return true;
         } else {
-            if (DBG) {
-                Log.d(TAG, "Supplicant is under steady state: " + SupplicantState);
+            if (mVerboseLoggingEnabled) {
+                Log.d(TAG, "Supplicant is under steady state: " + supplicantState);
             }
         }
 
@@ -1837,7 +1754,7 @@
     }
 
     public boolean isLinkDebouncing() {
-        return linkDebouncing;
+        return mIsLinkDebouncing;
     }
 
     /**
@@ -1874,7 +1791,7 @@
      * TODO: doc
      */
     public void setOperationalMode(int mode) {
-        if (DBG) log("setting operational mode to " + String.valueOf(mode));
+        if (mVerboseLoggingEnabled) log("setting operational mode to " + String.valueOf(mode));
         sendMessage(CMD_SET_OPERATIONAL_MODE, mode, 0);
     }
 
@@ -2305,14 +2222,6 @@
         } else {
             pw.println("CurrentCountryCode is not initialized");
         }
-        pw.println("mConnectedModeGScanOffloadStarted " + mConnectedModeGScanOffloadStarted);
-        pw.println("mGScanPeriodMilli " + mGScanPeriodMilli);
-        if (mWhiteListedSsids != null && mWhiteListedSsids.length > 0) {
-            pw.println("SSID whitelist :" );
-            for (int i=0; i < mWhiteListedSsids.length; i++) {
-                pw.println("       " + mWhiteListedSsids[i]);
-            }
-        }
         if (mNetworkFactory != null) {
             mNetworkFactory.dump(fd, pw, args);
         } else {
@@ -2353,7 +2262,7 @@
 
     private void logStateAndMessage(Message message, State state) {
         messageHandlingStatus = 0;
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             logd(" " + state.getClass().getSimpleName() + " " + getLogRecString(message));
         }
     }
@@ -2363,8 +2272,8 @@
      */
     String printTime() {
         StringBuilder sb = new StringBuilder();
-        sb.append(" rt=").append(SystemClock.uptimeMillis());
-        sb.append("/").append(SystemClock.elapsedRealtime());
+        sb.append(" rt=").append(mClock.getUptimeSinceBootMillis());
+        sb.append("/").append(mClock.getElapsedSinceBootMillis());
         return sb.toString();
     }
 
@@ -2374,6 +2283,7 @@
      * @param msg that was processed
      * @return information to be logged as a String
      */
+    @Override
     protected String getLogRecString(Message msg) {
         WifiConfiguration config;
         Long now;
@@ -2392,22 +2302,8 @@
         }
         sb.append(" ").append(printTime());
         switch (msg.what) {
-            case CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION:
-                sb.append(" ");
-                sb.append(Integer.toString(msg.arg1));
-                sb.append(" ");
-                sb.append(Integer.toString(msg.arg2));
-                sb.append(" autojoinAllowed=");
-                sb.append(mWifiConfigManager.getEnableAutoJoinWhenAssociated());
-                sb.append(" withTraffic=").append(getAllowScansWithTraffic());
-                sb.append(" tx=").append(mWifiInfo.txSuccessRate);
-                sb.append("/").append(mWifiConfigManager.MAX_TX_PACKET_FOR_FULL_SCANS);
-                sb.append(" rx=").append(mWifiInfo.rxSuccessRate);
-                sb.append("/").append(mWifiConfigManager.MAX_RX_PACKET_FOR_FULL_SCANS);
-                sb.append(" -> ").append(mConnectedModeGScanOffloadStarted);
-                break;
             case CMD_START_SCAN:
-                now = System.currentTimeMillis();
+                now = mClock.getWallClockMillis();
                 sb.append(" ");
                 sb.append(Integer.toString(msg.arg1));
                 sb.append(" ");
@@ -2581,7 +2477,7 @@
                     sb.append(" freq=").append(mWifiInfo.getFrequency());
                     sb.append(" rssi=").append(mWifiInfo.getRssi());
                 }
-                if (linkDebouncing) {
+                if (isLinkDebouncing()) {
                     sb.append(" debounce");
                 }
                 break;
@@ -2606,7 +2502,7 @@
                                 netWorkSelectionStatus.getNetworkDisableReasonString());
                     }
                     if (config.lastConnected != 0) {
-                        now = System.currentTimeMillis();
+                        now = mClock.getWallClockMillis();
                         sb.append(" lastconn=").append(now - config.lastConnected).append("(ms)");
                     }
                     if (mLastBssid != null) {
@@ -2647,11 +2543,6 @@
                 if (mWifiScoreReport != null) {
                     sb.append(mWifiScoreReport.getReport());
                 }
-                if (mConnectedModeGScanOffloadStarted) {
-                    sb.append(" offload-started periodMilli " + mGScanPeriodMilli);
-                } else {
-                    sb.append(" offload-stopped");
-                }
                 break;
             case CMD_AUTO_CONNECT:
             case WifiManager.CONNECT_NETWORK:
@@ -2685,7 +2576,7 @@
                 sb.append(Integer.toString(msg.arg2));
                 ScanResult result = (ScanResult) msg.obj;
                 if (result != null) {
-                    now = System.currentTimeMillis();
+                    now = mClock.getWallClockMillis();
                     sb.append(" bssid=").append(result.BSSID);
                     sb.append(" rssi=").append(result.level);
                     sb.append(" freq=").append(result.frequency);
@@ -2890,7 +2781,7 @@
 
     private void handleScreenStateChanged(boolean screenOn) {
         mScreenOn = screenOn;
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             logd(" handleScreenStateChanged Enter: screenOn=" + screenOn
                     + " mUserWantsSuspendOpt=" + mUserWantsSuspendOpt
                     + " state " + getCurrentState().getName()
@@ -2912,7 +2803,7 @@
         }
         mScreenBroadcastReceived.set(true);
 
-        getWifiLinkLayerStats(false);
+        getWifiLinkLayerStats();
         mOnTimeScreenStateChange = mOnTime;
         lastScreenStateChangeTimeStamp = lastLinkLayerStatsUpdate;
 
@@ -2922,7 +2813,7 @@
             mWifiConnectivityManager.handleScreenStateChanged(screenOn);
         }
 
-        if (DBG) log("handleScreenStateChanged Exit: " + screenOn);
+        if (mVerboseLoggingEnabled) log("handleScreenStateChanged Exit: " + screenOn);
     }
 
     private void checkAndSetConnectivityInstance() {
@@ -2943,7 +2834,7 @@
             if (mWifiConnectivityManager != null) {
                 mWifiConnectivityManager.setUserPreferredBand(band);
             }
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 logd("done set frequency band " + band);
             }
         } else {
@@ -2952,7 +2843,7 @@
     }
 
     private void setSuspendOptimizationsNative(int reason, boolean enabled) {
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             log("setSuspendOptimizationsNative: " + reason + " " + enabled
                     + " -want " + mUserWantsSuspendOpt.get()
                     + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
@@ -2966,7 +2857,7 @@
             mSuspendOptNeedsDisabled &= ~reason;
             /* None of dhcp, screen or highperf need it disabled and user wants it enabled */
             if (mSuspendOptNeedsDisabled == 0 && mUserWantsSuspendOpt.get()) {
-                if (DBG) {
+                if (mVerboseLoggingEnabled) {
                     log("setSuspendOptimizationsNative do it " + reason + " " + enabled
                             + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
                             + " - " + Thread.currentThread().getStackTrace()[3].getMethodName()
@@ -2982,13 +2873,13 @@
     }
 
     private void setSuspendOptimizations(int reason, boolean enabled) {
-        if (DBG) log("setSuspendOptimizations: " + reason + " " + enabled);
+        if (mVerboseLoggingEnabled) log("setSuspendOptimizations: " + reason + " " + enabled);
         if (enabled) {
             mSuspendOptNeedsDisabled &= ~reason;
         } else {
             mSuspendOptNeedsDisabled |= reason;
         }
-        if (DBG) log("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
+        if (mVerboseLoggingEnabled) log("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
     }
 
     private void setWifiState(int wifiState) {
@@ -3006,7 +2897,7 @@
 
         mWifiState.set(wifiState);
 
-        if (DBG) log("setWifiState: " + syncGetWifiStateByName());
+        if (mVerboseLoggingEnabled) log("setWifiState: " + syncGetWifiStateByName());
 
         final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -3031,7 +2922,7 @@
         // Update state
         mWifiApState.set(wifiApState);
 
-        if (DBG) log("setWifiApState: " + syncGetWifiApStateByName());
+        if (mVerboseLoggingEnabled) log("setWifiApState: " + syncGetWifiApStateByName());
 
         final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -3069,17 +2960,9 @@
         }
 
         synchronized (mScanResultsLock) {
-            ScanDetail activeScanDetail = null;
             mScanResults = scanResults;
             mNumScanResultsReturned = mScanResults.size();
             for (ScanDetail resultDetail : mScanResults) {
-                if (connected && resultDetail.getNetworkDetail().getBSSID() == activeBssid) {
-                    if (activeScanDetail == null
-                            || activeScanDetail.getNetworkDetail().getBSSID() != activeBssid
-                            || activeScanDetail.getNetworkDetail().getANQPElements() == null) {
-                        activeScanDetail = resultDetail;
-                    }
-                }
                 // Cache DTIM values parsed from the beacon frame Traffic Indication Map (TIM)
                 // Information Element (IE), into the associated WifiConfigurations. Most of the
                 // time there is no TIM IE in the scan result (Probe Response instead of Beacon
@@ -3098,10 +2981,9 @@
                     }
                 }
             }
-            mWifiConfigManager.setActiveScanDetail(activeScanDetail);
         }
 
-        if (linkDebouncing) {
+        if (isLinkDebouncing()) {
             // If debouncing, we dont re-select a SSID or BSSID hence
             // there is no need to call the network selection code
             // in WifiAutoJoinController, instead,
@@ -3140,7 +3022,7 @@
             }
         }
 
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             logd("fetchRssiLinkSpeedAndFrequencyNative rssi=" + newRssi +
                  " linkspeed=" + newLinkSpeed + " freq=" + newFrequency);
         }
@@ -3237,7 +3119,7 @@
     }
 
     private void updateLinkProperties(LinkProperties newLp) {
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             log("Link configuration changed for netId: " + mLastNetworkId
                     + " old: " + mLinkProperties + " new: " + newLp);
         }
@@ -3253,7 +3135,7 @@
             sendLinkConfigurationChangedBroadcast();
         }
 
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             StringBuilder sb = new StringBuilder();
             sb.append("updateLinkProperties nid: " + mLastNetworkId);
             sb.append(" state: " + getNetworkDetailedState());
@@ -3292,7 +3174,7 @@
             if (route.isDefaultRoute() && route.hasGateway()) {
                 InetAddress gateway = route.getGateway();
                 if (gateway instanceof Inet4Address) {
-                    if (DBG) {
+                    if (mVerboseLoggingEnabled) {
                         logd("updateDefaultRouteMacAddress found Ipv4 default :"
                                 + gateway.getHostAddress());
                     }
@@ -3310,7 +3192,7 @@
                             if (reachable == true) {
 
                                 address = macAddressFromRoute(gateway.getHostAddress());
-                                if (DBG) {
+                                if (mVerboseLoggingEnabled) {
                                     logd("updateDefaultRouteMacAddress reachable (tried again) :"
                                             + gateway.getHostAddress() + " found " + address);
                                 }
@@ -3409,7 +3291,7 @@
     private boolean setNetworkDetailedState(NetworkInfo.DetailedState state) {
         boolean hidden = false;
 
-        if (linkDebouncing || isRoaming()) {
+        if (isLinkDebouncing() || isRoaming()) {
             // There is generally a confusion in the system about colluding
             // WiFi Layer 2 state (as reported by supplicant) and the Network state
             // which leads to multiple confusion.
@@ -3424,7 +3306,7 @@
             //
             hidden = true;
         }
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             log("setDetailed state, old ="
                     + mNetworkInfo.getDetailedState() + " and new state=" + state
                     + " hidden=" + hidden);
@@ -3433,7 +3315,7 @@
                 && !mWifiInfo.getSSID().equals(WifiSsid.NONE)) {
             // Always indicate that SSID has changed
             if (!mNetworkInfo.getExtraInfo().equals(mWifiInfo.getSSID())) {
-                if (DBG) {
+                if (mVerboseLoggingEnabled) {
                     log("setDetailed state send new extra info" + mWifiInfo.getSSID());
                 }
                 mNetworkInfo.setExtraInfo(mWifiInfo.getSSID());
@@ -3471,7 +3353,7 @@
         // this implies that wpa_supplicant is already disconnected.
         // We should pretend we are still connected when linkDebouncing is on.
         if ((stateChangeResult.wifiSsid == null
-                || stateChangeResult.wifiSsid.toString().isEmpty()) && linkDebouncing) {
+                || stateChangeResult.wifiSsid.toString().isEmpty()) && isLinkDebouncing()) {
             return state;
         }
         // Network id is only valid when we start connecting
@@ -3483,30 +3365,6 @@
 
         mWifiInfo.setBSSID(stateChangeResult.BSSID);
 
-        if (mWhiteListedSsids != null
-                && mWhiteListedSsids.length > 0
-                && stateChangeResult.wifiSsid != null) {
-            String SSID = stateChangeResult.wifiSsid.toString();
-            String currentSSID = mWifiInfo.getSSID();
-            if (SSID != null && currentSSID != null && !SSID.equals(WifiSsid.NONE)) {
-                // Remove quote before comparing
-                if (SSID.length() >= 2 && SSID.charAt(0) == '"'
-                        && SSID.charAt(SSID.length() - 1) == '"') {
-                    SSID = SSID.substring(1, SSID.length() - 1);
-                }
-                if (currentSSID.length() >= 2 && currentSSID.charAt(0) == '"'
-                        && currentSSID.charAt(currentSSID.length() - 1) == '"') {
-                    currentSSID = currentSSID.substring(1, currentSSID.length() - 1);
-                }
-                if ((!SSID.equals(currentSSID)) && (getCurrentState() == mConnectedState)) {
-                    lastConnectAttemptTimestamp = System.currentTimeMillis();
-                    targetWificonfiguration =
-                            mWifiConfigManager.getWifiConfiguration(mWifiInfo.getNetworkId());
-                    transitionTo(mRoamingState);
-                }
-            }
-        }
-
         mWifiInfo.setSSID(stateChangeResult.wifiSsid);
         mWifiInfo.setEphemeral(mWifiConfigManager.isEphemeral(mWifiInfo.getNetworkId()));
         if (!mWifiInfo.getMeteredHint()) { // don't override the value if already set.
@@ -3523,11 +3381,13 @@
      * using the interface, stopping DHCP & disabling interface
      */
     private void handleNetworkDisconnect() {
-        if (DBG) log("handleNetworkDisconnect: Stopping DHCP and clearing IP"
-                + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
-                + " - " + Thread.currentThread().getStackTrace()[3].getMethodName()
-                + " - " + Thread.currentThread().getStackTrace()[4].getMethodName()
-                + " - " + Thread.currentThread().getStackTrace()[5].getMethodName());
+        if (mVerboseLoggingEnabled) {
+            log("handleNetworkDisconnect: Stopping DHCP and clearing IP"
+                    + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
+                    + " - " + Thread.currentThread().getStackTrace()[3].getMethodName()
+                    + " - " + Thread.currentThread().getStackTrace()[4].getMethodName()
+                    + " - " + Thread.currentThread().getStackTrace()[5].getMethodName());
+        }
 
         stopRssiMonitoringOffload();
 
@@ -3538,7 +3398,7 @@
         /* Reset data structures */
         mWifiScoreReport = null;
         mWifiInfo.reset();
-        linkDebouncing = false;
+        mIsLinkDebouncing = false;
         /* Reset roaming parameters */
         mAutoRoaming = false;
 
@@ -3594,7 +3454,7 @@
              */
             // Disable the coexistence mode
             mWifiNative.setBluetoothCoexistenceMode(
-                    mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
+                    WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
         }
 
         // Disable power save and suspend optimizations during DHCP
@@ -3605,15 +3465,17 @@
         mWifiNative.setPowerSave(false);
 
         // Update link layer stats
-        getWifiLinkLayerStats(false);
+        getWifiLinkLayerStats();
 
-        /* P2p discovery breaks dhcp, shut it down in order to get through this */
-        Message msg = new Message();
-        msg.what = WifiP2pServiceImpl.BLOCK_DISCOVERY;
-        msg.arg1 = WifiP2pServiceImpl.ENABLED;
-        msg.arg2 = DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE;
-        msg.obj = WifiStateMachine.this;
-        mWifiP2pChannel.sendMessage(msg);
+        if (mWifiP2pChannel != null) {
+            /* P2p discovery breaks dhcp, shut it down in order to get through this */
+            Message msg = new Message();
+            msg.what = WifiP2pServiceImpl.BLOCK_DISCOVERY;
+            msg.arg1 = WifiP2pServiceImpl.ENABLED;
+            msg.arg2 = DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE;
+            msg.obj = WifiStateMachine.this;
+            mWifiP2pChannel.sendMessage(msg);
+        }
     }
 
     void handlePostDhcpSetup() {
@@ -3621,12 +3483,11 @@
         setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true);
         mWifiNative.setPowerSave(true);
 
-        mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.BLOCK_DISCOVERY,
-                WifiP2pServiceImpl.DISABLED);
+        p2pSendMessage(WifiP2pServiceImpl.BLOCK_DISCOVERY, WifiP2pServiceImpl.DISABLED);
 
         // Set the coexistence mode back to its default value
         mWifiNative.setBluetoothCoexistenceMode(
-                mWifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
+                WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
     }
 
     /**
@@ -3638,6 +3499,7 @@
         switch (level2FailureCode) {
             case WifiMetrics.ConnectionEvent.FAILURE_NONE:
             case WifiMetrics.ConnectionEvent.FAILURE_REDUNDANT_CONNECTION_ATTEMPT:
+            case WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED:
                 // WifiLogger doesn't care about success, or pre-empted connections.
                 break;
             default:
@@ -3646,7 +3508,7 @@
     }
 
     private void handleIPv4Success(DhcpResults dhcpResults) {
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             logd("handleIPv4Success <" + dhcpResults.toString() + ">");
             logd("link address " + dhcpResults.ipAddress);
         }
@@ -3705,7 +3567,7 @@
         // TODO: Move this to provisioning failure, not DHCP failure.
         // DHCPv4 failure is expected on an IPv6-only network.
         mWifiLogger.captureBugReportData(WifiLogger.REPORT_REASON_DHCP_FAILURE);
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             int count = -1;
             WifiConfiguration config = getCurrentWifiConfiguration();
             if (config != null) {
@@ -3722,7 +3584,7 @@
                  mDhcpResults.clear();
              }
         }
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             logd("handleIPv4Failure");
         }
     }
@@ -3751,82 +3613,28 @@
         mWifiNative.disconnect();
     }
 
-    private int convertFrequencyToChannelNumber(int frequency) {
-        if (frequency >= 2412 && frequency <= 2484) {
-            return (frequency -2412) / 5 + 1;
-        } else if (frequency >= 5170  &&  frequency <=5825) {
-            //DFS is included
-            return (frequency -5170) / 5 + 34;
-        } else {
-            return 0;
-        }
-    }
-
-    private int chooseApChannel(int apBand) {
-        int apChannel;
-        int[] channel;
-
-        if (apBand == 0)  {
-            ArrayList<Integer> allowed2GChannel =
-                    mWifiApConfigStore.getAllowed2GChannel();
-            if (allowed2GChannel == null || allowed2GChannel.size() == 0) {
-                //most safe channel to use
-                if (DBG) {
-                    Log.d(TAG, "No specified 2G allowed channel list");
-                }
-                apChannel = 6;
-            } else {
-                int index = mRandom.nextInt(allowed2GChannel.size());
-                apChannel = allowed2GChannel.get(index).intValue();
-            }
-        } else {
-            //5G without DFS
-            channel = mWifiNative.getChannelsForBand(2);
-            if (channel != null && channel.length > 0) {
-                apChannel = channel[mRandom.nextInt(channel.length)];
-                apChannel = convertFrequencyToChannelNumber(apChannel);
-            } else {
-                Log.e(TAG, "SoftAp do not get available channel list");
-                apChannel = 0;
-            }
-        }
-
-        if (DBG) {
-            Log.d(TAG, "SoftAp set on channel " + apChannel);
-        }
-
-        return apChannel;
-    }
-
     /* Driver/firmware setup for soft AP. */
-    private boolean setupDriverForSoftAp() {
-        if (!mWifiNative.loadDriver()) {
-            Log.e(TAG, "Failed to load driver for softap");
-            return false;
+    private IApInterface setupDriverForSoftAp() {
+        if (mWificond == null) {
+            Log.e(TAG, "Failed to get reference to wificond");
+            return null;
         }
 
-        int index = mWifiNative.queryInterfaceIndex(mInterfaceName);
-        if (index != -1) {
-            if (!mWifiNative.setInterfaceUp(false)) {
-                Log.e(TAG, "toggleInterface failed");
-                return false;
-            }
-        } else {
-            if (DBG) Log.d(TAG, "No interfaces to bring down");
-        }
-
+        IApInterface apInterface = null;
         try {
-            mNwService.wifiFirmwareReload(mInterfaceName, "AP");
-            if (DBG) Log.d(TAG, "Firmware reloaded in AP mode");
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to reload AP firmware " + e);
+            apInterface = mWificond.createApInterface();
+        } catch (RemoteException e1) { }
+
+        if (apInterface == null) {
+            Log.e(TAG, "Could not get IApInterface instance from wificond");
+            return null;
         }
 
         if (!mWifiNative.startHal()) {
             /* starting HAL is optional */
             Log.e(TAG, "Failed to start HAL");
         }
-        return true;
+        return apInterface;
     }
 
     private byte[] macAddressFromString(String macString) {
@@ -3909,6 +3717,7 @@
             --mConnectionRequests;
         }
 
+        @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             pw.println("mConnectionRequests " + mConnectionRequests);
         }
@@ -3946,6 +3755,7 @@
             }
         }
 
+        @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             pw.println("mUntrustedReqCount " + mUntrustedReqCount);
         }
@@ -3975,6 +3785,7 @@
      *******************************************************/
 
     class DefaultState extends State {
+
         @Override
         public boolean processMessage(Message message) {
             logStateAndMessage(message, this);
@@ -3984,7 +3795,7 @@
                     AsyncChannel ac = (AsyncChannel) message.obj;
                     if (ac == mWifiP2pChannel) {
                         if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                            mWifiP2pChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+                            p2pSendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
                         } else {
                             loge("WifiP2pService connection failure, error=" + message.arg1);
                         }
@@ -4081,7 +3892,6 @@
                 case CMD_DISABLE_P2P_RSP:
                 case WifiMonitor.SUP_REQUEST_IDENTITY:
                 case CMD_TEST_NETWORK_DISCONNECT:
-                case CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER:
                 case WifiMonitor.SUP_REQUEST_SIM_AUTH:
                 case CMD_TARGET_BSSID:
                 case CMD_AUTO_CONNECT:
@@ -4092,7 +3902,6 @@
                 case CMD_DISCONNECTING_WATCHDOG_TIMER:
                 case CMD_ROAM_WATCHDOG_TIMER:
                 case CMD_DISABLE_EPHEMERAL_NETWORK:
-                case CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION:
                     messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
                     break;
                 case CMD_SET_SUSPEND_OPT_ENABLED:
@@ -4235,9 +4044,18 @@
     class InitialState extends State {
         @Override
         public void enter() {
+            if (mWificond != null) {
+                try {
+                    mWificond.tearDownInterfaces();
+                } catch (RemoteException e) {
+                    // There is very little we can do here
+                    Log.e(TAG, "Failed to tear down interfaces via wificond");
+                }
+                mWificond = null;
+            }
             mWifiNative.stopHal();
             mWifiNative.unloadDriver();
-            if (mWifiP2pChannel == null) {
+            if (mWifiP2pChannel == null && mWifiP2pServiceImpl != null) {
                 mWifiP2pChannel = new AsyncChannel();
                 mWifiP2pChannel.connect(mContext, getHandler(),
                     mWifiP2pServiceImpl.getP2pStateMachineMessenger());
@@ -4299,7 +4117,7 @@
                         if (mWifiNative.startSupplicant(mP2pSupported)) {
                             setSupplicantLogLevel();
                             setWifiState(WIFI_STATE_ENABLING);
-                            if (DBG) log("Supplicant start successful");
+                            if (mVerboseLoggingEnabled) log("Supplicant start successful");
                             mWifiMonitor.startMonitoring(mInterfaceName);
                             transitionTo(mSupplicantStartingState);
                         } else {
@@ -4312,17 +4130,9 @@
                     }
                     break;
                 case CMD_START_AP:
-                    if (setupDriverForSoftAp()) {
-                        transitionTo(mSoftApState);
-                    } else {
-                        setWifiApState(WIFI_AP_STATE_FAILED,
-                                WifiManager.SAP_START_FAILURE_GENERAL);
-                        /**
-                         * Transition to InitialState (current state) to reset the
-                         * driver/HAL back to the initial state.
-                         */
-                        transitionTo(mInitialState);
-                    }
+                    // Refresh our reference to wificond.  This allows us to tolerate restarts.
+                    mWificond = mWifiInjector.makeWificond();
+                    transitionTo(mSoftApState);
                     break;
                 default:
                     return NOT_HANDLED;
@@ -4368,7 +4178,7 @@
 
             switch(message.what) {
                 case WifiMonitor.SUP_CONNECTION_EVENT:
-                    if (DBG) log("Supplicant connection established");
+                    if (mVerboseLoggingEnabled) log("Supplicant connection established");
                     setWifiState(WIFI_STATE_ENABLED);
                     mSupplicantRestartCount = 0;
                     /* Reset the supplicant state to indicate the supplicant
@@ -4384,9 +4194,6 @@
                     setFrequencyBand();
                     mWifiNative.enableSaveConfig();
                     mWifiConfigManager.loadAndEnableAllNetworks();
-                    if (mWifiConfigManager.mEnableVerboseLogging.get() > 0) {
-                        enableVerboseLogging(mWifiConfigManager.mEnableVerboseLogging.get());
-                    }
                     initializeWpsDetails();
 
                     sendSupplicantConnectionChangedBroadcast(true);
@@ -4514,7 +4321,7 @@
                     }
                     break;
                 case CMD_GET_LINK_LAYER_STATS:
-                    WifiLinkLayerStats stats = getWifiLinkLayerStats(DBG);
+                    WifiLinkLayerStats stats = getWifiLinkLayerStats();
                     replyToMessage(message, message.what, stats);
                     break;
                 case CMD_RESET_SIM_NETWORKS:
@@ -4566,7 +4373,7 @@
                     loge("Supplicant connection received while stopping");
                     break;
                 case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                    if (DBG) log("Supplicant connection lost");
+                    if (mVerboseLoggingEnabled) log("Supplicant connection lost");
                     handleSupplicantConnectionLoss(false);
                     transitionTo(mInitialState);
                     break;
@@ -4610,7 +4417,7 @@
             switch(message.what) {
                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                     SupplicantState state = handleSupplicantStateChange(message);
-                    /* If suplicant is exiting out of INTERFACE_DISABLED state into
+                    /* If supplicant is exiting out of INTERFACE_DISABLED state into
                      * a state that indicates driver has started, it is ready to
                      * receive driver commands
                      */
@@ -4668,7 +4475,7 @@
     class DriverStartedState extends State {
         @Override
         public void enter() {
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 logd("DriverStartedState enter");
             }
 
@@ -4683,7 +4490,7 @@
                     getHandler().getLooper());
             }
 
-            mWifiLogger.startLogging(DBG);
+            mWifiLogger.startLogging(mVerboseLoggingEnabled);
             mIsRunning = true;
             updateBatteryWorkSource(null);
             /**
@@ -4714,19 +4521,18 @@
                 // Status pulls in the current supplicant state and network connection state
                 // events over the monitor connection. This helps framework sync up with
                 // current supplicant state
-                // TODO: actually check th supplicant status string and make sure the supplicant
+                // TODO: actually check the supplicant status string and make sure the supplicant
                 // is in disconnecte4d state.
                 mWifiNative.status();
                 // Transitioning to Disconnected state will trigger a scan and subsequently AutoJoin
                 transitionTo(mDisconnectedState);
-                transitionTo(mDisconnectedState);
             }
 
             // We may have missed screen update at boot
             if (mScreenBroadcastReceived.get() == false) {
                 PowerManager powerManager = (PowerManager)mContext.getSystemService(
                         Context.POWER_SERVICE);
-                handleScreenStateChanged(powerManager.isScreenOn());
+                handleScreenStateChanged(powerManager.isInteractive());
             } else {
                 // Set the right suspend mode settings
                 mWifiNative.setSuspendOptimizations(mSuspendOptNeedsDisabled == 0
@@ -4741,14 +4547,25 @@
 
             if (mP2pSupported) {
                 if (mOperationalMode == CONNECT_MODE) {
-                    mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_ENABLE_P2P);
+                    p2pSendMessage(WifiStateMachine.CMD_ENABLE_P2P);
                 } else {
-                    // P2P statemachine starts in disabled state, and is not enabled until
+                    // P2P state machine starts in disabled state, and is not enabled until
                     // CMD_ENABLE_P2P is sent from here; so, nothing needs to be done to
                     // keep it disabled.
                 }
             }
 
+            if (mNanSupported && mWifiNanManager != null) {
+                if (mOperationalMode == CONNECT_MODE) {
+                    mWifiNanManager.enableUsage();
+                } else {
+                    /*
+                     * NAN state machine starts in disabled state. Nothing
+                     * needed to keep it disabled.
+                     */
+                }
+            }
+
             final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE);
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_ENABLED);
@@ -4768,16 +4585,16 @@
                     break;
                 case CMD_SET_FREQUENCY_BAND:
                     int band =  message.arg1;
-                    if (DBG) log("set frequency band " + band);
+                    if (mVerboseLoggingEnabled) log("set frequency band " + band);
                     if (mWifiNative.setBand(band)) {
 
-                        if (DBG)  logd("did set frequency band " + band);
+                        if (mVerboseLoggingEnabled)  logd("did set frequency band " + band);
 
                         mFrequencyBand.set(band);
                         // Flush old data - like scan results
                         mWifiNative.bssFlush();
 
-                        if (DBG)  logd("done set frequency band " + band);
+                        if (mVerboseLoggingEnabled)  logd("done set frequency band " + band);
 
                     } else {
                         loge("Failed to set frequency band " + band);
@@ -4789,8 +4606,6 @@
                     mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
                     break;
                 case CMD_STOP_DRIVER:
-                    int mode = message.arg1;
-
                     log("stop driver");
                     mWifiConfigManager.disableAllNetworksNative();
 
@@ -4878,9 +4693,9 @@
             }
             return HANDLED;
         }
+
         @Override
         public void exit() {
-
             mWifiLogger.stopLogging();
 
             mIsRunning = false;
@@ -4892,6 +4707,10 @@
             intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_DISABLED);
             mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
             mBufferedScanMsg.clear();
+
+            if (mNanSupported && mWifiNanManager != null) {
+                mWifiNanManager.disableUsage();
+            }
         }
     }
 
@@ -4913,7 +4732,7 @@
                     mTransitionToState = mDriverStoppingState;
                     break;
             }
-            mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_REQ);
+            p2pSendMessage(WifiStateMachine.CMD_DISABLE_P2P_REQ);
         }
         @Override
         public boolean processMessage(Message message) {
@@ -5023,7 +4842,7 @@
                             // Load and re-enable networks when going back to enabled state
                             // This is essential for networks to show up after restore
                             mWifiConfigManager.loadAndEnableAllNetworks();
-                            mWifiP2pChannel.sendMessage(CMD_ENABLE_P2P);
+                            p2pSendMessage(CMD_ENABLE_P2P);
                         } else {
                             mWifiConfigManager.enableAllNetworks();
                         }
@@ -5047,7 +4866,7 @@
                     break;
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                     SupplicantState state = handleSupplicantStateChange(message);
-                    if (DBG) log("SupplicantState= " + state);
+                    if (mVerboseLoggingEnabled) log("SupplicantState= " + state);
                     break;
                 default:
                     return NOT_HANDLED;
@@ -5200,7 +5019,7 @@
             if (config != null) {
                 //Here we will clear all disable counters once a network is connected
                 //records how long this network is connected in future
-                config.lastConnected = System.currentTimeMillis();
+                config.lastConnected = mClock.getWallClockMillis();
                 config.numAssociation++;
                 WifiConfiguration.NetworkSelectionStatus networkSelectionStatus =
                         config.getNetworkSelectionStatus();
@@ -5218,7 +5037,7 @@
             // hence record the time we were connected last
             WifiConfiguration config = mWifiConfigManager.getWifiConfiguration(mLastNetworkId);
             if (config != null) {
-                config.lastDisconnected = System.currentTimeMillis();
+                config.lastDisconnected = mClock.getWallClockMillis();
                 if (config.ephemeral) {
                     // Remove ephemeral WifiConfigurations from file
                     mWifiConfigManager.forgetNetwork(mLastNetworkId);
@@ -5289,7 +5108,7 @@
     }
 
     String getCurrentBSSID() {
-        if (linkDebouncing) {
+        if (isLinkDebouncing()) {
             return null;
         }
         return mLastBssid;
@@ -5305,8 +5124,6 @@
             }
             // Inform metrics that Wifi is Enabled (but not yet connected)
             mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED);
-
-
         }
 
         @Override
@@ -5356,9 +5173,10 @@
                     reportConnectionAttemptEnd(
                             WifiMetrics.ConnectionEvent.FAILURE_ASSOCIATION_REJECTION,
                             WifiMetricsProto.ConnectionEvent.HLF_NONE);
-                    mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(getTargetSsid(),
-                            bssid,
-                            WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION);
+                    mWifiInjector.getWifiLastResortWatchdog()
+                            .noteConnectionFailureAndTriggerIfNeeded(
+                                    getTargetSsid(), bssid,
+                                    WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION);
                     break;
                 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
                     mWifiLogger.captureBugReportData(WifiLogger.REPORT_REASON_AUTH_FAILURE);
@@ -5372,9 +5190,10 @@
                     reportConnectionAttemptEnd(
                             WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
                             WifiMetricsProto.ConnectionEvent.HLF_NONE);
-                    mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(getTargetSsid(),
-                            mTargetRoamBSSID,
-                            WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION);
+                    mWifiInjector.getWifiLastResortWatchdog()
+                            .noteConnectionFailureAndTriggerIfNeeded(
+                                    getTargetSsid(), mTargetRoamBSSID,
+                                    WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION);
                     break;
                 case WifiMonitor.SSID_TEMP_DISABLED:
                     Log.e(TAG, "Supplicant SSID temporary disabled:"
@@ -5386,9 +5205,10 @@
                     reportConnectionAttemptEnd(
                             WifiMetrics.ConnectionEvent.FAILURE_SSID_TEMP_DISABLED,
                             WifiMetricsProto.ConnectionEvent.HLF_NONE);
-                    mWifiLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(getTargetSsid(),
-                            mTargetRoamBSSID,
-                            WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION);
+                    mWifiInjector.getWifiLastResortWatchdog()
+                            .noteConnectionFailureAndTriggerIfNeeded(
+                                    getTargetSsid(), mTargetRoamBSSID,
+                                    WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION);
                     break;
                 case WifiMonitor.SSID_REENABLED:
                     Log.d(TAG, "Supplicant SSID reenable:"
@@ -5415,9 +5235,11 @@
                     // we can figure this from the supplicant state. If supplicant
                     // state is DISCONNECTED, but the mNetworkInfo says we are not
                     // disconnected, we need to handle a disconnection
-                    if (!linkDebouncing && state == SupplicantState.DISCONNECTED &&
+                    if (!isLinkDebouncing() && state == SupplicantState.DISCONNECTED &&
                             mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
-                        if (DBG) log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
+                        if (mVerboseLoggingEnabled) {
+                            log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
+                        }
                         handleNetworkDisconnect();
                         transitionTo(mDisconnectedState);
                     }
@@ -5484,7 +5306,7 @@
                                 }
 
                                 // Remember time of last connection attempt
-                                lastConnectAttemptTimestamp = System.currentTimeMillis();
+                                lastConnectAttemptTimestamp = mClock.getWallClockMillis();
                                 mWifiConnectionStatistics.numWifiManagerJoinAttempt++;
 
                                 // As a courtesy to the caller, trigger a scan now
@@ -5545,7 +5367,7 @@
                     // networks need to be disabled
                     if (disableOthers) {
                         // Remember time of last connection attempt
-                        lastConnectAttemptTimestamp = System.currentTimeMillis();
+                        lastConnectAttemptTimestamp = mClock.getWallClockMillis();
                         mWifiConnectionStatistics.numWifiManagerJoinAttempt++;
                     }
                     // Cancel auto roam requests
@@ -5596,7 +5418,7 @@
                 case CMD_SAVE_CONFIG:
                     ok = mWifiConfigManager.saveConfig();
 
-                    if (DBG) logd("did save config " + ok);
+                    if (mVerboseLoggingEnabled) logd("did save config " + ok);
                     replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
 
                     // Inform the backup manager about a data change
@@ -5679,14 +5501,14 @@
                     }
                     break;
                 case CMD_REASSOCIATE:
-                    lastConnectAttemptTimestamp = System.currentTimeMillis();
+                    lastConnectAttemptTimestamp = mClock.getWallClockMillis();
                     mWifiNative.reassociate();
                     break;
                 case CMD_RELOAD_TLS_AND_RECONNECT:
                     if (mWifiConfigManager.needsUnlockedKeyStore()) {
                         logd("Reconnecting to give a chance to un-connected TLS networks");
                         mWifiNative.disconnect();
-                        lastConnectAttemptTimestamp = System.currentTimeMillis();
+                        lastConnectAttemptTimestamp = mClock.getWallClockMillis();
                         mWifiNative.reconnect();
                     }
                     break;
@@ -5783,7 +5605,7 @@
                     }
                     if (mWifiConfigManager.selectNetwork(config, /* updatePriorities = */ false,
                             lastConnectUid) && mWifiNative.reconnect()) {
-                        lastConnectAttemptTimestamp = System.currentTimeMillis();
+                        lastConnectAttemptTimestamp = mClock.getWallClockMillis();
                         targetWificonfiguration = mWifiConfigManager.getWifiConfiguration(netId);
                         config = mWifiConfigManager.getWifiConfiguration(netId);
                         if (config != null
@@ -5805,7 +5627,7 @@
                                          WifiConfiguration.INVALID_NETWORK_ID);
                         }
                         mAutoRoaming = false;
-                        if (isRoaming() || linkDebouncing) {
+                        if (isRoaming() || isLinkDebouncing()) {
                             transitionTo(mRoamingState);
                         } else if (didDisconnect) {
                             transitionTo(mDisconnectingState);
@@ -5946,7 +5768,7 @@
                             WifiMetricsProto.ConnectionEvent.ROAM_USER_SELECTED);
                     if (mWifiConfigManager.selectNetwork(config, /* updatePriorities = */ true,
                             message.sendingUid) && mWifiNative.reconnect()) {
-                        lastConnectAttemptTimestamp = System.currentTimeMillis();
+                        lastConnectAttemptTimestamp = mClock.getWallClockMillis();
                         targetWificonfiguration = mWifiConfigManager.getWifiConfiguration(netId);
 
                         /* The state tracker handles enabling networks upon completion/failure */
@@ -6045,7 +5867,7 @@
                         replyToMessage(message, WifiManager.SAVE_NETWORK_SUCCEEDED);
                         broadcastWifiCredentialChanged(WifiManager.WIFI_CREDENTIAL_SAVED, config);
 
-                        if (DBG) {
+                        if (mVerboseLoggingEnabled) {
                            logd("Success save network nid="
                                     + Integer.toString(result.getNetworkId()));
                         }
@@ -6167,14 +5989,15 @@
                     }
                     return NOT_HANDLED;
                 case WifiMonitor.NETWORK_CONNECTION_EVENT:
-                    if (DBG) log("Network connection established");
+                    if (mVerboseLoggingEnabled) log("Network connection established");
                     mLastNetworkId = message.arg1;
                     mLastBssid = (String) message.obj;
 
                     mWifiInfo.setBSSID(mLastBssid);
                     mWifiInfo.setNetworkId(mLastNetworkId);
-                    mWifiQualifiedNetworkSelector
-                            .enableBssidForQualityNetworkSelection(mLastBssid, true);
+                    if (mWifiConnectivityManager != null) {
+                        mWifiConnectivityManager.trackBssid(mLastBssid, true);
+                    }
                     sendNetworkStateChangeBroadcast(mLastBssid);
                     transitionTo(mObtainingIpState);
                     break;
@@ -6188,7 +6011,7 @@
                     // The side effect of calling handleNetworkDisconnect twice is that a bunch of
                     // idempotent commands are executed twice (stopping Dhcp, enabling the SPS mode
                     // at the chip etc...
-                    if (DBG) log("ConnectModeState: Network connection lost ");
+                    if (mVerboseLoggingEnabled) log("ConnectModeState: Network connection lost ");
                     handleNetworkDisconnect();
                     transitionTo(mDisconnectedState);
                     break;
@@ -6258,11 +6081,14 @@
                 NetworkCapabilities nc, LinkProperties lp, int score, NetworkMisc misc) {
             super(l, c, TAG, ni, nc, lp, score, misc);
         }
+
+        @Override
         protected void unwanted() {
             // Ignore if we're not the current networkAgent.
             if (this != mNetworkAgent) return;
-            if (DBG) log("WifiNetworkAgent -> Wifi unwanted score "
-                    + Integer.toString(mWifiInfo.score));
+            if (mVerboseLoggingEnabled) {
+                log("WifiNetworkAgent -> Wifi unwanted score " + Integer.toString(mWifiInfo.score));
+            }
             unwantedNetwork(NETWORK_STATUS_UNWANTED_DISCONNECT);
         }
 
@@ -6270,11 +6096,13 @@
         protected void networkStatus(int status, String redirectUrl) {
             if (this != mNetworkAgent) return;
             if (status == NetworkAgent.INVALID_NETWORK) {
-                if (DBG) log("WifiNetworkAgent -> Wifi networkStatus invalid, score="
-                        + Integer.toString(mWifiInfo.score));
+                if (mVerboseLoggingEnabled) {
+                    log("WifiNetworkAgent -> Wifi networkStatus invalid, score="
+                            + Integer.toString(mWifiInfo.score));
+                }
                 unwantedNetwork(NETWORK_STATUS_UNWANTED_VALIDATION_FAILED);
             } else if (status == NetworkAgent.VALID_NETWORK) {
-                if (DBG) {
+                if (mVerboseLoggingEnabled) {
                     log("WifiNetworkAgent -> Wifi networkStatus valid, score= "
                             + Integer.toString(mWifiInfo.score));
                 }
@@ -6412,7 +6240,7 @@
         }
         HashSet<Integer> freqs = mWifiConfigManager.makeChannelList(config, ONE_HOUR_MILLI);
         if (freqs != null && freqs.size() != 0) {
-            //if (DBG) {
+            //if (mVerboseLoggingEnabled) {
             logd("starting scan for " + config.configKey() + " with " + freqs);
             //}
             Set<Integer> hiddenNetworkIds = new HashSet<>();
@@ -6428,7 +6256,7 @@
             }
             return true;
         } else {
-            if (DBG) logd("no channels for " + config.configKey());
+            if (mVerboseLoggingEnabled) logd("no channels for " + config.configKey());
             return false;
         }
     }
@@ -6443,12 +6271,12 @@
     void clearConfigBSSID(WifiConfiguration config, String dbg) {
         if (config == null)
             return;
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
             logd(dbg + " " + mTargetRoamBSSID + " config " + config.configKey()
                     + " config.NetworkSelectionStatus.mNetworkSelectionBSSID "
                     + config.getNetworkSelectionStatus().getNetworkSelectionBSSID());
         }
-        if (DBG) {
+        if (mVerboseLoggingEnabled) {
            logd(dbg + " " + config.SSID
                     + " nid=" + Integer.toString(config.networkId));
         }
@@ -6489,7 +6317,7 @@
             // For paranoia's sake, call handleNetworkDisconnect
             // only if BSSID is null or last networkId
             // is not invalid.
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 StringBuilder sb = new StringBuilder();
                 sb.append("leaving L2ConnectedState state nid=" + Integer.toString(mLastNetworkId));
                 if (mLastBssid !=null) {
@@ -6543,12 +6371,15 @@
                     break;
                 case CMD_IP_CONFIGURATION_LOST:
                     // Get Link layer stats so that we get fresh tx packet counters.
-                    getWifiLinkLayerStats(true);
+                    getWifiLinkLayerStats();
                     handleIpConfigurationLost();
+                    reportConnectionAttemptEnd(
+                            WifiMetrics.ConnectionEvent.FAILURE_DHCP,
+                            WifiMetricsProto.ConnectionEvent.HLF_NONE);
                     transitionTo(mDisconnectingState);
                     break;
                 case CMD_IP_REACHABILITY_LOST:
-                    if (DBG && message.obj != null) log((String) message.obj);
+                    if (mVerboseLoggingEnabled && message.obj != null) log((String) message.obj);
                     handleIpReachabilityLost();
                     transitionTo(mDisconnectingState);
                     break;
@@ -6586,7 +6417,7 @@
                     mWifiInfo.setBSSID((String) message.obj);
                     mLastNetworkId = message.arg1;
                     mWifiInfo.setNetworkId(mLastNetworkId);
-                    if(!mLastBssid.equals((String) message.obj)) {
+                    if(!mLastBssid.equals(message.obj)) {
                         mLastBssid = (String) message.obj;
                         sendNetworkStateChangeBroadcast(mLastBssid);
                     }
@@ -6594,8 +6425,10 @@
                 case CMD_RSSI_POLL:
                     if (message.arg1 == mRssiPollToken) {
                         if (mWifiConfigManager.mEnableChipWakeUpWhenAssociated.get()) {
-                            if (DBG) log(" get link layer stats " + mWifiLinkLayerStatsSupported);
-                            WifiLinkLayerStats stats = getWifiLinkLayerStats(DBG);
+                            if (mVerboseLoggingEnabled) {
+                                log(" get link layer stats " + mWifiLinkLayerStatsSupported);
+                            }
+                            WifiLinkLayerStats stats = getWifiLinkLayerStats();
                             if (stats != null) {
                                 // Sanity check the results provided by driver
                                 if (mWifiInfo.getRssi() != WifiInfo.INVALID_RSSI
@@ -6612,11 +6445,12 @@
                                                                    mWifiConfigManager,
                                                                    mNetworkAgent,
                                                                    mWifiScoreReport,
-                                                                   mAggressiveHandover);
+                                                                   mAggressiveHandover,
+                                                                   mVerboseLoggingEnabled);
                         }
                         sendMessageDelayed(obtainMessage(CMD_RSSI_POLL,
                                 mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
-                        if (DBG) sendRssiChangeBroadcast(mWifiInfo.getRssi());
+                        if (mVerboseLoggingEnabled) sendRssiChangeBroadcast(mWifiInfo.getRssi());
                     } else {
                         // Polling has completed
                     }
@@ -6644,7 +6478,7 @@
                     replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED, info);
                     break;
                 case CMD_DELAYED_NETWORK_DISCONNECT:
-                    if (!linkDebouncing && mWifiConfigManager.mEnableLinkDebouncing) {
+                    if (!isLinkDebouncing()) {
 
                         // Ignore if we are not debouncing
                         logd("CMD_DELAYED_NETWORK_DISCONNECT and not debouncing - ignore "
@@ -6654,7 +6488,7 @@
                         logd("CMD_DELAYED_NETWORK_DISCONNECT and debouncing - disconnect "
                                 + message.arg1);
 
-                        linkDebouncing = false;
+                        mIsLinkDebouncing = false;
                         // If we are still debouncing while this message comes,
                         // it means we were not able to reconnect within the alloted time
                         // = LINK_FLAPPING_DEBOUNCE_MSEC
@@ -6706,7 +6540,7 @@
     class ObtainingIpState extends State {
         @Override
         public void enter() {
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 String key = "";
                 if (getCurrentWifiConfiguration() != null) {
                     key = getCurrentWifiConfiguration().configKey();
@@ -6714,13 +6548,12 @@
                 log("enter ObtainingIpState netId=" + Integer.toString(mLastNetworkId)
                         + " " + key + " "
                         + " roam=" + mAutoRoaming
-                        + " static=" + mWifiConfigManager.isUsingStaticIp(mLastNetworkId)
-                        + " watchdog= " + obtainingIpWatchdogCount);
+                        + " static=" + mWifiConfigManager.isUsingStaticIp(mLastNetworkId));
             }
 
             // Reset link Debouncing, indicating we have successfully re-connected to the AP
             // We might still be roaming
-            linkDebouncing = false;
+            mIsLinkDebouncing = false;
 
             // Send event to CM & network change broadcast
             setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
@@ -6749,17 +6582,13 @@
 
             if (!mWifiConfigManager.isUsingStaticIp(mLastNetworkId)) {
                 final IpManager.ProvisioningConfiguration prov =
-                        mIpManager.buildProvisioningConfiguration()
+                        IpManager.buildProvisioningConfiguration()
                             .withPreDhcpAction()
                             .withApfCapabilities(mWifiNative.getApfCapabilities())
                             .build();
                 mIpManager.startProvisioning(prov);
-                obtainingIpWatchdogCount++;
-                logd("Start Dhcp Watchdog " + obtainingIpWatchdogCount);
                 // Get Link layer stats so as we get fresh tx packet counters
-                getWifiLinkLayerStats(true);
-                sendMessageDelayed(obtainMessage(CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER,
-                        obtainingIpWatchdogCount, 0), OBTAINING_IP_ADDRESS_GUARD_TIMER_MSEC);
+                getWifiLinkLayerStats();
             } else {
                 StaticIpConfiguration config = mWifiConfigManager.getStaticIpConfiguration(
                         mLastNetworkId);
@@ -6768,7 +6597,7 @@
                     sendMessage(CMD_IPV4_PROVISIONING_FAILURE);
                 } else {
                     final IpManager.ProvisioningConfiguration prov =
-                            mIpManager.buildProvisioningConfiguration()
+                            IpManager.buildProvisioningConfiguration()
                                 .withStaticConfiguration(config)
                                 .withApfCapabilities(mWifiNative.getApfCapabilities())
                                 .build();
@@ -6807,16 +6636,6 @@
                     messageHandlingStatus = MESSAGE_HANDLING_STATUS_DEFERRED;
                     deferMessage(message);
                     break;
-                case CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER:
-                    if (message.arg1 == obtainingIpWatchdogCount) {
-                        logd("ObtainingIpAddress: Watchdog Triggered, count="
-                                + obtainingIpWatchdogCount);
-                        handleIpConfigurationLost();
-                        transitionTo(mDisconnectingState);
-                        break;
-                    }
-                    messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
-                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -6831,14 +6650,14 @@
         if (mWifiConfigManager.isLastSelectedConfiguration(config)) {
             boolean prompt =
                     mWifiConfigManager.checkConfigOverridePermission(config.lastConnectUid);
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 log("Network selected by UID " + config.lastConnectUid + " prompt=" + prompt);
             }
             if (prompt) {
                 // Selected by the user via Settings or QuickSettings. If this network has Internet
                 // access, switch to it. Otherwise, switch to it only if the user confirms that they
                 // really want to switch, or has already confirmed and selected "Don't ask again".
-                if (DBG) {
+                if (mVerboseLoggingEnabled) {
                     log("explictlySelected acceptUnvalidated=" + config.noInternetAccessExpected);
                 }
                 mNetworkAgent.explicitlySelected(config.noInternetAccessExpected);
@@ -6854,7 +6673,7 @@
         boolean mAssociated;
         @Override
         public void enter() {
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 log("RoamingState Enter"
                         + " mScreenOn=" + mScreenOn );
             }
@@ -6880,7 +6699,9 @@
                     }
                     return NOT_HANDLED;
                 case CMD_UNWANTED_NETWORK:
-                    if (DBG) log("Roaming and CS doesnt want the network -> ignore");
+                    if (mVerboseLoggingEnabled) {
+                        log("Roaming and CS doesnt want the network -> ignore");
+                    }
                     return HANDLED;
                 case CMD_SET_OPERATIONAL_MODE:
                     if (message.arg1 != CONNECT_MODE) {
@@ -6899,7 +6720,7 @@
                     if (stateChangeResult.state == SupplicantState.DISCONNECTED
                             || stateChangeResult.state == SupplicantState.INACTIVE
                             || stateChangeResult.state == SupplicantState.INTERFACE_DISABLED) {
-                        if (DBG) {
+                        if (mVerboseLoggingEnabled) {
                             log("STATE_CHANGE_EVENT in roaming state "
                                     + stateChangeResult.toString() );
                         }
@@ -6913,13 +6734,13 @@
                         // We completed the layer2 roaming part
                         mAssociated = true;
                         if (stateChangeResult.BSSID != null) {
-                            mTargetRoamBSSID = (String) stateChangeResult.BSSID;
+                            mTargetRoamBSSID = stateChangeResult.BSSID;
                         }
                     }
                     break;
                 case CMD_ROAM_WATCHDOG_TIMER:
                     if (roamWatchdogCount == message.arg1) {
-                        if (DBG) log("roaming watchdog! -> disconnect");
+                        if (mVerboseLoggingEnabled) log("roaming watchdog! -> disconnect");
                         mWifiMetrics.endConnectionEvent(
                                 WifiMetrics.ConnectionEvent.FAILURE_ROAM_TIMEOUT,
                                 WifiMetricsProto.ConnectionEvent.HLF_NONE);
@@ -6931,7 +6752,9 @@
                     break;
                 case WifiMonitor.NETWORK_CONNECTION_EVENT:
                     if (mAssociated) {
-                        if (DBG) log("roaming and Network connection established");
+                        if (mVerboseLoggingEnabled) {
+                            log("roaming and Network connection established");
+                        }
                         mLastNetworkId = message.arg1;
                         mLastBssid = (String) message.obj;
                         mWifiInfo.setBSSID(mLastBssid);
@@ -7018,9 +6841,8 @@
     class ConnectedState extends State {
         @Override
         public void enter() {
-            String address;
             updateDefaultRouteMacAddress(1000);
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 log("Enter ConnectedState "
                        + " mScreenOn=" + mScreenOn);
             }
@@ -7033,7 +6855,7 @@
             lastConnectAttemptTimestamp = 0;
             targetWificonfiguration = null;
             // Paranoia
-            linkDebouncing = false;
+            mIsLinkDebouncing = false;
 
             // Not roaming anymore
             mAutoRoaming = false;
@@ -7051,7 +6873,7 @@
 
             mLastDriverRoamAttempt = 0;
             mTargetNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
-            mWifiLastResortWatchdog.connectedStateTransition(true);
+            mWifiInjector.getWifiLastResortWatchdog().connectedStateTransition(true);
         }
         @Override
         public boolean processMessage(Message message) {
@@ -7059,9 +6881,6 @@
             logStateAndMessage(message, this);
 
             switch (message.what) {
-                case CMD_UPDATE_ASSOCIATED_SCAN_PERMISSION:
-                    updateAssociatedScanPermission();
-                    break;
                 case CMD_UNWANTED_NETWORK:
                     if (message.arg1 == NETWORK_STATUS_UNWANTED_DISCONNECT) {
                         mWifiConfigManager.handleBadNetworkDisconnectReport(
@@ -7121,7 +6940,7 @@
                 case CMD_ASSOCIATED_BSSID:
                     // ASSOCIATING to a new BSSID while already connected, indicates
                     // that driver is roaming
-                    mLastDriverRoamAttempt = System.currentTimeMillis();
+                    mLastDriverRoamAttempt = mClock.getWallClockMillis();
                     return NOT_HANDLED;
                 case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
                     long lastRoam = 0;
@@ -7130,7 +6949,7 @@
                             WifiMetricsProto.ConnectionEvent.HLF_NONE);
                     if (mLastDriverRoamAttempt != 0) {
                         // Calculate time since last driver roam attempt
-                        lastRoam = System.currentTimeMillis() - mLastDriverRoamAttempt;
+                        lastRoam = mClock.getWallClockMillis() - mLastDriverRoamAttempt;
                         mLastDriverRoamAttempt = 0;
                     }
                     if (unexpectedDisconnectedReason(message.arg2)) {
@@ -7138,8 +6957,9 @@
                                 WifiLogger.REPORT_REASON_UNEXPECTED_DISCONNECT);
                     }
                     config = getCurrentWifiConfiguration();
-                    if (mScreenOn
-                            && !linkDebouncing
+                    if (mWifiConfigManager.mEnableLinkDebouncing
+                            && mScreenOn
+                            && !isLinkDebouncing()
                             && config != null
                             && config.getNetworkSelectionStatus().isNetworkEnabled()
                             && !mWifiConfigManager.isLastSelectedConfiguration(config)
@@ -7158,11 +6978,11 @@
                         // roaming cycle and enter Obtaining IP address
                         // before signalling the disconnect to ConnectivityService and L3
                         startScanForConfiguration(getCurrentWifiConfiguration());
-                        linkDebouncing = true;
+                        mIsLinkDebouncing = true;
 
                         sendMessageDelayed(obtainMessage(CMD_DELAYED_NETWORK_DISCONNECT,
                                 0, mLastNetworkId), LINK_FLAPPING_DEBOUNCE_MSEC);
-                        if (DBG) {
+                        if (mVerboseLoggingEnabled) {
                             log("NETWORK_DISCONNECTION_EVENT in connected state"
                                     + " BSSID=" + mWifiInfo.getBSSID()
                                     + " RSSI=" + mWifiInfo.getRssi()
@@ -7172,12 +6992,12 @@
                         }
                         return HANDLED;
                     } else {
-                        if (DBG) {
+                        if (mVerboseLoggingEnabled) {
                             log("NETWORK_DISCONNECTION_EVENT in connected state"
                                     + " BSSID=" + mWifiInfo.getBSSID()
                                     + " RSSI=" + mWifiInfo.getRssi()
                                     + " freq=" + mWifiInfo.getFrequency()
-                                    + " was debouncing=" + linkDebouncing
+                                    + " was debouncing=" + isLinkDebouncing()
                                     + " reason=" + message.arg2
                                     + " Network Selection Status=" + (config == null ? "Unavailable"
                                     : config.getNetworkSelectionStatus().getNetworkStatusString()));
@@ -7262,7 +7082,7 @@
                         ret = mWifiNative.reassociate();
                     }
                     if (ret) {
-                        lastConnectAttemptTimestamp = System.currentTimeMillis();
+                        lastConnectAttemptTimestamp = mClock.getWallClockMillis();
                         targetWificonfiguration = mWifiConfigManager.getWifiConfiguration(netId);
 
                         // replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
@@ -7316,8 +7136,7 @@
             }
 
             mLastDriverRoamAttempt = 0;
-            mWhiteListedSsids = null;
-            mWifiLastResortWatchdog.connectedStateTransition(false);
+            mWifiInjector.getWifiLastResortWatchdog().connectedStateTransition(false);
         }
     }
 
@@ -7326,7 +7145,7 @@
         @Override
         public void enter() {
 
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 logd(" Enter DisconnectingState State screenOn=" + mScreenOn);
             }
 
@@ -7356,7 +7175,7 @@
                     return HANDLED;
                 case CMD_DISCONNECTING_WATCHDOG_TIMER:
                     if (disconnectingWatchdogCount == message.arg1) {
-                        if (DBG) log("disconnecting watchdog! -> disconnect");
+                        if (mVerboseLoggingEnabled) log("disconnecting watchdog! -> disconnect");
                         handleNetworkDisconnect();
                         transitionTo(mDisconnectedState);
                     }
@@ -7384,11 +7203,11 @@
             // We dont scan frequently if this is a temporary disconnect
             // due to p2p
             if (mTemporarilyDisconnectWifi) {
-                mWifiP2pChannel.sendMessage(WifiP2pServiceImpl.DISCONNECT_WIFI_RESPONSE);
+                p2pSendMessage(WifiP2pServiceImpl.DISCONNECT_WIFI_RESPONSE);
                 return;
             }
 
-            if (DBG) {
+            if (mVerboseLoggingEnabled) {
                 logd(" Enter DisconnectedState screenOn=" + mScreenOn);
             }
 
@@ -7411,7 +7230,7 @@
                         ++mPeriodicScanToken, 0), mNoNetworksPeriodicScan);
             }
 
-            mDisconnectedTimeStamp = System.currentTimeMillis();
+            mDisconnectedTimeStamp = mClock.getWallClockMillis();
         }
         @Override
         public boolean processMessage(Message message) {
@@ -7445,7 +7264,7 @@
                         mOperationalMode = message.arg1;
                         mWifiConfigManager.disableAllNetworksNative();
                         if (mOperationalMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
-                            mWifiP2pChannel.sendMessage(CMD_DISABLE_P2P_REQ);
+                            p2pSendMessage(CMD_DISABLE_P2P_REQ);
                             setWifiState(WIFI_STATE_DISABLED);
                         }
                         transitionTo(mScanModeState);
@@ -7460,10 +7279,10 @@
                     break;
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                     StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-                    if (DBG) {
+                    if (mVerboseLoggingEnabled) {
                         logd("SUPPLICANT_STATE_CHANGE_EVENT state=" + stateChangeResult.state +
                                 " -> state= " + WifiInfo.getDetailedStateOf(stateChangeResult.state)
-                                + " debouncing=" + linkDebouncing);
+                                + " debouncing=" + isLinkDebouncing());
                     }
                     setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
                     /* ConnectModeState does the rest of the handling */
@@ -7489,7 +7308,7 @@
                                 defaultInterval);
                         mWifiNative.setScanInterval((int) scanIntervalMs/1000);
                     } else if (mWifiConfigManager.getSavedNetworks().size() == 0) {
-                        if (DBG) log("Turn on scanning after p2p disconnected");
+                        if (mVerboseLoggingEnabled) log("Turn on scanning after p2p disconnected");
                         sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
                                     ++mPeriodicScanToken, 0), mNoNetworksPeriodicScan);
                     }
@@ -7560,7 +7379,9 @@
                         mSourceMessage = null;
                         transitionTo(mDisconnectedState);
                     } else {
-                        if (DBG) log("Ignore unspecified fail event during WPS connection");
+                        if (mVerboseLoggingEnabled) {
+                            log("Ignore unspecified fail event during WPS connection");
+                        }
                     }
                     break;
                 case WifiMonitor.WPS_TIMEOUT_EVENT:
@@ -7602,18 +7423,20 @@
                     messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD;
                     return HANDLED;
                 case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
-                    if (DBG) log("Network connection lost");
+                    if (mVerboseLoggingEnabled) log("Network connection lost");
                     handleNetworkDisconnect();
                     break;
                 case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
-                    if (DBG) log("Ignore Assoc reject event during WPS Connection");
+                    if (mVerboseLoggingEnabled) {
+                        log("Ignore Assoc reject event during WPS Connection");
+                    }
                     break;
                 case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
                     // Disregard auth failure events during WPS connection. The
                     // EAP sequence is retried several times, and there might be
                     // failures (especially for wps pin). We will get a WPS_XXX
                     // event at the end of the sequence anyway.
-                    if (DBG) log("Ignore auth failure during WPS connection");
+                    if (mVerboseLoggingEnabled) log("Ignore auth failure during WPS connection");
                     break;
                 case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
                     // Throw away supplicant state changes when WPS is running.
@@ -7652,30 +7475,41 @@
         @Override
         public void enter() {
             final Message message = getCurrentMessage();
-            if (message.what == CMD_START_AP) {
-                WifiConfiguration config = (WifiConfiguration) message.obj;
-
-                if (config == null) {
-                    /**
-                     * Configuration not provided in the command, fallback to use the current
-                     * configuration.
-                     */
-                    config = mWifiApConfigStore.getApConfiguration();
-                } else {
-                    /* Update AP configuration. */
-                    mWifiApConfigStore.setApConfiguration(config);
-                }
-
-                checkAndSetConnectivityInstance();
-                mSoftApManager = mFacade.makeSoftApManager(
-                        mContext, getHandler().getLooper(), mWifiNative, mNwService,
-                        mCm, mCountryCode.getCurrentCountryCode(),
-                        mWifiApConfigStore.getAllowed2GChannel(),
-                        new SoftApListener());
-                mSoftApManager.start(config);
-            } else {
+            if (message.what != CMD_START_AP) {
                 throw new RuntimeException("Illegal transition to SoftApState: " + message);
             }
+
+            IApInterface apInterface = setupDriverForSoftAp();
+            if (apInterface == null) {
+                setWifiApState(WIFI_AP_STATE_FAILED,
+                        WifiManager.SAP_START_FAILURE_GENERAL);
+                /**
+                 * Transition to InitialState to reset the
+                 * driver/HAL back to the initial state.
+                 */
+                transitionTo(mInitialState);
+                return;
+            }
+
+            WifiConfiguration config = (WifiConfiguration) message.obj;
+            if (config == null) {
+                /**
+                 * Configuration not provided in the command, fallback to use the current
+                 * configuration.
+                 */
+                config = mWifiApConfigStore.getApConfiguration();
+            } else {
+                /* Update AP configuration. */
+                mWifiApConfigStore.setApConfiguration(config);
+            }
+
+            checkAndSetConnectivityInstance();
+            mSoftApManager = mWifiInjector.makeSoftApManager(
+                    mWifiNative, mNwService,
+                    mCm, mCountryCode.getCurrentCountryCode(),
+                    mWifiApConfigStore.getAllowed2GChannel(),
+                    new SoftApListener(), apInterface);
+            mSoftApManager.start(config);
         }
 
         @Override
@@ -7745,7 +7579,7 @@
 
     /**
      * @param wifiCredentialEventType WIFI_CREDENTIAL_SAVED or WIFI_CREDENTIAL_FORGOT
-     * @param msg Must have a WifiConfiguration obj to succeed
+     * @param config Must have a WifiConfiguration object to succeed
      */
     private void broadcastWifiCredentialChanged(int wifiCredentialEventType,
             WifiConfiguration config) {
@@ -7808,54 +7642,6 @@
         return sb.toString();
     }
 
-    private static byte[] concat(byte[] array1, byte[] array2, byte[] array3) {
-
-        int len = array1.length + array2.length + array3.length;
-
-        if (array1.length != 0) {
-            len++;                      /* add another byte for size */
-        }
-
-        if (array2.length != 0) {
-            len++;                      /* add another byte for size */
-        }
-
-        if (array3.length != 0) {
-            len++;                      /* add another byte for size */
-        }
-
-        byte[] result = new byte[len];
-
-        int index = 0;
-        if (array1.length != 0) {
-            result[index] = (byte) (array1.length & 0xFF);
-            index++;
-            for (byte b : array1) {
-                result[index] = b;
-                index++;
-            }
-        }
-
-        if (array2.length != 0) {
-            result[index] = (byte) (array2.length & 0xFF);
-            index++;
-            for (byte b : array2) {
-                result[index] = b;
-                index++;
-            }
-        }
-
-        if (array3.length != 0) {
-            result[index] = (byte) (array3.length & 0xFF);
-            index++;
-            for (byte b : array3) {
-                result[index] = b;
-                index++;
-            }
-        }
-        return result;
-    }
-
     private static byte[] concatHex(byte[] array1, byte[] array2) {
 
         int len = array1.length + array2.length;
@@ -7901,13 +7687,13 @@
                     rand, android.util.Base64.NO_WRAP);
 
             // Try USIM first for authentication.
-            String tmResponse = tm.getIccAuthentication(tm.APPTYPE_USIM,
-                    tm.AUTHTYPE_EAP_SIM, base64Challenge);
+            String tmResponse = tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+                    TelephonyManager.AUTHTYPE_EAP_SIM, base64Challenge);
             if (tmResponse == null) {
                 /* Then, in case of failure, issue may be due to sim type, retry as a simple sim
                  */
-                tmResponse = tm.getIccAuthentication(tm.APPTYPE_SIM,
-                        tm.AUTHTYPE_EAP_SIM, base64Challenge);
+                tmResponse = tm.getIccAuthentication(TelephonyManager.APPTYPE_SIM,
+                        TelephonyManager.AUTHTYPE_EAP_SIM, base64Challenge);
             }
             logv("Raw Response - " + tmResponse);
 
@@ -8003,8 +7789,8 @@
             TelephonyManager tm = (TelephonyManager)
                     mContext.getSystemService(Context.TELEPHONY_SERVICE);
             if (tm != null) {
-                tmResponse = tm.getIccAuthentication(tm.APPTYPE_USIM,
-                        tm.AUTHTYPE_EAP_AKA, base64Challenge);
+                tmResponse = tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+                        TelephonyManager.AUTHTYPE_EAP_AKA, base64Challenge);
                 logv("Raw Response - " + tmResponse);
             } else {
                 loge("could not get telephony manager");
@@ -8144,7 +7930,7 @@
     }
 
     private static String getLinkPropertiesSummary(LinkProperties lp) {
-        List<String> attributes = new ArrayList(6);
+        List<String> attributes = new ArrayList<>(6);
         if (lp.hasIPv4Address()) {
             attributes.add("v4");
         }
@@ -8202,4 +7988,16 @@
         }
         return null;
     }
+
+    private void p2pSendMessage(int what) {
+        if (mWifiP2pChannel != null) {
+            mWifiP2pChannel.sendMessage(what);
+        }
+    }
+
+    private void p2pSendMessage(int what, int arg1) {
+        if (mWifiP2pChannel != null) {
+            mWifiP2pChannel.sendMessage(what, arg1);
+        }
+    }
 }
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiSupplicantControl.java
similarity index 72%
rename from service/java/com/android/server/wifi/WifiConfigStore.java
rename to service/java/com/android/server/wifi/WifiSupplicantControl.java
index b693e23..d05f3ef 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiSupplicantControl.java
@@ -20,18 +20,12 @@
 import android.net.IpConfiguration.IpAssignment;
 import android.net.IpConfiguration.ProxySettings;
 import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiConfiguration.Status;
 import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiSsid;
 import android.net.wifi.WpsInfo;
 import android.net.wifi.WpsResult;
 import android.os.FileObserver;
-import android.os.Process;
-import android.security.Credentials;
-import android.security.KeyChain;
-import android.security.KeyStore;
 import android.text.TextUtils;
-import android.util.ArraySet;
 import android.util.LocalLog;
 import android.util.Log;
 import android.util.SparseArray;
@@ -49,32 +43,18 @@
 import java.io.IOException;
 import java.net.URLDecoder;
 import java.nio.charset.StandardCharsets;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.BitSet;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
- * This class provides the API's to save/load/modify network configurations from a persistent
- * config database.
- * We use wpa_supplicant as our config database currently, but will be migrating to a different
- * one sometime in the future.
- * We use keystore for certificate/key management operations.
- *
- * NOTE: This class should only be used from WifiConfigManager!!!
+ * This class provides methods to send control commands to wpa_supplicant from WifiConfigManager.
+ * NOTE: This class should only be used from WifiConfigManager!
  */
-public class WifiConfigStore {
-
-    public static final String TAG = "WifiConfigStore";
+public class WifiSupplicantControl {
     // This is the only variable whose contents will not be interpreted by wpa_supplicant. We use it
     // to store metadata that allows us to correlate a wpa_supplicant.conf entry with additional
     // information about the same network stored in other files. The metadata is stored as a
@@ -85,40 +65,23 @@
     public static final String ID_STRING_KEY_CONFIG_KEY = "configKey";
     public static final String SUPPLICANT_CONFIG_FILE = "/data/misc/wifi/wpa_supplicant.conf";
     public static final String SUPPLICANT_CONFIG_FILE_BACKUP = SUPPLICANT_CONFIG_FILE + ".tmp";
-
     // Value stored by supplicant to requirePMF
     public static final int STORED_VALUE_FOR_REQUIRE_PMF = 2;
-
-    private static final boolean DBG = true;
-    private static boolean VDBG = false;
-
+    private static final String TAG = "WifiSupplicantControl";
     private final LocalLog mLocalLog;
     private final WpaConfigFileObserver mFileObserver;
     private final Context mContext;
     private final WifiNative mWifiNative;
-    private final KeyStore mKeyStore;
-    private final boolean mShowNetworks;
-    private final HashSet<String> mBssidBlacklist = new HashSet<String>();
 
-    private final BackupManagerProxy mBackupManagerProxy;
+    private boolean mVerboseLoggingEnabled = false;
 
-    WifiConfigStore(Context context, WifiNative wifiNative, KeyStore keyStore, LocalLog localLog,
-            boolean showNetworks, boolean verboseDebug) {
+    WifiSupplicantControl(Context context, WifiNative wifiNative, LocalLog localLog) {
         mContext = context;
         mWifiNative = wifiNative;
-        mKeyStore = keyStore;
-        mShowNetworks = showNetworks;
-        mBackupManagerProxy = new BackupManagerProxy();
 
-        if (mShowNetworks) {
-            mLocalLog = localLog;
-            mFileObserver = new WpaConfigFileObserver();
-            mFileObserver.startWatching();
-        } else {
-            mLocalLog = null;
-            mFileObserver = null;
-        }
-        VDBG = verboseDebug;
+        mLocalLog = localLog;
+        mFileObserver = new WpaConfigFileObserver();
+        mFileObserver.startWatching();
     }
 
     private static String removeDoubleQuotes(String string) {
@@ -136,7 +99,9 @@
      * Also transform the internal string format that uses _ (for bewildering
      * reasons) into a wpa_supplicant adjusted value, that uses - as a separator
      * (most of the time at least...).
-     * @param set a bit set with a one for each corresponding string to be included from strings.
+     *
+     * @param set     a bit set with a one for each corresponding string to be included from
+     *                strings.
      * @param strings the set of string literals to concatenate strinfs from.
      * @return A wpa_supplicant formatted value.
      */
@@ -146,8 +111,10 @@
 
     /**
      * Same as makeString with an exclusion parameter.
-     * @param set a bit set with a one for each corresponding string to be included from strings.
-     * @param strings the set of string literals to concatenate strinfs from.
+     *
+     * @param set       a bit set with a one for each corresponding string to be included from
+     *                  strings.
+     * @param strings   the set of string literals to concatenate strinfs from.
      * @param exception literal string to be excluded from the _ to - transformation.
      * @return A wpa_supplicant formatted value.
      */
@@ -159,9 +126,7 @@
         BitSet trimmedSet = set.get(0, strings.length);
 
         List<String> valueSet = new ArrayList<>();
-        for (int bit = trimmedSet.nextSetBit(0);
-             bit >= 0;
-             bit = trimmedSet.nextSetBit(bit+1)) {
+        for (int bit = trimmedSet.nextSetBit(0); bit >= 0; bit = trimmedSet.nextSetBit(bit + 1)) {
             String currentName = strings[bit];
             if (exception != null && currentName.equals(exception)) {
                 valueSet.add(currentName);
@@ -184,34 +149,6 @@
         return Utils.toHex(removeDoubleQuotes(str).getBytes(StandardCharsets.UTF_8));
     }
 
-    // Certificate and private key management for EnterpriseConfig
-    private static boolean needsKeyStore(WifiEnterpriseConfig config) {
-        return (!(config.getClientCertificate() == null && config.getCaCertificate() == null));
-    }
-
-    private static boolean isHardwareBackedKey(PrivateKey key) {
-        return KeyChain.isBoundKeyAlgorithm(key.getAlgorithm());
-    }
-
-    private static boolean hasHardwareBackedKey(Certificate certificate) {
-        return KeyChain.isBoundKeyAlgorithm(certificate.getPublicKey().getAlgorithm());
-    }
-
-    private static boolean needsSoftwareBackedKeyStore(WifiEnterpriseConfig config) {
-        java.lang.String client = config.getClientCertificateAlias();
-        if (!TextUtils.isEmpty(client)) {
-            // a valid client certificate is configured
-
-            // BUGBUG: keyStore.get() never returns certBytes; because it is not
-            // taking WIFI_UID as a parameter. It always looks for certificate
-            // with SYSTEM_UID, and never finds any Wifi certificates. Assuming that
-            // all certificates need software keystore until we get the get() API
-            // fixed.
-            return true;
-        }
-        return false;
-    }
-
     private int lookupString(String string, String[] strings) {
         int size = strings.length;
 
@@ -251,7 +188,7 @@
         if (config == null) {
             return;
         }
-        if (VDBG) localLog("readNetworkVariables: " + config.networkId);
+        if (mVerboseLoggingEnabled) localLog("readNetworkVariables: " + config.networkId);
         int netId = config.networkId;
         if (netId < 0) {
             return;
@@ -376,7 +313,7 @@
                 return lastPriority;
             }
             String[] lines = listStr.split("\n");
-            if (mShowNetworks) {
+            if (mVerboseLoggingEnabled) {
                 localLog("loadNetworks:  ");
                 for (String net : lines) {
                     localLog(net);
@@ -422,7 +359,7 @@
                 config.setIpAssignment(IpAssignment.DHCP);
                 config.setProxySettings(ProxySettings.NONE);
                 if (!WifiServiceImpl.isValid(config)) {
-                    if (mShowNetworks) {
+                    if (mVerboseLoggingEnabled) {
                         localLog("Ignoring network " + config.networkId + " because configuration "
                                 + "loaded from wpa_supplicant.conf is not valid.");
                     }
@@ -442,7 +379,7 @@
                 final WifiConfiguration duplicateConfig = configs.put(configKey, config);
                 if (duplicateConfig != null) {
                     // The network is already known. Overwrite the duplicate entry.
-                    if (mShowNetworks) {
+                    if (mVerboseLoggingEnabled) {
                         localLog("Replacing duplicate network " + duplicateConfig.networkId
                                 + " with " + config.networkId + ".");
                     }
@@ -458,132 +395,8 @@
     }
 
     /**
-     * Install keys for given enterprise network.
-     *
-     * @param existingConfig Existing config corresponding to the network already stored in our
-     *                       database. This maybe null if it's a new network.
-     * @param config         Config corresponding to the network.
-     * @return true if successful, false otherwise.
-     */
-    private boolean installKeys(WifiEnterpriseConfig existingConfig, WifiEnterpriseConfig config,
-            String name) {
-        boolean ret = true;
-        String privKeyName = Credentials.USER_PRIVATE_KEY + name;
-        String userCertName = Credentials.USER_CERTIFICATE + name;
-        if (config.getClientCertificate() != null) {
-            byte[] privKeyData = config.getClientPrivateKey().getEncoded();
-            if (DBG) {
-                if (isHardwareBackedKey(config.getClientPrivateKey())) {
-                    Log.d(TAG, "importing keys " + name + " in hardware backed store");
-                } else {
-                    Log.d(TAG, "importing keys " + name + " in software backed store");
-                }
-            }
-            ret = mKeyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
-                    KeyStore.FLAG_NONE);
-
-            if (!ret) {
-                return ret;
-            }
-
-            ret = putCertInKeyStore(userCertName, config.getClientCertificate());
-            if (!ret) {
-                // Remove private key installed
-                mKeyStore.delete(privKeyName, Process.WIFI_UID);
-                return ret;
-            }
-        }
-
-        X509Certificate[] caCertificates = config.getCaCertificates();
-        Set<String> oldCaCertificatesToRemove = new ArraySet<String>();
-        if (existingConfig != null && existingConfig.getCaCertificateAliases() != null) {
-            oldCaCertificatesToRemove.addAll(
-                    Arrays.asList(existingConfig.getCaCertificateAliases()));
-        }
-        List<String> caCertificateAliases = null;
-        if (caCertificates != null) {
-            caCertificateAliases = new ArrayList<String>();
-            for (int i = 0; i < caCertificates.length; i++) {
-                String alias = caCertificates.length == 1 ? name
-                        : String.format("%s_%d", name, i);
-
-                oldCaCertificatesToRemove.remove(alias);
-                ret = putCertInKeyStore(Credentials.CA_CERTIFICATE + alias, caCertificates[i]);
-                if (!ret) {
-                    // Remove client key+cert
-                    if (config.getClientCertificate() != null) {
-                        mKeyStore.delete(privKeyName, Process.WIFI_UID);
-                        mKeyStore.delete(userCertName, Process.WIFI_UID);
-                    }
-                    // Remove added CA certs.
-                    for (String addedAlias : caCertificateAliases) {
-                        mKeyStore.delete(Credentials.CA_CERTIFICATE + addedAlias, Process.WIFI_UID);
-                    }
-                    return ret;
-                } else {
-                    caCertificateAliases.add(alias);
-                }
-            }
-        }
-        // Remove old CA certs.
-        for (String oldAlias : oldCaCertificatesToRemove) {
-            mKeyStore.delete(Credentials.CA_CERTIFICATE + oldAlias, Process.WIFI_UID);
-        }
-        // Set alias names
-        if (config.getClientCertificate() != null) {
-            config.setClientCertificateAlias(name);
-            config.resetClientKeyEntry();
-        }
-
-        if (caCertificates != null) {
-            config.setCaCertificateAliases(
-                    caCertificateAliases.toArray(new String[caCertificateAliases.size()]));
-            config.resetCaCertificate();
-        }
-        return ret;
-    }
-
-    private boolean putCertInKeyStore(String name, Certificate cert) {
-        try {
-            byte[] certData = Credentials.convertToPem(cert);
-            if (DBG) Log.d(TAG, "putting certificate " + name + " in keystore");
-            return mKeyStore.put(name, certData, Process.WIFI_UID, KeyStore.FLAG_NONE);
-
-        } catch (IOException e1) {
-            return false;
-        } catch (CertificateException e2) {
-            return false;
-        }
-    }
-
-    /**
-     * Remove enterprise keys from the network config.
-     *
-     * @param config Config corresponding to the network.
-     */
-    private void removeKeys(WifiEnterpriseConfig config) {
-        String client = config.getClientCertificateAlias();
-        // a valid client certificate is configured
-        if (!TextUtils.isEmpty(client)) {
-            if (DBG) Log.d(TAG, "removing client private key and user cert");
-            mKeyStore.delete(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID);
-            mKeyStore.delete(Credentials.USER_CERTIFICATE + client, Process.WIFI_UID);
-        }
-
-        String[] aliases = config.getCaCertificateAliases();
-        // a valid ca certificate is configured
-        if (aliases != null) {
-            for (String ca : aliases) {
-                if (!TextUtils.isEmpty(ca)) {
-                    if (DBG) Log.d(TAG, "removing CA cert: " + ca);
-                    mKeyStore.delete(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID);
-                }
-            }
-        }
-    }
-
-    /**
      * Update the network metadata info stored in wpa_supplicant network extra field.
+     *
      * @param config Config corresponding to the network.
      * @return true if successful, false otherwise.
      */
@@ -612,7 +425,7 @@
         if (config == null) {
             return false;
         }
-        if (VDBG) localLog("saveNetwork: " + netId);
+        if (mVerboseLoggingEnabled) localLog("saveNetwork: " + netId);
         if (config.SSID != null && !mWifiNative.setNetworkVariable(
                 netId,
                 WifiConfiguration.ssidVarName,
@@ -750,53 +563,31 @@
     }
 
     /**
-     * Update/Install keys for given enterprise network.
+     * Save an enterprise network configuration to wpa_supplicant.
      *
-     * @param config         Config corresponding to the network.
-     * @param existingConfig Existing config corresponding to the network already stored in our
-     *                       database. This maybe null if it's a new network.
+     * @param config Config corresponding to the network.
      * @return true if successful, false otherwise.
      */
-    private boolean updateNetworkKeys(WifiConfiguration config, WifiConfiguration existingConfig) {
-        WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig;
-        if (needsKeyStore(enterpriseConfig)) {
-            try {
-                /* config passed may include only fields being updated.
-                 * In order to generate the key id, fetch uninitialized
-                 * fields from the currently tracked configuration
-                 */
-                String keyId = config.getKeyIdForCredentials(existingConfig);
-
-                if (!installKeys(existingConfig != null
-                        ? existingConfig.enterpriseConfig : null, enterpriseConfig, keyId)) {
-                    loge(config.SSID + ": failed to install keys");
-                    return false;
-                }
-            } catch (IllegalStateException e) {
-                loge(config.SSID + " invalid config for key installation: " + e.getMessage());
-                return false;
-            }
-        }
-        if (!enterpriseConfig.saveToSupplicant(
-                new SupplicantSaver(config.networkId, config.SSID))) {
-            removeKeys(enterpriseConfig);
+    public boolean saveEnterpriseConfiguration(WifiConfiguration config) {
+        if (config == null || config.enterpriseConfig == null) {
             return false;
         }
-        return true;
+        if (mVerboseLoggingEnabled) localLog("saveEnterpriseConfiguration: " + config.networkId);
+        return config.enterpriseConfig.saveToSupplicant(
+                new WifiSupplicantControl.SupplicantSaver(config.networkId, config.SSID));
     }
 
     /**
      * Add or update a network configuration to wpa_supplicant.
      *
      * @param config         Config corresponding to the network.
-     * @param existingConfig Existing config corresponding to the network saved in our database.
      * @return true if successful, false otherwise.
      */
-    public boolean addOrUpdateNetwork(WifiConfiguration config, WifiConfiguration existingConfig) {
+    public boolean addOrUpdateNetwork(WifiConfiguration config) {
         if (config == null) {
             return false;
         }
-        if (VDBG) localLog("addOrUpdateNetwork: " + config.networkId);
+        if (mVerboseLoggingEnabled) localLog("addOrUpdateNetwork: " + config.networkId);
         int netId = config.networkId;
         boolean newNetwork = false;
         /*
@@ -823,12 +614,6 @@
             }
             return false;
         }
-        if (config.enterpriseConfig != null
-                && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
-            return updateNetworkKeys(config, existingConfig);
-        }
-        // Stage the backup of the SettingsProvider package which backs this up
-        mBackupManagerProxy.notifyDataChanged();
         return true;
     }
 
@@ -842,17 +627,11 @@
         if (config == null) {
             return false;
         }
-        if (VDBG) localLog("removeNetwork: " + config.networkId);
+        if (mVerboseLoggingEnabled) localLog("removeNetwork: " + config.networkId);
         if (!mWifiNative.removeNetwork(config.networkId)) {
             loge("Remove network in wpa_supplicant failed on " + config.networkId);
             return false;
         }
-        // Remove any associated keys
-        if (config.enterpriseConfig != null) {
-            removeKeys(config.enterpriseConfig);
-        }
-        // Stage the backup of the SettingsProvider package which backs this up
-        mBackupManagerProxy.notifyDataChanged();
         return true;
     }
 
@@ -862,17 +641,15 @@
      * @param config Config corresponding to the network.
      * @return true if successful, false otherwise.
      */
-    public boolean selectNetwork(WifiConfiguration config, Collection<WifiConfiguration> configs) {
+    public boolean selectNetwork(WifiConfiguration config) {
         if (config == null) {
             return false;
         }
-        if (VDBG) localLog("selectNetwork: " + config.networkId);
+        if (mVerboseLoggingEnabled) localLog("selectNetwork: " + config.networkId);
         if (!mWifiNative.selectNetwork(config.networkId)) {
             loge("Select network in wpa_supplicant failed on " + config.networkId);
             return false;
         }
-        config.status = Status.ENABLED;
-        markAllNetworksDisabledExcept(config.networkId, configs);
         return true;
     }
 
@@ -886,12 +663,11 @@
         if (config == null) {
             return false;
         }
-        if (VDBG) localLog("disableNetwork: " + config.networkId);
+        if (mVerboseLoggingEnabled) localLog("disableNetwork: " + config.networkId);
         if (!mWifiNative.disableNetwork(config.networkId)) {
             loge("Disable network in wpa_supplicant failed on " + config.networkId);
             return false;
         }
-        config.status = Status.DISABLED;
         return true;
     }
 
@@ -905,7 +681,7 @@
         if (config == null) {
             return false;
         }
-        if (VDBG) localLog("setNetworkPriority: " + config.networkId);
+        if (mVerboseLoggingEnabled) localLog("setNetworkPriority: " + config.networkId);
         if (!mWifiNative.setNetworkVariable(config.networkId,
                 WifiConfiguration.priorityVarName, Integer.toString(priority))) {
             loge("Set priority of network in wpa_supplicant failed on " + config.networkId);
@@ -925,7 +701,7 @@
         if (config == null) {
             return false;
         }
-        if (VDBG) localLog("setNetworkSSID: " + config.networkId);
+        if (mVerboseLoggingEnabled) localLog("setNetworkSSID: " + config.networkId);
         if (!mWifiNative.setNetworkVariable(config.networkId, WifiConfiguration.ssidVarName,
                 encodeSSID(ssid))) {
             loge("Set SSID of network in wpa_supplicant failed on " + config.networkId);
@@ -949,7 +725,7 @@
                 && config.SSID == null)) {
             return false;
         }
-        if (VDBG) localLog("setNetworkBSSID: " + config.networkId);
+        if (mVerboseLoggingEnabled) localLog("setNetworkBSSID: " + config.networkId);
         if (!mWifiNative.setNetworkVariable(config.networkId, WifiConfiguration.bssidVarName,
                 bssid)) {
             loge("Set BSSID of network in wpa_supplicant failed on " + config.networkId);
@@ -960,6 +736,25 @@
     }
 
     /**
+     * Get BSSID for a network in wpa_supplicant.
+     *
+     * @param config Config corresponding to the network.
+     * @return BSSID for the network, if it exists, null otherwise.
+     */
+    public String getNetworkBSSID(WifiConfiguration config) {
+      // Sanity check the config is valid
+        if (config == null
+                || (config.networkId == WifiConfiguration.INVALID_NETWORK_ID
+                && config.SSID == null)) {
+            return null;
+        }
+        if (mVerboseLoggingEnabled) localLog("getNetworkBSSID: " + config.networkId);
+        String bssid =
+                mWifiNative.getNetworkVariable(config.networkId, WifiConfiguration.bssidVarName);
+        return (TextUtils.isEmpty(bssid) ? null : bssid);
+    }
+
+    /**
      * Enable/Disable HS20 parameter in wpa_supplicant.
      *
      * @param enable Enable/Disable the parameter.
@@ -975,7 +770,7 @@
      * @return true if successful, false otherwise.
      */
     public boolean disableAllNetworks(Collection<WifiConfiguration> configs) {
-        if (VDBG) localLog("disableAllNetworks");
+        if (mVerboseLoggingEnabled) localLog("disableAllNetworks");
         boolean networkDisabled = false;
         for (WifiConfiguration enabled : configs) {
             if (disableNetwork(enabled)) {
@@ -1006,16 +801,16 @@
             reader = new BufferedReader(new FileReader(SUPPLICANT_CONFIG_FILE));
             result = readNetworkVariablesFromReader(reader, key);
         } catch (FileNotFoundException e) {
-            if (VDBG) loge("Could not open " + SUPPLICANT_CONFIG_FILE + ", " + e);
+            if (mVerboseLoggingEnabled) loge("Could not open " + SUPPLICANT_CONFIG_FILE + ", " + e);
         } catch (IOException e) {
-            if (VDBG) loge("Could not read " + SUPPLICANT_CONFIG_FILE + ", " + e);
+            if (mVerboseLoggingEnabled) loge("Could not read " + SUPPLICANT_CONFIG_FILE + ", " + e);
         } finally {
             try {
                 if (reader != null) {
                     reader.close();
                 }
             } catch (IOException e) {
-                if (VDBG) {
+                if (mVerboseLoggingEnabled) {
                     loge("Could not close reader for " + SUPPLICANT_CONFIG_FILE + ", " + e);
                 }
             }
@@ -1028,13 +823,13 @@
      * readNetworkVariablesFromSupplicantFile() for testing.
      *
      * @param reader The reader to read the network variables from.
-     * @param key The parameter to be parsed.
+     * @param key    The parameter to be parsed.
      * @return Map of corresponding configKey to the value of the param requested.
      */
     public Map<String, String> readNetworkVariablesFromReader(BufferedReader reader, String key)
             throws IOException {
         Map<String, String> result = new HashMap<>();
-        if (VDBG) localLog("readNetworkVariablesFromReader key=" + key);
+        if (mVerboseLoggingEnabled) localLog("readNetworkVariablesFromReader key=" + key);
         boolean found = false;
         String configKey = null;
         String value = null;
@@ -1054,20 +849,19 @@
                     try {
                         // Trim the quotes wrapping the id_str value.
                         final String encodedExtras = trimmedLine.substring(
-                                8, trimmedLine.length() -1);
+                                8, trimmedLine.length() - 1);
                         final JSONObject json =
                                 new JSONObject(URLDecoder.decode(encodedExtras, "UTF-8"));
-                        if (json.has(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY)) {
+                        if (json.has(ID_STRING_KEY_CONFIG_KEY)) {
                             final Object configKeyFromJson =
-                                    json.get(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY);
+                                    json.get(ID_STRING_KEY_CONFIG_KEY);
                             if (configKeyFromJson instanceof String) {
                                 configKey = (String) configKeyFromJson;
                             }
                         }
                     } catch (JSONException e) {
-                        if (VDBG) {
-                            loge("Could not get "+ WifiConfigStore.ID_STRING_KEY_CONFIG_KEY
-                                    + ", " + e);
+                        if (mVerboseLoggingEnabled) {
+                            loge("Could not get " + ID_STRING_KEY_CONFIG_KEY + ", " + e);
                         }
                     }
                 }
@@ -1088,7 +882,7 @@
      * @param configs List of all the networks.
      */
     public void resetSimNetworks(Collection<WifiConfiguration> configs) {
-        if (VDBG) localLog("resetSimNetworks");
+        if (mVerboseLoggingEnabled) localLog("resetSimNetworks");
         for (WifiConfiguration config : configs) {
             if (TelephonyUtil.isSimConfig(config)) {
                 String currentIdentity = TelephonyUtil.getSimIdentity(mContext,
@@ -1115,11 +909,10 @@
     }
 
     /**
-     * Clear BSSID blacklist in wpa_supplicant.
+     * Clear BSSID blacklist in wpa_supplicant & HAL.
      */
     public void clearBssidBlacklist() {
-        if (VDBG) localLog("clearBlacklist");
-        mBssidBlacklist.clear();
+        if (mVerboseLoggingEnabled) localLog("clearBlacklist");
         mWifiNative.clearBlacklist();
         mWifiNative.setBssidBlacklist(null);
     }
@@ -1127,44 +920,15 @@
     /**
      * Add a BSSID to the blacklist.
      *
-     * @param bssid bssid to be added.
+     * @param bssid     to be added.
+     * @param bssidList entire BSSID list.
      */
-    public void blackListBssid(String bssid) {
-        if (bssid == null) {
-            return;
-        }
-        if (VDBG) localLog("blackListBssid: " + bssid);
-        mBssidBlacklist.add(bssid);
+    public void blackListBssid(String bssid, String[] bssidList) {
+        if (mVerboseLoggingEnabled) localLog("blackListBssid: " + bssid);
         // Blacklist at wpa_supplicant
         mWifiNative.addToBlacklist(bssid);
         // Blacklist at firmware
-        String[] list = mBssidBlacklist.toArray(new String[mBssidBlacklist.size()]);
-        mWifiNative.setBssidBlacklist(list);
-    }
-
-    /**
-     * Checks if the provided bssid is blacklisted or not.
-     *
-     * @param bssid bssid to be checked.
-     * @return true if present, false otherwise.
-     */
-    public boolean isBssidBlacklisted(String bssid) {
-        return mBssidBlacklist.contains(bssid);
-    }
-
-    /* Mark all networks except specified netId as disabled */
-    private void markAllNetworksDisabledExcept(int netId, Collection<WifiConfiguration> configs) {
-        for (WifiConfiguration config : configs) {
-            if (config != null && config.networkId != netId) {
-                if (config.status != Status.DISABLED) {
-                    config.status = Status.DISABLED;
-                }
-            }
-        }
-    }
-
-    private void markAllNetworksDisabled(Collection<WifiConfiguration> configs) {
-        markAllNetworksDisabledExcept(WifiConfiguration.INVALID_NETWORK_ID, configs);
+        mWifiNative.setBssidBlacklist(bssidList);
     }
 
     /**
@@ -1174,12 +938,9 @@
      * @param config WPS configuration
      * @return Wps result containing status and pin
      */
-    public WpsResult startWpsWithPinFromAccessPoint(WpsInfo config,
-            Collection<WifiConfiguration> configs) {
+    public WpsResult startWpsWithPinFromAccessPoint(WpsInfo config) {
         WpsResult result = new WpsResult();
         if (mWifiNative.startWpsRegistrar(config.BSSID, config.pin)) {
-            /* WPS leaves all networks disabled */
-            markAllNetworksDisabled(configs);
             result.status = WpsResult.Status.SUCCESS;
         } else {
             loge("Failed to start WPS pin method configuration");
@@ -1194,13 +955,10 @@
      *
      * @return WpsResult indicating status and pin
      */
-    public WpsResult startWpsWithPinFromDevice(WpsInfo config,
-            Collection<WifiConfiguration> configs) {
+    public WpsResult startWpsWithPinFromDevice(WpsInfo config) {
         WpsResult result = new WpsResult();
         result.pin = mWifiNative.startWpsPinDisplay(config.BSSID);
-        /* WPS leaves all networks disabled */
         if (!TextUtils.isEmpty(result.pin)) {
-            markAllNetworksDisabled(configs);
             result.status = WpsResult.Status.SUCCESS;
         } else {
             loge("Failed to start WPS pin method configuration");
@@ -1215,12 +973,9 @@
      * @param config WPS configuration
      * @return WpsResult indicating status and pin
      */
-    public WpsResult startWpsPbc(WpsInfo config,
-            Collection<WifiConfiguration> configs) {
+    public WpsResult startWpsPbc(WpsInfo config) {
         WpsResult result = new WpsResult();
         if (mWifiNative.startWpsPbc(config.BSSID)) {
-            /* WPS leaves all networks disabled */
-            markAllNetworksDisabled(configs);
             result.status = WpsResult.Status.SUCCESS;
         } else {
             loge("Failed to start WPS push button configuration");
@@ -1229,19 +984,19 @@
         return result;
     }
 
-    protected void logd(String s) {
+    private void logd(String s) {
         Log.d(TAG, s);
     }
 
-    protected void logi(String s) {
+    private void logi(String s) {
         Log.i(TAG, s);
     }
 
-    protected void loge(String s) {
+    private void loge(String s) {
         loge(s, false);
     }
 
-    protected void loge(String s, boolean stack) {
+    private void loge(String s, boolean stack) {
         if (stack) {
             Log.e(TAG, s + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
                     + " - " + Thread.currentThread().getStackTrace()[3].getMethodName()
@@ -1252,7 +1007,7 @@
         }
     }
 
-    protected void log(String s) {
+    private void log(String s) {
         Log.d(TAG, s);
     }
 
@@ -1267,6 +1022,13 @@
         Log.d(TAG, s);
     }
 
+    /**
+     * Enable verbose logging.
+     */
+    public void enableVerboseLogging(boolean verbose) {
+        mVerboseLoggingEnabled = verbose;
+    }
+
     private class SupplicantSaver implements WifiEnterpriseConfig.SupplicantSaver {
         private final int mNetId;
         private final String mSetterSSID;
@@ -1335,7 +1097,7 @@
         }
     }
 
-    // TODO(rpius): Remove this.
+    // TODO(rpius): Remove this (see b/27377614).
     private class WpaConfigFileObserver extends FileObserver {
 
         WpaConfigFileObserver() {
@@ -1346,7 +1108,9 @@
         public void onEvent(int event, String path) {
             if (event == CLOSE_WRITE) {
                 File file = new File(SUPPLICANT_CONFIG_FILE);
-                if (VDBG) localLog("wpa_supplicant.conf changed; new size = " + file.length());
+                if (mVerboseLoggingEnabled) {
+                    localLog("wpa_supplicant.conf changed; new size = " + file.length());
+                }
             }
         }
     }
diff --git a/service/java/com/android/server/wifi/WifiTrafficPoller.java b/service/java/com/android/server/wifi/WifiTrafficPoller.java
index 336e0d7..d05353b 100644
--- a/service/java/com/android/server/wifi/WifiTrafficPoller.java
+++ b/service/java/com/android/server/wifi/WifiTrafficPoller.java
@@ -41,9 +41,7 @@
 /* Polls for traffic stats and notifies the clients */
 final class WifiTrafficPoller {
 
-    private boolean DBG = false;
-    private boolean VDBG = false;
-
+    private static final boolean DBG = false;
     private static final String TAG = "WifiTrafficPoller";
     /**
      * Interval in milliseconds between polling for traffic
@@ -71,6 +69,8 @@
     private NetworkInfo mNetworkInfo;
     private final String mInterface;
 
+    private boolean mVerboseLoggingEnabled = false;
+
     WifiTrafficPoller(Context context, Looper looper, String iface) {
         mInterface = iface;
         mTrafficHandler = new TrafficHandler(looper);
@@ -110,10 +110,10 @@
     }
 
     void enableVerboseLogging(int verbose) {
-        if (verbose > 0 ) {
-            DBG = true;
+        if (verbose > 0) {
+            mVerboseLoggingEnabled = true;
         } else {
-            DBG = false;
+            mVerboseLoggingEnabled = false;
         }
     }
 
@@ -126,8 +126,8 @@
             switch (msg.what) {
                 case ENABLE_TRAFFIC_STATS_POLL:
                     mEnableTrafficStatsPoll = (msg.arg1 == 1);
-                    if (DBG) {
-                        Log.e(TAG, "ENABLE_TRAFFIC_STATS_POLL "
+                    if (mVerboseLoggingEnabled) {
+                        Log.d(TAG, "ENABLE_TRAFFIC_STATS_POLL "
                                 + mEnableTrafficStatsPoll + " Token "
                                 + Integer.toString(mTrafficStatsPollToken));
                     }
@@ -139,8 +139,8 @@
                     }
                     break;
                 case TRAFFIC_STATS_POLL:
-                    if (VDBG) {
-                        Log.e(TAG, "TRAFFIC_STATS_POLL "
+                    if (DBG) {
+                        Log.d(TAG, "TRAFFIC_STATS_POLL "
                                 + mEnableTrafficStatsPoll + " Token "
                                 + Integer.toString(mTrafficStatsPollToken)
                                 + " num clients " + mClients.size());
@@ -153,8 +153,8 @@
                     break;
                 case ADD_CLIENT:
                     mClients.add((Messenger) msg.obj);
-                    if (DBG) {
-                        Log.e(TAG, "ADD_CLIENT: "
+                    if (mVerboseLoggingEnabled) {
+                        Log.d(TAG, "ADD_CLIENT: "
                                 + Integer.toString(mClients.size()));
                     }
                     break;
@@ -187,8 +187,8 @@
         mTxPkts = TrafficStats.getTxPackets(mInterface);
         mRxPkts = TrafficStats.getRxPackets(mInterface);
 
-        if (VDBG) {
-            Log.e(TAG, " packet count Tx="
+        if (DBG) {
+            Log.d(TAG, " packet count Tx="
                     + Long.toString(mTxPkts)
                     + " Rx="
                     + Long.toString(mRxPkts));
@@ -206,7 +206,7 @@
 
             if (dataActivity != mDataActivity && mScreenOn.get()) {
                 mDataActivity = dataActivity;
-                if (DBG) {
+                if (mVerboseLoggingEnabled) {
                     Log.e(TAG, "notifying of data activity "
                             + Integer.toString(mDataActivity));
                 }
diff --git a/service/java/com/android/server/wifi/hotspot2/ANQPData.java b/service/java/com/android/server/wifi/hotspot2/ANQPData.java
index 164ea20..f3d67cc 100644
--- a/service/java/com/android/server/wifi/hotspot2/ANQPData.java
+++ b/service/java/com/android/server/wifi/hotspot2/ANQPData.java
@@ -46,7 +46,7 @@
         mClock = clock;
         mNetwork = network;
         mANQPElements = anqpElements != null ? new HashMap<>(anqpElements) : null;
-        mCtime = mClock.currentTimeMillis();
+        mCtime = mClock.getWallClockMillis();
         mRetry = 0;
         if (anqpElements == null) {
             mExpiry = mCtime + ANQP_HOLDOFF_TIME;
@@ -63,7 +63,7 @@
         mClock = clock;
         mNetwork = network;
         mANQPElements = null;
-        mCtime = mClock.currentTimeMillis();
+        mCtime = mClock.getWallClockMillis();
         if (existing == null) {
             mRetry = 0;
             mExpiry = mCtime + ANQP_HOLDOFF_TIME;
@@ -100,7 +100,7 @@
     }
 
     public boolean expired() {
-        return expired(mClock.currentTimeMillis());
+        return expired(mClock.getWallClockMillis());
     }
 
     public boolean expired(long at) {
@@ -120,7 +120,7 @@
     protected boolean isValid(NetworkDetail nwk) {
         return mANQPElements != null &&
                 nwk.getAnqpDomainID() == mNetwork.getAnqpDomainID() &&
-                mExpiry > mClock.currentTimeMillis();
+                mExpiry > mClock.getWallClockMillis();
     }
 
     private int getRetry() {
@@ -136,7 +136,7 @@
         else {
             sb.append(", ").append(mANQPElements.size()).append(" elements, ");
         }
-        long now = mClock.currentTimeMillis();
+        long now = mClock.getWallClockMillis();
         sb.append(Utils.toHMS(now-mCtime)).append(" old, expires in ").
                 append(Utils.toHMS(mExpiry-now)).append(' ');
         if (brief) {
diff --git a/service/java/com/android/server/wifi/hotspot2/AnqpCache.java b/service/java/com/android/server/wifi/hotspot2/AnqpCache.java
index a6cd42e..c655427 100644
--- a/service/java/com/android/server/wifi/hotspot2/AnqpCache.java
+++ b/service/java/com/android/server/wifi/hotspot2/AnqpCache.java
@@ -25,7 +25,7 @@
     public AnqpCache(Clock clock) {
         mClock = clock;
         mANQPCache = new HashMap<>();
-        mLastSweep = mClock.currentTimeMillis();
+        mLastSweep = mClock.getWallClockMillis();
     }
 
     private static class CacheKey {
@@ -172,7 +172,7 @@
 
     public void clear(boolean all, boolean debug) {
         if (DBG) Log.d(Utils.hs2LogTag(getClass()), "Clearing ANQP cache: all: " + all);
-        long now = mClock.currentTimeMillis();
+        long now = mClock.getWallClockMillis();
         synchronized (mANQPCache) {
             if (all) {
                 mANQPCache.clear();
@@ -197,7 +197,7 @@
     }
 
     public void dump(PrintWriter out) {
-        out.println("Last sweep " + Utils.toHMS(mClock.currentTimeMillis() - mLastSweep) + " ago.");
+        out.println("Last sweep " + Utils.toHMS(mClock.getWallClockMillis() - mLastSweep) + " ago.");
         for (ANQPData anqpData : mANQPCache.values()) {
             out.println(anqpData.toString(false));
         }
diff --git a/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java b/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java
index 402c0a8..5abf164 100644
--- a/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java
+++ b/service/java/com/android/server/wifi/hotspot2/NetworkDetail.java
@@ -24,9 +24,7 @@
 
 public class NetworkDetail {
 
-    //turn off when SHIP
-    private static final boolean DBG = true;
-    private static final boolean VDBG = false;
+    private static final boolean DBG = false;
 
     private static final String TAG = "NetworkDetail:";
 
@@ -290,7 +288,7 @@
             mMaxRate = 0;
             Log.w("WifiMode", mSSID + ", Invalid SupportedRates!!!");
         }
-        if (VDBG) {
+        if (DBG) {
             Log.d(TAG, mSSID + "ChannelWidth is: " + mChannelWidth + " PrimaryFreq: " + mPrimaryFreq
                     + " mCenterfreq0: " + mCenterfreq0 + " mCenterfreq1: " + mCenterfreq1
                     + (extendedCapabilities.is80211McRTTResponder ? "Support RTT reponder"
diff --git a/service/java/com/android/server/wifi/hotspot2/SupplicantBridge.java b/service/java/com/android/server/wifi/hotspot2/SupplicantBridge.java
index af2befb..9c35645 100644
--- a/service/java/com/android/server/wifi/hotspot2/SupplicantBridge.java
+++ b/service/java/com/android/server/wifi/hotspot2/SupplicantBridge.java
@@ -179,18 +179,25 @@
         }
 
         if (scanDetail == null) {
+            // Icon queries are not held on the request map, so a null scanDetail is very likely
+            // the result of an Icon query. Notify the OSU app if the query was unsuccessful,
+            // else bail out.
             if (!success) {
                 mCallbacks.notifyIconFailed(bssid);
             }
             return;
+        } else if (!success) {
+            // If there is an associated ScanDetail, notify of a failed regular ANQP query.
+            mCallbacks.notifyANQPResponse(scanDetail, null);
+            return;
         }
 
         String bssData = mSupplicantHook.scanResult(scanDetail.getBSSIDString());
+        Map<Constants.ANQPElementType, ANQPElement> elements = null;
         try {
-            Map<Constants.ANQPElementType, ANQPElement> elements = parseWPSData(bssData);
-            Log.d(Utils.hs2LogTag(getClass()), String.format("%s ANQP response for %012x: %s",
-                    success ? "successful" : "failed", bssid, elements));
-            mCallbacks.notifyANQPResponse(scanDetail, success ? elements : null);
+            elements = parseWPSData(bssData);
+            Log.d(Utils.hs2LogTag(getClass()),
+                    String.format("Successful ANQP response for %012x: %s", bssid, elements));
         }
         catch (IOException ioe) {
             Log.e(Utils.hs2LogTag(getClass()), "Failed to parse ANQP: " +
@@ -200,7 +207,7 @@
             Log.e(Utils.hs2LogTag(getClass()), "Failed to parse ANQP: " +
                     rte.toString() + ": " + bssData, rte);
         }
-        mCallbacks.notifyANQPResponse(scanDetail, null);
+        mCallbacks.notifyANQPResponse(scanDetail, elements);
     }
 
     private static String escapeSSID(NetworkDetail networkDetail) {
diff --git a/service/java/com/android/server/wifi/nan/WifiNanClientState.java b/service/java/com/android/server/wifi/nan/WifiNanClientState.java
index 0707270..74fa71d 100644
--- a/service/java/com/android/server/wifi/nan/WifiNanClientState.java
+++ b/service/java/com/android/server/wifi/nan/WifiNanClientState.java
@@ -16,17 +16,26 @@
 
 package com.android.server.wifi.nan;
 
+import android.net.wifi.RttManager;
 import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.IWifiNanEventListener;
-import android.net.wifi.nan.IWifiNanSessionListener;
-import android.net.wifi.nan.WifiNanEventListener;
+import android.net.wifi.nan.IWifiNanEventCallback;
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.SparseArray;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Arrays;
 
+/**
+ * Manages the service-side NAN state of an individual "client". A client
+ * corresponds to a single instantiation of the WifiNanManager - there could be
+ * multiple ones per UID/process (each of which is a separate client with its
+ * own session namespace). The client state is primarily: (1) callback (a
+ * singleton per client) through which NAN-wide events are called, and (2) a set
+ * of discovery sessions (publish and/or subscribe) which are created through
+ * this client and whose lifetime is tied to the lifetime of the client.
+ */
 public class WifiNanClientState {
     private static final String TAG = "WifiNanClientState";
     private static final boolean DBG = false;
@@ -35,40 +44,56 @@
     /* package */ static final int CLUSTER_CHANGE_EVENT_STARTED = 0;
     /* package */ static final int CLUSTER_CHANGE_EVENT_JOINED = 1;
 
-    private IWifiNanEventListener mListener;
-    private int mEvents;
+    private IWifiNanEventCallback mCallback;
     private final SparseArray<WifiNanSessionState> mSessions = new SparseArray<>();
 
-    private int mUid;
+    private int mClientId;
     private ConfigRequest mConfigRequest;
+    private int mUid;
 
-    public WifiNanClientState(int uid, IWifiNanEventListener listener, int events) {
+    private static final byte[] ALL_ZERO_MAC = new byte[] {0, 0, 0, 0, 0, 0};
+    private byte[] mLastDiscoveryInterfaceMac = ALL_ZERO_MAC;
+
+    public WifiNanClientState(int clientId, int uid, IWifiNanEventCallback callback,
+            ConfigRequest configRequest) {
+        mClientId = clientId;
         mUid = uid;
-        mListener = listener;
-        mEvents = events;
+        mCallback = callback;
+        mConfigRequest = configRequest;
     }
 
+    /**
+     * Destroy the current client - corresponds to a disconnect() request from
+     * the client. Destroys all discovery sessions belonging to this client.
+     */
     public void destroy() {
-        mListener = null;
         for (int i = 0; i < mSessions.size(); ++i) {
-            mSessions.valueAt(i).destroy();
+            mSessions.valueAt(i).terminate();
         }
         mSessions.clear();
         mConfigRequest = null;
     }
 
-    public void setConfigRequest(ConfigRequest configRequest) {
-        mConfigRequest = configRequest;
-    }
-
     public ConfigRequest getConfigRequest() {
         return mConfigRequest;
     }
 
+    public int getClientId() {
+        return mClientId;
+    }
+
     public int getUid() {
         return mUid;
     }
 
+    /**
+     * Searches the discovery sessions of this client and returns the one
+     * corresponding to the publish/subscribe ID. Used on callbacks from HAL to
+     * map callbacks to the correct discovery session.
+     *
+     * @param pubSubId The publish/subscribe match session ID.
+     * @return NAN session corresponding to the requested ID.
+     */
     public WifiNanSessionState getNanSessionStateForPubSubId(int pubSubId) {
         for (int i = 0; i < mSessions.size(); ++i) {
             WifiNanSessionState session = mSessions.valueAt(i);
@@ -80,98 +105,159 @@
         return null;
     }
 
-    public void createSession(int sessionId, IWifiNanSessionListener listener, int events) {
-        WifiNanSessionState session = mSessions.get(sessionId);
-        if (session != null) {
-            Log.e(TAG, "createSession: sessionId already exists (replaced) - " + sessionId);
+    /**
+     * Add the session to the client database.
+     *
+     * @param session Session to be added.
+     */
+    public void addSession(WifiNanSessionState session) {
+        int sessionId = session.getSessionId();
+        if (mSessions.get(sessionId) != null) {
+            Log.w(TAG, "createSession: sessionId already exists (replaced) - " + sessionId);
         }
 
-        mSessions.put(sessionId, new WifiNanSessionState(sessionId, listener, events));
+        mSessions.put(sessionId, session);
     }
 
-    public void destroySession(int sessionId) {
-        WifiNanSessionState session = mSessions.get(sessionId);
-        if (session == null) {
-            Log.e(TAG, "destroySession: sessionId doesn't exist - " + sessionId);
+    /**
+     * Remove the specified session from the client database - without doing a
+     * terminate on the session. The assumption is that it is already
+     * terminated.
+     *
+     * @param sessionId The session ID of the session to be removed.
+     */
+    public void removeSession(int sessionId) {
+        if (mSessions.get(sessionId) == null) {
+            Log.e(TAG, "removeSession: sessionId doesn't exist - " + sessionId);
             return;
         }
 
         mSessions.delete(sessionId);
-        session.destroy();
     }
 
+    /**
+     * Destroy the discovery session: terminates discovery and frees up
+     * resources.
+     *
+     * @param sessionId The session ID of the session to be destroyed.
+     */
+    public void terminateSession(int sessionId) {
+        WifiNanSessionState session = mSessions.get(sessionId);
+        if (session == null) {
+            Log.e(TAG, "terminateSession: sessionId doesn't exist - " + sessionId);
+            return;
+        }
+
+        session.terminate();
+        mSessions.delete(sessionId);
+    }
+
+    /**
+     * Retrieve a session.
+     *
+     * @param sessionId Session ID of the session to be retrieved.
+     * @return Session or null if there's no session corresponding to the
+     *         sessionId.
+     */
     public WifiNanSessionState getSession(int sessionId) {
         return mSessions.get(sessionId);
     }
 
-    public void onConfigCompleted(ConfigRequest completedConfig) {
-        if (mListener != null && (mEvents & WifiNanEventListener.LISTEN_CONFIG_COMPLETED) != 0) {
+    /**
+     * Called to dispatch the NAN interface address change to the client - as an
+     * identity change (interface address information not propagated to client -
+     * privacy concerns).
+     *
+     * @param mac The new MAC address of the discovery interface - optionally propagated to the
+     *            client.
+     */
+    public void onInterfaceAddressChange(byte[] mac) {
+        if (mConfigRequest.mEnableIdentityChangeCallback && !Arrays.equals(mac,
+                mLastDiscoveryInterfaceMac)) {
             try {
-                mListener.onConfigCompleted(completedConfig);
-            } catch (RemoteException e) {
-                Log.w(TAG, "onConfigCompleted: RemoteException - ignored: " + e);
-            }
-        }
-    }
-
-    public void onConfigFailed(ConfigRequest failedConfig, int reason) {
-        if (mListener != null && (mEvents & WifiNanEventListener.LISTEN_CONFIG_FAILED) != 0) {
-            try {
-                mListener.onConfigFailed(failedConfig, reason);
-            } catch (RemoteException e) {
-                Log.w(TAG, "onConfigFailed: RemoteException - ignored: " + e);
-            }
-        }
-    }
-
-    public int onNanDown(int reason) {
-        if (mListener != null && (mEvents & WifiNanEventListener.LISTEN_NAN_DOWN) != 0) {
-            try {
-                mListener.onNanDown(reason);
-            } catch (RemoteException e) {
-                Log.w(TAG, "onNanDown: RemoteException - ignored: " + e);
-            }
-
-            return 1;
-        }
-
-        return 0;
-    }
-
-    public int onInterfaceAddressChange(byte[] mac) {
-        if (mListener != null && (mEvents & WifiNanEventListener.LISTEN_IDENTITY_CHANGED) != 0) {
-            try {
-                mListener.onIdentityChanged();
+                // TODO: b/30000323 - resolve privacy concerns
+                mCallback.onIdentityChanged(mac);
             } catch (RemoteException e) {
                 Log.w(TAG, "onIdentityChanged: RemoteException - ignored: " + e);
             }
-
-            return 1;
         }
 
-        return 0;
+        mLastDiscoveryInterfaceMac = mac;
     }
 
-    public int onClusterChange(int flag, byte[] mac) {
-        if (mListener != null && (mEvents & WifiNanEventListener.LISTEN_IDENTITY_CHANGED) != 0) {
+    /**
+     * Called to dispatch the NAN cluster change (due to joining of a new
+     * cluster or starting a cluster) to the client - as an identity change
+     * (interface address information not propagated to client - privacy
+     * concerns). Dispatched if the client registered for the identity changed
+     * event.
+     *
+     * @param mac The cluster ID of the cluster started or joined.
+     * @param currentDiscoveryInterfaceMac The MAC address of the discovery interface.
+     */
+    public void onClusterChange(int flag, byte[] mac, byte[] currentDiscoveryInterfaceMac) {
+        if (mConfigRequest.mEnableIdentityChangeCallback && !Arrays.equals(
+                currentDiscoveryInterfaceMac, mLastDiscoveryInterfaceMac)) {
             try {
-                mListener.onIdentityChanged();
+                // TODO: b/30000323 - resolve privacy concerns
+                mCallback.onIdentityChanged(currentDiscoveryInterfaceMac);
             } catch (RemoteException e) {
                 Log.w(TAG, "onIdentityChanged: RemoteException - ignored: " + e);
             }
-
-            return 1;
         }
 
-        return 0;
+        mLastDiscoveryInterfaceMac = currentDiscoveryInterfaceMac;
     }
 
+    /**
+     * Called on RTT success - forwards call to client.
+     */
+    public void onRangingSuccess(int rangingId, RttManager.ParcelableRttResults results) {
+        if (VDBG) {
+            Log.v(TAG, "onRangingSuccess: rangingId=" + rangingId + ", results=" + results);
+        }
+        try {
+            mCallback.onRangingSuccess(rangingId, results);
+        } catch (RemoteException e) {
+            Log.w(TAG, "onRangingSuccess: RemoteException - ignored: " + e);
+        }
+    }
+
+    /**
+     * Called on RTT failure - forwards call to client.
+     */
+    public void onRangingFailure(int rangingId, int reason, String description) {
+        if (VDBG) {
+            Log.v(TAG, "onRangingSuccess: rangingId=" + rangingId + ", reason=" + reason
+                    + ", description=" + description);
+        }
+        try {
+            mCallback.onRangingFailure(rangingId, reason, description);
+        } catch (RemoteException e) {
+            Log.w(TAG, "onRangingFailure: RemoteException - ignored: " + e);
+        }
+    }
+
+    /**
+     * Called on RTT operation aborted - forwards call to client.
+     */
+    public void onRangingAborted(int rangingId) {
+        if (VDBG) Log.v(TAG, "onRangingSuccess: rangingId=" + rangingId);
+        try {
+            mCallback.onRangingAborted(rangingId);
+        } catch (RemoteException e) {
+            Log.w(TAG, "onRangingAborted: RemoteException - ignored: " + e);
+        }
+    }
+
+    /**
+     * Dump the internal state of the class.
+     */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("NanClientState:");
-        pw.println("  mUid: " + mUid);
+        pw.println("  mClientId: " + mClientId);
         pw.println("  mConfigRequest: " + mConfigRequest);
-        pw.println("  mListener: " + mListener);
-        pw.println("  mEvents: " + mEvents);
+        pw.println("  mCallback: " + mCallback);
         pw.println("  mSessions: [" + mSessions + "]");
         for (int i = 0; i < mSessions.size(); ++i) {
             mSessions.valueAt(i).dump(fd, pw, args);
diff --git a/service/java/com/android/server/wifi/nan/WifiNanDataPathStateManager.java b/service/java/com/android/server/wifi/nan/WifiNanDataPathStateManager.java
new file mode 100644
index 0000000..c3a9b9b
--- /dev/null
+++ b/service/java/com/android/server/wifi/nan/WifiNanDataPathStateManager.java
@@ -0,0 +1,1002 @@
+/*
+ * 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 com.android.server.wifi.nan;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.IpPrefix;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.NetworkAgent;
+import android.net.NetworkCapabilities;
+import android.net.NetworkFactory;
+import android.net.NetworkInfo;
+import android.net.NetworkRequest;
+import android.net.RouteInfo;
+import android.net.UidRange;
+import android.net.wifi.nan.WifiNanManager;
+import android.os.IBinder;
+import android.os.INetworkManagementService;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
+import android.util.Base64;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import libcore.util.HexEncoding;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Manages NAN data-path lifetime: interface creation/deletion, data-path setup and tear-down.
+ * The NAN network configuration is:
+ * - transport = TRANSPORT_WIFI_NAN
+ * - capabilities = NET_CAPABILITY_NOT_VPN
+ * - network specifier generated by WifiNanSession.createNetworkSpecifier(...) or
+ *   WifiNanManager.createNetworkSpecifier(...).
+ *   The network specifier is encoded as a JSON string with the following key combos:
+ *     TYPE_1A: type, role, client_id, session_id, peer_id, token
+ *     TYPE_1B: type, role, client_id, session_id, peer_id [only permitted for RESPONDER]
+ *     TYPE_2A: type, role, client_id, peer_mac, token
+ *     TYPE_2B: type, role, client_id, peer_mac [only permitted for RESPONDER]
+ *     TYPE_2C: type, role, client_id, token [only permitted for RESPONDER]
+ *     TYPE_2D: type, role, client_id [only permitted for RESPONDER]
+ */
+public class WifiNanDataPathStateManager {
+    private static final String TAG = "WifiNanDataPathStateMgr";
+
+    private static final boolean DBG = false;
+    private static final boolean VDBG = false; // STOPSHIP if true
+
+    private static final String NAN_INTERFACE_PREFIX = "nan";
+    private static final String NETWORK_TAG = "WIFI_NAN_FACTORY";
+    private static final String AGENT_TAG_PREFIX = "WIFI_NAN_AGENT_";
+    private static final int NETWORK_FACTORY_SCORE_AVAIL = 1;
+    private static final int NETWORK_FACTORY_BANDWIDTH_AVAIL = 1;
+    private static final int NETWORK_FACTORY_SIGNAL_STRENGTH_AVAIL = 1;
+
+    private final WifiNanStateManager mMgr;
+    private final NetworkInterfaceWrapper mNiWrapper = new NetworkInterfaceWrapper();
+    private final NetworkCapabilities mNetworkCapabilitiesFilter = new NetworkCapabilities();
+    private final Set<String> mInterfaces = new HashSet<>();
+    private final Map<String, NanNetworkRequestInformation> mNetworkRequestsCache = new HashMap<>();
+    private Context mContext;
+    private Looper mLooper;
+    private WifiNanNetworkFactory mNetworkFactory;
+    private INetworkManagementService mNwService;
+
+    public WifiNanDataPathStateManager(WifiNanStateManager mgr) {
+        mMgr = mgr;
+    }
+
+    /**
+     * Initialize the NAN data-path state manager. Specifically register the network factory with
+     * connectivity service.
+     */
+    public void start(Context context, Looper looper) {
+        if (VDBG) Log.v(TAG, "start");
+
+        mContext = context;
+        mLooper = looper;
+
+        mNetworkCapabilitiesFilter.clearAll();
+        mNetworkCapabilitiesFilter.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_NAN);
+        mNetworkCapabilitiesFilter
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED);
+        mNetworkCapabilitiesFilter
+                .setNetworkSpecifier(NetworkCapabilities.MATCH_ALL_REQUESTS_NETWORK_SPECIFIER);
+        mNetworkCapabilitiesFilter.setLinkUpstreamBandwidthKbps(NETWORK_FACTORY_BANDWIDTH_AVAIL);
+        mNetworkCapabilitiesFilter.setLinkDownstreamBandwidthKbps(NETWORK_FACTORY_BANDWIDTH_AVAIL);
+        mNetworkCapabilitiesFilter.setSignalStrength(NETWORK_FACTORY_SIGNAL_STRENGTH_AVAIL);
+
+        mNetworkFactory = new WifiNanNetworkFactory(looper, context, mNetworkCapabilitiesFilter);
+        mNetworkFactory.setScoreFilter(NETWORK_FACTORY_SCORE_AVAIL);
+        mNetworkFactory.register();
+
+        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+        mNwService = INetworkManagementService.Stub.asInterface(b);
+    }
+
+    private Map.Entry<String, NanNetworkRequestInformation> getNetworkRequestByNdpId(int ndpId) {
+        for (Map.Entry<String, NanNetworkRequestInformation> entry : mNetworkRequestsCache
+                .entrySet()) {
+            if (entry.getValue().ndpId == ndpId) {
+                return entry;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Create all NAN data-path interfaces which are possible on the device - based on the
+     * capabilities of the firmware.
+     */
+    public void createAllInterfaces() {
+        if (VDBG) Log.v(TAG, "createAllInterfaces");
+
+        if (mMgr.mCapabilities == null) {
+            Log.e(TAG, "createAllInterfaces: capabilities aren't initialized yet!");
+            return;
+        }
+
+        for (int i = 0; i < mMgr.mCapabilities.maxNdiInterfaces; ++i) {
+            String name = NAN_INTERFACE_PREFIX + i;
+            if (mInterfaces.contains(name)) {
+                Log.e(TAG, "createAllInterfaces(): interface already up, " + name
+                        + ", possibly failed to delete - deleting/creating again to be safe");
+                mMgr.deleteDataPathInterface(name);
+
+                // critical to remove so that don't get infinite loop if the delete fails again
+                mInterfaces.remove(name);
+            }
+
+            mMgr.createDataPathInterface(name);
+        }
+    }
+
+    /**
+     * Delete all NAN data-path interfaces which are currently up.
+     */
+    public void deleteAllInterfaces() {
+        if (VDBG) Log.v(TAG, "deleteAllInterfaces");
+
+        for (String name : mInterfaces) {
+            mMgr.deleteDataPathInterface(name);
+        }
+    }
+
+    /**
+     * Called when firmware indicates the an interface was created.
+     */
+    public void onInterfaceCreated(String interfaceName) {
+        if (VDBG) Log.v(TAG, "onInterfaceCreated: interfaceName=" + interfaceName);
+
+        if (mInterfaces.contains(interfaceName)) {
+            Log.w(TAG, "onInterfaceCreated: already contains interface -- " + interfaceName);
+        }
+
+        mInterfaces.add(interfaceName);
+    }
+
+    /**
+     * Called when firmware indicates the an interface was deleted.
+     */
+    public void onInterfaceDeleted(String interfaceName) {
+        if (VDBG) Log.v(TAG, "onInterfaceDeleted: interfaceName=" + interfaceName);
+
+        if (!mInterfaces.contains(interfaceName)) {
+            Log.w(TAG, "onInterfaceDeleted: interface not on list -- " + interfaceName);
+        }
+
+        mInterfaces.remove(interfaceName);
+    }
+
+    /**
+     * Response to initiating data-path request. Indicates that request is successful (not
+     * complete!) and is now in progress.
+     *
+     * @param networkSpecifier The network specifier provided as part of the initiate request.
+     * @param ndpId            The ID assigned to the data-path.
+     */
+    public void onDataPathInitiateSuccess(String networkSpecifier, int ndpId) {
+        if (VDBG) {
+            Log.v(TAG,
+                    "onDataPathInitiateSuccess: networkSpecifier=" + networkSpecifier + ", ndpId="
+                            + ndpId);
+        }
+
+        NanNetworkRequestInformation nnri = mNetworkRequestsCache.get(networkSpecifier);
+        if (nnri == null) {
+            Log.w(TAG, "onDataPathInitiateSuccess: network request not found for networkSpecifier="
+                    + networkSpecifier);
+            mMgr.endDataPath(ndpId);
+            return;
+        }
+
+        if (nnri.state != NanNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE) {
+            Log.w(TAG, "onDataPathInitiateSuccess: network request in incorrect state: state="
+                    + nnri.state);
+            mNetworkRequestsCache.remove(networkSpecifier);
+            mMgr.endDataPath(ndpId);
+            return;
+        }
+
+        nnri.state = NanNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_CONFIRM;
+        nnri.ndpId = ndpId;
+    }
+
+    /**
+     * Response to an attempt to set up a data-path (on the initiator side).
+     *
+     * @param networkSpecifier The network specifier provided as part of the initiate request.
+     * @param reason           Failure reason.
+     */
+    public void onDataPathInitiateFail(String networkSpecifier, int reason) {
+        if (VDBG) {
+            Log.v(TAG,
+                    "onDataPathInitiateFail: networkSpecifier=" + networkSpecifier + ", reason="
+                            + reason);
+        }
+
+        NanNetworkRequestInformation nnri = mNetworkRequestsCache.remove(networkSpecifier);
+        if (nnri == null) {
+            Log.w(TAG, "onDataPathInitiateFail: network request not found for networkSpecifier="
+                    + networkSpecifier);
+            return;
+        }
+
+        if (nnri.state != NanNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE) {
+            Log.w(TAG, "onDataPathInitiateFail: network request in incorrect state: state="
+                    + nnri.state);
+        }
+
+        mNetworkRequestsCache.remove(networkSpecifier);
+    }
+
+
+    /**
+     * Notification (unsolicited/asynchronous) that a peer has requested to set up a data-path
+     * connection with us.
+     *
+     * @param pubSubId      The ID of the discovery session context for the data-path - or 0 if not
+     *                      related to a discovery session.
+     * @param mac           The discovery MAC address of the peer.
+     * @param ndpId         The locally assigned ID for the data-path.
+     * @param message       A message sent from the peer as part of the data-path setup process.
+     * @param messageLength The length of the {@code message}.
+     * @return The network specifier of the data-path (or null if none/error)
+     */
+    public String onDataPathRequest(int pubSubId, byte[] mac, int ndpId, byte[] message, int
+            messageLength) {
+        if (VDBG) {
+            Log.v(TAG,
+                    "onDataPathRequest: pubSubId=" + pubSubId + ", mac=" + String.valueOf(
+                            HexEncoding.encode(mac)) + ", ndpId=" + ndpId + ", messageLength="
+                            + messageLength);
+        }
+
+        String networkSpecifier = null;
+        NanNetworkRequestInformation nnri = null;
+        for (Map.Entry<String, NanNetworkRequestInformation> entry : mNetworkRequestsCache
+                .entrySet()) {
+            /*
+             * Checking that the incoming request (from the Initiator) matches the request
+             * we (the Responder) already have set up. The rules are:
+             * - The discovery session (pub/sub ID) must match.
+             * - The token (if specified - i.e. non-null) must match. A null token == accept any
+             *   Initiator token.
+             * - The peer MAC address (if specified - i.e. non-null) must match. A null peer MAC ==
+             *   accept (otherwise matching) requests from any peer MAC.
+             */
+            if (entry.getValue().pubSubId != 0 && entry.getValue().pubSubId != pubSubId) {
+                continue;
+            }
+
+            if (entry.getValue().token != null && !Arrays.equals(entry.getValue().token,
+                    Arrays.copyOfRange(message, 0, messageLength))) {
+                continue;
+            }
+
+            if (entry.getValue().peerDiscoveryMac != null && !Arrays.equals(
+                    entry.getValue().peerDiscoveryMac, mac)) {
+                continue;
+            }
+
+            networkSpecifier = entry.getKey();
+            nnri = entry.getValue();
+            break;
+        }
+
+        if (nnri == null) {
+            Log.w(TAG, "onDataPathRequest: can't find a request with specified pubSubId=" + pubSubId
+                    + ", mac=" + String.valueOf(HexEncoding.encode(mac)) + ", message=" + message
+                    + ", messageLength=" + messageLength);
+            if (DBG) {
+                Log.d(TAG, "onDataPathRequest: network request cache = " + mNetworkRequestsCache);
+            }
+            mMgr.respondToDataPathRequest(false, ndpId, "", "");
+            // TODO: validate respond with REJECT (when respond has a meaning)
+            return null;
+        }
+
+        if (nnri.state != NanNetworkRequestInformation.STATE_RESPONDER_WAIT_FOR_REQUEST) {
+            Log.w(TAG, "onDataPathRequest: request " + networkSpecifier + " is incorrect state="
+                    + nnri.state);
+            mMgr.respondToDataPathRequest(false, ndpId, "", "");
+            // TODO: validate respond with REJECT (when respond has a meaning)
+            mNetworkRequestsCache.remove(networkSpecifier);
+            return null;
+        }
+
+        nnri.state = NanNetworkRequestInformation.STATE_RESPONDER_WAIT_FOR_CONFIRM;
+        nnri.ndpId = ndpId;
+        nnri.interfaceName = selectInterfaceForRequest(nnri);
+        mMgr.respondToDataPathRequest(true, ndpId, nnri.interfaceName, "");
+
+        return networkSpecifier;
+        // TODO: validate respond with ACCEPT (when respond has a meaning)
+    }
+
+    /**
+     * Notification (unsolicited/asynchronous) that the data-path (which we've been setting up)
+     * is possibly (if {@code accept} is {@code true}) ready for use from the firmware's
+     * perspective - now can do L3 configuration.
+     *
+     * @param ndpId         Id of the data-path
+     * @param mac           The MAC address of the peer's data-path (not discovery interface). Only
+     *                      valid
+     *                      if {@code accept} is {@code true}.
+     * @param accept        Indicates whether the data-path setup has succeeded (been accepted) or
+     *                      failed (been rejected).
+     * @param reason        If {@code accept} is {@code false} provides a reason code for the
+     *                      rejection/failure.
+     * @param message       The message provided by the peer as part of the data-path setup
+     *                      process.
+     * @param messageLength Length of the {@code message}.
+     * @return The network specifier of the data-path or a null if none/error.
+     */
+    public String onDataPathConfirm(int ndpId, byte[] mac, boolean accept, int reason,
+            byte[] message, int messageLength) {
+        if (VDBG) {
+            Log.v(TAG, "onDataPathConfirm: ndpId=" + ndpId + ", mac=" + String.valueOf(
+                    HexEncoding.encode(mac)) + ", accept=" + accept + ", reason=" + reason
+                    + ", messageLength=" + messageLength);
+        }
+
+        Map.Entry<String, NanNetworkRequestInformation> nnriE = getNetworkRequestByNdpId(ndpId);
+        if (nnriE == null) {
+            Log.w(TAG, "onDataPathConfirm: network request not found for ndpId=" + ndpId);
+            if (accept) {
+                mMgr.endDataPath(ndpId);
+            }
+            return null;
+        }
+
+        String networkSpecifier = nnriE.getKey();
+        NanNetworkRequestInformation nnri = nnriE.getValue();
+
+        // validate state
+        if (nnri.role == WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR
+                && nnri.state != NanNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_CONFIRM) {
+            Log.w(TAG, "onDataPathConfirm: INITIATOR in invalid state=" + nnri.state);
+            mNetworkRequestsCache.remove(networkSpecifier);
+            if (accept) {
+                mMgr.endDataPath(ndpId);
+            }
+            return networkSpecifier;
+        }
+        if (nnri.role == WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_RESPONDER
+                && nnri.state != NanNetworkRequestInformation.STATE_RESPONDER_WAIT_FOR_CONFIRM) {
+            Log.w(TAG, "onDataPathConfirm: RESPONDER in invalid state=" + nnri.state);
+            mNetworkRequestsCache.remove(networkSpecifier);
+            if (accept) {
+                mMgr.endDataPath(ndpId);
+            }
+            return networkSpecifier;
+        }
+
+        if (accept) {
+            nnri.state = (nnri.role == WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR)
+                    ? NanNetworkRequestInformation.STATE_INITIATOR_CONFIRMED
+                    : NanNetworkRequestInformation.STATE_RESPONDER_CONFIRMED;
+            nnri.peerDataMac = mac;
+
+            NetworkInfo networkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0,
+                    NETWORK_TAG, "");
+            NetworkCapabilities networkCapabilities = new NetworkCapabilities(
+                    mNetworkCapabilitiesFilter);
+            LinkProperties linkProperties = new LinkProperties();
+
+            try {
+                // TODO: b/29608448 to track other IPv6 related optimizations and move to IpManager
+                mNwService.setInterfaceUp(nnri.interfaceName);
+                mNwService.enableIpv6(nnri.interfaceName);
+            } catch (RemoteException e) {
+                Log.e(TAG, "onDataPathConfirm: ACCEPT nnri=" + nnri + ": can't configure network - "
+                        + e);
+                mMgr.endDataPath(ndpId);
+                return networkSpecifier;
+            }
+
+            if (!mNiWrapper.configureAgentProperties(nnri, networkSpecifier, ndpId, networkInfo,
+                    networkCapabilities, linkProperties)) {
+                return networkSpecifier;
+            }
+
+            nnri.networkAgent = new WifiNanNetworkAgent(mLooper, mContext,
+                    AGENT_TAG_PREFIX + nnri.ndpId, networkInfo, networkCapabilities, linkProperties,
+                    NETWORK_FACTORY_SCORE_AVAIL, networkSpecifier, ndpId);
+        } else {
+            if (DBG) {
+                Log.d(TAG, "onDataPathConfirm: data-path for networkSpecifier=" + networkSpecifier
+                        + " rejected - reason=" + reason);
+            }
+            mNetworkRequestsCache.remove(networkSpecifier);
+        }
+
+        return networkSpecifier;
+    }
+
+    /**
+     * Notification (unsolicited/asynchronous) from the firmware that the specified data-path has
+     * been terminated.
+     *
+     * @param ndpId The ID of the terminated data-path.
+     */
+    public void onDataPathEnd(int ndpId) {
+        if (VDBG) Log.v(TAG, "onDataPathEnd: ndpId=" + ndpId);
+
+        Map.Entry<String, NanNetworkRequestInformation> nnriE = getNetworkRequestByNdpId(ndpId);
+        if (nnriE == null) {
+            if (DBG) {
+                Log.d(TAG, "onDataPathEnd: network request not found for ndpId=" + ndpId);
+            }
+            return;
+        }
+
+        tearDownInterface(nnriE.getValue());
+        mNetworkRequestsCache.remove(nnriE.getKey());
+    }
+
+    /**
+     * Called whenever NAN comes down. Clean up all pending and up network requeests and agents.
+     */
+    public void onNanDownCleanupDataPaths() {
+        if (VDBG) Log.v(TAG, "onNanDownCleanupDataPaths");
+
+        for (NanNetworkRequestInformation nnri : mNetworkRequestsCache.values()) {
+            tearDownInterface(nnri);
+        }
+        mNetworkRequestsCache.clear();
+    }
+
+    /**
+     * Called when timed-out waiting for confirmation of the data-path setup (i.e.
+     * onDataPathConfirm). Started on the initiator when executing the request for the data-path
+     * and on the responder when received a request for data-path (in both cases only on success
+     * - i.e. when we're proceeding with data-path setup).
+     */
+    public void handleDataPathTimeout(String networkSpecifier) {
+        if (VDBG) Log.v(TAG, "handleDataPathTimeout: networkSpecifier=" + networkSpecifier);
+
+        NanNetworkRequestInformation nnri = mNetworkRequestsCache.remove(networkSpecifier);
+        if (nnri == null) {
+            if (DBG) {
+                Log.d(TAG,
+                        "handleDataPathTimeout: network request not found for networkSpecifier="
+                                + networkSpecifier);
+            }
+            return;
+        }
+
+        mMgr.endDataPath(nnri.ndpId);
+    }
+
+    private class WifiNanNetworkFactory extends NetworkFactory {
+        WifiNanNetworkFactory(Looper looper, Context context, NetworkCapabilities filter) {
+            super(looper, context, NETWORK_TAG, filter);
+        }
+
+        @Override
+        public boolean acceptRequest(NetworkRequest request, int score) {
+            if (VDBG) {
+                Log.v(TAG, "WifiNanNetworkFactory.acceptRequest: request=" + request + ", score="
+                        + score);
+            }
+
+            if (!mMgr.isUsageEnabled()) {
+                if (VDBG) {
+                    Log.v(TAG, "WifiNanNetworkFactory.acceptRequest: request=" + request
+                            + " -- NAN disabled");
+                }
+                return false;
+            }
+
+            if (mInterfaces.isEmpty()) {
+                Log.w(TAG, "WifiNanNetworkFactory.acceptRequest: request=" + request
+                        + " -- No NAN interfaces are up");
+                return false;
+            }
+
+            String networkSpecifier = request.networkCapabilities.getNetworkSpecifier();
+            if (TextUtils.isEmpty(networkSpecifier)) {
+                Log.w(TAG, "WifiNanNetworkFactory.acceptRequest: request=" + request
+                        + " - empty (or null) NetworkSpecifier");
+                return false;
+            }
+
+            // look up specifier - are we being called again?
+            NanNetworkRequestInformation nnri = mNetworkRequestsCache.get(networkSpecifier);
+            if (nnri != null) {
+                if (DBG) {
+                    Log.d(TAG, "WifiNanNetworkFactory.acceptRequest: request=" + request
+                            + " - already in cache!?");
+                }
+
+                // seems to happen after a network agent is created - trying to rematch all
+                // requests again!?
+                return true;
+            }
+
+            // parse network specifier (JSON) & cache
+            // TODO: validate that the client ID actually comes from the correct process and is
+            // not faked?
+            nnri = NanNetworkRequestInformation.parseNetworkSpecifier(networkSpecifier, mMgr);
+            if (nnri == null) {
+                Log.e(TAG, "WifiNanNetworkFactory.acceptRequest: request=" + request
+                        + " - can't parse network specifier");
+                return false;
+            }
+            mNetworkRequestsCache.put(networkSpecifier, nnri);
+
+            return true;
+        }
+
+        @Override
+        protected void needNetworkFor(NetworkRequest networkRequest, int score) {
+            if (VDBG) {
+                Log.v(TAG, "WifiNanNetworkFactory.needNetworkFor: networkRequest=" + networkRequest
+                        + ", score=" + score);
+            }
+
+            String networkSpecifier = networkRequest.networkCapabilities.getNetworkSpecifier();
+            NanNetworkRequestInformation nnri = mNetworkRequestsCache.get(networkSpecifier);
+            if (nnri == null) {
+                Log.e(TAG, "WifiNanNetworkFactory.needNetworkFor: networkRequest=" + networkRequest
+                        + " not in cache!?");
+                return;
+            }
+
+            if (nnri.role == WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR) {
+                if (nnri.state != NanNetworkRequestInformation.STATE_INITIATOR_IDLE) {
+                    if (DBG) {
+                        Log.d(TAG, "WifiNanNetworkFactory.needNetworkFor: networkRequest="
+                                + networkRequest + " - already in progress");
+                        // TODO: understand how/when can be called again/while in progress (seems
+                        // to be related to score re-calculation after a network agent is created)
+                    }
+                    return;
+                }
+
+                nnri.interfaceName = selectInterfaceForRequest(nnri);
+                mMgr.initiateDataPathSetup(networkSpecifier, nnri.peerId,
+                        WifiNanNative.CHANNEL_REQUEST_TYPE_REQUESTED, selectChannelForRequest(nnri),
+                        nnri.peerDiscoveryMac, nnri.interfaceName, nnri.token);
+                nnri.state = NanNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE;
+            } else {
+                if (nnri.state != NanNetworkRequestInformation.STATE_RESPONDER_IDLE) {
+                    if (DBG) {
+                        Log.d(TAG, "WifiNanNetworkFactory.needNetworkFor: networkRequest="
+                                + networkRequest + " - already in progress");
+                        // TODO: understand how/when can be called again/while in progress (seems
+                        // to be related to score re-calculation after a network agent is created)
+                    }
+                    return;
+                }
+
+                nnri.state = NanNetworkRequestInformation.STATE_RESPONDER_WAIT_FOR_REQUEST;
+            }
+        }
+
+        @Override
+        protected void releaseNetworkFor(NetworkRequest networkRequest) {
+            if (VDBG) {
+                Log.v(TAG, "WifiNanNetworkFactory.releaseNetworkFor: networkRequest="
+                        + networkRequest);
+            }
+
+            String networkSpecifier = networkRequest.networkCapabilities.getNetworkSpecifier();
+            NanNetworkRequestInformation nnri = mNetworkRequestsCache.get(networkSpecifier);
+            if (nnri == null) {
+                Log.e(TAG,
+                        "WifiNanNetworkFactory.releaseNetworkFor: networkRequest=" + networkRequest
+                                + " not in cache!?");
+                return;
+            }
+
+            if (nnri.networkAgent != null) {
+                if (VDBG) {
+                    Log.v(TAG, "WifiNanNetworkFactory.releaseNetworkFor: networkRequest="
+                            + networkRequest + ", nnri=" + nnri
+                            + ": agent already created - deferring ending data-path to agent"
+                            + ".unwanted()");
+                }
+                return;
+            }
+
+            if (nnri.role == WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR && nnri.state
+                    > NanNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE) {
+                mMgr.endDataPath(nnri.ndpId);
+            }
+            if (nnri.role == WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_RESPONDER
+                    && nnri.state > NanNetworkRequestInformation.STATE_RESPONDER_WAIT_FOR_REQUEST) {
+                mMgr.endDataPath(nnri.ndpId);
+            }
+
+            // Will get a callback (on both initiator and responder) when data-path actually
+            // terminated. At that point will inform the agent and will clear the cache.
+        }
+    }
+
+    private class WifiNanNetworkAgent extends NetworkAgent {
+        private NetworkInfo mNetworkInfo;
+        private String mNetworkSpecifier;
+        private int mNdpId;
+
+        WifiNanNetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
+                NetworkCapabilities nc, LinkProperties lp, int score, String networkSpecifier,
+                int ndpId) {
+            super(looper, context, logTag, ni, nc, lp, score);
+
+            mNetworkInfo = ni;
+            mNetworkSpecifier = networkSpecifier;
+            mNdpId = ndpId;
+        }
+
+        @Override
+        protected void unwanted() {
+            if (VDBG) {
+                Log.v(TAG, "WifiNanNetworkAgent.unwanted: networkSpecifier=" + mNetworkSpecifier
+                        + ", ndpId=" + mNdpId);
+            }
+
+            mMgr.endDataPath(mNdpId);
+
+            // Will get a callback (on both initiator and responder) when data-path actually
+            // terminated. At that point will inform the agent and will clear the cache.
+        }
+
+        void reconfigureAgentAsDisconnected() {
+            if (VDBG) {
+                Log.v(TAG, "WifiNanNetworkAgent.reconfigureAgentAsDisconnected: networkSpecifier="
+                        + mNetworkSpecifier + ", ndpId=" + mNdpId);
+            }
+
+            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, "");
+            sendNetworkInfo(mNetworkInfo);
+        }
+    }
+
+    private void tearDownInterface(NanNetworkRequestInformation nnri) {
+        if (VDBG) Log.v(TAG, "tearDownInterface: nnri=" + nnri);
+
+        if (nnri.interfaceName != null && !nnri.interfaceName.isEmpty()) {
+            try {
+                // TODO: b/29608448 replace with IpManager
+                mNwService.setInterfaceDown(nnri.interfaceName);
+            } catch (RemoteException e) {
+                Log.e(TAG,
+                        "tearDownInterface: nnri=" + nnri + ": can't bring interface down - " + e);
+            }
+        }
+
+        if (nnri.networkAgent != null) {
+            nnri.networkAgent.reconfigureAgentAsDisconnected();
+        }
+    }
+
+    /**
+     * Select one of the existing interfaces for the new network request.
+     *
+     * TODO: for now there is only a single interface - simply pick it.
+     */
+    private String selectInterfaceForRequest(NanNetworkRequestInformation req) {
+        Iterator<String> it = mInterfaces.iterator();
+        if (it.hasNext()) {
+            return it.next();
+        }
+
+        Log.e(TAG, "selectInterfaceForRequest: req=" + req + " - but no interfaces available!");
+
+        return "";
+    }
+
+    /**
+     * Select a channel for the network request.
+     *
+     * TODO: for now simply select channel 6
+     */
+    private int selectChannelForRequest(NanNetworkRequestInformation req) {
+        return 2437;
+    }
+
+    /**
+     * NAN network request. State object: contains network request information/state through its
+     * lifetime.
+     */
+    @VisibleForTesting
+    public static class NanNetworkRequestInformation {
+        static final int STATE_INITIATOR_IDLE = 100;
+        static final int STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE = 101;
+        static final int STATE_INITIATOR_WAIT_FOR_CONFIRM = 102;
+        static final int STATE_INITIATOR_CONFIRMED = 103;
+
+        static final int STATE_RESPONDER_IDLE = 200;
+        static final int STATE_RESPONDER_WAIT_FOR_REQUEST = 201;
+        static final int STATE_RESPONDER_WAIT_FOR_RESPOND_RESPONSE = 202;
+        static final int STATE_RESPONDER_WAIT_FOR_CONFIRM = 203;
+        static final int STATE_RESPONDER_CONFIRMED = 204;
+
+        public int state;
+        public int role;
+
+        public int uid;
+        public String interfaceName;
+        public int pubSubId = 0;
+        public int peerId = 0;
+        public byte[] peerDiscoveryMac = null;
+        public byte[] token = null;
+        public int ndpId;
+        public byte[] peerDataMac;
+
+        public WifiNanNetworkAgent networkAgent;
+
+        static NanNetworkRequestInformation parseNetworkSpecifier(String networkSpecifier,
+                WifiNanStateManager mgr) {
+            int type, role, uid, clientId, sessionId = 0, peerId = 0, pubSubId = 0;
+            byte[] peerMac = null;
+            byte[] token = null;
+
+            if (VDBG) {
+                Log.v(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier);
+            }
+
+            try {
+                JSONObject jsonObject = new JSONObject(networkSpecifier);
+
+                // type: always present
+                type = jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_TYPE);
+                if (type < 0 || type > WifiNanManager.NETWORK_SPECIFIER_TYPE_MAX_VALID) {
+                    Log.e(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+                            + ", invalid 'type' value");
+                    return null;
+                }
+
+                // role: always present
+                role = jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_ROLE);
+                if (role != WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR
+                        && role != WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_RESPONDER) {
+                    Log.e(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+                            + " -- invalid 'role' value");
+                    return null;
+                }
+
+                if (role == WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR
+                        && type != WifiNanManager.NETWORK_SPECIFIER_TYPE_1A
+                        && type != WifiNanManager.NETWORK_SPECIFIER_TYPE_2A) {
+                    Log.e(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+                            + " -- invalid 'type' value for INITIATOR (only 1A and 2A are "
+                            + "permitted)");
+                    return null;
+                }
+
+                // clientId: always present
+                clientId = jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_CLIENT_ID);
+
+                // sessionId: present for types 1A, 1B, 1C, 1D
+                if (type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1A
+                        || type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1B
+                        || type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1C
+                        || type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1D) {
+                    sessionId = jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_SESSION_ID);
+                }
+
+                // peer Id: present for types 1A, 1B
+                if (type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1A
+                        || type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1B) {
+                    peerId = jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_PEER_ID);
+                }
+
+                // peerMac: present for types 2A, 2B
+                if (type == WifiNanManager.NETWORK_SPECIFIER_TYPE_2A
+                        || type == WifiNanManager.NETWORK_SPECIFIER_TYPE_2B) {
+                    try {
+                        peerMac = HexEncoding.decode(jsonObject.getString(
+                                WifiNanManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
+                                false);
+                        if (peerMac == null || peerMac.length != 6) {
+                            Log.e(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+                                    + " -- invalid peer MAC address - null or not 6 bytes");
+                            return null;
+                        }
+                    } catch (IllegalArgumentException e) {
+                        Log.e(TAG, "parseNetworkSpecifier: networkSpecifier="
+                                + networkSpecifier + " -- invalid peer MAC address -- e=" + e);
+                        return null;
+                    }
+                }
+
+                // token: present for types 1A, 1C, 2A, 2C
+                if (type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1A
+                        || type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1C
+                        || type == WifiNanManager.NETWORK_SPECIFIER_TYPE_2A
+                        || type == WifiNanManager.NETWORK_SPECIFIER_TYPE_2C) {
+                    token = Base64.decode(
+                            jsonObject.getString(WifiNanManager.NETWORK_SPECIFIER_KEY_TOKEN),
+                            Base64.DEFAULT);
+                }
+            } catch (JSONException e) {
+                Log.e(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+                        + " -- invalid JSON format -- e=" + e);
+                return null;
+            }
+
+            // look up network specifier information in NAN state manager
+            WifiNanClientState client = mgr.getClient(clientId);
+            if (client == null) {
+                Log.e(TAG, "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+                        + " -- not client with this id -- clientId=" + clientId);
+                return null;
+            }
+            uid = client.getUid();
+
+            if (type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1A
+                    || type == WifiNanManager.NETWORK_SPECIFIER_TYPE_1B) {
+                WifiNanSessionState session = client.getSession(sessionId);
+                if (session == null) {
+                    Log.e(TAG,
+                            "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+                                    + " -- not session with this id -- sessionId=" + sessionId);
+                    return null;
+                }
+                pubSubId = session.getPubSubId();
+                String peerMacStr = session.getMac(peerId, null);
+                if (peerMacStr == null) {
+                    Log.e(TAG,
+                            "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+                                    + " -- no MAC address associated with this peer id -- peerId="
+                                    + peerId);
+                    return null;
+                }
+                try {
+                    peerMac = HexEncoding.decode(peerMacStr.toCharArray(), false);
+                    if (peerMac == null || peerMac.length != 6) {
+                        Log.e(TAG, "parseNetworkSpecifier: networkSpecifier="
+                                + networkSpecifier + " -- invalid peer MAC address");
+                        return null;
+                    }
+                } catch (IllegalArgumentException e) {
+                    Log.e(TAG,
+                            "parseNetworkSpecifier: networkSpecifier=" + networkSpecifier
+                                    + " -- invalid peer MAC address -- e=" + e);
+                    return null;
+                }
+            }
+
+            // create container and populate
+            NanNetworkRequestInformation nnri = new NanNetworkRequestInformation();
+            nnri.state = (role == WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR)
+                    ? NanNetworkRequestInformation.STATE_INITIATOR_IDLE
+                    : NanNetworkRequestInformation.STATE_RESPONDER_IDLE;
+            nnri.role = role;
+            nnri.uid = uid;
+            nnri.pubSubId = pubSubId;
+            nnri.peerId = peerId;
+            nnri.peerDiscoveryMac = peerMac;
+            nnri.token = token;
+
+            return nnri;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder("NanNetworkRequestInformation: ");
+            sb.append("state=").append(state).append(", role=").append(role).append(
+                    ", uid=").append(uid).append(", interfaceName=").append(interfaceName).append(
+                    ", pubSubId=").append(pubSubId).append(", peerDiscoveryMac=").append(
+                    peerDiscoveryMac == null ? ""
+                            : String.valueOf(HexEncoding.encode(peerDiscoveryMac))).append(
+                    ", token=").append(token).append(", ndpId=").append(ndpId).append(
+                    ", peerDataMac=").append(
+                    peerDataMac == null ? "" : String.valueOf(HexEncoding.encode(peerDataMac)));
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Enables mocking.
+     */
+    @VisibleForTesting
+    public class NetworkInterfaceWrapper {
+        /**
+         * Configures network agent properties: link-local address, connected status, interface
+         * name. Delegated to enable mocking.
+         */
+        public boolean configureAgentProperties(NanNetworkRequestInformation nnri,
+                String networkSpecifier, int ndpId, NetworkInfo networkInfo,
+                NetworkCapabilities networkCapabilities, LinkProperties linkProperties) {
+            // find link-local address
+            InetAddress linkLocal = null;
+            NetworkInterface ni;
+            try {
+                ni = NetworkInterface.getByName(nnri.interfaceName);
+            } catch (SocketException e) {
+                Log.e(TAG, "onDataPathConfirm: ACCEPT nnri=" + nnri
+                        + ": can't get network interface - " + e);
+                mMgr.endDataPath(ndpId);
+                return false;
+            }
+            if (ni == null) {
+                Log.e(TAG, "onDataPathConfirm: ACCEPT nnri=" + nnri
+                        + ": can't get network interface (null)");
+                mMgr.endDataPath(ndpId);
+                return false;
+            }
+            Enumeration<InetAddress> addresses = ni.getInetAddresses();
+            while (addresses.hasMoreElements()) {
+                InetAddress ip = addresses.nextElement();
+                if (ip instanceof Inet6Address && ip.isLinkLocalAddress()) {
+                    linkLocal = ip;
+                    break;
+                }
+            }
+
+            if (linkLocal == null) {
+                Log.e(TAG, "onDataPathConfirm: ACCEPT nnri=" + nnri + ": no link local addresses");
+                mMgr.endDataPath(ndpId);
+                return false;
+            }
+
+            // configure agent
+            networkInfo.setIsAvailable(true);
+            networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
+
+            networkCapabilities.setNetworkSpecifier(networkSpecifier);
+
+            linkProperties.setInterfaceName(nnri.interfaceName);
+            linkProperties.addLinkAddress(new LinkAddress(linkLocal, 64));
+            linkProperties.addRoute(
+                    new RouteInfo(new IpPrefix("fe80::/64"), null, nnri.interfaceName));
+
+            return true;
+        }
+    }
+
+    /**
+     * Dump the internal state of the class.
+     */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("WifiNanDataPathStateManager:");
+        pw.println("  mInterfaces: " + mInterfaces);
+        pw.println("  mNetworkCapabilitiesFilter: " + mNetworkCapabilitiesFilter);
+        pw.println("  mNetworkRequestsCache: " + mNetworkRequestsCache);
+        pw.println("  mNetworkFactory:");
+        mNetworkFactory.dump(fd, pw, args);
+    }
+}
diff --git a/service/java/com/android/server/wifi/nan/WifiNanNative.java b/service/java/com/android/server/wifi/nan/WifiNanNative.java
index 8715719..8ecba96 100644
--- a/service/java/com/android/server/wifi/nan/WifiNanNative.java
+++ b/service/java/com/android/server/wifi/nan/WifiNanNative.java
@@ -17,23 +17,22 @@
 package com.android.server.wifi.nan;
 
 import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.PublishData;
-import android.net.wifi.nan.PublishSettings;
-import android.net.wifi.nan.SubscribeData;
-import android.net.wifi.nan.SubscribeSettings;
-import android.net.wifi.nan.WifiNanSessionListener;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
+import android.net.wifi.nan.WifiNanEventCallback;
+import android.net.wifi.nan.WifiNanSessionCallback;
 import android.util.Log;
 
 import com.android.server.wifi.WifiNative;
 
 import libcore.util.HexEncoding;
 
+import java.util.Arrays;
+
 /**
  * Native calls to access the Wi-Fi NAN HAL.
  *
  * Relies on WifiNative to perform the actual HAL registration.
- *
- * {@hide}
  */
 public class WifiNanNative {
     private static final String TAG = "WifiNanNative";
@@ -42,12 +41,18 @@
 
     private static final int WIFI_SUCCESS = 0;
 
-    private static boolean sNanNativeInit = false;
-
     private static WifiNanNative sWifiNanNativeSingleton;
 
+    private boolean mNativeHandlersIsInitialized = false;
+
     private static native int registerNanNatives();
 
+    /**
+     * Returns the singleton WifiNanNative used to manage the actual NAN HAL
+     * interface.
+     *
+     * @return Singleton object.
+     */
     public static WifiNanNative getInstance() {
         // dummy reference - used to make sure that WifiNative is loaded before
         // us since it is the one to load the shared library and starts its
@@ -66,6 +71,10 @@
         return sWifiNanNativeSingleton;
     }
 
+    /**
+     * A container class for NAN (vendor) implementation capabilities (or
+     * limitations). Filled-in by the firmware.
+     */
     public static class Capabilities {
         public int maxConcurrentNanClusters;
         public int maxPublishes;
@@ -79,6 +88,7 @@
         public int maxNdiInterfaces;
         public int maxNdpSessions;
         public int maxAppInfoLen;
+        public int maxQueuedTransmitMessages;
 
         @Override
         public String toString() {
@@ -89,233 +99,513 @@
                     + ", maxServiceSpecificInfoLen=" + maxServiceSpecificInfoLen
                     + ", maxVsaDataLen=" + maxVsaDataLen + ", maxMeshDataLen=" + maxMeshDataLen
                     + ", maxNdiInterfaces=" + maxNdiInterfaces + ", maxNdpSessions="
-                    + maxNdpSessions + ", maxAppInfoLen=" + maxAppInfoLen + "]";
+                    + maxNdpSessions + ", maxAppInfoLen=" + maxAppInfoLen
+                    + ", maxQueuedTransmitMessages=" + maxQueuedTransmitMessages + "]";
         }
     }
 
-    /* package */ static native int initNanHandlersNative(Object cls, int iface);
+    /* package */ static native int initNanHandlersNative(Class<WifiNative> cls, int iface);
 
-    private static native int getCapabilitiesNative(short transactionId, Object cls, int iface);
-
-    private boolean isNanInit(boolean tryToInit) {
-        if (!tryToInit || sNanNativeInit) {
-            return sNanNativeInit;
-        }
-
-        if (DBG) Log.d(TAG, "isNanInit: trying to init");
+    private boolean isNanInit() {
         synchronized (WifiNative.sLock) {
-            boolean halStarted = WifiNative.getWlanNativeInterface().isHalStarted();
-            if (!halStarted) {
-                halStarted = WifiNative.getWlanNativeInterface().startHal();
-            }
-            if (halStarted) {
+            if (!WifiNative.getWlanNativeInterface().isHalStarted()) {
+                /*
+                 * We should never start the HAL - that's done at a higher level
+                 * by the Wi-Fi state machine.
+                 */
+                mNativeHandlersIsInitialized = false;
+                return false;
+            } else if (!mNativeHandlersIsInitialized) {
                 int ret = initNanHandlersNative(WifiNative.class, WifiNative.sWlan0Index);
                 if (DBG) Log.d(TAG, "initNanHandlersNative: res=" + ret);
-                sNanNativeInit = ret == WIFI_SUCCESS;
+                mNativeHandlersIsInitialized = ret == WIFI_SUCCESS;
 
-                if (sNanNativeInit) {
-                    ret = getCapabilitiesNative(
-                            WifiNanStateManager.getInstance().createNextTransactionId(),
-                            WifiNative.class,
-                            WifiNative.sWlan0Index);
-                    if (DBG) Log.d(TAG, "getCapabilitiesNative: res=" + ret);
-                }
-
-                return sNanNativeInit;
+                return mNativeHandlersIsInitialized;
             } else {
-                Log.w(TAG, "isNanInit: HAL not initialized");
-                return false;
+                return true;
             }
         }
     }
 
+    /**
+     * Tell the NAN JNI to re-initialize the NAN callback pointers next time it starts up.
+     */
+    public void deInitNan() {
+        mNativeHandlersIsInitialized = false;
+    }
+
     private WifiNanNative() {
         // do nothing
     }
 
-    private static native int enableAndConfigureNative(short transactionId, Object cls, int iface,
-            ConfigRequest configRequest);
+    private static native int getCapabilitiesNative(short transactionId, Class<WifiNative> cls,
+            int iface);
 
-    public void enableAndConfigure(short transactionId, ConfigRequest configRequest) {
-        boolean success;
-
-        if (VDBG) Log.d(TAG, "enableAndConfigure: configRequest=" + configRequest);
-        if (isNanInit(true)) {
+    /**
+     * Query the NAN firmware's capabilities.
+     *
+     * @param transactionId Transaction ID for the transaction - used in the async callback to
+     *                      match with the original request.
+     */
+    public boolean getCapabilities(short transactionId) {
+        if (VDBG) Log.d(TAG, "getCapabilities");
+        if (isNanInit()) {
             int ret;
             synchronized (WifiNative.sLock) {
-                ret = enableAndConfigureNative(transactionId, WifiNative.class,
-                        WifiNative.sWlan0Index, configRequest);
+                ret = getCapabilitiesNative(transactionId, WifiNative.class,
+                        WifiNative.sWlan0Index);
             }
-            if (DBG) Log.d(TAG, "enableAndConfigureNative: ret=" + ret);
-            success = ret == WIFI_SUCCESS;
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG, "getCapabilities: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
         } else {
-            Log.w(TAG, "enableAndConfigure: NanInit fails");
-            success = false;
+            Log.w(TAG, "getCapabilities: cannot initialize NAN");
+            return false;
         }
-
-
-        // TODO: do something on !success - send failure message back
     }
 
-    private static native int disableNative(short transactionId, Object cls, int iface);
+    private static native int enableAndConfigureNative(short transactionId, Class<WifiNative> cls,
+            int iface, ConfigRequest configRequest);
 
-    public void disable(short transactionId) {
-        boolean success;
+    private static native int updateConfigurationNative(short transactionId, Class<WifiNative> cls,
+            int iface, ConfigRequest configRequest);
 
+    /**
+     * Enable and configure NAN.
+     *
+     * @param transactionId Transaction ID for the transaction - used in the
+     *            async callback to match with the original request.
+     * @param configRequest Requested NAN configuration.
+     * @param initialConfiguration Specifies whether initial configuration
+     *            (true) or an update (false) to the configuration.
+     */
+    public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest,
+            boolean initialConfiguration) {
+        if (VDBG) Log.d(TAG, "enableAndConfigure: configRequest=" + configRequest);
+        if (isNanInit()) {
+            int ret;
+            if (initialConfiguration) {
+                synchronized (WifiNative.sLock) {
+                    ret = enableAndConfigureNative(transactionId, WifiNative.class,
+                            WifiNative.sWlan0Index, configRequest);
+                }
+                if (ret != WIFI_SUCCESS) {
+                    Log.w(TAG, "enableAndConfigureNative: HAL API returned non-success -- " + ret);
+                }
+            } else {
+                synchronized (WifiNative.sLock) {
+                    ret = updateConfigurationNative(transactionId, WifiNative.class,
+                            WifiNative.sWlan0Index, configRequest);
+                }
+                if (ret != WIFI_SUCCESS) {
+                    Log.w(TAG, "updateConfigurationNative: HAL API returned non-success -- " + ret);
+                }
+            }
+            return ret == WIFI_SUCCESS;
+        } else {
+            Log.w(TAG, "enableAndConfigure: NanInit fails");
+            return false;
+        }
+    }
+
+    private static native int disableNative(short transactionId, Class<WifiNative> cls, int iface);
+
+    /**
+     * Disable NAN.
+     *
+     * @param transactionId transactionId Transaction ID for the transaction -
+     *            used in the async callback to match with the original request.
+     */
+    public boolean disable(short transactionId) {
         if (VDBG) Log.d(TAG, "disableNan");
-        if (isNanInit(true)) {
+        if (isNanInit()) {
             int ret;
             synchronized (WifiNative.sLock) {
                 ret = disableNative(transactionId, WifiNative.class, WifiNative.sWlan0Index);
             }
-            if (DBG) Log.d(TAG, "disableNative: ret=" + ret);
-            success = ret == WIFI_SUCCESS;
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG, "disableNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
         } else {
             Log.w(TAG, "disable: cannot initialize NAN");
-            success = false;
+            return false;
         }
-
-        // TODO: do something on !success - send failure message back
     }
 
-    private static native int publishNative(short transactionId, int publishId, Object cls,
-            int iface,
-            PublishData publishData, PublishSettings publishSettings);
+    private static native int publishNative(short transactionId, int publishId,
+            Class<WifiNative> cls, int iface, PublishConfig publishConfig);
 
-    public void publish(short transactionId, int publishId, PublishData publishData,
-            PublishSettings publishSettings) {
-        boolean success;
-
+    /**
+     * Start or modify a service publish session.
+     *
+     * @param transactionId transactionId Transaction ID for the transaction -
+     *            used in the async callback to match with the original request.
+     * @param publishId ID of the requested session - 0 to request a new publish
+     *            session.
+     * @param publishConfig Configuration of the discovery session.
+     */
+    public boolean publish(short transactionId, int publishId, PublishConfig publishConfig) {
         if (VDBG) {
-            Log.d(TAG, "publish: transactionId=" + transactionId + ",data='" + publishData
-                    + "', settings=" + publishSettings);
+            Log.d(TAG, "publish: transactionId=" + transactionId + ", config=" + publishConfig);
         }
 
-        if (isNanInit(true)) {
+        if (isNanInit()) {
             int ret;
             synchronized (WifiNative.sLock) {
                 ret = publishNative(transactionId, publishId, WifiNative.class,
-                        WifiNative.sWlan0Index, publishData, publishSettings);
+                        WifiNative.sWlan0Index, publishConfig);
             }
-            if (DBG) Log.d(TAG, "publishNative: ret=" + ret);
-            success = ret == WIFI_SUCCESS;
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG, "publishNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
         } else {
             Log.w(TAG, "publish: cannot initialize NAN");
-            success = false;
+            return false;
         }
-
-        // TODO: do something on !success - send failure message back
     }
 
-    private static native int subscribeNative(short transactionId, int subscribeId, Object cls,
-            int iface, SubscribeData subscribeData, SubscribeSettings subscribeSettings);
+    private static native int subscribeNative(short transactionId, int subscribeId,
+            Class<WifiNative> cls, int iface, SubscribeConfig subscribeConfig);
 
-    public void subscribe(short transactionId, int subscribeId, SubscribeData subscribeData,
-            SubscribeSettings subscribeSettings) {
-        boolean success;
-
+    /**
+     * Start or modify a service subscription session.
+     *
+     * @param transactionId transactionId Transaction ID for the transaction -
+     *            used in the async callback to match with the original request.
+     * @param subscribeId ID of the requested session - 0 to request a new
+     *            subscribe session.
+     * @param subscribeConfig Configuration of the discovery session.
+     */
+    public boolean subscribe(short transactionId, int subscribeId,
+            SubscribeConfig subscribeConfig) {
         if (VDBG) {
-            Log.d(TAG, "subscribe: transactionId=" + transactionId + ", data='" + subscribeData
-                    + "', settings=" + subscribeSettings);
+            Log.d(TAG, "subscribe: transactionId=" + transactionId + ", config=" + subscribeConfig);
         }
 
-        if (isNanInit(true)) {
+        if (isNanInit()) {
             int ret;
             synchronized (WifiNative.sLock) {
                 ret = subscribeNative(transactionId, subscribeId, WifiNative.class,
-                        WifiNative.sWlan0Index, subscribeData, subscribeSettings);
+                        WifiNative.sWlan0Index, subscribeConfig);
             }
-            if (DBG) Log.d(TAG, "subscribeNative: ret=" + ret);
-            success = ret == WIFI_SUCCESS;
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG, "subscribeNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
         } else {
             Log.w(TAG, "subscribe: cannot initialize NAN");
-            success = false;
+            return false;
         }
-
-        // TODO: do something on !success - send failure message back
     }
 
-    private static native int sendMessageNative(short transactionId, Object cls, int iface,
-            int pubSubId, int requestorInstanceId, byte[] dest, byte[] message, int messageLength);
+    private static native int sendMessageNative(short transactionId, Class<WifiNative> cls,
+            int iface, int pubSubId, int requestorInstanceId, byte[] dest, byte[] message,
+            int messageLength);
 
-    public void sendMessage(short transactionId, int pubSubId, int requestorInstanceId, byte[] dest,
-            byte[] message, int messageLength) {
-        boolean success;
-
+    /**
+     * Send a message through an existing discovery session.
+     *
+     * @param transactionId transactionId Transaction ID for the transaction -
+     *            used in the async callback to match with the original request.
+     * @param pubSubId ID of the existing publish/subscribe session.
+     * @param requestorInstanceId ID of the peer to communicate with - obtained
+     *            through a previous discovery (match) operation with that peer.
+     * @param dest MAC address of the peer to communicate with - obtained
+     *            together with requestorInstanceId.
+     * @param message Message.
+     * @param messageLength Message byte array length.
+     * @param messageId Arbitary integer from host (not sent to HAL - useful for
+     *                  testing/debugging at this level)
+     */
+    public boolean sendMessage(short transactionId, int pubSubId, int requestorInstanceId,
+            byte[] dest, byte[] message, int messageLength, int messageId) {
         if (VDBG) {
             Log.d(TAG,
                     "sendMessage: transactionId=" + transactionId + ", pubSubId=" + pubSubId
                             + ", requestorInstanceId=" + requestorInstanceId + ", dest="
                             + String.valueOf(HexEncoding.encode(dest)) + ", messageLength="
-                            + messageLength);
+                            + messageLength + ", messageId=" + messageId);
         }
 
-        if (isNanInit(true)) {
+        if (isNanInit()) {
             int ret;
             synchronized (WifiNative.sLock) {
                 ret = sendMessageNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
                         pubSubId, requestorInstanceId, dest, message, messageLength);
             }
-            if (DBG) Log.d(TAG, "sendMessageNative: ret=" + ret);
-            success = ret == WIFI_SUCCESS;
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG, "sendMessageNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
         } else {
             Log.w(TAG, "sendMessage: cannot initialize NAN");
-            success = false;
+            return false;
         }
-
-        // TODO: do something on !success - send failure message back
     }
 
-    private static native int stopPublishNative(short transactionId, Object cls, int iface,
-            int pubSubId);
+    private static native int stopPublishNative(short transactionId, Class<WifiNative> cls,
+            int iface, int pubSubId);
 
-    public void stopPublish(short transactionId, int pubSubId) {
-        boolean success;
-
+    /**
+     * Terminate a publish discovery session.
+     *
+     * @param transactionId transactionId Transaction ID for the transaction -
+     *            used in the async callback to match with the original request.
+     * @param pubSubId ID of the publish/subscribe session - obtained when
+     *            creating a session.
+     */
+    public boolean stopPublish(short transactionId, int pubSubId) {
         if (VDBG) {
             Log.d(TAG, "stopPublish: transactionId=" + transactionId + ", pubSubId=" + pubSubId);
         }
 
-        if (isNanInit(true)) {
+        if (isNanInit()) {
             int ret;
             synchronized (WifiNative.sLock) {
                 ret = stopPublishNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
                         pubSubId);
             }
-            if (DBG) Log.d(TAG, "stopPublishNative: ret=" + ret);
-            success = ret == WIFI_SUCCESS;
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG, "stopPublishNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
         } else {
             Log.w(TAG, "stopPublish: cannot initialize NAN");
-            success = false;
+            return false;
         }
-
-        // TODO: do something on !success - send failure message back
     }
 
-    private static native int stopSubscribeNative(short transactionId, Object cls, int iface,
-            int pubSubId);
+    private static native int stopSubscribeNative(short transactionId, Class<WifiNative> cls,
+            int iface, int pubSubId);
 
-    public void stopSubscribe(short transactionId, int pubSubId) {
-        boolean success;
-
+    /**
+     * Terminate a subscribe discovery session.
+     *
+     * @param transactionId transactionId Transaction ID for the transaction -
+     *            used in the async callback to match with the original request.
+     * @param pubSubId ID of the publish/subscribe session - obtained when
+     *            creating a session.
+     */
+    public boolean stopSubscribe(short transactionId, int pubSubId) {
         if (VDBG) {
             Log.d(TAG, "stopSubscribe: transactionId=" + transactionId + ", pubSubId=" + pubSubId);
         }
 
-        if (isNanInit(true)) {
+        if (isNanInit()) {
             int ret;
             synchronized (WifiNative.sLock) {
                 ret = stopSubscribeNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
                         pubSubId);
             }
-            if (DBG) Log.d(TAG, "stopSubscribeNative: ret=" + ret);
-            success = ret == WIFI_SUCCESS;
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG, "stopSubscribeNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
         } else {
             Log.w(TAG, "stopSubscribe: cannot initialize NAN");
-            success = false;
+            return false;
+        }
+    }
+
+    private static native int createNanNetworkInterfaceNative(short transactionId,
+                                                              Class<WifiNative> cls, int iface,
+                                                              String interfaceName);
+
+    /**
+     * Create a NAN network interface. This only creates the Linux interface - it doesn't actually
+     * create the data connection.
+     *
+     * @param transactionId Transaction ID for the transaction - used in the async callback to
+     *                      match with the original request.
+     * @param interfaceName The name of the interface, e.g. "nan0".
+     */
+    public boolean createNanNetworkInterface(short transactionId, String interfaceName) {
+        if (VDBG) {
+            Log.v(TAG, "createNanNetworkInterface: transactionId=" + transactionId + ", "
+                    + "interfaceName=" + interfaceName);
         }
 
-        // TODO: do something on !success - send failure message back
+        if (isNanInit()) {
+            int ret;
+            synchronized (WifiNative.sLock) {
+                ret = createNanNetworkInterfaceNative(transactionId, WifiNative.class, WifiNative
+                        .sWlan0Index, interfaceName);
+            }
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG,
+                        "createNanNetworkInterfaceNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
+        } else {
+            Log.w(TAG, "createNanNetworkInterface: cannot initialize NAN");
+            return false;
+        }
+    }
+
+    private static native int deleteNanNetworkInterfaceNative(short transactionId,
+                                                              Class<WifiNative> cls, int iface,
+                                                              String interfaceName);
+
+    /**
+     * Deletes a NAN network interface. The data connection can (should?) be torn down previously.
+     *
+     * @param transactionId Transaction ID for the transaction - used in the async callback to
+     *                      match with the original request.
+     * @param interfaceName The name of the interface, e.g. "nan0".
+     */
+    public boolean deleteNanNetworkInterface(short transactionId, String interfaceName) {
+        if (VDBG) {
+            Log.v(TAG, "deleteNanNetworkInterface: transactionId=" + transactionId + ", "
+                    + "interfaceName=" + interfaceName);
+        }
+
+        if (isNanInit()) {
+            int ret;
+            synchronized (WifiNative.sLock) {
+                ret = deleteNanNetworkInterfaceNative(transactionId, WifiNative.class, WifiNative
+                        .sWlan0Index, interfaceName);
+            }
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG,
+                        "deleteNanNetworkInterfaceNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
+        } else {
+            Log.w(TAG, "deleteNanNetworkInterface: cannot initialize NAN");
+            return false;
+        }
+    }
+
+    private static native int initiateDataPathNative(short transactionId, Class<WifiNative> cls,
+                                                     int iface, int peerId, int
+                                                             channelRequestType, int channel,
+                                                     byte[] peer, String interfaceName, byte[]
+                                                             message, int messageLength);
+
+    public static final int CHANNEL_REQUEST_TYPE_NONE = 0;
+    public static final int CHANNEL_REQUEST_TYPE_REQUESTED = 1;
+    public static final int CHANNEL_REQUEST_TYPE_REQUIRED = 2;
+
+    /**
+     * Initiates setting up a data-path between device and peer.
+     *
+     * @param transactionId      Transaction ID for the transaction - used in the async callback to
+     *                           match with the original request.
+     * @param peerId             ID of the peer ID to associate the data path with. A value of 0
+     *                           indicates that not associated with an existing session.
+     * @param channelRequestType Indicates whether the specified channel is available, if available
+     *                           requested or forced (resulting in failure if cannot be
+     *                           accommodated).
+     * @param channel            The channel on which to set up the data-path.
+     * @param peer               The MAC address of the peer to create a connection with.
+     * @param interfaceName      The interface on which to create the data connection.
+     * @param message An arbitrary byte array to forward to the peer as part of the data path
+     *                request.
+     * @param messageLength The size of the message.
+     */
+    public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
+                                    int channel, byte[] peer, String interfaceName, byte[]
+                                            message, int messageLength) {
+        if (VDBG) {
+            Log.v(TAG, "initiateDataPath: transactionId=" + transactionId + ", peerId=" + peerId
+                    + ", channelRequestType=" + channelRequestType + ", channel=" + channel
+                    + ", peer=" + String.valueOf(HexEncoding.encode(peer)) + ", interfaceName="
+                    + interfaceName + ", " + "messageLength=" + messageLength);
+        }
+
+        if (isNanInit()) {
+            int ret;
+            synchronized (WifiNative.sLock) {
+                ret = initiateDataPathNative(transactionId, WifiNative.class, WifiNative
+                        .sWlan0Index, peerId, channelRequestType, channel, peer, interfaceName,
+                        message, messageLength);
+            }
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG, "initiateDataPathNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
+        } else {
+            Log.w(TAG, "initiateDataPath: cannot initialize NAN");
+            return false;
+        }
+    }
+
+    private static native int respondToDataPathRequestNative(short transactionId,
+                                                             Class<WifiNative> cls, int iface,
+                                                             boolean accept, int ndpId, String
+                                                                     interfaceName, byte[]
+                                                                     message, int messageLength);
+
+    /**
+     * Responds to a data request from a peer.
+     *
+     * @param transactionId Transaction ID for the transaction - used in the async callback to
+     *                      match with the original request.
+     * @param accept Accept (true) or reject (false) the original call.
+     * @param ndpId The NDP (NAN data path) ID. Obtained from the request callback.
+     * @param interfaceName The interface on which the data path will be setup. Obtained from the
+     *                      request callback.
+     * @param message An arbitrary byte array to forward to the peer in the respond message.
+     * @param messageLength The length of the message array.
+     */
+    public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
+                                            String interfaceName, byte[] message, int
+                                                    messageLength) {
+        if (VDBG) {
+            Log.v(TAG, "respondToDataPathRequest: transactionId=" + transactionId + ", accept="
+                    + accept + ", int ndpId=" + ndpId + ", interfaceName=" + interfaceName + ", "
+                    + "messageLength=" + messageLength);
+        }
+
+        if (isNanInit()) {
+            int ret;
+            synchronized (WifiNative.sLock) {
+                ret = respondToDataPathRequestNative(transactionId, WifiNative.class, WifiNative
+                        .sWlan0Index, accept, ndpId, interfaceName, message, messageLength);
+            }
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG,
+                        "respondToDataPathRequestNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
+        } else {
+            Log.w(TAG, "respondToDataPathRequest: cannot initialize NAN");
+            return false;
+        }
+    }
+
+    private static native int endDataPathNative(short transactionId, Class<WifiNative> cls,
+            int iface, int ndpId);
+
+    /**
+     * Terminate an existing data-path (does not delete the interface).
+     *
+     * @param transactionId Transaction ID for the transaction - used in the async callback to
+     *                      match with the original request.
+     * @param ndpId The NDP (NAN data path) ID to be terminated.
+     */
+    public boolean endDataPath(short transactionId, int ndpId) {
+        if (VDBG) {
+            Log.v(TAG, "endDataPath: transactionId=" + transactionId + ", ndpId=" + ndpId);
+        }
+
+        if (isNanInit()) {
+            int ret;
+            synchronized (WifiNative.sLock) {
+                ret = endDataPathNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
+                        ndpId);
+            }
+            if (ret != WIFI_SUCCESS) {
+                Log.w(TAG, "endDataPathNative: HAL API returned non-success -- " + ret);
+            }
+            return ret == WIFI_SUCCESS;
+        } else {
+            Log.w(TAG, "endDataPath: cannot initialize NAN");
+            return false;
+        }
     }
 
     // EVENTS
@@ -327,9 +617,16 @@
     public static final int NAN_RESPONSE_TRANSMIT_FOLLOWUP = 4;
     public static final int NAN_RESPONSE_SUBSCRIBE = 5;
     public static final int NAN_RESPONSE_SUBSCRIBE_CANCEL = 6;
+    public static final int NAN_RESPONSE_CONFIG = 8;
     public static final int NAN_RESPONSE_GET_CAPABILITIES = 12;
+    public static final int NAN_RESPONSE_DP_INTERFACE_CREATE = 13;
+    public static final int NAN_RESPONSE_DP_INTERFACE_DELETE = 14;
+    public static final int NAN_RESPONSE_DP_INITIATOR_RESPONSE = 15;
+    public static final int NAN_RESPONSE_DP_RESPONDER_RESPONSE = 16;
+    public static final int NAN_RESPONSE_DP_END = 17;
 
     // direct copy from wifi_nan.h: need to keep in sync
+    /* NAN Protocol Response Codes */
     public static final int NAN_STATUS_SUCCESS = 0;
     public static final int NAN_STATUS_TIMEOUT = 1;
     public static final int NAN_STATUS_DE_FAILURE = 2;
@@ -350,8 +647,14 @@
     public static final int NAN_STATUS_INVALID_TLV_VALUE = 17;
     public static final int NAN_STATUS_INVALID_TX_PRIORITY = 18;
     public static final int NAN_STATUS_INVALID_CONNECTION_MAP = 19;
+    public static final int NAN_STATUS_INVALID_TCA_ID = 20;
+    public static final int NAN_STATUS_INVALID_STATS_ID = 21;
+    public static final int NAN_STATUS_NAN_NOT_ALLOWED = 22;
+    public static final int NAN_STATUS_NO_OTA_ACK = 23;
+    public static final int NAN_STATUS_TX_FAIL = 24;
+    public static final int NAN_STATUS_ALREADY_ENABLED = 25;
 
-    // NAN Configuration Response codes
+    /* NAN Configuration Response codes */
     public static final int NAN_STATUS_INVALID_RSSI_CLOSE_VALUE = 4096;
     public static final int NAN_STATUS_INVALID_RSSI_MIDDLE_VALUE = 4097;
     public static final int NAN_STATUS_INVALID_HOP_COUNT_LIMIT = 4098;
@@ -374,8 +677,12 @@
     public static final int NAN_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE = 4115;
     public static final int NAN_STATUS_MISSING_FUTHER_AVAILABILITY_MAP = 4116;
     public static final int NAN_STATUS_INVALID_BAND_CONFIG_FLAGS = 4117;
+    public static final int NAN_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE = 4118;
+    public static final int NAN_STATUS_INVALID_ONGOING_SCAN_PERIOD = 4119;
+    public static final int NAN_STATUS_INVALID_DW_INTERVAL_VALUE = 4120;
+    public static final int NAN_STATUS_INVALID_DB_INTERVAL_VALUE = 4121;
 
-    // publish/subscribe termination reasons
+    /* publish/subscribe termination reasons */
     public static final int NAN_TERMINATED_REASON_INVALID = 8192;
     public static final int NAN_TERMINATED_REASON_TIMEOUT = 8193;
     public static final int NAN_TERMINATED_REASON_USER_REQUEST = 8194;
@@ -387,31 +694,34 @@
     public static final int NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED = 8200;
     public static final int NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY = 8201;
 
-    private static int translateHalStatusToPublicStatus(int halStatus) {
+    /* 9000-9500 NDP Status type */
+    public static final int NAN_STATUS_NDP_UNSUPPORTED_CONCURRENCY = 9000;
+    public static final int NAN_STATUS_NDP_NAN_DATA_IFACE_CREATE_FAILED = 9001;
+    public static final int NAN_STATUS_NDP_NAN_DATA_IFACE_DELETE_FAILED = 9002;
+    public static final int NAN_STATUS_NDP_DATA_INITIATOR_REQUEST_FAILED = 9003;
+    public static final int NAN_STATUS_NDP_DATA_RESPONDER_REQUEST_FAILED = 9004;
+    public static final int NAN_STATUS_NDP_INVALID_SERVICE_INSTANCE_ID = 9005;
+    public static final int NAN_STATUS_NDP_INVALID_NDP_INSTANCE_ID = 9006;
+    public static final int NAN_STATUS_NDP_INVALID_RESPONSE_CODE = 9007;
+    public static final int NAN_STATUS_NDP_INVALID_APP_INFO_LEN = 9008;
+
+    /* OTA failures and timeouts during negotiation */
+    public static final int NAN_STATUS_NDP_MGMT_FRAME_REQUEST_FAILED = 9009;
+    public static final int NAN_STATUS_NDP_MGMT_FRAME_RESPONSE_FAILED = 9010;
+    public static final int NAN_STATUS_NDP_MGMT_FRAME_CONFIRM_FAILED = 9011;
+    public static final int NAN_STATUS_NDP_END_FAILED = 9012;
+    public static final int NAN_STATUS_NDP_MGMT_FRAME_END_REQUEST_FAILED = 9013;
+
+    /* 9500 onwards vendor specific error codes */
+    public static final int NAN_STATUS_NDP_VENDOR_SPECIFIC_ERROR = 9500;
+
+    private static int translateHalStatusToNanEventCallbackReason(int halStatus) {
         switch (halStatus) {
-            case NAN_STATUS_NO_SPACE_AVAILABLE:
-                return WifiNanSessionListener.FAIL_REASON_NO_RESOURCES;
-
-            case NAN_STATUS_TIMEOUT:
-            case NAN_STATUS_DE_FAILURE:
-            case NAN_STATUS_DISABLE_IN_PROGRESS:
-                return WifiNanSessionListener.FAIL_REASON_OTHER;
-
-            case NAN_STATUS_INVALID_MSG_VERSION:
-            case NAN_STATUS_INVALID_MSG_LEN:
-            case NAN_STATUS_INVALID_MSG_ID:
-            case NAN_STATUS_INVALID_HANDLE:
-            case NAN_STATUS_INVALID_PUBLISH_TYPE:
-            case NAN_STATUS_INVALID_TX_TYPE:
-            case NAN_STATUS_INVALID_MATCH_ALGORITHM:
-            case NAN_STATUS_INVALID_TLV_LEN:
-            case NAN_STATUS_INVALID_TLV_TYPE:
-            case NAN_STATUS_MISSING_TLV_TYPE:
-            case NAN_STATUS_INVALID_TOTAL_TLVS_LEN:
-            case NAN_STATUS_INVALID_MATCH_HANDLE:
-            case NAN_STATUS_INVALID_TLV_VALUE:
-            case NAN_STATUS_INVALID_TX_PRIORITY:
-            case NAN_STATUS_INVALID_CONNECTION_MAP:
+            case NAN_STATUS_SUCCESS:
+                /*
+                 * TODO: b/27914592 all of these codes will be cleaned-up/reduced.
+                 */
+                return WifiNanEventCallback.REASON_OTHER;
             case NAN_STATUS_INVALID_RSSI_CLOSE_VALUE:
             case NAN_STATUS_INVALID_RSSI_MIDDLE_VALUE:
             case NAN_STATUS_INVALID_HOP_COUNT_LIMIT:
@@ -434,13 +744,22 @@
             case NAN_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE:
             case NAN_STATUS_MISSING_FUTHER_AVAILABILITY_MAP:
             case NAN_STATUS_INVALID_BAND_CONFIG_FLAGS:
-                return WifiNanSessionListener.FAIL_REASON_INVALID_ARGS;
+            case NAN_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE:
+            case NAN_STATUS_INVALID_ONGOING_SCAN_PERIOD:
+            case NAN_STATUS_INVALID_DW_INTERVAL_VALUE:
+            case NAN_STATUS_INVALID_DB_INTERVAL_VALUE:
+                return WifiNanEventCallback.REASON_INVALID_ARGS;
+        }
 
-                // publish/subscribe termination reasons
+        return WifiNanEventCallback.REASON_OTHER;
+    }
+
+    private static int translateHalStatusToNanSessionCallbackTerminate(int halStatus) {
+        switch (halStatus) {
             case NAN_TERMINATED_REASON_TIMEOUT:
             case NAN_TERMINATED_REASON_USER_REQUEST:
             case NAN_TERMINATED_REASON_COUNT_REACHED:
-                return WifiNanSessionListener.TERMINATE_REASON_DONE;
+                return WifiNanSessionCallback.TERMINATE_REASON_DONE;
 
             case NAN_TERMINATED_REASON_INVALID:
             case NAN_TERMINATED_REASON_FAILURE:
@@ -449,10 +768,46 @@
             case NAN_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED:
             case NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED:
             case NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY:
-                return WifiNanSessionListener.TERMINATE_REASON_FAIL;
+                return WifiNanSessionCallback.TERMINATE_REASON_FAIL;
         }
 
-        return WifiNanSessionListener.FAIL_REASON_OTHER;
+        return WifiNanSessionCallback.TERMINATE_REASON_FAIL;
+    }
+
+    private static int translateHalStatusToNanSessionCallbackReason(int halStatus) {
+        switch (halStatus) {
+            case NAN_STATUS_TIMEOUT:
+            case NAN_STATUS_DE_FAILURE:
+            case NAN_STATUS_INVALID_MSG_VERSION:
+            case NAN_STATUS_INVALID_MSG_LEN:
+            case NAN_STATUS_INVALID_MSG_ID:
+            case NAN_STATUS_INVALID_HANDLE:
+                return WifiNanSessionCallback.REASON_OTHER;
+            case NAN_STATUS_NO_SPACE_AVAILABLE:
+                return WifiNanSessionCallback.REASON_NO_RESOURCES;
+            case NAN_STATUS_INVALID_PUBLISH_TYPE:
+            case NAN_STATUS_INVALID_TX_TYPE:
+            case NAN_STATUS_INVALID_MATCH_ALGORITHM:
+                return WifiNanSessionCallback.REASON_INVALID_ARGS;
+            case NAN_STATUS_DISABLE_IN_PROGRESS:
+            case NAN_STATUS_INVALID_TLV_LEN:
+            case NAN_STATUS_INVALID_TLV_TYPE:
+            case NAN_STATUS_MISSING_TLV_TYPE:
+            case NAN_STATUS_INVALID_TOTAL_TLVS_LEN:
+            case NAN_STATUS_INVALID_MATCH_HANDLE:
+            case NAN_STATUS_INVALID_TLV_VALUE:
+            case NAN_STATUS_INVALID_TX_PRIORITY:
+            case NAN_STATUS_INVALID_CONNECTION_MAP:
+            case NAN_STATUS_INVALID_TCA_ID:
+            case NAN_STATUS_INVALID_STATS_ID:
+            case NAN_STATUS_NAN_NOT_ALLOWED:
+                return WifiNanSessionCallback.REASON_OTHER;
+            case NAN_STATUS_NO_OTA_ACK:
+            case NAN_STATUS_TX_FAIL:
+                return WifiNanSessionCallback.REASON_TX_FAIL;
+        }
+
+        return WifiNanSessionCallback.REASON_OTHER;
     }
 
     // callback from native
@@ -463,14 +818,17 @@
                     "onNanNotifyResponse: transactionId=" + transactionId + ", responseType="
                     + responseType + ", status=" + status + ", value=" + value);
         }
+        WifiNanStateManager stateMgr = WifiNanStateManager.getInstance();
 
         switch (responseType) {
             case NAN_RESPONSE_ENABLED:
+                /* fall through */
+            case NAN_RESPONSE_CONFIG:
                 if (status == NAN_STATUS_SUCCESS) {
-                    WifiNanStateManager.getInstance().onConfigCompleted(transactionId);
+                    stateMgr.onConfigSuccessResponse(transactionId);
                 } else {
-                    WifiNanStateManager.getInstance().onConfigFailed(transactionId,
-                            translateHalStatusToPublicStatus(status));
+                    stateMgr.onConfigFailedResponse(transactionId,
+                            translateHalStatusToNanEventCallbackReason(status));
                 }
                 break;
             case NAN_RESPONSE_PUBLISH_CANCEL:
@@ -481,10 +839,10 @@
                 break;
             case NAN_RESPONSE_TRANSMIT_FOLLOWUP:
                 if (status == NAN_STATUS_SUCCESS) {
-                    WifiNanStateManager.getInstance().onMessageSendSuccess(transactionId);
+                    stateMgr.onMessageSendQueuedSuccessResponse(transactionId);
                 } else {
-                    WifiNanStateManager.getInstance().onMessageSendFail(transactionId,
-                            translateHalStatusToPublicStatus(status));
+                    stateMgr.onMessageSendQueuedFailResponse(transactionId,
+                            translateHalStatusToNanSessionCallbackReason(status));
                 }
                 break;
             case NAN_RESPONSE_SUBSCRIBE_CANCEL:
@@ -493,9 +851,43 @@
                             + status + ", value=" + value);
                 }
                 break;
+            case NAN_RESPONSE_DP_INTERFACE_CREATE:
+                if (status != NAN_STATUS_SUCCESS) {
+                    Log.e(TAG,
+                            "onNanNotifyResponse: NAN_RESPONSE_DP_INTERFACE_CREATE error - status="
+                                    + status + ", value=" + value);
+                }
+                stateMgr.onCreateDataPathInterfaceResponse(transactionId,
+                        status == NAN_STATUS_SUCCESS, status);
+                break;
+            case NAN_RESPONSE_DP_INTERFACE_DELETE:
+                if (status != NAN_STATUS_SUCCESS) {
+                    Log.e(TAG,
+                            "onNanNotifyResponse: NAN_RESPONSE_DP_INTERFACE_DELETE error - status="
+                                    + status + ", value=" + value);
+                }
+                stateMgr.onDeleteDataPathInterfaceResponse(transactionId,
+                        status == NAN_STATUS_SUCCESS, status);
+                break;
+            case NAN_RESPONSE_DP_RESPONDER_RESPONSE:
+                if (status != NAN_STATUS_SUCCESS) {
+                    Log.e(TAG,
+                            "onNanNotifyResponse: NAN_RESPONSE_DP_RESPONDER_RESPONSE error - "
+                                    + "status=" + status + ", value=" + value);
+                }
+                stateMgr.onRespondToDataPathSetupRequestResponse(transactionId,
+                        status == NAN_STATUS_SUCCESS, status);
+                break;
+            case NAN_RESPONSE_DP_END:
+                if (status != NAN_STATUS_SUCCESS) {
+                    Log.e(TAG, "onNanNotifyResponse: NAN_RESPONSE_DP_END error - status=" + status
+                            + ", value=" + value);
+                }
+                stateMgr.onEndDataPathResponse(transactionId, status == NAN_STATUS_SUCCESS,
+                        status);
+                break;
             default:
-                WifiNanStateManager.getInstance().onUnknownTransaction(responseType, transactionId,
-                        translateHalStatusToPublicStatus(status));
+                Log.e(TAG, "onNanNotifyResponse: unclassified responseType=" + responseType);
                 break;
         }
     }
@@ -512,23 +904,25 @@
         switch (responseType) {
             case NAN_RESPONSE_PUBLISH:
                 if (status == NAN_STATUS_SUCCESS) {
-                    WifiNanStateManager.getInstance().onPublishSuccess(transactionId, pubSubId);
+                    WifiNanStateManager.getInstance().onSessionConfigSuccessResponse(transactionId,
+                            true, pubSubId);
                 } else {
-                    WifiNanStateManager.getInstance().onPublishFail(transactionId,
-                            translateHalStatusToPublicStatus(status));
+                    WifiNanStateManager.getInstance().onSessionConfigFailResponse(transactionId,
+                            true, translateHalStatusToNanSessionCallbackReason(status));
                 }
                 break;
             case NAN_RESPONSE_SUBSCRIBE:
                 if (status == NAN_STATUS_SUCCESS) {
-                    WifiNanStateManager.getInstance().onSubscribeSuccess(transactionId, pubSubId);
+                    WifiNanStateManager.getInstance().onSessionConfigSuccessResponse(transactionId,
+                            false, pubSubId);
                 } else {
-                    WifiNanStateManager.getInstance().onSubscribeFail(transactionId,
-                            translateHalStatusToPublicStatus(status));
+                    WifiNanStateManager.getInstance().onSessionConfigFailResponse(transactionId,
+                            false, translateHalStatusToNanSessionCallbackReason(status));
                 }
                 break;
             default:
-                WifiNanStateManager.getInstance().onUnknownTransaction(responseType, transactionId,
-                        translateHalStatusToPublicStatus(status));
+                Log.wtf(TAG, "onNanNotifyResponsePublishSubscribe: unclassified responseType="
+                        + responseType);
                 break;
         }
     }
@@ -536,18 +930,34 @@
     private static void onNanNotifyResponseCapabilities(short transactionId, int status, int value,
             Capabilities capabilities) {
         if (VDBG) {
-            Log.v(TAG, "onNanNotifyResponsePublishSubscribe: transactionId=" + transactionId
+            Log.v(TAG, "onNanNotifyResponseCapabilities: transactionId=" + transactionId
                     + ", status=" + status + ", value=" + value + ", capabilities=" + capabilities);
         }
 
         if (status == NAN_STATUS_SUCCESS) {
-            WifiNanStateManager.getInstance().onCapabilitiesUpdate(transactionId, capabilities);
+            WifiNanStateManager.getInstance().onCapabilitiesUpdateResponse(transactionId,
+                    capabilities);
         } else {
             Log.e(TAG,
                     "onNanNotifyResponseCapabilities: error status=" + status + ", value=" + value);
         }
     }
 
+    private static void onNanNotifyResponseDataPathInitiate(short transactionId, int status,
+            int value, int ndpId) {
+        if (VDBG) {
+            Log.v(TAG,
+                    "onNanNotifyResponseDataPathInitiate: transactionId=" + transactionId
+                            + ", status=" + status + ", value=" + value + ", ndpId=" + ndpId);
+        }
+        if (status == NAN_STATUS_SUCCESS) {
+            WifiNanStateManager.getInstance().onInitiateDataPathResponseSuccess(transactionId,
+                    ndpId);
+        } else {
+            WifiNanStateManager.getInstance().onInitiateDataPathResponseFail(transactionId, status);
+        }
+    }
+
     public static final int NAN_EVENT_ID_DISC_MAC_ADDR = 0;
     public static final int NAN_EVENT_ID_STARTED_CLUSTER = 1;
     public static final int NAN_EVENT_ID_JOINED_CLUSTER = 2;
@@ -560,13 +970,13 @@
         }
 
         if (eventType == NAN_EVENT_ID_DISC_MAC_ADDR) {
-            WifiNanStateManager.getInstance().onInterfaceAddressChange(mac);
+            WifiNanStateManager.getInstance().onInterfaceAddressChangeNotification(mac);
         } else if (eventType == NAN_EVENT_ID_STARTED_CLUSTER) {
-            WifiNanStateManager.getInstance()
-                    .onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_STARTED, mac);
+            WifiNanStateManager.getInstance().onClusterChangeNotification(
+                    WifiNanClientState.CLUSTER_CHANGE_EVENT_STARTED, mac);
         } else if (eventType == NAN_EVENT_ID_JOINED_CLUSTER) {
-            WifiNanStateManager.getInstance()
-                    .onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_JOINED, mac);
+            WifiNanStateManager.getInstance().onClusterChangeNotification(
+                    WifiNanClientState.CLUSTER_CHANGE_EVENT_JOINED, mac);
         } else {
             Log.w(TAG, "onDiscoveryEngineEvent: invalid eventType=" + eventType);
         }
@@ -579,11 +989,12 @@
         if (VDBG) {
             Log.v(TAG, "onMatchEvent: pubSubId=" + pubSubId + ", requestorInstanceId="
                     + requestorInstanceId + ", mac=" + String.valueOf(HexEncoding.encode(mac))
-                    + ", serviceSpecificInfo=" + serviceSpecificInfo + ", matchFilterLength="
-                    + matchFilterLength + ", matchFilter=" + matchFilter);
+                    + ", serviceSpecificInfo=" + Arrays.toString(serviceSpecificInfo)
+                    + ", matchFilterLength=" + matchFilterLength + ", matchFilter="
+                    + Arrays.toString(matchFilter));
         }
 
-        WifiNanStateManager.getInstance().onMatch(pubSubId, requestorInstanceId, mac,
+        WifiNanStateManager.getInstance().onMatchNotification(pubSubId, requestorInstanceId, mac,
                 serviceSpecificInfo, serviceSpecificInfoLength, matchFilter, matchFilterLength);
     }
 
@@ -591,8 +1002,8 @@
     private static void onPublishTerminated(int publishId, int status) {
         if (VDBG) Log.v(TAG, "onPublishTerminated: publishId=" + publishId + ", status=" + status);
 
-        WifiNanStateManager.getInstance().onPublishTerminated(publishId,
-                translateHalStatusToPublicStatus(status));
+        WifiNanStateManager.getInstance().onSessionTerminatedNotification(publishId,
+                translateHalStatusToNanSessionCallbackTerminate(status), true);
     }
 
     // callback from native
@@ -601,8 +1012,8 @@
             Log.v(TAG, "onSubscribeTerminated: subscribeId=" + subscribeId + ", status=" + status);
         }
 
-        WifiNanStateManager.getInstance().onSubscribeTerminated(subscribeId,
-                translateHalStatusToPublicStatus(status));
+        WifiNanStateManager.getInstance().onSessionTerminatedNotification(subscribeId,
+                translateHalStatusToNanSessionCallbackTerminate(status), false);
     }
 
     // callback from native
@@ -614,14 +1025,62 @@
                     + ", messageLength=" + messageLength);
         }
 
-        WifiNanStateManager.getInstance().onMessageReceived(pubSubId, requestorInstanceId, mac,
-                message, messageLength);
+        WifiNanStateManager.getInstance().onMessageReceivedNotification(pubSubId,
+                requestorInstanceId, mac, message, messageLength);
     }
 
     // callback from native
     private static void onDisabledEvent(int status) {
         if (VDBG) Log.v(TAG, "onDisabledEvent: status=" + status);
 
-        WifiNanStateManager.getInstance().onNanDown(translateHalStatusToPublicStatus(status));
+        WifiNanStateManager.getInstance()
+                .onNanDownNotification(translateHalStatusToNanEventCallbackReason(status));
+    }
+
+    // callback from native
+    private static void onTransmitFollowupEvent(short transactionId, int reason) {
+        if (VDBG) {
+            Log.v(TAG, "onTransmitFollowupEvent: transactionId=" + transactionId + ", reason="
+                    + reason);
+        }
+
+        if (reason == NAN_STATUS_SUCCESS) {
+            WifiNanStateManager.getInstance().onMessageSendSuccessNotification(transactionId);
+        } else {
+            WifiNanStateManager.getInstance().onMessageSendFailNotification(transactionId,
+                    translateHalStatusToNanSessionCallbackReason(reason));
+        }
+    }
+
+    private static void onDataPathRequest(int pubSubId, byte[] mac, int ndpId, byte[] message, int
+            messageLength) {
+        if (VDBG) {
+            Log.v(TAG, "onDataPathRequest: pubSubId=" + pubSubId + ", mac=" + String.valueOf(
+                    HexEncoding.encode(mac)) + ", ndpId=" + ndpId + ", messageLength="
+                    + messageLength);
+        }
+
+        WifiNanStateManager.getInstance()
+                .onDataPathRequestNotification(pubSubId, mac, ndpId, message, messageLength);
+    }
+
+    private static void onDataPathConfirm(int ndpId, byte[] mac, boolean accept, int reason, byte[]
+            message, int messageLength) {
+        if (VDBG) {
+            Log.v(TAG, "onDataPathConfirm: ndpId=" + ndpId + ", mac=" + String.valueOf(HexEncoding
+                    .encode(mac)) + ", accept=" + accept + ", reason=" + reason + ", "
+                    + "messageLength=" + messageLength);
+        }
+
+        WifiNanStateManager.getInstance()
+                .onDataPathConfirmNotification(ndpId, mac, accept, reason, message, messageLength);
+    }
+
+    private static void onDataPathEnd(int ndpId) {
+        if (VDBG) {
+            Log.v(TAG, "onDataPathEndNotification: ndpId=" + ndpId);
+        }
+
+        WifiNanStateManager.getInstance().onDataPathEndNotification(ndpId);
     }
 }
diff --git a/service/java/com/android/server/wifi/nan/WifiNanRttStateManager.java b/service/java/com/android/server/wifi/nan/WifiNanRttStateManager.java
new file mode 100644
index 0000000..4e15486
--- /dev/null
+++ b/service/java/com/android/server/wifi/nan/WifiNanRttStateManager.java
@@ -0,0 +1,203 @@
+/*
+ * 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 com.android.server.wifi.nan;
+
+import android.content.Context;
+import android.net.wifi.IRttManager;
+import android.net.wifi.RttManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.AsyncChannel;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+
+/**
+ * Manages interactions between the NAN and the RTT service. Duplicates some of the functionality
+ * of the RttManager.
+ */
+public class WifiNanRttStateManager {
+    private static final String TAG = "WifiNanRttStateManager";
+
+    private static final boolean DBG = false;
+    private static final boolean VDBG = false; // STOPSHIP if true
+
+    private final SparseArray<WifiNanClientState> mPendingOperations = new SparseArray<>();
+    private AsyncChannel mAsyncChannel;
+
+    /**
+     * Initializes the connection to the RTT service.
+     */
+    public void start(Context context, Looper looper) {
+        if (VDBG) Log.v(TAG, "start()");
+
+        IBinder b = ServiceManager.getService(Context.WIFI_RTT_SERVICE);
+        IRttManager service = IRttManager.Stub.asInterface(b);
+        if (service == null) {
+            Log.e(TAG, "start(): not able to get WIFI_RTT_SERVICE");
+            return;
+        }
+
+        startWithRttService(context, looper, service);
+    }
+
+    /**
+     * Initializes the connection to the RTT service.
+     */
+    @VisibleForTesting
+    public void startWithRttService(Context context, Looper looper, IRttManager service) {
+        Messenger messenger;
+        try {
+            messenger = service.getMessenger();
+        } catch (RemoteException e) {
+            Log.e(TAG, "start(): not able to getMessenger() of WIFI_RTT_SERVICE");
+            return;
+        }
+
+        mAsyncChannel = new AsyncChannel();
+        mAsyncChannel.connect(context, new NanRttHandler(looper), messenger);
+    }
+
+    private WifiNanClientState getAndRemovePendingOperationClient(int rangingId) {
+        WifiNanClientState client = mPendingOperations.get(rangingId);
+        mPendingOperations.delete(rangingId);
+        return client;
+    }
+
+    /**
+     * Start a ranging operation for the client + peer MAC.
+     */
+    public void startRanging(int rangingId, WifiNanClientState client,
+                             RttManager.RttParams[] params) {
+        if (VDBG) {
+            Log.v(TAG, "startRanging: rangingId=" + rangingId + ", parms="
+                    + Arrays.toString(params));
+        }
+
+        if (mAsyncChannel == null) {
+            Log.d(TAG, "startRanging(): AsyncChannel to RTT service not configured - failing");
+            client.onRangingFailure(rangingId, RttManager.REASON_NOT_AVAILABLE,
+                    "NAN service not able to configure connection to RTT service");
+            return;
+        }
+
+        mPendingOperations.put(rangingId, client);
+        RttManager.ParcelableRttParams pparams = new RttManager.ParcelableRttParams(params);
+        mAsyncChannel.sendMessage(RttManager.CMD_OP_START_RANGING, 0, rangingId, pparams);
+    }
+
+    private class NanRttHandler extends Handler {
+        NanRttHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (VDBG) Log.v(TAG, "handleMessage(): " + msg.what);
+
+            // channel configuration messages
+            switch (msg.what) {
+                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+                        mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+                    } else {
+                        Log.e(TAG, "Failed to set up channel connection to RTT service");
+                        mAsyncChannel = null;
+                    }
+                    return;
+                case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
+                    /* NOP */
+                    return;
+                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+                    Log.e(TAG, "Channel connection to RTT service lost");
+                    mAsyncChannel = null;
+                    return;
+            }
+
+            // RTT-specific messages
+            WifiNanClientState client = getAndRemovePendingOperationClient(msg.arg2);
+            if (client == null) {
+                Log.e(TAG, "handleMessage(): RTT message (" + msg.what
+                        + ") -- cannot find registered pending operation client for ID "
+                        + msg.arg2);
+                return;
+            }
+
+            switch (msg.what) {
+                case RttManager.CMD_OP_SUCCEEDED: {
+                    int rangingId = msg.arg2;
+                    RttManager.ParcelableRttResults results = (RttManager.ParcelableRttResults)
+                            msg.obj;
+                    if (VDBG) {
+                        Log.v(TAG, "CMD_OP_SUCCEEDED: rangingId=" + rangingId + ", results="
+                                + results);
+                    }
+                    for (int i = 0; i < results.mResults.length; ++i) {
+                        /*
+                         * TODO: store peer ID rather than null in the return result.
+                         */
+                        results.mResults[i].bssid = null;
+                    }
+                    client.onRangingSuccess(rangingId, results);
+                    break;
+                }
+                case RttManager.CMD_OP_FAILED: {
+                    int rangingId = msg.arg2;
+                    int reason = msg.arg1;
+                    String description = ((Bundle) msg.obj).getString(RttManager.DESCRIPTION_KEY);
+                    if (VDBG) {
+                        Log.v(TAG, "CMD_OP_FAILED: rangingId=" + rangingId + ", reason=" + reason
+                                + ", description=" + description);
+                    }
+                    client.onRangingFailure(rangingId, reason, description);
+                    break;
+                }
+                case RttManager.CMD_OP_ABORTED: {
+                    int rangingId = msg.arg2;
+                    if (VDBG) {
+                        Log.v(TAG, "CMD_OP_ABORTED: rangingId=" + rangingId);
+                    }
+                    client.onRangingAborted(rangingId);
+                    break;
+                }
+                default:
+                    Log.e(TAG, "handleMessage(): ignoring message " + msg.what);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Dump the internal state of the class.
+     */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("WifiNanRttStateManager:");
+        pw.println("  mPendingOperations: [" + mPendingOperations + "]");
+    }
+}
diff --git a/service/java/com/android/server/wifi/nan/WifiNanService.java b/service/java/com/android/server/wifi/nan/WifiNanService.java
index b5920f2..6589067 100644
--- a/service/java/com/android/server/wifi/nan/WifiNanService.java
+++ b/service/java/com/android/server/wifi/nan/WifiNanService.java
@@ -21,6 +21,10 @@
 
 import com.android.server.SystemService;
 
+/**
+ * Service implementing Wi-Fi NAN functionality. Delegates actual interface
+ * implementation to WifiNanServiceImpl.
+ */
 public final class WifiNanService extends SystemService {
     private static final String TAG = "WifiNanService";
     final WifiNanServiceImpl mImpl;
@@ -40,6 +44,8 @@
     public void onBootPhase(int phase) {
         if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
             mImpl.start();
+        } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
+            mImpl.startLate();
         }
     }
 }
diff --git a/service/java/com/android/server/wifi/nan/WifiNanServiceImpl.java b/service/java/com/android/server/wifi/nan/WifiNanServiceImpl.java
index deefe94..140c6fd 100644
--- a/service/java/com/android/server/wifi/nan/WifiNanServiceImpl.java
+++ b/service/java/com/android/server/wifi/nan/WifiNanServiceImpl.java
@@ -18,24 +18,33 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.net.wifi.RttManager;
 import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.IWifiNanEventListener;
+import android.net.wifi.nan.IWifiNanEventCallback;
 import android.net.wifi.nan.IWifiNanManager;
-import android.net.wifi.nan.IWifiNanSessionListener;
-import android.net.wifi.nan.PublishData;
-import android.net.wifi.nan.PublishSettings;
-import android.net.wifi.nan.SubscribeData;
-import android.net.wifi.nan.SubscribeSettings;
+import android.net.wifi.nan.IWifiNanSessionCallback;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
+import android.net.wifi.nan.WifiNanEventCallback;
+import android.net.wifi.nan.WifiNanSession;
 import android.os.Binder;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Arrays;
 
+/**
+ * Implementation of the IWifiNanManager AIDL interface. Performs validity
+ * (permission and clientID-UID mapping) checks and delegates execution to the
+ * WifiNanStateManager singleton handler. Limited state to feedback which has to
+ * be provided instantly: client and session IDs.
+ */
 public class WifiNanServiceImpl extends IWifiNanManager.Stub {
     private static final String TAG = "WifiNanService";
     private static final boolean DBG = false;
@@ -43,180 +52,336 @@
 
     private Context mContext;
     private WifiNanStateManager mStateManager;
-    private final boolean mNanSupported;
 
     private final Object mLock = new Object();
-    private final SparseArray<IBinder.DeathRecipient> mDeathRecipientsByUid = new SparseArray<>();
-    private int mNextNetworkRequestToken = 1;
-    private int mNextSessionId = 1;
+    private final SparseArray<IBinder.DeathRecipient> mDeathRecipientsByClientId =
+            new SparseArray<>();
+    private int mNextClientId = 1;
+    private int mNextRangingId = 1;
+    private final SparseIntArray mUidByClientId = new SparseIntArray();
 
     public WifiNanServiceImpl(Context context) {
         mContext = context.getApplicationContext();
-
-        mNanSupported = mContext.getPackageManager()
-                .hasSystemFeature(PackageManager.FEATURE_WIFI_NAN);
-        if (DBG) Log.w(TAG, "WifiNanServiceImpl: mNanSupported=" + mNanSupported);
-
         mStateManager = WifiNanStateManager.getInstance();
     }
 
+    /**
+     * Proxy for the final native call of the parent class. Enables mocking of
+     * the function.
+     */
+    public int getMockableCallingUid() {
+        return getCallingUid();
+    }
+
+    /**
+     * Start the service: allocate a new thread (for now), start the handlers of
+     * the components of the service.
+     */
     public void start() {
         Log.i(TAG, "Starting Wi-Fi NAN service");
 
-        // TODO: share worker thread with other Wi-Fi handlers
+        // TODO: share worker thread with other Wi-Fi handlers (b/27924886)
         HandlerThread wifiNanThread = new HandlerThread("wifiNanService");
         wifiNanThread.start();
 
-        mStateManager.start(wifiNanThread.getLooper());
+        mStateManager.start(mContext, wifiNanThread.getLooper());
+    }
+
+    /**
+     * Start/initialize portions of the service which require the boot stage to be complete.
+     */
+    public void startLate() {
+        Log.i(TAG, "Late initialization of Wi-Fi NAN service");
+
+        mStateManager.startLate();
     }
 
     @Override
-    public void connect(final IBinder binder, IWifiNanEventListener listener, int events) {
+    public void enableUsage() {
         enforceAccessPermission();
         enforceChangePermission();
+        /*
+         * TODO: enforce additional permissions b/27696149.
+         */
 
-        final int uid = getCallingUid();
+        mStateManager.enableUsage();
+    }
 
-        if (VDBG) Log.v(TAG, "connect: uid=" + uid);
+    @Override
+    public void disableUsage() {
+        enforceAccessPermission();
+        enforceChangePermission();
+        /*
+         * TODO: enforce additional permissions b/27696149.
+         */
 
+        mStateManager.disableUsage();
+
+        /*
+         * Potential leak (b/27796984) since we keep app information here (uid,
+         * binder-link-to-death), while clearing all state information. However:
+         * (1) can't clear all information since don't have binder, (2)
+         * information will clear once app dies, (3) allows us to do security
+         * checks in the future.
+         */
+    }
+
+    @Override
+    public boolean isUsageEnabled() {
+        enforceAccessPermission();
+
+        return mStateManager.isUsageEnabled();
+    }
+
+    @Override
+    public int connect(final IBinder binder, IWifiNanEventCallback callback,
+            ConfigRequest configRequest) {
+        enforceAccessPermission();
+        enforceChangePermission();
+        if (callback == null) {
+            throw new IllegalArgumentException("Callback must not be null");
+        }
+        if (binder == null) {
+            throw new IllegalArgumentException("Binder must not be null");
+        }
+
+        if (configRequest != null) {
+            /*
+             * TODO: enforce additional permissions if configuration is
+             * non-standard (i.e. the system API). (b/27696149)
+             */
+        } else {
+            configRequest = new ConfigRequest.Builder().build();
+        }
+        configRequest.validate();
+
+        final int uid = getMockableCallingUid();
+
+        final int clientId;
+        synchronized (mLock) {
+            clientId = mNextClientId++;
+        }
+
+        if (VDBG) {
+            Log.v(TAG, "connect: uid=" + uid + ", clientId=" + clientId + ", configRequest"
+                    + configRequest);
+        }
 
         IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
             @Override
             public void binderDied() {
-                if (DBG) Log.d(TAG, "binderDied: uid=" + uid);
+                if (DBG) Log.d(TAG, "binderDied: clientId=" + clientId);
                 binder.unlinkToDeath(this, 0);
 
                 synchronized (mLock) {
-                    mDeathRecipientsByUid.delete(uid);
+                    mDeathRecipientsByClientId.delete(clientId);
+                    mUidByClientId.delete(clientId);
                 }
 
-                mStateManager.disconnect(uid);
+                mStateManager.disconnect(clientId);
             }
         };
-        synchronized (mLock) {
-            mDeathRecipientsByUid.put(uid, dr);
-        }
+
         try {
             binder.linkToDeath(dr, 0);
         } catch (RemoteException e) {
-            Log.w(TAG, "Error on linkToDeath - " + e);
+            Log.e(TAG, "Error on linkToDeath - " + e);
+            try {
+                callback.onConnectFail(WifiNanEventCallback.REASON_OTHER);
+            } catch (RemoteException e1) {
+                Log.e(TAG, "Error on onConnectFail()");
+            }
+            return 0;
         }
 
-        mStateManager.connect(uid, listener, events);
+        synchronized (mLock) {
+            mDeathRecipientsByClientId.put(clientId, dr);
+            mUidByClientId.put(clientId, uid);
+        }
+
+        mStateManager.connect(clientId, uid, callback, configRequest);
+
+        return clientId;
     }
 
     @Override
-    public void disconnect(IBinder binder) {
+    public void disconnect(int clientId, IBinder binder) {
         enforceAccessPermission();
         enforceChangePermission();
 
-        int uid = getCallingUid();
+        int uid = getMockableCallingUid();
+        enforceClientValidity(uid, clientId);
+        if (VDBG) Log.v(TAG, "disconnect: uid=" + uid + ", clientId=" + clientId);
 
-        if (VDBG) Log.v(TAG, "disconnect: uid=" + uid);
+        if (binder == null) {
+            throw new IllegalArgumentException("Binder must not be null");
+        }
 
         synchronized (mLock) {
-            IBinder.DeathRecipient dr = mDeathRecipientsByUid.get(uid);
+            IBinder.DeathRecipient dr = mDeathRecipientsByClientId.get(clientId);
             if (dr != null) {
                 binder.unlinkToDeath(dr, 0);
-                mDeathRecipientsByUid.delete(uid);
+                mDeathRecipientsByClientId.delete(clientId);
             }
+            mUidByClientId.delete(clientId);
         }
 
-        mStateManager.disconnect(uid);
+        mStateManager.disconnect(clientId);
     }
 
     @Override
-    public void requestConfig(ConfigRequest configRequest) {
+    public void terminateSession(int clientId, int sessionId) {
         enforceAccessPermission();
         enforceChangePermission();
 
+        int uid = getMockableCallingUid();
+        enforceClientValidity(uid, clientId);
+        if (VDBG) {
+            Log.v(TAG, "terminateSession: sessionId=" + sessionId + ", uid=" + uid + ", clientId="
+                    + clientId);
+        }
+
+        mStateManager.terminateSession(clientId, sessionId);
+    }
+
+    @Override
+    public void publish(int clientId, PublishConfig publishConfig,
+            IWifiNanSessionCallback callback) {
+        enforceAccessPermission();
+        enforceChangePermission();
+
+        if (callback == null) {
+            throw new IllegalArgumentException("Callback must not be null");
+        }
+        if (publishConfig == null) {
+            throw new IllegalArgumentException("PublishConfig must not be null");
+        }
+        publishConfig.validate();
+
+        int uid = getMockableCallingUid();
+        enforceClientValidity(uid, clientId);
+        if (VDBG) {
+            Log.v(TAG, "publish: uid=" + uid + ", clientId=" + clientId + ", publishConfig="
+                    + publishConfig + ", callback=" + callback);
+        }
+
+        mStateManager.publish(clientId, publishConfig, callback);
+    }
+
+    @Override
+    public void updatePublish(int clientId, int sessionId, PublishConfig publishConfig) {
+        enforceAccessPermission();
+        enforceChangePermission();
+
+        if (publishConfig == null) {
+            throw new IllegalArgumentException("PublishConfig must not be null");
+        }
+        publishConfig.validate();
+
+        int uid = getMockableCallingUid();
+        enforceClientValidity(uid, clientId);
+        if (VDBG) {
+            Log.v(TAG, "updatePublish: uid=" + uid + ", clientId=" + clientId + ", sessionId="
+                    + sessionId + ", config=" + publishConfig);
+        }
+
+        mStateManager.updatePublish(clientId, sessionId, publishConfig);
+    }
+
+    @Override
+    public void subscribe(int clientId, SubscribeConfig subscribeConfig,
+            IWifiNanSessionCallback callback) {
+        enforceAccessPermission();
+        enforceChangePermission();
+
+        if (callback == null) {
+            throw new IllegalArgumentException("Callback must not be null");
+        }
+        if (subscribeConfig == null) {
+            throw new IllegalArgumentException("SubscribeConfig must not be null");
+        }
+        subscribeConfig.validate();
+
+        int uid = getMockableCallingUid();
+        enforceClientValidity(uid, clientId);
+        if (VDBG) {
+            Log.v(TAG, "subscribe: uid=" + uid + ", clientId=" + clientId + ", config="
+                    + subscribeConfig + ", callback=" + callback);
+        }
+
+        mStateManager.subscribe(clientId, subscribeConfig, callback);
+    }
+
+    @Override
+    public void updateSubscribe(int clientId, int sessionId, SubscribeConfig subscribeConfig) {
+        enforceAccessPermission();
+        enforceChangePermission();
+
+        if (subscribeConfig == null) {
+            throw new IllegalArgumentException("SubscribeConfig must not be null");
+        }
+        subscribeConfig.validate();
+
+        int uid = getMockableCallingUid();
+        enforceClientValidity(uid, clientId);
+        if (VDBG) {
+            Log.v(TAG, "updateSubscribe: uid=" + uid + ", clientId=" + clientId + ", sessionId="
+                    + sessionId + ", config=" + subscribeConfig);
+        }
+
+        mStateManager.updateSubscribe(clientId, sessionId, subscribeConfig);
+    }
+
+    @Override
+    public void sendMessage(int clientId, int sessionId, int peerId, byte[] message,
+            int messageLength, int messageId, int retryCount) {
+        enforceAccessPermission();
+        enforceChangePermission();
+
+        if (messageLength != 0 && (message == null || message.length < messageLength)) {
+            throw new IllegalArgumentException(
+                    "Non-matching combination of message and messageLength");
+        }
+        if (retryCount < 0 || retryCount > WifiNanSession.MAX_SEND_RETRY_COUNT) {
+            throw new IllegalArgumentException("Invalid 'retryCount' must be non-negative "
+                    + "and <= WifiNanSession.MAX_SEND_RETRY_COUNT");
+        }
+
+        int uid = getMockableCallingUid();
+        enforceClientValidity(uid, clientId);
         if (VDBG) {
             Log.v(TAG,
-                    "requestConfig: uid=" + getCallingUid() + ", configRequest=" + configRequest);
+                    "sendMessage: sessionId=" + sessionId + ", uid=" + uid + ", clientId="
+                            + clientId + ", peerId=" + peerId + ", messageLength=" + messageLength
+                            + ", messageId=" + messageId + ", retryCount=" + retryCount);
         }
 
-        mStateManager.requestConfig(getCallingUid(), configRequest);
+        mStateManager.sendMessage(clientId, sessionId, peerId, message, messageLength, messageId,
+                retryCount);
     }
 
     @Override
-    public void stopSession(int sessionId) {
+    public int startRanging(int clientId, int sessionId, RttManager.ParcelableRttParams params) {
         enforceAccessPermission();
-        enforceChangePermission();
+        enforceLocationPermission();
 
-        if (VDBG) Log.v(TAG, "stopSession: sessionId=" + sessionId + ", uid=" + getCallingUid());
+        int uid = getMockableCallingUid();
+        enforceClientValidity(uid, clientId);
+        if (VDBG) {
+            Log.v(TAG, "startRanging: clientId=" + clientId + ", sessionId=" + sessionId + ", "
+                    + ", parms=" + Arrays.toString(params.mParams));
+        }
 
-        mStateManager.stopSession(getCallingUid(), sessionId);
-    }
+        if (params.mParams.length == 0) {
+            throw new IllegalArgumentException("Empty ranging parameters");
+        }
 
-    @Override
-    public void destroySession(int sessionId) {
-        enforceAccessPermission();
-        enforceChangePermission();
-
-        if (VDBG) Log.v(TAG, "destroySession: sessionId=" + sessionId + ", uid=" + getCallingUid());
-
-        mStateManager.destroySession(getCallingUid(), sessionId);
-    }
-
-    @Override
-    public int createSession(IWifiNanSessionListener listener, int events) {
-        enforceAccessPermission();
-        enforceChangePermission();
-
-        if (VDBG) Log.v(TAG, "createSession: uid=" + getCallingUid());
-
-        int sessionId;
+        int rangingId;
         synchronized (mLock) {
-            sessionId = mNextSessionId++;
+            rangingId = mNextRangingId++;
         }
-
-        mStateManager.createSession(getCallingUid(), sessionId, listener, events);
-
-        return sessionId;
-    }
-
-    @Override
-    public void publish(int sessionId, PublishData publishData, PublishSettings publishSettings) {
-        enforceAccessPermission();
-        enforceChangePermission();
-
-        if (VDBG) {
-            Log.v(TAG, "publish: uid=" + getCallingUid() + ", sessionId=" + sessionId + ", data='"
-                    + publishData + "', settings=" + publishSettings);
-        }
-
-        mStateManager.publish(getCallingUid(), sessionId, publishData, publishSettings);
-    }
-
-    @Override
-    public void subscribe(int sessionId, SubscribeData subscribeData,
-            SubscribeSettings subscribeSettings) {
-        enforceAccessPermission();
-        enforceChangePermission();
-
-        if (VDBG) {
-            Log.v(TAG, "subscribe: uid=" + getCallingUid() + ", sessionId=" + sessionId + ", data='"
-                    + subscribeData + "', settings=" + subscribeSettings);
-        }
-
-        mStateManager.subscribe(getCallingUid(), sessionId, subscribeData, subscribeSettings);
-    }
-
-    @Override
-    public void sendMessage(int sessionId, int peerId, byte[] message, int messageLength,
-            int messageId) {
-        enforceAccessPermission();
-        enforceChangePermission();
-
-        if (VDBG) {
-            Log.v(TAG,
-                    "sendMessage: sessionId=" + sessionId + ", uid=" + getCallingUid() + ", peerId="
-                            + peerId + ", messageLength=" + messageLength + ", messageId="
-                            + messageId);
-        }
-
-        mStateManager.sendMessage(getCallingUid(), sessionId, peerId, message, messageLength,
-                messageId);
+        mStateManager.startRanging(clientId, sessionId, params.mParams, rangingId);
+        return rangingId;
     }
 
     @Override
@@ -228,13 +393,24 @@
             return;
         }
         pw.println("Wi-Fi NAN Service");
-        pw.println("  mNanSupported: " + mNanSupported);
-        pw.println("  mNextNetworkRequestToken: " + mNextNetworkRequestToken);
-        pw.println("  mNextSessionId: " + mNextSessionId);
-        pw.println("  mDeathRecipientsByUid: " + mDeathRecipientsByUid);
+        synchronized (mLock) {
+            pw.println("  mNextClientId: " + mNextClientId);
+            pw.println("  mDeathRecipientsByClientId: " + mDeathRecipientsByClientId);
+            pw.println("  mUidByClientId: " + mUidByClientId);
+        }
         mStateManager.dump(fd, pw, args);
     }
 
+    private void enforceClientValidity(int uid, int clientId) {
+        synchronized (mLock) {
+            int uidIndex = mUidByClientId.indexOfKey(clientId);
+            if (uidIndex < 0 || mUidByClientId.valueAt(uidIndex) != uid) {
+                throw new SecurityException("Attempting to use invalid uid+clientId mapping: uid="
+                        + uid + ", clientId=" + clientId);
+            }
+        }
+    }
+
     private void enforceAccessPermission() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE, TAG);
     }
@@ -242,4 +418,9 @@
     private void enforceChangePermission() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE, TAG);
     }
+
+    private void enforceLocationPermission() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,
+                TAG);
+    }
 }
diff --git a/service/java/com/android/server/wifi/nan/WifiNanSessionState.java b/service/java/com/android/server/wifi/nan/WifiNanSessionState.java
index ea64403..56c7d3a 100644
--- a/service/java/com/android/server/wifi/nan/WifiNanSessionState.java
+++ b/service/java/com/android/server/wifi/nan/WifiNanSessionState.java
@@ -16,12 +16,10 @@
 
 package com.android.server.wifi.nan;
 
-import android.net.wifi.nan.IWifiNanSessionListener;
-import android.net.wifi.nan.PublishData;
-import android.net.wifi.nan.PublishSettings;
-import android.net.wifi.nan.SubscribeData;
-import android.net.wifi.nan.SubscribeSettings;
-import android.net.wifi.nan.WifiNanSessionListener;
+import android.net.wifi.nan.IWifiNanSessionCallback;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
+import android.net.wifi.nan.WifiNanSessionCallback;
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.SparseArray;
@@ -31,183 +29,172 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
+/**
+ * Manages the state of a single NAN discovery session (publish or subscribe).
+ * Primary state consists of a callback through which session callbacks are
+ * executed as well as state related to currently active discovery sessions:
+ * publish/subscribe ID, and MAC address caching (hiding) from clients.
+ */
 public class WifiNanSessionState {
     private static final String TAG = "WifiNanSessionState";
     private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
+    private int mSessionId;
+    private int mPubSubId;
+    private IWifiNanSessionCallback mCallback;
+    private boolean mIsPublishSession;
+
     private final SparseArray<String> mMacByRequestorInstanceId = new SparseArray<>();
 
-    private int mSessionId;
-    private IWifiNanSessionListener mListener;
-    private int mEvents;
-
-    private boolean mPubSubIdValid = false;
-    private int mPubSubId;
-
-    private static final int SESSION_TYPE_NOT_INIT = 0;
-    private static final int SESSION_TYPE_PUBLISH = 1;
-    private static final int SESSION_TYPE_SUBSCRIBE = 2;
-    private int mSessionType = SESSION_TYPE_NOT_INIT;
-
-    public WifiNanSessionState(int sessionId, IWifiNanSessionListener listener, int events) {
+    public WifiNanSessionState(int sessionId, int pubSubId, IWifiNanSessionCallback callback,
+                               boolean isPublishSession) {
         mSessionId = sessionId;
-        mListener = listener;
-        mEvents = events;
-    }
-
-    public void destroy() {
-        stop(WifiNanStateManager.getInstance().createNextTransactionId());
-        if (mPubSubIdValid) {
-            mMacByRequestorInstanceId.clear();
-            mListener = null;
-            mPubSubIdValid = false;
-        }
+        mPubSubId = pubSubId;
+        mCallback = callback;
+        mIsPublishSession = isPublishSession;
     }
 
     public int getSessionId() {
         return mSessionId;
     }
 
+    public int getPubSubId() {
+        return mPubSubId;
+    }
+
+    public IWifiNanSessionCallback getCallback() {
+        return mCallback;
+    }
+
+    /**
+     * Return the MAC address (String) of the specified peer ID - or a null if no such address is
+     * registered.
+     */
+    public String getMac(int peerId, String sep) {
+        String mac = mMacByRequestorInstanceId.get(peerId);
+        if (mac != null && sep != null && !sep.isEmpty()) {
+            mac = new StringBuilder(mac).insert(10, sep).insert(8, sep).insert(6, sep)
+                    .insert(4, sep).insert(2, sep).toString();
+        }
+        return mac;
+    }
+
+    /**
+     * Destroy the current discovery session - stops publishing or subscribing
+     * if currently active.
+     */
+    public void terminate() {
+        mCallback = null;
+
+        if (mIsPublishSession) {
+            WifiNanNative.getInstance().stopPublish((short) 0, mPubSubId);
+        } else {
+            WifiNanNative.getInstance().stopSubscribe((short) 0, mPubSubId);
+        }
+    }
+
+    /**
+     * Indicates whether the publish/subscribe ID (a HAL ID) corresponds to this
+     * session.
+     *
+     * @param pubSubId The publish/subscribe HAL ID to be tested.
+     * @return true if corresponds to this session, false otherwise.
+     */
     public boolean isPubSubIdSession(int pubSubId) {
-        return mPubSubIdValid && mPubSubId == pubSubId;
+        return mPubSubId == pubSubId;
     }
 
-    public void publish(short transactionId, PublishData data, PublishSettings settings) {
-        if (mSessionType == SESSION_TYPE_SUBSCRIBE) {
-            throw new IllegalStateException("A SUBSCRIBE session is being used for publish");
+    /**
+     * Modify a publish discovery session.
+     *
+     * @param transactionId Transaction ID for the transaction - used in the
+     *            async callback to match with the original request.
+     * @param config Configuration of the publish session.
+     */
+    public boolean updatePublish(short transactionId, PublishConfig config) {
+        if (!mIsPublishSession) {
+            Log.e(TAG, "A SUBSCRIBE session is being used to publish");
+            try {
+                mCallback.onSessionConfigFail(WifiNanSessionCallback.REASON_OTHER);
+            } catch (RemoteException e) {
+                Log.e(TAG, "updatePublish: RemoteException=" + e);
+            }
+            return false;
         }
-        mSessionType = SESSION_TYPE_PUBLISH;
 
-        WifiNanNative.getInstance().publish(transactionId, mPubSubIdValid ? mPubSubId : 0, data,
-                settings);
+        return WifiNanNative.getInstance().publish(transactionId, mPubSubId, config);
     }
 
-    public void subscribe(short transactionId, SubscribeData data, SubscribeSettings settings) {
-        if (mSessionType == SESSION_TYPE_PUBLISH) {
-            throw new IllegalStateException("A PUBLISH session is being used for publish");
+    /**
+     * Modify a subscribe discovery session.
+     *
+     * @param transactionId Transaction ID for the transaction - used in the
+     *            async callback to match with the original request.
+     * @param config Configuration of the subscribe session.
+     */
+    public boolean updateSubscribe(short transactionId, SubscribeConfig config) {
+        if (mIsPublishSession) {
+            Log.e(TAG, "A PUBLISH session is being used to subscribe");
+            try {
+                mCallback.onSessionConfigFail(WifiNanSessionCallback.REASON_OTHER);
+            } catch (RemoteException e) {
+                Log.e(TAG, "updateSubscribe: RemoteException=" + e);
+            }
+            return false;
         }
-        mSessionType = SESSION_TYPE_SUBSCRIBE;
 
-        WifiNanNative.getInstance().subscribe(transactionId, mPubSubIdValid ? mPubSubId : 0, data,
-                settings);
+        return WifiNanNative.getInstance().subscribe(transactionId, mPubSubId, config);
     }
 
-    public void sendMessage(short transactionId, int peerId, byte[] message, int messageLength,
+    /**
+     * Send a message to a peer which is part of a discovery session.
+     *
+     * @param transactionId Transaction ID for the transaction - used in the
+     *            async callback to match with the original request.
+     * @param peerId ID of the peer. Obtained through previous communication (a
+     *            match indication).
+     * @param message Message byte array to send to the peer.
+     * @param messageLength Length of the message byte array.
+     * @param messageId A message ID provided by caller to be used in any
+     *            callbacks related to the message (success/failure).
+     */
+    public boolean sendMessage(short transactionId, int peerId, byte[] message, int messageLength,
             int messageId) {
-        if (!mPubSubIdValid) {
-            Log.e(TAG, "sendMessage: attempting to send a message on a non-live session "
-                    + "(no successful publish or subscribe");
-            onMessageSendFail(messageId, WifiNanSessionListener.FAIL_REASON_NO_MATCH_SESSION);
-            return;
-        }
-
         String peerMacStr = mMacByRequestorInstanceId.get(peerId);
         if (peerMacStr == null) {
             Log.e(TAG, "sendMessage: attempting to send a message to an address which didn't "
                     + "match/contact us");
-            onMessageSendFail(messageId, WifiNanSessionListener.FAIL_REASON_NO_MATCH_SESSION);
-            return;
+            try {
+                mCallback.onMessageSendFail(messageId,
+                        WifiNanSessionCallback.REASON_NO_MATCH_SESSION);
+            } catch (RemoteException e) {
+                Log.e(TAG, "sendMessage: RemoteException=" + e);
+            }
+            return false;
         }
         byte[] peerMac = HexEncoding.decode(peerMacStr.toCharArray(), false);
 
-        WifiNanNative.getInstance().sendMessage(transactionId, mPubSubId, peerId, peerMac, message,
-                messageLength);
+        return WifiNanNative.getInstance().sendMessage(transactionId, mPubSubId, peerId, peerMac,
+                message, messageLength, messageId);
     }
 
-    public void stop(short transactionId) {
-        if (!mPubSubIdValid || mSessionType == SESSION_TYPE_NOT_INIT) {
-            Log.e(TAG, "sendMessage: attempting to stop pub/sub on a non-live session (no "
-                    + "successful publish or subscribe");
-            return;
-        }
-
-        if (mSessionType == SESSION_TYPE_PUBLISH) {
-            WifiNanNative.getInstance().stopPublish(transactionId, mPubSubId);
-        } else if (mSessionType == SESSION_TYPE_SUBSCRIBE) {
-            WifiNanNative.getInstance().stopSubscribe(transactionId, mPubSubId);
-        }
-    }
-
-    public void onPublishSuccess(int publishId) {
-        mPubSubId = publishId;
-        mPubSubIdValid = true;
-    }
-
-    public void onPublishFail(int status) {
-        mPubSubIdValid = false;
-        try {
-            if (mListener != null && (mEvents & WifiNanSessionListener.LISTEN_PUBLISH_FAIL) != 0) {
-                mListener.onPublishFail(status);
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "onPublishFail: RemoteException (FYI): " + e);
-        }
-    }
-
-    public void onPublishTerminated(int status) {
-        mPubSubIdValid = false;
-        try {
-            if (mListener != null
-                    && (mEvents & WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED) != 0) {
-                mListener.onPublishTerminated(status);
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "onPublishTerminated: RemoteException (FYI): " + e);
-        }
-    }
-
-    public void onSubscribeSuccess(int subscribeId) {
-        mPubSubId = subscribeId;
-        mPubSubIdValid = true;
-    }
-
-    public void onSubscribeFail(int status) {
-        mPubSubIdValid = false;
-        try {
-            if (mListener != null
-                    && (mEvents & WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL) != 0) {
-                mListener.onSubscribeFail(status);
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "onSubscribeFail: RemoteException (FYI): " + e);
-        }
-    }
-
-    public void onSubscribeTerminated(int status) {
-        mPubSubIdValid = false;
-        try {
-            if (mListener != null
-                    && (mEvents & WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED) != 0) {
-                mListener.onSubscribeTerminated(status);
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "onSubscribeTerminated: RemoteException (FYI): " + e);
-        }
-    }
-
-    public void onMessageSendSuccess(int messageId) {
-        try {
-            if (mListener != null
-                    && (mEvents & WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS) != 0) {
-                mListener.onMessageSendSuccess(messageId);
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "onMessageSendSuccess: RemoteException (FYI): " + e);
-        }
-    }
-
-    public void onMessageSendFail(int messageId, int status) {
-        try {
-            if (mListener != null
-                    && (mEvents & WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL) != 0) {
-                mListener.onMessageSendFail(messageId, status);
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "onMessageSendFail: RemoteException (FYI): " + e);
-        }
-    }
-
+    /**
+     * Callback from HAL when a discovery occurs - i.e. when a match to an
+     * active subscription request or to a solicited publish request occurs.
+     * Propagates to client if registered.
+     *
+     * @param requestorInstanceId The ID used to identify the peer in this
+     *            matched session.
+     * @param peerMac The MAC address of the peer. Never propagated to client
+     *            due to privacy concerns.
+     * @param serviceSpecificInfo Information from the discovery advertisement
+     *            (usually not used in the match decisions).
+     * @param serviceSpecificInfoLength Length of the above information field.
+     * @param matchFilter The filter from the discovery advertisement (which was
+     *            used in the match decision).
+     * @param matchFilterLength Length of the above filter field.
+     */
     public void onMatch(int requestorInstanceId, byte[] peerMac, byte[] serviceSpecificInfo,
             int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) {
         String prevMac = mMacByRequestorInstanceId.get(requestorInstanceId);
@@ -216,15 +203,24 @@
         if (DBG) Log.d(TAG, "onMatch: previous peer MAC replaced - " + prevMac);
 
         try {
-            if (mListener != null && (mEvents & WifiNanSessionListener.LISTEN_MATCH) != 0) {
-                mListener.onMatch(requestorInstanceId, serviceSpecificInfo,
-                        serviceSpecificInfoLength, matchFilter, matchFilterLength);
-            }
+            mCallback.onMatch(requestorInstanceId, serviceSpecificInfo, serviceSpecificInfoLength,
+                    matchFilter, matchFilterLength);
         } catch (RemoteException e) {
             Log.w(TAG, "onMatch: RemoteException (FYI): " + e);
         }
     }
 
+    /**
+     * Callback from HAL when a message is received from a peer in a discovery
+     * session. Propagated to client if registered.
+     *
+     * @param requestorInstanceId An ID used to identify the peer.
+     * @param peerMac The MAC address of the peer sending the message. This
+     *            information is never propagated to the client due to privacy
+     *            concerns.
+     * @param message The received message.
+     * @param messageLength The length of the received message.
+     */
     public void onMessageReceived(int requestorInstanceId, byte[] peerMac, byte[] message,
             int messageLength) {
         String prevMac = mMacByRequestorInstanceId.get(requestorInstanceId);
@@ -235,21 +231,20 @@
         }
 
         try {
-            if (mListener != null
-                    && (mEvents & WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED) != 0) {
-                mListener.onMessageReceived(requestorInstanceId, message, messageLength);
-            }
+            mCallback.onMessageReceived(requestorInstanceId, message, messageLength);
         } catch (RemoteException e) {
             Log.w(TAG, "onMessageReceived: RemoteException (FYI): " + e);
         }
     }
 
+    /**
+     * Dump the internal state of the class.
+     */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("NanSessionState:");
         pw.println("  mSessionId: " + mSessionId);
-        pw.println("  mSessionType: " + mSessionType);
-        pw.println("  mEvents: " + mEvents);
-        pw.println("  mPubSubId: " + (mPubSubIdValid ? Integer.toString(mPubSubId) : "not valid"));
+        pw.println("  mIsPublishSession: " + mIsPublishSession);
+        pw.println("  mPubSubId: " + mPubSubId);
         pw.println("  mMacByRequestorInstanceId: [" + mMacByRequestorInstanceId + "]");
     }
 }
diff --git a/service/java/com/android/server/wifi/nan/WifiNanStateManager.java b/service/java/com/android/server/wifi/nan/WifiNanStateManager.java
index f7bfa55..86ff2dc 100644
--- a/service/java/com/android/server/wifi/nan/WifiNanStateManager.java
+++ b/service/java/com/android/server/wifi/nan/WifiNanStateManager.java
@@ -16,71 +16,140 @@
 
 package com.android.server.wifi.nan;
 
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.RttManager;
 import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.IWifiNanEventListener;
-import android.net.wifi.nan.IWifiNanSessionListener;
-import android.net.wifi.nan.PublishData;
-import android.net.wifi.nan.PublishSettings;
-import android.net.wifi.nan.SubscribeData;
-import android.net.wifi.nan.SubscribeSettings;
+import android.net.wifi.nan.IWifiNanEventCallback;
+import android.net.wifi.nan.IWifiNanSessionCallback;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
+import android.net.wifi.nan.WifiNanEventCallback;
+import android.net.wifi.nan.WifiNanManager;
+import android.net.wifi.nan.WifiNanSessionCallback;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
 import android.util.Log;
+import android.util.Pair;
 import android.util.SparseArray;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.MessageUtils;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+import com.android.internal.util.WakeupMessage;
+
 import libcore.util.HexEncoding;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
 
+/**
+ * Manages the state of the Wi-Fi NAN system service.
+ */
 public class WifiNanStateManager {
     private static final String TAG = "WifiNanStateManager";
     private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
+    @VisibleForTesting
+    public static final String HAL_COMMAND_TIMEOUT_TAG = TAG + " HAL Command Timeout";
+
+    @VisibleForTesting
+    public static final String HAL_SEND_MESSAGE_TIMEOUT_TAG = TAG + " HAL Send Message Timeout";
+
+    @VisibleForTesting
+    public static final String HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG =
+            TAG + " HAL Data Path Confirm Timeout";
+
     private static WifiNanStateManager sNanStateManagerSingleton;
 
-    private static final int MESSAGE_CONNECT = 0;
-    private static final int MESSAGE_DISCONNECT = 1;
-    private static final int MESSAGE_REQUEST_CONFIG = 4;
-    private static final int MESSAGE_CREATE_SESSION = 5;
-    private static final int MESSAGE_DESTROY_SESSION = 6;
-    private static final int MESSAGE_PUBLISH = 7;
-    private static final int MESSAGE_SUBSCRIBE = 8;
-    private static final int MESSAGE_SEND_MESSAGE = 9;
-    private static final int MESSAGE_STOP_SESSION = 10;
-    private static final int MESSAGE_ON_CONFIG_COMPLETED = 11;
-    private static final int MESSAGE_ON_CONFIG_FAILED = 12;
-    private static final int MESSAGE_ON_NAN_DOWN = 13;
-    private static final int MESSAGE_ON_INTERFACE_CHANGE = 14;
-    private static final int MESSAGE_ON_CLUSTER_CHANGE = 15;
-    private static final int MESSAGE_ON_PUBLISH_SUCCESS = 16;
-    private static final int MESSAGE_ON_PUBLISH_FAIL = 17;
-    private static final int MESSAGE_ON_PUBLISH_TERMINATED = 18;
-    private static final int MESSAGE_ON_SUBSCRIBE_SUCCESS = 19;
-    private static final int MESSAGE_ON_SUBSCRIBE_FAIL = 20;
-    private static final int MESSAGE_ON_SUBSCRIBE_TERMINATED = 21;
-    private static final int MESSAGE_ON_MESSAGE_SEND_SUCCESS = 22;
-    private static final int MESSAGE_ON_MESSAGE_SEND_FAIL = 23;
-    private static final int MESSAGE_ON_UNKNOWN_TRANSACTION = 24;
-    private static final int MESSAGE_ON_MATCH = 25;
-    private static final int MESSAGE_ON_MESSAGE_RECEIVED = 26;
-    private static final int MESSAGE_ON_CAPABILITIES_UPDATED = 27;
+    /*
+     * State machine message types. There are sub-types for the messages (except for TIMEOUTs).
+     * Format:
+     * - Message.arg1: contains message sub-type
+     * - Message.arg2: contains transaction ID for RESPONSE & RESPONSE_TIMEOUT
+     */
+    private static final int MESSAGE_TYPE_COMMAND = 1;
+    private static final int MESSAGE_TYPE_RESPONSE = 2;
+    private static final int MESSAGE_TYPE_NOTIFICATION = 3;
+    private static final int MESSAGE_TYPE_RESPONSE_TIMEOUT = 4;
+    private static final int MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT = 5;
+    private static final int MESSAGE_TYPE_DATA_PATH_TIMEOUT = 6;
 
+    /*
+     * Message sub-types:
+     */
+    private static final int COMMAND_TYPE_CONNECT = 100;
+    private static final int COMMAND_TYPE_DISCONNECT = 101;
+    private static final int COMMAND_TYPE_TERMINATE_SESSION = 102;
+    private static final int COMMAND_TYPE_PUBLISH = 103;
+    private static final int COMMAND_TYPE_UPDATE_PUBLISH = 104;
+    private static final int COMMAND_TYPE_SUBSCRIBE = 105;
+    private static final int COMMAND_TYPE_UPDATE_SUBSCRIBE = 106;
+    private static final int COMMAND_TYPE_ENQUEUE_SEND_MESSAGE = 107;
+    private static final int COMMAND_TYPE_ENABLE_USAGE = 108;
+    private static final int COMMAND_TYPE_DISABLE_USAGE = 109;
+    private static final int COMMAND_TYPE_START_RANGING = 110;
+    private static final int COMMAND_TYPE_GET_CAPABILITIES = 111;
+    private static final int COMMAND_TYPE_CREATE_ALL_DATA_PATH_INTERFACES = 112;
+    private static final int COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES = 113;
+    private static final int COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE = 114;
+    private static final int COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE = 115;
+    private static final int COMMAND_TYPE_INITIATE_DATA_PATH_SETUP = 116;
+    private static final int COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST = 117;
+    private static final int COMMAND_TYPE_END_DATA_PATH = 118;
+    private static final int COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE = 119;
+
+    private static final int RESPONSE_TYPE_ON_CONFIG_SUCCESS = 200;
+    private static final int RESPONSE_TYPE_ON_CONFIG_FAIL = 201;
+    private static final int RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS = 202;
+    private static final int RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL = 203;
+    private static final int RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS = 204;
+    private static final int RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL = 205;
+    private static final int RESPONSE_TYPE_ON_CAPABILITIES_UPDATED = 206;
+    private static final int RESPONSE_TYPE_ON_CREATE_INTERFACE = 207;
+    private static final int RESPONSE_TYPE_ON_DELETE_INTERFACE = 208;
+    private static final int RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS = 209;
+    private static final int RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL = 210;
+    private static final int RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST = 211;
+    private static final int RESPONSE_TYPE_ON_END_DATA_PATH = 212;
+
+    private static final int NOTIFICATION_TYPE_INTERFACE_CHANGE = 301;
+    private static final int NOTIFICATION_TYPE_CLUSTER_CHANGE = 302;
+    private static final int NOTIFICATION_TYPE_MATCH = 303;
+    private static final int NOTIFICATION_TYPE_SESSION_TERMINATED = 304;
+    private static final int NOTIFICATION_TYPE_MESSAGE_RECEIVED = 305;
+    private static final int NOTIFICATION_TYPE_NAN_DOWN = 306;
+    private static final int NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS = 307;
+    private static final int NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL = 308;
+    private static final int NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST = 309;
+    private static final int NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM = 310;
+    private static final int NOTIFICATION_TYPE_ON_DATA_PATH_END = 311;
+
+    private static final SparseArray<String> sSmToString = MessageUtils.findMessageNames(
+            new Class[]{WifiNanStateManager.class},
+            new String[]{"MESSAGE_TYPE", "COMMAND_TYPE", "RESPONSE_TYPE", "NOTIFICATION_TYPE"});
+
+    /*
+     * Keys used when passing (some) arguments to the Handler thread (too many
+     * arguments to pass in the short-cut Message members).
+     */
+    private static final String MESSAGE_BUNDLE_KEY_SESSION_TYPE = "session_type";
     private static final String MESSAGE_BUNDLE_KEY_SESSION_ID = "session_id";
-    private static final String MESSAGE_BUNDLE_KEY_EVENTS = "events";
-    private static final String MESSAGE_BUNDLE_KEY_PUBLISH_DATA = "publish_data";
-    private static final String MESSAGE_BUNDLE_KEY_PUBLISH_SETTINGS = "publish_settings";
-    private static final String MESSAGE_BUNDLE_KEY_SUBSCRIBE_DATA = "subscribe_data";
-    private static final String MESSAGE_BUNDLE_KEY_SUBSCRIBE_SETTINGS = "subscribe_settings";
+    private static final String MESSAGE_BUNDLE_KEY_CONFIG = "config";
     private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
     private static final String MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID = "message_peer_id";
     private static final String MESSAGE_BUNDLE_KEY_MESSAGE_ID = "message_id";
-    private static final String MESSAGE_BUNDLE_KEY_RESPONSE_TYPE = "response_type";
     private static final String MESSAGE_BUNDLE_KEY_SSI_LENGTH = "ssi_length";
     private static final String MESSAGE_BUNDLE_KEY_SSI_DATA = "ssi_data";
     private static final String MESSAGE_BUNDLE_KEY_FILTER_LENGTH = "filter_length";
@@ -88,20 +157,52 @@
     private static final String MESSAGE_BUNDLE_KEY_MAC_ADDRESS = "mac_address";
     private static final String MESSAGE_BUNDLE_KEY_MESSAGE_DATA = "message_data";
     private static final String MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH = "message_length";
+    private static final String MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID = "req_instance_id";
+    private static final String MESSAGE_BUNDLE_KEY_RANGING_ID = "ranging_id";
+    private static final String MESSAGE_BUNDLE_KEY_SEND_MESSAGE_ENQUEUE_TIME = "message_queue_time";
+    private static final String MESSAGE_BUNDLE_KEY_RETRY_COUNT = "retry_count";
+    private static final String MESSAGE_BUNDLE_KEY_SUCCESS_FLAG = "success_flag";
+    private static final String MESSAGE_BUNDLE_KEY_STATUS_CODE = "status_code";
+    private static final String MESSAGE_BUNDLE_KEY_INTERFACE_NAME = "interface_name";
+    private static final String MESSAGE_BUNDLE_KEY_PUB_SUB_ID = "pub_sub_id";
+    private static final String MESSAGE_BUNDLE_KEY_CHANNEL_REQ_TYPE = "channel_request_type";
+    private static final String MESSAGE_BUNDLE_KEY_CHANNEL = "channel";
+    private static final String MESSAGE_BUNDLE_KEY_PEER_ID = "peer_id";
+    private static final String MESSAGE_BUNDLE_KEY_UID = "uid";
+    private static final String MESSAGE_BUNDLE_KEY_SENT_MESSAGE = "send_message";
+    private static final String MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ = "message_arrival_seq";
 
-    private WifiNanNative.Capabilities mCapabilities;
+    /*
+     * Asynchronous access with no lock
+     */
+    private volatile boolean mUsageEnabled = false;
 
-    private WifiNanStateHandler mHandler;
+    /*
+     * Synchronous access: state is only accessed through the state machine
+     * handler thread: no need to use a lock.
+     */
+    private Context mContext;
+    /* package */ WifiNanNative.Capabilities mCapabilities;
+    private WifiNanStateMachine mSm;
+    private WifiNanRttStateManager mRtt;
+    private WifiNanDataPathStateManager mDataPathMgr;
 
-    // no synchronization necessary: only access through Handler
     private final SparseArray<WifiNanClientState> mClients = new SparseArray<>();
-    private final SparseArray<TransactionInfoBase> mPendingResponses = new SparseArray<>();
-    private short mNextTransactionId = 1;
+    private ConfigRequest mCurrentNanConfiguration = null;
+
+    private static final byte[] ALL_ZERO_MAC = new byte[] {0, 0, 0, 0, 0, 0};
+    private byte[] mCurrentDiscoveryInterfaceMac = ALL_ZERO_MAC;
 
     private WifiNanStateManager() {
         // EMPTY: singleton pattern
     }
 
+    /**
+     * Access the singleton NAN state manager. Use a singleton since need to be
+     * accessed (for now) from several other child classes.
+     *
+     * @return The state manager singleton.
+     */
     public static WifiNanStateManager getInstance() {
         if (sNanStateManagerSingleton == null) {
             sNanStateManagerSingleton = new WifiNanStateManager();
@@ -110,384 +211,810 @@
         return sNanStateManagerSingleton;
     }
 
-    public void start(Looper looper) {
+    /**
+     * Initialize the handler of the state manager with the specified thread
+     * looper.
+     *
+     * @param looper Thread looper on which to run the handler.
+     */
+    public void start(Context context, Looper looper) {
         Log.i(TAG, "start()");
 
-        mHandler = new WifiNanStateHandler(looper);
+        mContext = context;
+        mSm = new WifiNanStateMachine(TAG, looper);
+        mSm.setDbg(DBG);
+        mSm.start();
+
+        mRtt = new WifiNanRttStateManager();
+        mDataPathMgr = new WifiNanDataPathStateManager(this);
+        mDataPathMgr.start(mContext, mSm.getHandler().getLooper());
     }
 
-    public void connect(int uid, IWifiNanEventListener listener, int events) {
-        Message msg = mHandler.obtainMessage(MESSAGE_CONNECT);
-        msg.arg1 = uid;
-        msg.arg2 = events;
-        msg.obj = listener;
-        mHandler.sendMessage(msg);
+    /**
+     * Initialize the late-initialization sub-services: depend on other services already existing.
+     */
+    public void startLate() {
+        mRtt.start(mContext, mSm.getHandler().getLooper());
     }
 
-    public void disconnect(int uid) {
-        Message msg = mHandler.obtainMessage(MESSAGE_DISCONNECT);
-        msg.arg1 = uid;
-        mHandler.sendMessage(msg);
+    /**
+     * Get the client state for the specified ID (or null if none exists).
+     */
+    /* package */ WifiNanClientState getClient(int clientId) {
+        return mClients.get(clientId);
     }
 
-    public void requestConfig(int uid, ConfigRequest configRequest) {
-        Message msg = mHandler.obtainMessage(MESSAGE_REQUEST_CONFIG);
-        msg.arg1 = uid;
-        msg.obj = configRequest;
-        mHandler.sendMessage(msg);
+    /*
+     * COMMANDS
+     */
+
+    /**
+     * Place a request for a new client connection on the state machine queue.
+     */
+    public void connect(int clientId, int uid, IWifiNanEventCallback callback,
+            ConfigRequest configRequest) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_CONNECT;
+        msg.arg2 = clientId;
+        msg.obj = callback;
+        msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_CONFIG, configRequest);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_UID, uid);
+        mSm.sendMessage(msg);
     }
 
-    public void stopSession(int uid, int sessionId) {
-        Message msg = mHandler.obtainMessage(MESSAGE_STOP_SESSION);
-        msg.arg1 = uid;
-        msg.arg2 = sessionId;
-        mHandler.sendMessage(msg);
+    /**
+     * Place a request to disconnect (destroy) an existing client on the state
+     * machine queue.
+     */
+    public void disconnect(int clientId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_DISCONNECT;
+        msg.arg2 = clientId;
+        mSm.sendMessage(msg);
     }
 
-    public void destroySession(int uid, int sessionId) {
-        Message msg = mHandler.obtainMessage(MESSAGE_DESTROY_SESSION);
-        msg.arg1 = uid;
-        msg.arg2 = sessionId;
-        mHandler.sendMessage(msg);
+    /**
+     * Place a request to stop a discovery session on the state machine queue.
+     */
+    public void terminateSession(int clientId, int sessionId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_TERMINATE_SESSION;
+        msg.arg2 = clientId;
+        msg.obj = sessionId;
+        mSm.sendMessage(msg);
     }
 
-    public void createSession(int uid, int sessionId, IWifiNanSessionListener listener,
-            int events) {
-        Bundle data = new Bundle();
-        data.putInt(MESSAGE_BUNDLE_KEY_EVENTS, events);
-
-        Message msg = mHandler.obtainMessage(MESSAGE_CREATE_SESSION);
-        msg.setData(data);
-        msg.arg1 = uid;
-        msg.arg2 = sessionId;
-        msg.obj = listener;
-        mHandler.sendMessage(msg);
+    /**
+     * Place a request to start a new publish discovery session on the state
+     * machine queue.
+     */
+    public void publish(int clientId, PublishConfig publishConfig,
+            IWifiNanSessionCallback callback) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_PUBLISH;
+        msg.arg2 = clientId;
+        msg.obj = callback;
+        msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_CONFIG, publishConfig);
+        mSm.sendMessage(msg);
     }
 
-    public void publish(int uid, int sessionId, PublishData publishData,
-            PublishSettings publishSettings) {
-        Bundle data = new Bundle();
-        data.putParcelable(MESSAGE_BUNDLE_KEY_PUBLISH_DATA, publishData);
-        data.putParcelable(MESSAGE_BUNDLE_KEY_PUBLISH_SETTINGS, publishSettings);
-
-        Message msg = mHandler.obtainMessage(MESSAGE_PUBLISH);
-        msg.setData(data);
-        msg.arg1 = uid;
-        msg.arg2 = sessionId;
-        mHandler.sendMessage(msg);
+    /**
+     * Place a request to modify an existing publish discovery session on the
+     * state machine queue.
+     */
+    public void updatePublish(int clientId, int sessionId, PublishConfig publishConfig) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_UPDATE_PUBLISH;
+        msg.arg2 = clientId;
+        msg.obj = publishConfig;
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId);
+        mSm.sendMessage(msg);
     }
 
-    public void subscribe(int uid, int sessionId, SubscribeData subscribeData,
-            SubscribeSettings subscribeSettings) {
-        Bundle data = new Bundle();
-        data.putParcelable(MESSAGE_BUNDLE_KEY_SUBSCRIBE_DATA, subscribeData);
-        data.putParcelable(MESSAGE_BUNDLE_KEY_SUBSCRIBE_SETTINGS, subscribeSettings);
-
-        Message msg = mHandler.obtainMessage(MESSAGE_SUBSCRIBE);
-        msg.setData(data);
-        msg.arg1 = uid;
-        msg.arg2 = sessionId;
-        mHandler.sendMessage(msg);
+    /**
+     * Place a request to start a new subscribe discovery session on the state
+     * machine queue.
+     */
+    public void subscribe(int clientId, SubscribeConfig subscribeConfig,
+            IWifiNanSessionCallback callback) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_SUBSCRIBE;
+        msg.arg2 = clientId;
+        msg.obj = callback;
+        msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_CONFIG, subscribeConfig);
+        mSm.sendMessage(msg);
     }
 
-    public void sendMessage(int uid, int sessionId, int peerId, byte[] message, int messageLength,
-            int messageId) {
-        Bundle data = new Bundle();
-        data.putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId);
-        data.putInt(MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID, peerId);
-        data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message);
-        data.putInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID, messageId);
-
-        Message msg = mHandler.obtainMessage(MESSAGE_SEND_MESSAGE);
-        msg.arg1 = uid;
-        msg.arg2 = messageLength;
-        msg.setData(data);
-        mHandler.sendMessage(msg);
+    /**
+     * Place a request to modify an existing subscribe discovery session on the
+     * state machine queue.
+     */
+    public void updateSubscribe(int clientId, int sessionId, SubscribeConfig subscribeConfig) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_UPDATE_SUBSCRIBE;
+        msg.arg2 = clientId;
+        msg.obj = subscribeConfig;
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId);
+        mSm.sendMessage(msg);
     }
 
-    public void onCapabilitiesUpdate(short transactionId, WifiNanNative.Capabilities capabilities) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_CAPABILITIES_UPDATED);
-        msg.arg1 = transactionId;
+    /**
+     * Place a request to send a message on a discovery session on the state
+     * machine queue.
+     */
+    public void sendMessage(int clientId, int sessionId, int peerId, byte[] message,
+            int messageLength, int messageId, int retryCount) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_ENQUEUE_SEND_MESSAGE;
+        msg.arg2 = clientId;
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID, peerId);
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID, messageId);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH, messageLength);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_RETRY_COUNT, retryCount);
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a request to range a peer on the discovery session on the state machine queue.
+     */
+    public void startRanging(int clientId, int sessionId, RttManager.RttParams[] params,
+                             int rangingId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_START_RANGING;
+        msg.arg2 = clientId;
+        msg.obj = params;
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_RANGING_ID, rangingId);
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Enable usage of NAN. Doesn't actually turn on NAN (form clusters) - that
+     * only happens when a connection is created.
+     */
+    public void enableUsage() {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_ENABLE_USAGE;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Disable usage of NAN. Terminates all existing clients with onNanDown().
+     */
+    public void disableUsage() {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_DISABLE_USAGE;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Checks whether NAN usage is enabled (not necessarily that NAN is up right
+     * now) or disabled.
+     *
+     * @return A boolean indicating whether NAN usage is enabled (true) or
+     *         disabled (false).
+     */
+    public boolean isUsageEnabled() {
+        return mUsageEnabled;
+    }
+
+    /**
+     * Get the capabilities of the current NAN firmware.
+     */
+    public void getCapabilities() {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_GET_CAPABILITIES;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Create all NAN data path interfaces which are supported by the firmware capabilities.
+     */
+    public void createAllDataPathInterfaces() {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_CREATE_ALL_DATA_PATH_INTERFACES;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * delete all NAN data path interfaces.
+     */
+    public void deleteAllDataPathInterfaces() {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Create the specified data-path interface. Doesn't actually creates a data-path.
+     */
+    public void createDataPathInterface(String interfaceName) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE;
+        msg.obj = interfaceName;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Deletes the specified data-path interface.
+     */
+    public void deleteDataPathInterface(String interfaceName) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE;
+        msg.obj = interfaceName;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Command to initiate a data-path (executed by the initiator).
+     */
+    public void initiateDataPathSetup(String networkSpecifier, int peerId, int channelRequestType,
+            int channel, byte[] peer, String interfaceName, byte[] token) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_INITIATE_DATA_PATH_SETUP;
+        msg.obj = networkSpecifier;
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_CHANNEL_REQ_TYPE, channelRequestType);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_CHANNEL, channel);
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peer);
+        msg.getData().putString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME, interfaceName);
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, token);
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Command to respond to the data-path request (executed by the responder).
+     */
+    public void respondToDataPathRequest(boolean accept, int ndpId, String interfaceName,
+            String token) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST;
+        msg.arg2 = ndpId;
+        msg.obj = accept;
+        msg.getData().putString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME, interfaceName);
+        msg.getData().putString(MESSAGE_BUNDLE_KEY_MESSAGE, token);
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Command to terminate the specified data-path.
+     */
+    public void endDataPath(int ndpId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_END_DATA_PATH;
+        msg.arg2 = ndpId;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * NAN follow-on messages (L2 messages) are queued by the firmware for transmission
+     * on-the-air. The firmware has limited queue depth. The host queues all messages and doles
+     * them out to the firmware when possible. This command removes the next messages for
+     * transmission from the host queue and attempts to send it through the firmware. The queues
+     * are inspected when the command is executed - not when the command is placed on the handler
+     * (i.e. not evaluated here).
+     */
+    private void transmitNextMessage() {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
+        msg.arg1 = COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE;
+        mSm.sendMessage(msg);
+    }
+
+    /*
+     * RESPONSES
+     */
+
+    /**
+     * Place a callback request on the state machine queue: configuration
+     * request completed (successfully).
+     */
+    public void onConfigSuccessResponse(short transactionId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_CONFIG_SUCCESS;
+        msg.arg2 = transactionId;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a callback request on the state machine queue: configuration
+     * request failed.
+     */
+    public void onConfigFailedResponse(short transactionId, int reason) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_CONFIG_FAIL;
+        msg.arg2 = transactionId;
+        msg.obj = reason;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a callback request on the state machine queue: session
+     * configuration (new or update) request succeeded.
+     */
+    public void onSessionConfigSuccessResponse(short transactionId, boolean isPublish,
+            int pubSubId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS;
+        msg.arg2 = transactionId;
+        msg.obj = pubSubId;
+        msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE, isPublish);
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a callback request on the state machine queue: session
+     * configuration (new or update) request failed.
+     */
+    public void onSessionConfigFailResponse(short transactionId, boolean isPublish, int reason) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL;
+        msg.arg2 = transactionId;
+        msg.obj = reason;
+        msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE, isPublish);
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a callback request on the state machine queue: message has been queued successfully.
+     */
+    public void onMessageSendQueuedSuccessResponse(short transactionId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS;
+        msg.arg2 = transactionId;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a callback request on the state machine queue: attempt to queue the message failed.
+     */
+    public void onMessageSendQueuedFailResponse(short transactionId, int reason) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL;
+        msg.arg2 = transactionId;
+        msg.obj = reason;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a callback request on the state machine queue: update vendor
+     * capabilities of the NAN stack.
+     */
+    public void onCapabilitiesUpdateResponse(short transactionId,
+            WifiNanNative.Capabilities capabilities) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_CAPABILITIES_UPDATED;
+        msg.arg2 = transactionId;
         msg.obj = capabilities;
-        mHandler.sendMessage(msg);
+        mSm.sendMessage(msg);
     }
 
-    public void onConfigCompleted(short transactionId) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_CONFIG_COMPLETED);
-        msg.arg1 = transactionId;
-        mHandler.sendMessage(msg);
+    /**
+     * Places a callback request on the state machine queue: data-path interface creation command
+     * completed.
+     */
+    public void onCreateDataPathInterfaceResponse(short transactionId, boolean success,
+            int reasonOnFailure) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_CREATE_INTERFACE;
+        msg.arg2 = transactionId;
+        msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, success);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reasonOnFailure);
+        mSm.sendMessage(msg);
     }
 
-    public void onConfigFailed(short transactionId, int reason) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_CONFIG_FAILED);
-        msg.arg1 = transactionId;
-        msg.arg2 = reason;
-        mHandler.sendMessage(msg);
+    /**
+     * Places a callback request on the state machine queue: data-path interface deletion command
+     * completed.
+     */
+    public void onDeleteDataPathInterfaceResponse(short transactionId, boolean success,
+            int reasonOnFailure) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_DELETE_INTERFACE;
+        msg.arg2 = transactionId;
+        msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, success);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reasonOnFailure);
+        mSm.sendMessage(msg);
     }
 
-    public void onPublishSuccess(short transactionId, int publishId) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_PUBLISH_SUCCESS);
-        msg.arg1 = transactionId;
-        msg.arg2 = publishId;
-        mHandler.sendMessage(msg);
+    /**
+     * Response from firmware to {@link #initiateDataPathSetup(String, int, int, int, byte[],
+     * String, byte[])}. Indicates that command has started succesfully (not completed!).
+     */
+    public void onInitiateDataPathResponseSuccess(short transactionId, int ndpId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS;
+        msg.arg2 = transactionId;
+        msg.obj = ndpId;
+        mSm.sendMessage(msg);
     }
 
-    public void onPublishFail(short transactionId, int status) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_PUBLISH_FAIL);
-        msg.arg1 = transactionId;
-        msg.arg2 = status;
-        mHandler.sendMessage(msg);
+    /**
+     * Response from firmware to
+     * {@link #initiateDataPathSetup(String, int, int, int, byte[], String, byte[])}. Indicates
+     * that command has failed.
+     */
+    public void onInitiateDataPathResponseFail(short transactionId, int reason) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL;
+        msg.arg2 = transactionId;
+        msg.obj = reason;
+        mSm.sendMessage(msg);
     }
 
-    public void onMessageSendSuccess(short transactionId) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_MESSAGE_SEND_SUCCESS);
-        msg.arg1 = transactionId;
-        mHandler.sendMessage(msg);
+    /**
+     * Response from firmware to {@link #respondToDataPathRequest(boolean, int, String, String)}.
+     */
+    public void onRespondToDataPathSetupRequestResponse(short transactionId, boolean success,
+            int reasonOnFailure) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST;
+        msg.arg2 = transactionId;
+        msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, success);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reasonOnFailure);
+        mSm.sendMessage(msg);
     }
 
-    public void onMessageSendFail(short transactionId, int status) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_MESSAGE_SEND_FAIL);
-        msg.arg1 = transactionId;
-        msg.arg2 = status;
-        mHandler.sendMessage(msg);
+    /**
+     * Response from firmware to {@link #endDataPath(int)}.
+     */
+    public void onEndDataPathResponse(short transactionId, boolean success, int reasonOnFailure) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE);
+        msg.arg1 = RESPONSE_TYPE_ON_END_DATA_PATH;
+        msg.arg2 = transactionId;
+        msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, success);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reasonOnFailure);
+        mSm.sendMessage(msg);
     }
 
-    public void onSubscribeSuccess(short transactionId, int subscribeId) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_SUBSCRIBE_SUCCESS);
-        msg.arg1 = transactionId;
-        msg.arg2 = subscribeId;
-        mHandler.sendMessage(msg);
-    }
+    /*
+     * NOTIFICATIONS
+     */
 
-    public void onSubscribeFail(short transactionId, int status) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_SUBSCRIBE_FAIL);
-        msg.arg1 = transactionId;
-        msg.arg2 = status;
-        mHandler.sendMessage(msg);
-    }
-
-    public void onUnknownTransaction(int responseType, short transactionId, int status) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_UNKNOWN_TRANSACTION);
-        Bundle data = new Bundle();
-        data.putInt(MESSAGE_BUNDLE_KEY_RESPONSE_TYPE, responseType);
-        msg.setData(data);
-        msg.arg1 = transactionId;
-        msg.arg2 = status;
-        mHandler.sendMessage(msg);
-    }
-
-    public void onInterfaceAddressChange(byte[] mac) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_INTERFACE_CHANGE);
+    /**
+     * Place a callback request on the state machine queue: the discovery
+     * interface has changed.
+     */
+    public void onInterfaceAddressChangeNotification(byte[] mac) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_INTERFACE_CHANGE;
         msg.obj = mac;
-        mHandler.sendMessage(msg);
+        mSm.sendMessage(msg);
     }
 
-    public void onClusterChange(int flag, byte[] clusterId) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_CLUSTER_CHANGE);
-        msg.arg1 = flag;
+    /**
+     * Place a callback request on the state machine queue: the cluster
+     * membership has changed (e.g. due to starting a new cluster or joining
+     * another cluster).
+     */
+    public void onClusterChangeNotification(int flag, byte[] clusterId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_CLUSTER_CHANGE;
+        msg.arg2 = flag;
         msg.obj = clusterId;
-        mHandler.sendMessage(msg);
+        mSm.sendMessage(msg);
     }
 
-    public void onMatch(int pubSubId, int requestorInstanceId, byte[] peerMac,
+    /**
+     * Place a callback request on the state machine queue: a discovery match
+     * has occurred - e.g. our subscription discovered someone else publishing a
+     * matching service (to the one we were looking for).
+     */
+    public void onMatchNotification(int pubSubId, int requestorInstanceId, byte[] peerMac,
             byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] matchFilter,
             int matchFilterLength) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_MATCH);
-        msg.arg1 = pubSubId;
-        msg.arg2 = requestorInstanceId;
-        Bundle data = new Bundle();
-        data.putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peerMac);
-        data.putByteArray(MESSAGE_BUNDLE_KEY_SSI_DATA, serviceSpecificInfo);
-        data.putInt(MESSAGE_BUNDLE_KEY_SSI_LENGTH, serviceSpecificInfoLength);
-        data.putByteArray(MESSAGE_BUNDLE_KEY_FILTER_DATA, matchFilter);
-        data.putInt(MESSAGE_BUNDLE_KEY_FILTER_LENGTH, matchFilterLength);
-        msg.setData(data);
-        mHandler.sendMessage(msg);
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_MATCH;
+        msg.arg2 = pubSubId;
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID, requestorInstanceId);
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peerMac);
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_SSI_DATA, serviceSpecificInfo);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_SSI_LENGTH, serviceSpecificInfoLength);
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_FILTER_DATA, matchFilter);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_FILTER_LENGTH, matchFilterLength);
+        mSm.sendMessage(msg);
     }
 
-    public void onPublishTerminated(int publishId, int status) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_PUBLISH_TERMINATED);
-        msg.arg1 = publishId;
-        msg.arg2 = status;
-        mHandler.sendMessage(msg);
+    /**
+     * Place a callback request on the state machine queue: a session (publish
+     * or subscribe) has terminated (per plan or due to an error).
+     */
+    public void onSessionTerminatedNotification(int pubSubId, int reason, boolean isPublish) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_SESSION_TERMINATED;
+        msg.arg2 = pubSubId;
+        msg.obj = reason;
+        msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE, isPublish);
+        mSm.sendMessage(msg);
     }
 
-    public void onSubscribeTerminated(int subscribeId, int status) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_SUBSCRIBE_TERMINATED);
-        msg.arg1 = subscribeId;
-        msg.arg2 = status;
-        mHandler.sendMessage(msg);
-    }
-
-    public void onMessageReceived(int pubSubId, int requestorInstanceId, byte[] peerMac,
+    /**
+     * Place a callback request on the state machine queue: a message has been
+     * received as part of a discovery session.
+     */
+    public void onMessageReceivedNotification(int pubSubId, int requestorInstanceId, byte[] peerMac,
             byte[] message, int messageLength) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_MESSAGE_RECEIVED);
-        msg.arg1 = pubSubId;
-        msg.arg2 = requestorInstanceId;
-        Bundle data = new Bundle();
-        data.putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peerMac);
-        data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA, message);
-        data.putInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH, messageLength);
-        msg.setData(data);
-        mHandler.sendMessage(msg);
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_MESSAGE_RECEIVED;
+        msg.arg2 = pubSubId;
+        msg.obj = requestorInstanceId;
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peerMac);
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA, message);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH, messageLength);
+        mSm.sendMessage(msg);
     }
 
-    public void onNanDown(int reason) {
-        Message msg = mHandler.obtainMessage(MESSAGE_ON_NAN_DOWN);
-        msg.arg1 = reason;
-        mHandler.sendMessage(msg);
+    /**
+     * Place a callback request on the state machine queue: NAN is going down.
+     */
+    public void onNanDownNotification(int reason) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_NAN_DOWN;
+        msg.arg2 = reason;
+        mSm.sendMessage(msg);
     }
 
-    private class WifiNanStateHandler extends Handler {
-        WifiNanStateHandler(android.os.Looper looper) {
-            super(looper);
+    /**
+     * Notification that a message has been sent successfully (i.e. an ACK has been received).
+     */
+    public void onMessageSendSuccessNotification(short transactionId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS;
+        msg.arg2 = transactionId;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Notification that a message transmission has failed due to the indicated reason - e.g. no ACK
+     * was received.
+     */
+    public void onMessageSendFailNotification(short transactionId, int reason) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL;
+        msg.arg2 = transactionId;
+        msg.obj = reason;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a callback request on the state machine queue: data-path request (from peer) received.
+     */
+    public void onDataPathRequestNotification(int pubSubId, byte[] mac, int ndpId, byte[] message,
+            int messageLength) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST;
+        msg.arg2 = pubSubId;
+        msg.obj = ndpId;
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, mac);
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA, message);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH, messageLength);
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a callback request on the state machine queue: data-path confirmation received - i.e.
+     * data-path is now up.
+     */
+    public void onDataPathConfirmNotification(int ndpId, byte[] mac, boolean accept, int reason,
+            byte[] message, int messageLength) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM;
+        msg.arg2 = ndpId;
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, mac);
+        msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, accept);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reason);
+        msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA, message);
+        msg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH, messageLength);
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * Place a callback request on the state machine queue: the specified data-path has been
+     * terminated.
+     */
+    public void onDataPathEndNotification(int ndpId) {
+        Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION);
+        msg.arg1 = NOTIFICATION_TYPE_ON_DATA_PATH_END;
+        msg.arg2 = ndpId;
+        mSm.sendMessage(msg);
+    }
+
+    /**
+     * State machine.
+     */
+    @VisibleForTesting
+    class WifiNanStateMachine extends StateMachine {
+        private static final int TRANSACTION_ID_IGNORE = 0;
+
+        private DefaultState mDefaultState = new DefaultState();
+        private WaitState mWaitState = new WaitState();
+        private WaitForResponseState mWaitForResponseState = new WaitForResponseState();
+
+        private short mNextTransactionId = 1;
+        public int mNextSessionId = 1;
+
+        private Message mCurrentCommand;
+        private short mCurrentTransactionId = TRANSACTION_ID_IGNORE;
+
+        private static final long NAN_SEND_MESSAGE_TIMEOUT = 10_000;
+        private int mSendArrivalSequenceCounter = 0;
+        private boolean mSendQueueBlocked = false;
+        private final SparseArray<Message> mHostQueuedSendMessages = new SparseArray<>();
+        private final Map<Short, Message> mFwQueuedSendMessages = new LinkedHashMap<>();
+        private WakeupMessage mSendMessageTimeoutMessage = new WakeupMessage(mContext, getHandler(),
+                HAL_SEND_MESSAGE_TIMEOUT_TAG, MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT);
+
+        private static final long NAN_WAIT_FOR_DP_CONFIRM_TIMEOUT = 5_000;
+        private final Map<String, WakeupMessage> mDataPathConfirmTimeoutMessages = new HashMap<>();
+
+        WifiNanStateMachine(String name, Looper looper) {
+            super(name, looper);
+
+            addState(mDefaultState);
+            /* --> */ addState(mWaitState, mDefaultState);
+            /* --> */ addState(mWaitForResponseState, mDefaultState);
+
+            setInitialState(mWaitState);
         }
 
-        @Override
-        public void handleMessage(Message msg) {
-            if (DBG) {
-                Log.d(TAG, "Message: " + msg.what);
+        public void onNanDownCleanupSendQueueState() {
+            mSendQueueBlocked = false;
+            mHostQueuedSendMessages.clear();
+            mFwQueuedSendMessages.clear();
+        }
+
+        private class DefaultState extends State {
+            @Override
+            public boolean processMessage(Message msg) {
+                if (VDBG) {
+                    Log.v(TAG, getName() + msg.toString());
+                }
+
+                switch (msg.what) {
+                    case MESSAGE_TYPE_NOTIFICATION:
+                        processNotification(msg);
+                        return HANDLED;
+                    case MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT:
+                        processSendMessageTimeout();
+                        return HANDLED;
+                    case MESSAGE_TYPE_DATA_PATH_TIMEOUT: {
+                        String networkSpecifier = (String) msg.obj;
+
+                        if (VDBG) {
+                            Log.v(TAG, "MESSAGE_TYPE_DATA_PATH_TIMEOUT: networkSpecifier="
+                                    + networkSpecifier);
+                        }
+
+                        mDataPathMgr.handleDataPathTimeout(networkSpecifier);
+                        mDataPathConfirmTimeoutMessages.remove(networkSpecifier);
+                        return HANDLED;
+                    }
+                    default:
+                        /* fall-through */
+                }
+
+                Log.wtf(TAG,
+                        "DefaultState: should not get non-NOTIFICATION in this state: msg=" + msg);
+                return NOT_HANDLED;
             }
-            switch (msg.what) {
-                case MESSAGE_CONNECT: {
-                    if (VDBG) {
-                        Log.d(TAG, "NAN connection request received");
-                    }
-                    connectLocal(msg.arg1, (IWifiNanEventListener) msg.obj, msg.arg2);
-                    break;
-                }
-                case MESSAGE_DISCONNECT: {
-                    if (VDBG) {
-                        Log.d(TAG, "NAN disconnection request received");
-                    }
-                    disconnectLocal(msg.arg1);
-                    break;
-                }
-                case MESSAGE_REQUEST_CONFIG: {
-                    if (VDBG) {
-                        Log.d(TAG, "NAN configuration request received");
-                    }
-                    requestConfigLocal(msg.arg1, (ConfigRequest) msg.obj);
-                    break;
-                }
-                case MESSAGE_CREATE_SESSION: {
-                    if (VDBG) {
-                        Log.d(TAG, "Create session");
-                    }
-                    int events = msg.getData().getInt(MESSAGE_BUNDLE_KEY_EVENTS);
-                    createSessionLocal(msg.arg1, msg.arg2, (IWifiNanSessionListener) msg.obj,
-                            events);
-                    break;
-                }
-                case MESSAGE_DESTROY_SESSION: {
-                    if (VDBG) {
-                        Log.d(TAG, "Destroy session");
-                    }
-                    destroySessionLocal(msg.arg1, msg.arg2);
-                    break;
-                }
-                case MESSAGE_PUBLISH: {
-                    Bundle data = msg.getData();
-                    PublishData publishData = (PublishData) data
-                            .getParcelable(MESSAGE_BUNDLE_KEY_PUBLISH_DATA);
-                    PublishSettings publishSettings = (PublishSettings) data
-                            .getParcelable(MESSAGE_BUNDLE_KEY_PUBLISH_SETTINGS);
-                    if (VDBG) {
-                        Log.d(TAG,
-                                "Publish: data='" + publishData + "', settings=" + publishSettings);
-                    }
+        }
 
-                    publishLocal(msg.arg1, msg.arg2, publishData, publishSettings);
-                    break;
+        private class WaitState extends State {
+            @Override
+            public boolean processMessage(Message msg) {
+                if (VDBG) {
+                    Log.v(TAG, getName() + msg.toString());
                 }
-                case MESSAGE_SUBSCRIBE: {
-                    Bundle data = msg.getData();
-                    SubscribeData subscribeData = (SubscribeData) data
-                            .getParcelable(MESSAGE_BUNDLE_KEY_SUBSCRIBE_DATA);
-                    SubscribeSettings subscribeSettings = (SubscribeSettings) data
-                            .getParcelable(MESSAGE_BUNDLE_KEY_SUBSCRIBE_SETTINGS);
-                    if (VDBG) {
-                        Log.d(TAG, "Subscribe: data='" + subscribeData + "', settings="
-                                + subscribeSettings);
-                    }
 
-                    subscribeLocal(msg.arg1, msg.arg2, subscribeData, subscribeSettings);
-                    break;
+                switch (msg.what) {
+                    case MESSAGE_TYPE_COMMAND:
+                        if (processCommand(msg)) {
+                            transitionTo(mWaitForResponseState);
+                        }
+                        return HANDLED;
+                    case MESSAGE_TYPE_RESPONSE:
+                        /* fall-through */
+                    case MESSAGE_TYPE_RESPONSE_TIMEOUT:
+                        /*
+                         * remnants/delayed/out-of-sync messages - but let
+                         * WaitForResponseState deal with them (identified as
+                         * out-of-date by transaction ID).
+                         */
+                        deferMessage(msg);
+                        return HANDLED;
+                    default:
+                        /* fall-through */
                 }
-                case MESSAGE_SEND_MESSAGE: {
-                    Bundle data = msg.getData();
-                    int sessionId = msg.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID);
-                    int peerId = data.getInt(MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID);
-                    byte[] message = data.getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE);
-                    int messageId = data.getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID);
 
-                    if (VDBG) {
-                        Log.d(TAG, "Send Message: message='" + message + "' (ID=" + messageId
-                                + ") to peerId=" + peerId);
-                    }
+                return NOT_HANDLED;
+            }
+        }
 
-                    sendFollowonMessageLocal(msg.arg1, sessionId, peerId, message, msg.arg2,
-                            messageId);
+        private class WaitForResponseState extends State {
+            private static final long NAN_COMMAND_TIMEOUT = 5_000;
+            private WakeupMessage mTimeoutMessage;
+
+            @Override
+            public void enter() {
+                mTimeoutMessage = new WakeupMessage(mContext, getHandler(), HAL_COMMAND_TIMEOUT_TAG,
+                        MESSAGE_TYPE_RESPONSE_TIMEOUT, mCurrentCommand.arg1, mCurrentTransactionId);
+                mTimeoutMessage.schedule(SystemClock.elapsedRealtime() + NAN_COMMAND_TIMEOUT);
+            }
+
+            @Override
+            public void exit() {
+                mTimeoutMessage.cancel();
+            }
+
+            @Override
+            public boolean processMessage(Message msg) {
+                if (VDBG) {
+                    Log.v(TAG, getName() + msg.toString());
+                }
+
+                switch (msg.what) {
+                    case MESSAGE_TYPE_COMMAND:
+                        /*
+                         * don't want COMMANDs in this state - defer until back
+                         * in WaitState
+                         */
+                        deferMessage(msg);
+                        return HANDLED;
+                    case MESSAGE_TYPE_RESPONSE:
+                        if (msg.arg2 == mCurrentTransactionId) {
+                            processResponse(msg);
+                            transitionTo(mWaitState);
+                        } else {
+                            Log.w(TAG,
+                                    "WaitForResponseState: processMessage: non-matching "
+                                            + "transaction ID on RESPONSE (a very late "
+                                            + "response) -- msg=" + msg);
+                            /* no transition */
+                        }
+                        return HANDLED;
+                    case MESSAGE_TYPE_RESPONSE_TIMEOUT:
+                        if (msg.arg2 == mCurrentTransactionId) {
+                            processTimeout(msg);
+                            transitionTo(mWaitState);
+                        } else {
+                            Log.w(TAG, "WaitForResponseState: processMessage: non-matching "
+                                    + "transaction ID on RESPONSE_TIMEOUT (either a non-cancelled "
+                                    + "timeout or a race condition with cancel) -- msg=" + msg);
+                            /* no transition */
+                        }
+                        return HANDLED;
+                    default:
+                        /* fall-through */
+                }
+
+                return NOT_HANDLED;
+            }
+        }
+
+        private void processNotification(Message msg) {
+            if (VDBG) {
+                Log.v(TAG, "processNotification: msg=" + msg);
+            }
+
+            switch (msg.arg1) {
+                case NOTIFICATION_TYPE_INTERFACE_CHANGE: {
+                    byte[] mac = (byte[]) msg.obj;
+
+                    onInterfaceAddressChangeLocal(mac);
                     break;
                 }
-                case MESSAGE_STOP_SESSION: {
-                    if (VDBG) {
-                        Log.d(TAG, "Stop session");
-                    }
-                    stopSessionLocal(msg.arg1, msg.arg2);
+                case NOTIFICATION_TYPE_CLUSTER_CHANGE: {
+                    int flag = msg.arg2;
+                    byte[] clusterId = (byte[]) msg.obj;
+
+                    onClusterChangeLocal(flag, clusterId);
                     break;
                 }
-                case MESSAGE_ON_CAPABILITIES_UPDATED:
-                    onCapabilitiesUpdatedLocal((short) msg.arg1,
-                            (WifiNanNative.Capabilities) msg.obj);
-                    break;
-                case MESSAGE_ON_CONFIG_COMPLETED:
-                    onConfigCompletedLocal((short) msg.arg1);
-                    break;
-                case MESSAGE_ON_CONFIG_FAILED:
-                    onConfigFailedLocal((short) msg.arg1, msg.arg2);
-                    break;
-                case MESSAGE_ON_NAN_DOWN:
-                    onNanDownLocal(msg.arg1);
-                    break;
-                case MESSAGE_ON_INTERFACE_CHANGE:
-                    onInterfaceAddressChangeLocal((byte[]) msg.obj);
-                    break;
-                case MESSAGE_ON_CLUSTER_CHANGE:
-                    onClusterChangeLocal(msg.arg1, (byte[]) msg.obj);
-                    break;
-                case MESSAGE_ON_PUBLISH_SUCCESS:
-                    onPublishSuccessLocal((short) msg.arg1, msg.arg2);
-                    break;
-                case MESSAGE_ON_PUBLISH_FAIL:
-                    onPublishFailLocal((short) msg.arg1, msg.arg2);
-                    break;
-                case MESSAGE_ON_PUBLISH_TERMINATED:
-                    onPublishTerminatedLocal(msg.arg1, msg.arg2);
-                    break;
-                case MESSAGE_ON_SUBSCRIBE_SUCCESS:
-                    onSubscribeSuccessLocal((short) msg.arg1, msg.arg2);
-                    break;
-                case MESSAGE_ON_SUBSCRIBE_FAIL:
-                    onSubscribeFailLocal((short) msg.arg1, msg.arg2);
-                    break;
-                case MESSAGE_ON_SUBSCRIBE_TERMINATED:
-                    onSubscribeTerminatedLocal(msg.arg1, msg.arg2);
-                    break;
-                case MESSAGE_ON_MESSAGE_SEND_SUCCESS:
-                    onMessageSendSuccessLocal((short) msg.arg1);
-                    break;
-                case MESSAGE_ON_MESSAGE_SEND_FAIL:
-                    onMessageSendFailLocal((short) msg.arg1, msg.arg2);
-                    break;
-                case MESSAGE_ON_UNKNOWN_TRANSACTION:
-                    onUnknownTransactionLocal(
-                            msg.getData().getInt(MESSAGE_BUNDLE_KEY_RESPONSE_TYPE),
-                            (short) msg.arg1, msg.arg2);
-                    break;
-                case MESSAGE_ON_MATCH: {
-                    int pubSubId = msg.arg1;
-                    int requestorInstanceId = msg.arg2;
+                case NOTIFICATION_TYPE_MATCH: {
+                    int pubSubId = msg.arg2;
+                    int requestorInstanceId = msg.getData()
+                            .getInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID);
                     byte[] peerMac = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS);
                     byte[] serviceSpecificInfo = msg.getData()
                             .getByteArray(MESSAGE_BUNDLE_KEY_SSI_DATA);
@@ -495,394 +1022,1361 @@
                             .getInt(MESSAGE_BUNDLE_KEY_SSI_LENGTH);
                     byte[] matchFilter = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_FILTER_DATA);
                     int matchFilterLength = msg.getData().getInt(MESSAGE_BUNDLE_KEY_FILTER_LENGTH);
+
                     onMatchLocal(pubSubId, requestorInstanceId, peerMac, serviceSpecificInfo,
                             serviceSpecificInfoLength, matchFilter, matchFilterLength);
                     break;
                 }
-                case MESSAGE_ON_MESSAGE_RECEIVED: {
-                    int pubSubId = msg.arg1;
-                    int requestorInstanceId = msg.arg2;
+                case NOTIFICATION_TYPE_SESSION_TERMINATED: {
+                    int pubSubId = msg.arg2;
+                    int reason = (Integer) msg.obj;
+                    boolean isPublish = msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE);
+
+                    onSessionTerminatedLocal(pubSubId, isPublish, reason);
+                    break;
+                }
+                case NOTIFICATION_TYPE_MESSAGE_RECEIVED: {
+                    int pubSubId = msg.arg2;
+                    int requestorInstanceId = (Integer) msg.obj;
                     byte[] peerMac = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS);
                     byte[] message = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA);
                     int messageLength = msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH);
+
                     onMessageReceivedLocal(pubSubId, requestorInstanceId, peerMac, message,
                             messageLength);
                     break;
                 }
+                case NOTIFICATION_TYPE_NAN_DOWN: {
+                    int reason = msg.arg2;
+
+                    /*
+                     * TODO: b/28615938. Use reason code to determine whether or not need clean-up
+                     * local state (only needed if NAN_DOWN is due to internal firmware reason, e.g.
+                     * concurrency, rather than due to a requested shutdown).
+                     */
+
+                    onNanDownLocal();
+
+                    break;
+                }
+                case NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS: {
+                    short transactionId = (short) msg.arg2;
+                    Message queuedSendCommand = mFwQueuedSendMessages.get(transactionId);
+                    if (VDBG) {
+                        Log.v(TAG, "NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS: queuedSendCommand="
+                                + queuedSendCommand);
+                    }
+                    if (queuedSendCommand == null) {
+                        Log.w(TAG,
+                                "processNotification: NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS:"
+                                        + " transactionId=" + transactionId
+                                        + " - no such queued send command (timed-out?)");
+                    } else {
+                        mFwQueuedSendMessages.remove(transactionId);
+                        updateSendMessageTimeout();
+                        onMessageSendSuccessLocal(queuedSendCommand);
+                    }
+                    mSendQueueBlocked = false;
+                    transmitNextMessage();
+
+                    break;
+                }
+                case NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL: {
+                    short transactionId = (short) msg.arg2;
+                    int reason = (Integer) msg.obj;
+                    Message sentMessage = mFwQueuedSendMessages.get(transactionId);
+                    if (VDBG) {
+                        Log.v(TAG, "NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL: sentMessage="
+                                + sentMessage);
+                    }
+                    if (sentMessage == null) {
+                        Log.w(TAG,
+                                "processNotification: NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL:"
+                                        + " transactionId=" + transactionId
+                                        + " - no such queued send command (timed-out?)");
+                    } else {
+                        mFwQueuedSendMessages.remove(transactionId);
+                        updateSendMessageTimeout();
+
+                        int retryCount = sentMessage.getData()
+                                .getInt(MESSAGE_BUNDLE_KEY_RETRY_COUNT);
+                        if (retryCount > 0 && reason == WifiNanSessionCallback.REASON_TX_FAIL) {
+                            if (DBG) {
+                                Log.d(TAG,
+                                        "NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL: transactionId="
+                                                + transactionId + ", reason=" + reason
+                                                + ": retransmitting - retryCount=" + retryCount);
+                            }
+                            sentMessage.getData().putInt(MESSAGE_BUNDLE_KEY_RETRY_COUNT,
+                                    retryCount - 1);
+
+                            int arrivalSeq = sentMessage.getData().getInt(
+                                    MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ);
+                            mHostQueuedSendMessages.put(arrivalSeq, sentMessage);
+                        } else {
+                            onMessageSendFailLocal(sentMessage, reason);
+                        }
+                        mSendQueueBlocked = false;
+                        transmitNextMessage();
+                    }
+                    break;
+                }
+                case NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST: {
+                    String networkSpecifier = mDataPathMgr.onDataPathRequest(msg.arg2,
+                            msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS),
+                            (int) msg.obj,
+                            msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA),
+                            msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH));
+
+                    if (networkSpecifier != null) {
+                        WakeupMessage timeout = new WakeupMessage(mContext, getHandler(),
+                                HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG, MESSAGE_TYPE_DATA_PATH_TIMEOUT,
+                                0, 0, networkSpecifier);
+                        mDataPathConfirmTimeoutMessages.put(networkSpecifier, timeout);
+                        timeout.schedule(
+                                SystemClock.elapsedRealtime() + NAN_WAIT_FOR_DP_CONFIRM_TIMEOUT);
+                    }
+
+                    break;
+                }
+                case NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM: {
+                    String networkSpecifier = mDataPathMgr.onDataPathConfirm(msg.arg2,
+                            msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS),
+                            msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG),
+                            msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE),
+                            msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA),
+                            msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH));
+
+                    if (networkSpecifier != null) {
+                        WakeupMessage timeout = mDataPathConfirmTimeoutMessages.remove(
+                                networkSpecifier);
+                        if (timeout != null) {
+                            timeout.cancel();
+                        }
+                    }
+
+                    break;
+                }
+                case NOTIFICATION_TYPE_ON_DATA_PATH_END:
+                    mDataPathMgr.onDataPathEnd(msg.arg2);
+                    break;
                 default:
-                    Log.e(TAG, "Unknown message code: " + msg.what);
+                    Log.wtf(TAG, "processNotification: this isn't a NOTIFICATION -- msg=" + msg);
+                    return;
             }
         }
+
+        /**
+         * Execute the command specified by the input Message. Returns a true if
+         * need to wait for a RESPONSE, otherwise a false. We may not have to
+         * wait for a RESPONSE if there was an error in the state (so no command
+         * is sent to HAL) OR if we choose not to wait for response - e.g. for
+         * disconnected/terminate commands failure is not possible.
+         */
+        private boolean processCommand(Message msg) {
+            if (VDBG) {
+                Log.v(TAG, "processCommand: msg=" + msg);
+            }
+
+            if (mCurrentCommand != null) {
+                Log.wtf(TAG,
+                        "processCommand: receiving a command (msg=" + msg
+                                + ") but current (previous) command isn't null (prev_msg="
+                                + mCurrentCommand + ")");
+                mCurrentCommand = null;
+            }
+
+            mCurrentTransactionId = mNextTransactionId++;
+
+            boolean waitForResponse = true;
+
+            switch (msg.arg1) {
+                case COMMAND_TYPE_CONNECT: {
+                    int clientId = msg.arg2;
+                    IWifiNanEventCallback callback = (IWifiNanEventCallback) msg.obj;
+                    ConfigRequest configRequest = (ConfigRequest) msg.getData()
+                            .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG);
+                    int uid = msg.getData().getInt(MESSAGE_BUNDLE_KEY_UID);
+
+                    waitForResponse = connectLocal(mCurrentTransactionId, clientId, uid, callback,
+                            configRequest);
+                    break;
+                }
+                case COMMAND_TYPE_DISCONNECT: {
+                    int clientId = msg.arg2;
+
+                    waitForResponse = disconnectLocal(mCurrentTransactionId, clientId);
+                    break;
+                }
+                case COMMAND_TYPE_TERMINATE_SESSION: {
+                    int clientId = msg.arg2;
+                    int sessionId = (Integer) msg.obj;
+
+                    terminateSessionLocal(clientId, sessionId);
+                    waitForResponse = false;
+                    break;
+                }
+                case COMMAND_TYPE_PUBLISH: {
+                    int clientId = msg.arg2;
+                    IWifiNanSessionCallback callback = (IWifiNanSessionCallback) msg.obj;
+                    PublishConfig publishConfig = (PublishConfig) msg.getData()
+                            .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG);
+
+                    waitForResponse = publishLocal(mCurrentTransactionId, clientId, publishConfig,
+                            callback);
+                    break;
+                }
+                case COMMAND_TYPE_UPDATE_PUBLISH: {
+                    int clientId = msg.arg2;
+                    int sessionId = msg.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID);
+                    PublishConfig publishConfig = (PublishConfig) msg.obj;
+
+                    waitForResponse = updatePublishLocal(mCurrentTransactionId, clientId, sessionId,
+                            publishConfig);
+                    break;
+                }
+                case COMMAND_TYPE_SUBSCRIBE: {
+                    int clientId = msg.arg2;
+                    IWifiNanSessionCallback callback = (IWifiNanSessionCallback) msg.obj;
+                    SubscribeConfig subscribeConfig = (SubscribeConfig) msg.getData()
+                            .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG);
+
+                    waitForResponse = subscribeLocal(mCurrentTransactionId, clientId,
+                            subscribeConfig, callback);
+                    break;
+                }
+                case COMMAND_TYPE_UPDATE_SUBSCRIBE: {
+                    int clientId = msg.arg2;
+                    int sessionId = msg.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID);
+                    SubscribeConfig subscribeConfig = (SubscribeConfig) msg.obj;
+
+                    waitForResponse = updateSubscribeLocal(mCurrentTransactionId, clientId,
+                            sessionId, subscribeConfig);
+                    break;
+                }
+                case COMMAND_TYPE_ENQUEUE_SEND_MESSAGE: {
+                    if (VDBG) {
+                        Log.v(TAG, "processCommand: ENQUEUE_SEND_MESSAGE - messageId="
+                                + msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID)
+                                + ", mSendArrivalSequenceCounter=" + mSendArrivalSequenceCounter);
+                    }
+                    Message sendMsg = obtainMessage(msg.what);
+                    sendMsg.copyFrom(msg);
+                    sendMsg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ,
+                            mSendArrivalSequenceCounter);
+                    mHostQueuedSendMessages.put(mSendArrivalSequenceCounter, sendMsg);
+                    mSendArrivalSequenceCounter++;
+                    waitForResponse = false;
+
+                    if (!mSendQueueBlocked) {
+                        transmitNextMessage();
+                    }
+
+                    break;
+                }
+                case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE: {
+                    if (mSendQueueBlocked || mHostQueuedSendMessages.size() == 0) {
+                        if (VDBG) {
+                            Log.v(TAG, "processCommand: SEND_TOP_OF_QUEUE_MESSAGE - blocked or "
+                                    + "empty host queue");
+                        }
+                        waitForResponse = false;
+                    } else {
+                        if (VDBG) {
+                            Log.v(TAG, "processCommand: SEND_TOP_OF_QUEUE_MESSAGE - "
+                                    + "sendArrivalSequenceCounter="
+                                    + mHostQueuedSendMessages.keyAt(0));
+                        }
+                        Message sendMessage = mHostQueuedSendMessages.valueAt(0);
+                        mHostQueuedSendMessages.removeAt(0);
+
+                        Bundle data = sendMessage.getData();
+                        int clientId = sendMessage.arg2;
+                        int sessionId = sendMessage.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID);
+                        int peerId = data.getInt(MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID);
+                        byte[] message = data.getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE);
+                        int messageId = data.getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID);
+                        int messageLength = data.getInt(MESSAGE_BUNDLE_KEY_MESSAGE_LENGTH);
+
+                        msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_SENT_MESSAGE, sendMessage);
+
+                        waitForResponse = sendFollowonMessageLocal(mCurrentTransactionId, clientId,
+                                sessionId, peerId, message, messageLength, messageId);
+                    }
+                    break;
+                }
+                case COMMAND_TYPE_ENABLE_USAGE:
+                    enableUsageLocal();
+                    waitForResponse = false;
+                    break;
+                case COMMAND_TYPE_DISABLE_USAGE:
+                    disableUsageLocal();
+                    waitForResponse = false;
+                    break;
+                case COMMAND_TYPE_START_RANGING: {
+                    Bundle data = msg.getData();
+
+                    int clientId = msg.arg2;
+                    RttManager.RttParams[] params = (RttManager.RttParams[]) msg.obj;
+                    int sessionId = data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID);
+                    int rangingId = data.getInt(MESSAGE_BUNDLE_KEY_RANGING_ID);
+
+                    startRangingLocal(clientId, sessionId, params, rangingId);
+                    waitForResponse = false;
+                    break;
+                }
+                case COMMAND_TYPE_GET_CAPABILITIES:
+                    if (mCapabilities == null) {
+                        waitForResponse = WifiNanNative.getInstance().getCapabilities(
+                                mCurrentTransactionId);
+                    } else {
+                        if (VDBG) {
+                            Log.v(TAG, "COMMAND_TYPE_GET_CAPABILITIES: already have capabilities - "
+                                    + "skipping");
+                        }
+                        waitForResponse = false;
+                    }
+                    break;
+                case COMMAND_TYPE_CREATE_ALL_DATA_PATH_INTERFACES:
+                    mDataPathMgr.createAllInterfaces();
+                    waitForResponse = false;
+                    break;
+                case COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES:
+                    mDataPathMgr.deleteAllInterfaces();
+                    waitForResponse = false;
+                    break;
+                case COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE:
+                    waitForResponse = WifiNanNative.getInstance().createNanNetworkInterface(
+                            mCurrentTransactionId, (String) msg.obj);
+                    break;
+                case COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE:
+                    waitForResponse = WifiNanNative.getInstance().deleteNanNetworkInterface(
+                            mCurrentTransactionId, (String) msg.obj);
+                    break;
+                case COMMAND_TYPE_INITIATE_DATA_PATH_SETUP: {
+                    Bundle data = msg.getData();
+
+                    String networkSpecifier = (String) msg.obj;
+
+                    int peerId = data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID);
+                    int channelRequestType = data.getInt(MESSAGE_BUNDLE_KEY_CHANNEL_REQ_TYPE);
+                    int channel = data.getInt(MESSAGE_BUNDLE_KEY_CHANNEL);
+                    byte[] peer = data.getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS);
+                    String interfaceName = data.getString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME);
+                    byte[] token = data.getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE);
+
+                    waitForResponse = initiateDataPathSetupLocal(mCurrentTransactionId, peerId,
+                            channelRequestType, channel, peer, interfaceName, token);
+
+                    if (waitForResponse) {
+                        WakeupMessage timeout = new WakeupMessage(mContext, getHandler(),
+                                HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG, MESSAGE_TYPE_DATA_PATH_TIMEOUT,
+                                0, 0, networkSpecifier);
+                        mDataPathConfirmTimeoutMessages.put(networkSpecifier, timeout);
+                        timeout.schedule(
+                                SystemClock.elapsedRealtime() + NAN_WAIT_FOR_DP_CONFIRM_TIMEOUT);
+                    }
+                    break;
+                }
+                case COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST: {
+                    Bundle data = msg.getData();
+
+                    int ndpId = msg.arg2;
+                    boolean accept = (boolean) msg.obj;
+                    String interfaceName = data.getString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME);
+                    String token = data.getString(MESSAGE_BUNDLE_KEY_MESSAGE);
+
+                    waitForResponse = respondToDataPathRequestLocal(mCurrentTransactionId, accept,
+                            ndpId, interfaceName, token);
+
+                    break;
+                }
+                case COMMAND_TYPE_END_DATA_PATH:
+                    waitForResponse = endDataPathLocal(mCurrentTransactionId, msg.arg2);
+                    break;
+                default:
+                    waitForResponse = false;
+                    Log.wtf(TAG, "processCommand: this isn't a COMMAND -- msg=" + msg);
+                    /* fall-through */
+            }
+
+            if (!waitForResponse) {
+                mCurrentTransactionId = TRANSACTION_ID_IGNORE;
+            } else {
+                mCurrentCommand = obtainMessage(msg.what);
+                mCurrentCommand.copyFrom(msg);
+            }
+
+            return waitForResponse;
+        }
+
+        private void processResponse(Message msg) {
+            if (VDBG) {
+                Log.v(TAG, "processResponse: msg=" + msg);
+            }
+
+            if (mCurrentCommand == null) {
+                Log.wtf(TAG, "processResponse: no existing command stored!? msg=" + msg);
+                mCurrentTransactionId = TRANSACTION_ID_IGNORE;
+                return;
+            }
+
+            switch (msg.arg1) {
+                case RESPONSE_TYPE_ON_CONFIG_SUCCESS:
+                    onConfigCompletedLocal(mCurrentCommand);
+                    break;
+                case RESPONSE_TYPE_ON_CONFIG_FAIL: {
+                    int reason = (Integer) msg.obj;
+
+                    onConfigFailedLocal(mCurrentCommand, reason);
+                    break;
+                }
+                case RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS: {
+                    int pubSubId = (Integer) msg.obj;
+                    boolean isPublish = msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE);
+
+                    onSessionConfigSuccessLocal(mCurrentCommand, pubSubId, isPublish);
+                    break;
+                }
+                case RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL: {
+                    int reason = (Integer) msg.obj;
+                    boolean isPublish = msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE);
+
+                    onSessionConfigFailLocal(mCurrentCommand, isPublish, reason);
+                    break;
+                }
+                case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS: {
+                    Message sentMessage = mCurrentCommand.getData().getParcelable(
+                            MESSAGE_BUNDLE_KEY_SENT_MESSAGE);
+                    sentMessage.getData().putLong(MESSAGE_BUNDLE_KEY_SEND_MESSAGE_ENQUEUE_TIME,
+                            SystemClock.elapsedRealtime());
+                    mFwQueuedSendMessages.put(mCurrentTransactionId, sentMessage);
+                    updateSendMessageTimeout();
+                    if (!mSendQueueBlocked) {
+                        transmitNextMessage();
+                    }
+
+                    if (VDBG) {
+                        Log.v(TAG, "processResponse: ON_MESSAGE_SEND_QUEUED_SUCCESS - arrivalSeq="
+                                + sentMessage.getData().getInt(
+                                MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ));
+                    }
+                    break;
+                }
+                case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL: {
+                    if (VDBG) {
+                        Log.v(TAG, "processResponse: ON_MESSAGE_SEND_QUEUED_FAIL - blocking!");
+                    }
+                    // TODO: b/29459286 - once there's a unique code for "queue is full" use it!
+                    int reason = (Integer) msg.obj;
+
+                    Message sentMessage = mCurrentCommand.getData().getParcelable(
+                            MESSAGE_BUNDLE_KEY_SENT_MESSAGE);
+                    int arrivalSeq = sentMessage.getData().getInt(
+                            MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ);
+                    mHostQueuedSendMessages.put(arrivalSeq, sentMessage);
+                    mSendQueueBlocked = true;
+
+                    if (VDBG) {
+                        Log.v(TAG,
+                                "processResponse: ON_MESSAGE_SEND_QUEUED_FAIL - arrivalSeq="
+                                        + arrivalSeq + " -- blocking");
+                    }
+                    break;
+                }
+                case RESPONSE_TYPE_ON_CAPABILITIES_UPDATED: {
+                    onCapabilitiesUpdatedResponseLocal((WifiNanNative.Capabilities) msg.obj);
+                    break;
+                }
+                case RESPONSE_TYPE_ON_CREATE_INTERFACE:
+                    onCreateDataPathInterfaceResponseLocal(mCurrentCommand,
+                            msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG),
+                            msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE));
+                    break;
+                case RESPONSE_TYPE_ON_DELETE_INTERFACE:
+                    onDeleteDataPathInterfaceResponseLocal(mCurrentCommand,
+                            msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG),
+                            msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE));
+                    break;
+                case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS:
+                    onInitiateDataPathResponseSuccessLocal(mCurrentCommand, (int) msg.obj);
+                    break;
+                case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL:
+                    onInitiateDataPathResponseFailLocal(mCurrentCommand, (int) msg.obj);
+                    break;
+                case RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST:
+                    onRespondToDataPathSetupRequestResponseLocal(mCurrentCommand,
+                            msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG),
+                            msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE));
+                    break;
+                case RESPONSE_TYPE_ON_END_DATA_PATH:
+                    onEndPathEndResponseLocal(mCurrentCommand,
+                            msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG),
+                            msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE));
+                    break;
+                default:
+                    Log.wtf(TAG, "processResponse: this isn't a RESPONSE -- msg=" + msg);
+                    mCurrentCommand = null;
+                    mCurrentTransactionId = TRANSACTION_ID_IGNORE;
+                    return;
+            }
+
+            mCurrentCommand = null;
+            mCurrentTransactionId = TRANSACTION_ID_IGNORE;
+        }
+
+        private void processTimeout(Message msg) {
+            if (VDBG) {
+                Log.v(TAG, "processTimeout: msg=" + msg);
+            }
+
+            if (mCurrentCommand == null) {
+                Log.wtf(TAG, "processTimeout: no existing command stored!? msg=" + msg);
+                mCurrentTransactionId = TRANSACTION_ID_IGNORE;
+                return;
+            }
+
+            /*
+             * Only have to handle those COMMANDs which wait for a response.
+             */
+            switch (msg.arg1) {
+                case COMMAND_TYPE_CONNECT: {
+                    onConfigFailedLocal(mCurrentCommand, WifiNanEventCallback.REASON_OTHER);
+                    break;
+                }
+                case COMMAND_TYPE_DISCONNECT: {
+                    /*
+                     * Will only get here on DISCONNECT if was downgrading. The
+                     * callback will do a NOP - but should still call it.
+                     */
+                    onConfigFailedLocal(mCurrentCommand, WifiNanEventCallback.REASON_OTHER);
+                    break;
+                }
+                case COMMAND_TYPE_TERMINATE_SESSION: {
+                    Log.wtf(TAG, "processTimeout: TERMINATE_SESSION - shouldn't be waiting!");
+                    break;
+                }
+                case COMMAND_TYPE_PUBLISH: {
+                    onSessionConfigFailLocal(mCurrentCommand, true,
+                            WifiNanSessionCallback.REASON_OTHER);
+                    break;
+                }
+                case COMMAND_TYPE_UPDATE_PUBLISH: {
+                    onSessionConfigFailLocal(mCurrentCommand, true,
+                            WifiNanSessionCallback.REASON_OTHER);
+                    break;
+                }
+                case COMMAND_TYPE_SUBSCRIBE: {
+                    onSessionConfigFailLocal(mCurrentCommand, false,
+                            WifiNanSessionCallback.REASON_OTHER);
+                    break;
+                }
+                case COMMAND_TYPE_UPDATE_SUBSCRIBE: {
+                    onSessionConfigFailLocal(mCurrentCommand, false,
+                            WifiNanSessionCallback.REASON_OTHER);
+                    break;
+                }
+                case COMMAND_TYPE_ENQUEUE_SEND_MESSAGE: {
+                    Log.wtf(TAG, "processTimeout: ENQUEUE_SEND_MESSAGE - shouldn't be waiting!");
+                    break;
+                }
+                case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE: {
+                    Message sentMessage = mCurrentCommand.getData().getParcelable(
+                            MESSAGE_BUNDLE_KEY_SENT_MESSAGE);
+                    onMessageSendFailLocal(sentMessage, WifiNanSessionCallback.REASON_TX_FAIL);
+                    mSendQueueBlocked = false;
+                    transmitNextMessage();
+                    break;
+                }
+                case COMMAND_TYPE_ENABLE_USAGE:
+                    Log.wtf(TAG, "processTimeout: ENABLE_USAGE - shouldn't be waiting!");
+                    break;
+                case COMMAND_TYPE_DISABLE_USAGE:
+                    Log.wtf(TAG, "processTimeout: DISABLE_USAGE - shouldn't be waiting!");
+                    break;
+                case COMMAND_TYPE_START_RANGING:
+                    Log.wtf(TAG, "processTimeout: START_RANGING - shouldn't be waiting!");
+                    break;
+                case COMMAND_TYPE_GET_CAPABILITIES:
+                    Log.e(TAG,
+                            "processTimeout: GET_CAPABILITIES timed-out - strange, will try again"
+                                    + " when next enabled!?");
+                    break;
+                case COMMAND_TYPE_CREATE_ALL_DATA_PATH_INTERFACES:
+                    Log.wtf(TAG,
+                            "processTimeout: CREATE_ALL_DATA_PATH_INTERFACES - shouldn't be "
+                                    + "waiting!");
+                    break;
+                case COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES:
+                    Log.wtf(TAG,
+                            "processTimeout: DELETE_ALL_DATA_PATH_INTERFACES - shouldn't be "
+                                    + "waiting!");
+                    break;
+                case COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE:
+                    // TODO: fix status: timeout
+                    onCreateDataPathInterfaceResponseLocal(mCurrentCommand, false, 0);
+                    break;
+                case COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE:
+                    // TODO: fix status: timeout
+                    onDeleteDataPathInterfaceResponseLocal(mCurrentCommand, false, 0);
+                    break;
+                case COMMAND_TYPE_INITIATE_DATA_PATH_SETUP:
+                    // TODO: fix status: timeout
+                    onInitiateDataPathResponseFailLocal(mCurrentCommand, 0);
+                    break;
+                case COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST:
+                    // TODO: fix status: timeout
+                    onRespondToDataPathSetupRequestResponseLocal(mCurrentCommand, false, 0);
+                    break;
+                case COMMAND_TYPE_END_DATA_PATH:
+                    // TODO: fix status: timeout
+                    onEndPathEndResponseLocal(mCurrentCommand, false, 0);
+                    break;
+                default:
+                    Log.wtf(TAG, "processTimeout: this isn't a COMMAND -- msg=" + msg);
+                    /* fall-through */
+            }
+
+            mCurrentCommand = null;
+            mCurrentTransactionId = TRANSACTION_ID_IGNORE;
+        }
+
+        private void updateSendMessageTimeout() {
+            if (VDBG) {
+                Log.v(TAG, "updateSendMessageTimeout: mHostQueuedSendMessages.size()="
+                        + mHostQueuedSendMessages.size() + ", mFwQueuedSendMessages.size()="
+                        + mFwQueuedSendMessages.size() + ", mSendQueueBlocked="
+                        + mSendQueueBlocked);
+            }
+            Iterator<Message> it = mFwQueuedSendMessages.values().iterator();
+            if (it.hasNext()) {
+                /*
+                 * Schedule timeout based on the first message in the queue (which is the earliest
+                 * submitted message). Timeout = queuing time + timeout constant.
+                 */
+                Message msg = it.next();
+                mSendMessageTimeoutMessage.schedule(
+                        msg.getData().getLong(MESSAGE_BUNDLE_KEY_SEND_MESSAGE_ENQUEUE_TIME)
+                        + NAN_SEND_MESSAGE_TIMEOUT);
+            } else {
+                mSendMessageTimeoutMessage.cancel();
+            }
+        }
+
+        private void processSendMessageTimeout() {
+            if (VDBG) {
+                Log.v(TAG, "processSendMessageTimeout: mHostQueuedSendMessages.size()="
+                        + mHostQueuedSendMessages.size() + ", mFwQueuedSendMessages.size()="
+                        + mFwQueuedSendMessages.size() + ", mSendQueueBlocked="
+                        + mSendQueueBlocked);
+
+            }
+            /*
+             * Note: using 'first' to always time-out (remove) at least 1 notification (partially)
+             * due to test code needs: there's no way to mock elapsedRealtime(). TODO: replace with
+             * injected getClock() once moved off of mmwd.
+             */
+            boolean first = true;
+            long currentTime = SystemClock.elapsedRealtime();
+            Iterator<Map.Entry<Short, Message>> it = mFwQueuedSendMessages.entrySet().iterator();
+            while (it.hasNext()) {
+                Map.Entry<Short, Message> entry = it.next();
+                short transactionId = entry.getKey();
+                Message message = entry.getValue();
+                long messageEnqueueTime = message.getData().getLong(
+                        MESSAGE_BUNDLE_KEY_SEND_MESSAGE_ENQUEUE_TIME);
+                if (first || messageEnqueueTime + NAN_SEND_MESSAGE_TIMEOUT <= currentTime) {
+                    if (VDBG) {
+                        Log.v(TAG, "processSendMessageTimeout: expiring - transactionId="
+                                + transactionId + ", message=" + message
+                                + ", due to messageEnqueueTime=" + messageEnqueueTime
+                                + ", currentTime=" + currentTime);
+                    }
+                    onMessageSendFailLocal(message, WifiNanSessionCallback.REASON_TX_FAIL);
+                    it.remove();
+                    first = false;
+                } else {
+                    break;
+                }
+            }
+            updateSendMessageTimeout();
+            mSendQueueBlocked = false;
+            transmitNextMessage();
+        }
+
+        @Override
+        protected String getLogRecString(Message msg) {
+            StringBuilder sb = new StringBuilder(WifiNanStateManager.messageToString(msg));
+
+            if (msg.what == MESSAGE_TYPE_COMMAND
+                    && mCurrentTransactionId != TRANSACTION_ID_IGNORE) {
+                sb.append(" (Transaction ID=").append(mCurrentTransactionId).append(")");
+            }
+
+            return sb.toString();
+        }
+
+        @Override
+        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            pw.println("WifiNanStateMachine:");
+            pw.println("  mNextTransactionId: " + mNextTransactionId);
+            pw.println("  mNextSessionId: " + mNextSessionId);
+            pw.println("  mCurrentCommand: " + mCurrentCommand);
+            pw.println("  mCurrentTransaction: " + mCurrentTransactionId);
+            pw.println("  mSendQueueBlocked: " + mSendQueueBlocked);
+            pw.println("  mSendArrivalSequenceCounter: " + mSendArrivalSequenceCounter);
+            pw.println("  mHostQueuedSendMessages: [" + mHostQueuedSendMessages + "]");
+            pw.println("  mFwQueuedSendMessages: [" + mFwQueuedSendMessages + "]");
+            super.dump(fd, pw, args);
+        }
+    }
+
+    private void sendNanStateChangedBroadcast(boolean enabled) {
+        if (VDBG) {
+            Log.v(TAG, "sendNanStateChangedBroadcast: enabled=" + enabled);
+        }
+        final Intent intent = new Intent(WifiNanManager.WIFI_NAN_STATE_CHANGED_ACTION);
+        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        if (enabled) {
+            intent.putExtra(WifiNanManager.EXTRA_WIFI_STATE, WifiNanManager.WIFI_NAN_STATE_ENABLED);
+        } else {
+            intent.putExtra(WifiNanManager.EXTRA_WIFI_STATE,
+                    WifiNanManager.WIFI_NAN_STATE_DISABLED);
+        }
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
     }
 
     /*
-     * Transaction management classes & operations
+     * COMMANDS
      */
 
-    // non-synchronized (should be ok as long as only used from NanStateManager,
-    // NanClientState, and NanSessionState)
-    /* package */ short createNextTransactionId() {
-        return mNextTransactionId++;
-    }
-
-    private static class TransactionInfoBase {
-        short mTransactionId;
-    }
-
-    private static class TransactionInfoSession extends TransactionInfoBase {
-        public WifiNanClientState mClient;
-        public WifiNanSessionState mSession;
-    }
-
-    private static class TransactionInfoMessage extends TransactionInfoSession {
-        public int mMessageId;
-    }
-
-    private static class TransactionInfoConfig extends TransactionInfoBase {
-        public ConfigRequest mConfig;
-    }
-
-    private void allocateAndRegisterTransactionId(TransactionInfoBase info) {
-        info.mTransactionId = createNextTransactionId();
-
-        mPendingResponses.put(info.mTransactionId, info);
-    }
-
-    private void fillInTransactionInfoSession(TransactionInfoSession info, int uid,
-            int sessionId) {
-        WifiNanClientState client = mClients.get(uid);
-        if (client == null) {
-            throw new IllegalStateException(
-                    "getAndRegisterTransactionId: no client exists for uid=" + uid);
-        }
-        info.mClient = client;
-
-        WifiNanSessionState session = info.mClient.getSession(sessionId);
-        if (session == null) {
-            throw new IllegalStateException(
-                    "getAndRegisterSessionTransactionId: no session exists for uid=" + uid
-                            + ", sessionId=" + sessionId);
-        }
-        info.mSession = session;
-    }
-
-    private TransactionInfoBase createTransactionInfo() {
-        TransactionInfoBase info = new TransactionInfoBase();
-        allocateAndRegisterTransactionId(info);
-        return info;
-    }
-
-    private TransactionInfoSession createTransactionInfoSession(int uid, int sessionId) {
-        TransactionInfoSession info = new TransactionInfoSession();
-        fillInTransactionInfoSession(info, uid, sessionId);
-        allocateAndRegisterTransactionId(info);
-        return info;
-    }
-
-    private TransactionInfoMessage createTransactionInfoMessage(int uid, int sessionId,
-            int messageId) {
-        TransactionInfoMessage info = new TransactionInfoMessage();
-        fillInTransactionInfoSession(info, uid, sessionId);
-        info.mMessageId = messageId;
-        allocateAndRegisterTransactionId(info);
-        return info;
-    }
-
-    private TransactionInfoConfig createTransactionInfoConfig(ConfigRequest configRequest) {
-        TransactionInfoConfig info = new TransactionInfoConfig();
-        info.mConfig = configRequest;
-        allocateAndRegisterTransactionId(info);
-        return info;
-    }
-
-    private TransactionInfoBase getAndRemovePendingResponseTransactionInfo(short transactionId) {
-        TransactionInfoBase transInfo = mPendingResponses.get(transactionId);
-        if (transInfo != null) {
-            mPendingResponses.remove(transactionId);
-        }
-
-        return transInfo;
-    }
-
-    private WifiNanSessionState getNanSessionStateForPubSubId(int pubSubId) {
-        for (int i = 0; i < mClients.size(); ++i) {
-            WifiNanSessionState session = mClients.valueAt(i)
-                    .getNanSessionStateForPubSubId(pubSubId);
-            if (session != null) {
-                return session;
-            }
-        }
-
-        return null;
-    }
-
-    /*
-     * Actions (calls from API to service)
-     */
-    private void connectLocal(int uid, IWifiNanEventListener listener, int events) {
+    private boolean connectLocal(short transactionId, int clientId, int uid,
+            IWifiNanEventCallback callback, ConfigRequest configRequest) {
         if (VDBG) {
-            Log.v(TAG, "connect(): uid=" + uid + ", listener=" + listener + ", events=" + events);
+            Log.v(TAG, "connectLocal(): transactionId=" + transactionId + ", clientId=" + clientId
+                    + ", uid=" + uid + ", callback=" + callback + ", configRequest="
+                    + configRequest);
         }
 
-        if (mClients.get(uid) != null) {
-            Log.e(TAG, "connect: entry already exists for uid=" + uid);
-            return;
+        if (!mUsageEnabled) {
+            Log.w(TAG, "connect(): called with mUsageEnabled=false");
+            return false;
         }
 
-        WifiNanClientState client = new WifiNanClientState(uid, listener, events);
-        mClients.put(uid, client);
+        if (mClients.get(clientId) != null) {
+            Log.e(TAG, "connectLocal: entry already exists for clientId=" + clientId);
+        }
+
+        if (mCurrentNanConfiguration != null
+                && !mCurrentNanConfiguration.equalsOnTheAir(configRequest)) {
+            try {
+                callback.onConnectFail(
+                        WifiNanEventCallback.REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG);
+            } catch (RemoteException e) {
+                Log.w(TAG, "connectLocal onConnectFail(): RemoteException (FYI): " + e);
+            }
+            return false;
+        }
+
+        ConfigRequest merged = mergeConfigRequests(configRequest);
+        if (mCurrentNanConfiguration != null && mCurrentNanConfiguration.equals(merged)) {
+            try {
+                callback.onConnectSuccess();
+            } catch (RemoteException e) {
+                Log.w(TAG, "connectLocal onConnectSuccess(): RemoteException (FYI): " + e);
+            }
+            WifiNanClientState client = new WifiNanClientState(clientId, uid, callback,
+                    configRequest);
+            client.onInterfaceAddressChange(mCurrentDiscoveryInterfaceMac);
+            mClients.append(clientId, client);
+            return false;
+        }
+
+        return WifiNanNative.getInstance().enableAndConfigure(transactionId, merged,
+                mCurrentNanConfiguration == null);
     }
 
-    private void disconnectLocal(int uid) {
+    private boolean disconnectLocal(short transactionId, int clientId) {
         if (VDBG) {
-            Log.v(TAG, "disconnect(): uid=" + uid);
+            Log.v(TAG,
+                    "disconnectLocal(): transactionId=" + transactionId + ", clientId=" + clientId);
         }
 
-        WifiNanClientState client = mClients.get(uid);
-        mClients.delete(uid);
-
+        WifiNanClientState client = mClients.get(clientId);
         if (client == null) {
-            Log.e(TAG, "disconnect: no entry for uid=" + uid);
-            return;
+            Log.e(TAG, "disconnectLocal: no entry for clientId=" + clientId);
+            return false;
         }
-
-        List<Integer> toRemove = new ArrayList<>();
-        for (int i = 0; i < mPendingResponses.size(); ++i) {
-            TransactionInfoBase info = mPendingResponses.valueAt(i);
-            if (!(info instanceof TransactionInfoSession)) {
-                continue;
-            }
-            if (((TransactionInfoSession) info).mClient.getUid() == uid) {
-                toRemove.add(i);
-            }
-        }
-        for (Integer id : toRemove) {
-            mPendingResponses.removeAt(id);
-        }
-
+        mClients.delete(clientId);
         client.destroy();
 
         if (mClients.size() == 0) {
-            WifiNanNative.getInstance().disable(createTransactionInfo().mTransactionId);
-            return;
+            mCurrentNanConfiguration = null;
+            WifiNanNative.getInstance().disable((short) 0);
+            return false;
         }
 
-        ConfigRequest merged = mergeConfigRequests();
+        ConfigRequest merged = mergeConfigRequests(null);
+        if (merged.equals(mCurrentNanConfiguration)) {
+            return false;
+        }
 
-        WifiNanNative.getInstance()
-                .enableAndConfigure(createTransactionInfoConfig(merged).mTransactionId, merged);
+        return WifiNanNative.getInstance().enableAndConfigure(transactionId, merged, false);
     }
 
-    private void requestConfigLocal(int uid, ConfigRequest configRequest) {
+    private void terminateSessionLocal(int clientId, int sessionId) {
         if (VDBG) {
-            Log.v(TAG, "requestConfig(): uid=" + uid + ", configRequest=" + configRequest);
+            Log.v(TAG,
+                    "terminateSessionLocal(): clientId=" + clientId + ", sessionId=" + sessionId);
         }
 
-        WifiNanClientState client = mClients.get(uid);
+        WifiNanClientState client = mClients.get(clientId);
         if (client == null) {
-            Log.e(TAG, "requestConfig: no client exists for uid=" + uid);
+            Log.e(TAG, "terminateSession: no client exists for clientId=" + clientId);
             return;
         }
 
-        client.setConfigRequest(configRequest);
-
-        ConfigRequest merged = mergeConfigRequests();
-
-        WifiNanNative.getInstance()
-                .enableAndConfigure(createTransactionInfoConfig(merged).mTransactionId, merged);
+        client.terminateSession(sessionId);
     }
 
-    private void createSessionLocal(int uid, int sessionId, IWifiNanSessionListener listener,
-            int events) {
+    private boolean publishLocal(short transactionId, int clientId, PublishConfig publishConfig,
+            IWifiNanSessionCallback callback) {
         if (VDBG) {
-            Log.v(TAG, "createSession(): uid=" + uid + ", sessionId=" + sessionId + ", listener="
-                    + listener + ", events=" + events);
+            Log.v(TAG, "publishLocal(): transactionId=" + transactionId + ", clientId=" + clientId
+                    + ", publishConfig=" + publishConfig + ", callback=" + callback);
         }
 
-        WifiNanClientState client = mClients.get(uid);
+        WifiNanClientState client = mClients.get(clientId);
         if (client == null) {
-            Log.e(TAG, "createSession: no client exists for uid=" + uid);
-            return;
+            Log.e(TAG, "publishLocal: no client exists for clientId=" + clientId);
+            return false;
         }
 
-        client.createSession(sessionId, listener, events);
+        return WifiNanNative.getInstance().publish(transactionId, 0, publishConfig);
     }
 
-    private void destroySessionLocal(int uid, int sessionId) {
+    private boolean updatePublishLocal(short transactionId, int clientId, int sessionId,
+            PublishConfig publishConfig) {
         if (VDBG) {
-            Log.v(TAG, "destroySession(): uid=" + uid + ", sessionId=" + sessionId);
+            Log.v(TAG, "updatePublishLocal(): transactionId=" + transactionId + ", clientId="
+                    + clientId + ", sessionId=" + sessionId + ", publishConfig=" + publishConfig);
         }
 
-        WifiNanClientState client = mClients.get(uid);
+        WifiNanClientState client = mClients.get(clientId);
         if (client == null) {
-            Log.e(TAG, "destroySession: no client exists for uid=" + uid);
+            Log.e(TAG, "updatePublishLocal: no client exists for clientId=" + clientId);
+            return false;
+        }
+
+        WifiNanSessionState session = client.getSession(sessionId);
+        if (session == null) {
+            Log.e(TAG, "updatePublishLocal: no session exists for clientId=" + clientId
+                    + ", sessionId=" + sessionId);
+            return false;
+        }
+
+        return session.updatePublish(transactionId, publishConfig);
+    }
+
+    private boolean subscribeLocal(short transactionId, int clientId,
+            SubscribeConfig subscribeConfig, IWifiNanSessionCallback callback) {
+        if (VDBG) {
+            Log.v(TAG, "subscribeLocal(): transactionId=" + transactionId + ", clientId=" + clientId
+                    + ", subscribeConfig=" + subscribeConfig + ", callback=" + callback);
+        }
+
+        WifiNanClientState client = mClients.get(clientId);
+        if (client == null) {
+            Log.e(TAG, "subscribeLocal: no client exists for clientId=" + clientId);
+            return false;
+        }
+
+        return WifiNanNative.getInstance().subscribe(transactionId, 0, subscribeConfig);
+    }
+
+    private boolean updateSubscribeLocal(short transactionId, int clientId, int sessionId,
+            SubscribeConfig subscribeConfig) {
+        if (VDBG) {
+            Log.v(TAG,
+                    "updateSubscribeLocal(): transactionId=" + transactionId + ", clientId="
+                            + clientId + ", sessionId=" + sessionId + ", subscribeConfig="
+                            + subscribeConfig);
+        }
+
+        WifiNanClientState client = mClients.get(clientId);
+        if (client == null) {
+            Log.e(TAG, "updateSubscribeLocal: no client exists for clientId=" + clientId);
+            return false;
+        }
+
+        WifiNanSessionState session = client.getSession(sessionId);
+        if (session == null) {
+            Log.e(TAG, "updateSubscribeLocal: no session exists for clientId=" + clientId
+                    + ", sessionId=" + sessionId);
+            return false;
+        }
+
+        return session.updateSubscribe(transactionId, subscribeConfig);
+    }
+
+    private boolean sendFollowonMessageLocal(short transactionId, int clientId, int sessionId,
+            int peerId, byte[] message, int messageLength, int messageId) {
+        if (VDBG) {
+            Log.v(TAG,
+                    "sendFollowonMessageLocal(): transactionId=" + transactionId + ", clientId="
+                            + clientId + ", sessionId=" + sessionId + ", peerId=" + peerId
+                            + ", messageLength=" + messageLength + ", messageId=" + messageId);
+        }
+
+        WifiNanClientState client = mClients.get(clientId);
+        if (client == null) {
+            Log.e(TAG, "sendFollowonMessageLocal: no client exists for clientId=" + clientId);
+            return false;
+        }
+
+        WifiNanSessionState session = client.getSession(sessionId);
+        if (session == null) {
+            Log.e(TAG, "sendFollowonMessageLocal: no session exists for clientId=" + clientId
+                    + ", sessionId=" + sessionId);
+            return false;
+        }
+
+        return session.sendMessage(transactionId, peerId, message, messageLength, messageId);
+    }
+
+    private void enableUsageLocal() {
+        if (mUsageEnabled) {
             return;
         }
 
-        List<Integer> toRemove = new ArrayList<>();
-        for (int i = 0; i < mPendingResponses.size(); ++i) {
-            TransactionInfoBase info = mPendingResponses.valueAt(i);
-            if (!(info instanceof TransactionInfoSession)) {
-                continue;
-            }
-            TransactionInfoSession infoSession = (TransactionInfoSession) info;
-            if (infoSession.mClient.getUid() == uid
-                    && infoSession.mSession.getSessionId() == sessionId) {
-                toRemove.add(i);
+        mUsageEnabled = true;
+        getCapabilities();
+        createAllDataPathInterfaces();
+        sendNanStateChangedBroadcast(true);
+    }
+
+    private void disableUsageLocal() {
+        if (!mUsageEnabled) {
+            return;
+        }
+
+        mUsageEnabled = false;
+        WifiNanNative.getInstance().disable((short) 0);
+        WifiNanNative.getInstance().deInitNan();
+        onNanDownLocal();
+
+        deleteAllDataPathInterfaces();
+        sendNanStateChangedBroadcast(false);
+    }
+
+    private void startRangingLocal(int clientId, int sessionId, RttManager.RttParams[] params,
+                                   int rangingId) {
+        if (VDBG) {
+            Log.v(TAG, "startRangingLocal: clientId=" + clientId + ", sessionId=" + sessionId
+                    + ", parms=" + Arrays.toString(params) + ", rangingId=" + rangingId);
+        }
+
+        WifiNanClientState client = mClients.get(clientId);
+        if (client == null) {
+            Log.e(TAG, "startRangingLocal: no client exists for clientId=" + clientId);
+            return;
+        }
+
+        WifiNanSessionState session = client.getSession(sessionId);
+        if (session == null) {
+            Log.e(TAG, "startRangingLocal: no session exists for clientId=" + clientId
+                    + ", sessionId=" + sessionId);
+            client.onRangingFailure(rangingId, RttManager.REASON_INVALID_REQUEST,
+                    "Invalid session ID");
+            return;
+        }
+
+        for (RttManager.RttParams param : params) {
+            String peerIdStr = param.bssid;
+            try {
+                param.bssid = session.getMac(Integer.parseInt(peerIdStr), ":");
+                if (param.bssid == null) {
+                    Log.d(TAG, "startRangingLocal: no MAC address for peer ID=" + peerIdStr);
+                    param.bssid = "";
+                }
+            } catch (NumberFormatException e) {
+                Log.e(TAG, "startRangingLocal: invalid peer ID specification (in bssid field): '"
+                        + peerIdStr + "'");
+                param.bssid = "";
             }
         }
-        for (Integer id : toRemove) {
-            mPendingResponses.removeAt(id);
-        }
 
-        client.destroySession(sessionId);
+        mRtt.startRanging(rangingId, client, params);
     }
 
-    private void publishLocal(int uid, int sessionId, PublishData publishData,
-            PublishSettings publishSettings) {
+    private boolean initiateDataPathSetupLocal(short transactionId, int peerId,
+            int channelRequestType, int channel, byte[] peer, String interfaceName, byte[] token) {
         if (VDBG) {
-            Log.v(TAG, "publish(): uid=" + uid + ", sessionId=" + sessionId + ", data="
-                    + publishData + ", settings=" + publishSettings);
+            Log.v(TAG,
+                    "initiateDataPathSetupLocal(): transactionId=" + transactionId + ", peerId="
+                            + peerId + ", channelRequestType=" + channelRequestType + ", channel="
+                            + channel + ", peer=" + String.valueOf(HexEncoding.encode(peer))
+                            + ", interfaceName=" + interfaceName + ", token=" + token);
         }
 
-        TransactionInfoSession info = createTransactionInfoSession(uid, sessionId);
-
-        info.mSession.publish(info.mTransactionId, publishData, publishSettings);
+        return WifiNanNative.getInstance().initiateDataPath(transactionId, peerId,
+                channelRequestType, channel, peer, interfaceName, token, token.length);
     }
 
-    private void subscribeLocal(int uid, int sessionId, SubscribeData subscribeData,
-            SubscribeSettings subscribeSettings) {
+    private boolean respondToDataPathRequestLocal(short transactionId, boolean accept,
+            int ndpId, String interfaceName, String token) {
         if (VDBG) {
-            Log.v(TAG, "subscribe(): uid=" + uid + ", sessionId=" + sessionId + ", data="
-                    + subscribeData + ", settings=" + subscribeSettings);
+            Log.v(TAG,
+                    "respondToDataPathRequestLocal(): transactionId=" + transactionId + ", accept="
+                            + accept + ", ndpId=" + ndpId + ", interfaceName=" + interfaceName
+                            + ", token=" + token);
         }
 
-        TransactionInfoSession info = createTransactionInfoSession(uid, sessionId);
+        byte[] tokenBytes = token.getBytes();
 
-        info.mSession.subscribe(info.mTransactionId, subscribeData, subscribeSettings);
+        return WifiNanNative.getInstance().respondToDataPathRequest(transactionId, accept, ndpId,
+                interfaceName, tokenBytes, tokenBytes.length);
     }
 
-    private void sendFollowonMessageLocal(int uid, int sessionId, int peerId, byte[] message,
-            int messageLength, int messageId) {
+    private boolean endDataPathLocal(short transactionId, int ndpId) {
         if (VDBG) {
-            Log.v(TAG, "sendMessage(): uid=" + uid + ", sessionId=" + sessionId + ", peerId="
-                    + peerId + ", messageLength=" + messageLength + ", messageId=" + messageId);
+            Log.v(TAG,
+                    "endDataPathLocal: transactionId=" + transactionId + ", ndpId=" + ndpId);
         }
 
-        TransactionInfoMessage info = createTransactionInfoMessage(uid, sessionId, messageId);
-
-        info.mSession.sendMessage(info.mTransactionId, peerId, message, messageLength, messageId);
-    }
-
-    private void stopSessionLocal(int uid, int sessionId) {
-        if (VDBG) {
-            Log.v(TAG, "stopSession(): uid=" + uid + ", sessionId=" + sessionId);
-        }
-
-        TransactionInfoSession info = createTransactionInfoSession(uid, sessionId);
-
-        info.mSession.stop(info.mTransactionId);
+        return WifiNanNative.getInstance().endDataPath(transactionId, ndpId);
     }
 
     /*
-     * Callbacks (calls from HAL/Native to service)
+     * RESPONSES
      */
 
-    private void onCapabilitiesUpdatedLocal(short transactionId,
-            WifiNanNative.Capabilities capabilities) {
+    private void onConfigCompletedLocal(Message completedCommand) {
         if (VDBG) {
-            Log.v(TAG, "onCapabilitiesUpdatedLocal: transactionId=" + transactionId
-                    + ", capabilites=" + capabilities);
+            Log.v(TAG, "onConfigCompleted: completedCommand=" + completedCommand);
+        }
+
+        if (completedCommand.arg1 == COMMAND_TYPE_CONNECT) {
+            Bundle data = completedCommand.getData();
+
+            int clientId = completedCommand.arg2;
+            IWifiNanEventCallback callback = (IWifiNanEventCallback) completedCommand.obj;
+            ConfigRequest configRequest = (ConfigRequest) data
+                    .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG);
+            int uid = data.getInt(MESSAGE_BUNDLE_KEY_UID);
+
+            WifiNanClientState client = new WifiNanClientState(clientId, uid, callback,
+                    configRequest);
+            mClients.put(clientId, client);
+            try {
+                callback.onConnectSuccess();
+            } catch (RemoteException e) {
+                Log.w(TAG,
+                        "onConfigCompletedLocal onConnectSuccess(): RemoteException (FYI): " + e);
+            }
+            client.onInterfaceAddressChange(mCurrentDiscoveryInterfaceMac);
+        } else if (completedCommand.arg1 == COMMAND_TYPE_DISCONNECT) {
+            /*
+             * NOP (i.e. updated configuration after disconnecting a client)
+             */
+        } else {
+            Log.wtf(TAG, "onConfigCompletedLocal: unexpected completedCommand=" + completedCommand);
+            return;
+        }
+
+        mCurrentNanConfiguration = mergeConfigRequests(null);
+    }
+
+    private void onConfigFailedLocal(Message failedCommand, int reason) {
+        if (VDBG) {
+            Log.v(TAG,
+                    "onConfigFailedLocal: failedCommand=" + failedCommand + ", reason=" + reason);
+        }
+
+        if (failedCommand.arg1 == COMMAND_TYPE_CONNECT) {
+            IWifiNanEventCallback callback = (IWifiNanEventCallback) failedCommand.obj;
+
+            try {
+                callback.onConnectFail(reason);
+            } catch (RemoteException e) {
+                Log.w(TAG, "onConfigFailedLocal onConnectFail(): RemoteException (FYI): " + e);
+            }
+        } else if (failedCommand.arg1 == COMMAND_TYPE_DISCONNECT) {
+            /*
+             * NOP (tried updating configuration after disconnecting a client -
+             * shouldn't fail but there's nothing to do - the old configuration
+             * is still up-and-running).
+             */
+        } else {
+            Log.wtf(TAG, "onConfigFailedLocal: unexpected failedCommand=" + failedCommand);
+            return;
+        }
+
+    }
+
+    private void onSessionConfigSuccessLocal(Message completedCommand, int pubSubId,
+            boolean isPublish) {
+        if (VDBG) {
+            Log.v(TAG, "onSessionConfigSuccessLocal: completedCommand=" + completedCommand
+                    + ", pubSubId=" + pubSubId + ", isPublish=" + isPublish);
+        }
+
+        if (completedCommand.arg1 == COMMAND_TYPE_PUBLISH
+                || completedCommand.arg1 == COMMAND_TYPE_SUBSCRIBE) {
+            int clientId = completedCommand.arg2;
+            IWifiNanSessionCallback callback = (IWifiNanSessionCallback) completedCommand.obj;
+
+            WifiNanClientState client = mClients.get(clientId);
+            if (client == null) {
+                Log.e(TAG,
+                        "onSessionConfigSuccessLocal: no client exists for clientId=" + clientId);
+                return;
+            }
+
+            int sessionId = mSm.mNextSessionId++;
+            try {
+                callback.onSessionStarted(sessionId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "onSessionConfigSuccessLocal: onSessionStarted() RemoteException=" + e);
+                return;
+            }
+
+            WifiNanSessionState session = new WifiNanSessionState(sessionId, pubSubId, callback,
+                    isPublish);
+            client.addSession(session);
+        } else if (completedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH
+                || completedCommand.arg1 == COMMAND_TYPE_UPDATE_SUBSCRIBE) {
+            int clientId = completedCommand.arg2;
+            int sessionId = completedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID);
+
+            WifiNanClientState client = mClients.get(clientId);
+            if (client == null) {
+                Log.e(TAG,
+                        "onSessionConfigSuccessLocal: no client exists for clientId=" + clientId);
+                return;
+            }
+
+            WifiNanSessionState session = client.getSession(sessionId);
+            if (session == null) {
+                Log.e(TAG, "onSessionConfigSuccessLocal: no session exists for clientId=" + clientId
+                        + ", sessionId=" + sessionId);
+                return;
+            }
+
+            try {
+                session.getCallback().onSessionConfigSuccess();
+            } catch (RemoteException e) {
+                Log.e(TAG, "onSessionConfigSuccessLocal: onSessionConfigSuccess() RemoteException="
+                        + e);
+            }
+        } else {
+            Log.wtf(TAG,
+                    "onSessionConfigSuccessLocal: unexpected completedCommand=" + completedCommand);
+        }
+    }
+
+    private void onSessionConfigFailLocal(Message failedCommand, boolean isPublish, int reason) {
+        if (VDBG) {
+            Log.v(TAG, "onSessionConfigFailLocal: failedCommand=" + failedCommand + ", isPublish="
+                    + isPublish + ", reason=" + reason);
+        }
+
+        if (failedCommand.arg1 == COMMAND_TYPE_PUBLISH
+                || failedCommand.arg1 == COMMAND_TYPE_SUBSCRIBE) {
+            IWifiNanSessionCallback callback = (IWifiNanSessionCallback) failedCommand.obj;
+            try {
+                callback.onSessionConfigFail(reason);
+            } catch (RemoteException e) {
+                Log.w(TAG, "onSessionConfigFailLocal onSessionConfigFail(): RemoteException (FYI): "
+                        + e);
+            }
+        } else if (failedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH
+                || failedCommand.arg1 == COMMAND_TYPE_UPDATE_SUBSCRIBE) {
+            int clientId = failedCommand.arg2;
+            int sessionId = failedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID);
+
+            WifiNanClientState client = mClients.get(clientId);
+            if (client == null) {
+                Log.e(TAG, "onSessionConfigFailLocal: no client exists for clientId=" + clientId);
+                return;
+            }
+
+            WifiNanSessionState session = client.getSession(sessionId);
+            if (session == null) {
+                Log.e(TAG, "onSessionConfigFailLocal: no session exists for clientId=" + clientId
+                        + ", sessionId=" + sessionId);
+                return;
+            }
+
+            try {
+                session.getCallback().onSessionConfigFail(reason);
+            } catch (RemoteException e) {
+                Log.e(TAG, "onSessionConfigFailLocal: onSessionConfigFail() RemoteException=" + e);
+            }
+        } else {
+            Log.wtf(TAG, "onSessionConfigFailLocal: unexpected failedCommand=" + failedCommand);
+        }
+    }
+
+    private void onMessageSendSuccessLocal(Message completedCommand) {
+        if (VDBG) {
+            Log.v(TAG, "onMessageSendSuccess: completedCommand=" + completedCommand);
+        }
+
+        int clientId = completedCommand.arg2;
+        int sessionId = completedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID);
+        int messageId = completedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID);
+
+        WifiNanClientState client = mClients.get(clientId);
+        if (client == null) {
+            Log.e(TAG, "onMessageSendSuccessLocal: no client exists for clientId=" + clientId);
+            return;
+        }
+
+        WifiNanSessionState session = client.getSession(sessionId);
+        if (session == null) {
+            Log.e(TAG, "onMessageSendSuccessLocal: no session exists for clientId=" + clientId
+                    + ", sessionId=" + sessionId);
+            return;
+        }
+
+        try {
+            session.getCallback().onMessageSendSuccess(messageId);
+        } catch (RemoteException e) {
+            Log.w(TAG, "onMessageSendSuccessLocal: RemoteException (FYI): " + e);
+        }
+    }
+
+    private void onMessageSendFailLocal(Message failedCommand, int reason) {
+        if (VDBG) {
+            Log.v(TAG, "onMessageSendFail: failedCommand=" + failedCommand + ", reason=" + reason);
+        }
+
+        int clientId = failedCommand.arg2;
+        int sessionId = failedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID);
+        int messageId = failedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID);
+
+        WifiNanClientState client = mClients.get(clientId);
+        if (client == null) {
+            Log.e(TAG, "onMessageSendFailLocal: no client exists for clientId=" + clientId);
+            return;
+        }
+
+        WifiNanSessionState session = client.getSession(sessionId);
+        if (session == null) {
+            Log.e(TAG, "onMessageSendFailLocal: no session exists for clientId=" + clientId
+                    + ", sessionId=" + sessionId);
+            return;
+        }
+
+        try {
+            session.getCallback().onMessageSendFail(messageId, reason);
+        } catch (RemoteException e) {
+            Log.e(TAG, "onMessageSendFailLocal: onMessageSendFail RemoteException=" + e);
+        }
+    }
+
+    private void onCapabilitiesUpdatedResponseLocal(WifiNanNative.Capabilities capabilities) {
+        if (VDBG) {
+            Log.v(TAG, "onCapabilitiesUpdatedResponseLocal: capabilites=" + capabilities);
         }
 
         mCapabilities = capabilities;
     }
 
-    private void onConfigCompletedLocal(short transactionId) {
+    private void onCreateDataPathInterfaceResponseLocal(Message command, boolean success,
+            int reasonOnFailure) {
         if (VDBG) {
-            Log.v(TAG, "onConfigCompleted: transactionId=" + transactionId);
+            Log.v(TAG, "onCreateDataPathInterfaceResponseLocal: command=" + command + ", success="
+                    + success + ", reasonOnFailure=" + reasonOnFailure);
         }
 
-        TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId);
-        if (info == null) {
-            Log.e(TAG, "onConfigCompleted: no transaction info for transactionId=" + transactionId);
-            return;
-        }
-        if (!(info instanceof TransactionInfoConfig)) {
-            Log.e(TAG, "onConfigCompleted: invalid info structure stored for transactionId="
-                    + transactionId);
-            return;
-        }
-        TransactionInfoConfig infoConfig = (TransactionInfoConfig) info;
-
-        if (DBG) {
-            Log.d(TAG, "onConfigCompleted: request=" + infoConfig.mConfig);
-        }
-
-        for (int i = 0; i < mClients.size(); ++i) {
-            WifiNanClientState client = mClients.valueAt(i);
-            client.onConfigCompleted(infoConfig.mConfig);
+        if (success) {
+            if (DBG) {
+                Log.d(TAG, "onCreateDataPathInterfaceResponseLocal: successfully created interface "
+                        + command.obj);
+            }
+            mDataPathMgr.onInterfaceCreated((String) command.obj);
+        } else {
+            Log.e(TAG,
+                    "onCreateDataPathInterfaceResponseLocal: failed when trying to create "
+                            + "interface "
+                            + command.obj + ". Reason code=" + reasonOnFailure);
         }
     }
 
-    private void onConfigFailedLocal(short transactionId, int reason) {
+    private void onDeleteDataPathInterfaceResponseLocal(Message command, boolean success,
+            int reasonOnFailure) {
         if (VDBG) {
-            Log.v(TAG, "onEnableFailed: transactionId=" + transactionId + ", reason=" + reason);
+            Log.v(TAG, "onDeleteDataPathInterfaceResponseLocal: command=" + command + ", success="
+                    + success + ", reasonOnFailure=" + reasonOnFailure);
         }
 
-        TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId);
-        if (info == null) {
-            Log.e(TAG, "onConfigFailed: no transaction info for transactionId=" + transactionId);
-            return;
-        }
-        if (!(info instanceof TransactionInfoConfig)) {
-            Log.e(TAG, "onConfigCompleted: invalid info structure stored for transactionId="
-                    + transactionId);
-            return;
-        }
-        TransactionInfoConfig infoConfig = (TransactionInfoConfig) info;
-
-        if (DBG) {
-            Log.d(TAG, "onConfigFailed: request=" + infoConfig.mConfig);
-        }
-
-        for (int i = 0; i < mClients.size(); ++i) {
-            WifiNanClientState client = mClients.valueAt(i);
-            client.onConfigFailed(infoConfig.mConfig, reason);
+        if (success) {
+            if (DBG) {
+                Log.d(TAG, "onDeleteDataPathInterfaceResponseLocal: successfully deleted interface "
+                        + command.obj);
+            }
+            mDataPathMgr.onInterfaceDeleted((String) command.obj);
+        } else {
+            Log.e(TAG,
+                    "onDeleteDataPathInterfaceResponseLocal: failed when trying to delete "
+                            + "interface "
+                            + command.obj + ". Reason code=" + reasonOnFailure);
         }
     }
 
-    private void onNanDownLocal(int reason) {
+    private void onInitiateDataPathResponseSuccessLocal(Message command, int ndpId) {
         if (VDBG) {
-            Log.v(TAG, "onNanDown: reason=" + reason);
+            Log.v(TAG, "onInitiateDataPathResponseSuccessLocal: command=" + command + ", ndpId="
+                    + ndpId);
         }
 
-        int interested = 0;
-        for (int i = 0; i < mClients.size(); ++i) {
-            WifiNanClientState client = mClients.valueAt(i);
-            interested += client.onNanDown(reason);
-        }
-
-        if (interested == 0) {
-            Log.e(TAG, "onNanDown: event received but no listeners registered for this event "
-                    + "- should be disabled from fw!");
-        }
+        mDataPathMgr.onDataPathInitiateSuccess((String) command.obj, ndpId);
     }
 
+    private void onInitiateDataPathResponseFailLocal(Message command, int reason) {
+        if (VDBG) {
+            Log.v(TAG, "onInitiateDataPathResponseFailLocal: command=" + command + ", reason="
+                    + reason);
+        }
+
+        mDataPathMgr.onDataPathInitiateFail((String) command.obj, reason);
+    }
+
+    private void onRespondToDataPathSetupRequestResponseLocal(Message command, boolean success,
+            int reasonOnFailure) {
+        if (VDBG) {
+            Log.v(TAG, "onRespondToDataPathSetupRequestResponseLocal: command=" + command
+                    + ", success=" + success + ", reasonOnFailure=" + reasonOnFailure);
+        }
+
+        // TODO: do something with this
+    }
+
+    private void onEndPathEndResponseLocal(Message command, boolean success, int reasonOnFailure) {
+        if (VDBG) {
+            Log.v(TAG, "onEndPathEndResponseLocal: command=" + command
+                    + ", success=" + success + ", reasonOnFailure=" + reasonOnFailure);
+        }
+
+        // TODO: do something with this
+    }
+
+    /*
+     * NOTIFICATIONS
+     */
+
     private void onInterfaceAddressChangeLocal(byte[] mac) {
         if (VDBG) {
             Log.v(TAG, "onInterfaceAddressChange: mac=" + String.valueOf(HexEncoding.encode(mac)));
         }
 
-        int interested = 0;
+        mCurrentDiscoveryInterfaceMac = mac;
+
         for (int i = 0; i < mClients.size(); ++i) {
             WifiNanClientState client = mClients.valueAt(i);
-            interested += client.onInterfaceAddressChange(mac);
-        }
-
-        if (interested == 0) {
-            Log.e(TAG, "onInterfaceAddressChange: event received but no listeners registered "
-                    + "for this event - should be disabled from fw!");
+            client.onInterfaceAddressChange(mac);
         }
     }
 
@@ -892,179 +2386,9 @@
                     + String.valueOf(HexEncoding.encode(clusterId)));
         }
 
-        int interested = 0;
         for (int i = 0; i < mClients.size(); ++i) {
             WifiNanClientState client = mClients.valueAt(i);
-            interested += client.onClusterChange(flag, clusterId);
-        }
-
-        if (interested == 0) {
-            Log.e(TAG, "onClusterChange: event received but no listeners registered for this "
-                    + "event - should be disabled from fw!");
-        }
-    }
-
-    private void onPublishSuccessLocal(short transactionId, int publishId) {
-        if (VDBG) {
-            Log.v(TAG, "onPublishSuccess: transactionId=" + transactionId + ", publishId="
-                    + publishId);
-        }
-
-        TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId);
-        if (info == null) {
-            Log.e(TAG, "onPublishSuccess(): no info registered for transactionId=" + transactionId);
-            return;
-        }
-        if (!(info instanceof TransactionInfoSession)) {
-            Log.e(TAG, "onPublishSuccess: invalid info structure stored for transactionId="
-                    + transactionId);
-            return;
-        }
-        TransactionInfoSession infoSession = (TransactionInfoSession) info;
-
-        infoSession.mSession.onPublishSuccess(publishId);
-    }
-
-    private void onPublishFailLocal(short transactionId, int status) {
-        if (VDBG) {
-            Log.v(TAG, "onPublishFail: transactionId=" + transactionId + ", status=" + status);
-        }
-
-        TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId);
-        if (info == null) {
-            Log.e(TAG, "onPublishFail(): no info registered for transactionId=" + transactionId);
-            return;
-        }
-        if (!(info instanceof TransactionInfoSession)) {
-            Log.e(TAG, "onPublishFail: invalid info structure stored for transactionId="
-                    + transactionId);
-            return;
-        }
-        TransactionInfoSession infoSession = (TransactionInfoSession) info;
-
-        infoSession.mSession.onPublishFail(status);
-    }
-
-    private void onPublishTerminatedLocal(int publishId, int status) {
-        if (VDBG) {
-            Log.v(TAG, "onPublishTerminated: publishId=" + publishId + ", status=" + status);
-        }
-
-        WifiNanSessionState session = getNanSessionStateForPubSubId(publishId);
-        if (session == null) {
-            Log.e(TAG, "onPublishTerminated: no session found for publishId=" + publishId);
-            return;
-        }
-
-        session.onPublishTerminated(status);
-    }
-
-    private void onSubscribeSuccessLocal(short transactionId, int subscribeId) {
-        if (VDBG) {
-            Log.v(TAG, "onSubscribeSuccess: transactionId=" + transactionId + ", subscribeId="
-                    + subscribeId);
-        }
-
-        TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId);
-        if (info == null) {
-            Log.e(TAG,
-                    "onSubscribeSuccess(): no info registered for transactionId=" + transactionId);
-            return;
-        }
-        if (!(info instanceof TransactionInfoSession)) {
-            Log.e(TAG, "onSubscribeSuccess: invalid info structure stored for transactionId="
-                    + transactionId);
-            return;
-        }
-        TransactionInfoSession infoSession = (TransactionInfoSession) info;
-
-        infoSession.mSession.onSubscribeSuccess(subscribeId);
-    }
-
-    private void onSubscribeFailLocal(short transactionId, int status) {
-        if (VDBG) {
-            Log.v(TAG, "onSubscribeFail: transactionId=" + transactionId + ", status=" + status);
-        }
-
-        TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId);
-        if (info == null) {
-            Log.e(TAG, "onSubscribeFail(): no info registered for transactionId=" + transactionId);
-            return;
-        }
-        if (!(info instanceof TransactionInfoSession)) {
-            Log.e(TAG, "onSubscribeFail: invalid info structure stored for transactionId="
-                    + transactionId);
-            return;
-        }
-        TransactionInfoSession infoSession = (TransactionInfoSession) info;
-
-        infoSession.mSession.onSubscribeFail(status);
-    }
-
-    private void onSubscribeTerminatedLocal(int subscribeId, int status) {
-        if (VDBG) {
-            Log.v(TAG, "onPublishTerminated: subscribeId=" + subscribeId + ", status=" + status);
-        }
-
-        WifiNanSessionState session = getNanSessionStateForPubSubId(subscribeId);
-        if (session == null) {
-            Log.e(TAG, "onSubscribeTerminated: no session found for subscribeId=" + subscribeId);
-            return;
-        }
-
-        session.onSubscribeTerminated(status);
-    }
-
-    private void onMessageSendSuccessLocal(short transactionId) {
-        if (VDBG) {
-            Log.v(TAG, "onMessageSendSuccess: transactionId=" + transactionId);
-        }
-
-        TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId);
-        if (info == null) {
-            Log.e(TAG, "onMessageSendSuccess(): no info registered for transactionId="
-                    + transactionId);
-            return;
-        }
-        if (!(info instanceof TransactionInfoMessage)) {
-            Log.e(TAG, "onMessageSendSuccess: invalid info structure stored for transactionId="
-                    + transactionId);
-            return;
-        }
-        TransactionInfoMessage infoMessage = (TransactionInfoMessage) info;
-
-        infoMessage.mSession.onMessageSendSuccess(infoMessage.mMessageId);
-    }
-
-    private void onMessageSendFailLocal(short transactionId, int status) {
-        if (VDBG) {
-            Log.v(TAG, "onMessageSendFail: transactionId=" + transactionId + ", status=" + status);
-        }
-
-        TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId);
-        if (info == null) {
-            Log.e(TAG,
-                    "onMessageSendFail(): no info registered for transactionId=" + transactionId);
-            return;
-        }
-        if (!(info instanceof TransactionInfoMessage)) {
-            Log.e(TAG, "onMessageSendFail: invalid info structure stored for transactionId="
-                    + transactionId);
-            return;
-        }
-        TransactionInfoMessage infoMessage = (TransactionInfoMessage) info;
-
-        infoMessage.mSession.onMessageSendFail(infoMessage.mMessageId, status);
-    }
-
-    private void onUnknownTransactionLocal(int responseType, short transactionId, int status) {
-        Log.e(TAG, "onUnknownTransaction: responseType=" + responseType + ", transactionId="
-                + transactionId + ", status=" + status);
-
-        TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId);
-        if (info == null) {
-            Log.e(TAG, "onUnknownTransaction(): no info registered for transactionId="
-                    + transactionId);
+            client.onClusterChange(flag, clusterId, mCurrentDiscoveryInterfaceMac);
         }
     }
 
@@ -1073,65 +2397,123 @@
             int matchFilterLength) {
         if (VDBG) {
             Log.v(TAG, "onMatch: pubSubId=" + pubSubId + ", requestorInstanceId="
-                    + requestorInstanceId + ", peerMac="
+                    + requestorInstanceId + ", peerDiscoveryMac="
                     + String.valueOf(HexEncoding.encode(peerMac)) + ", serviceSpecificInfoLength="
-                    + serviceSpecificInfoLength + ", serviceSpecificInfo=" + serviceSpecificInfo
-                    + ", matchFilterLength=" + matchFilterLength + ", matchFilter=" + matchFilter);
+                    + serviceSpecificInfoLength + ", serviceSpecificInfo="
+                    + Arrays.toString(serviceSpecificInfo) + ", matchFilterLength="
+                    + matchFilterLength + ", matchFilter=" + Arrays.toString(matchFilter));
         }
 
-        WifiNanSessionState session = getNanSessionStateForPubSubId(pubSubId);
-        if (session == null) {
+        Pair<WifiNanClientState, WifiNanSessionState> data = getClientSessionForPubSubId(pubSubId);
+        if (data == null) {
             Log.e(TAG, "onMatch: no session found for pubSubId=" + pubSubId);
             return;
         }
 
-        session.onMatch(requestorInstanceId, peerMac, serviceSpecificInfo,
+        data.second.onMatch(requestorInstanceId, peerMac, serviceSpecificInfo,
                 serviceSpecificInfoLength, matchFilter, matchFilterLength);
     }
 
+    private void onSessionTerminatedLocal(int pubSubId, boolean isPublish, int reason) {
+        if (VDBG) {
+            Log.v(TAG, "onSessionTerminatedLocal: pubSubId=" + pubSubId + ", isPublish=" + isPublish
+                    + ", reason=" + reason);
+        }
+
+        Pair<WifiNanClientState, WifiNanSessionState> data = getClientSessionForPubSubId(pubSubId);
+        if (data == null) {
+            Log.e(TAG, "onSessionTerminatedLocal: no session found for pubSubId=" + pubSubId);
+            return;
+        }
+
+        try {
+            data.second.getCallback().onSessionTerminated(reason);
+        } catch (RemoteException e) {
+            Log.w(TAG,
+                    "onSessionTerminatedLocal onSessionTerminated(): RemoteException (FYI): " + e);
+        }
+        data.first.removeSession(data.second.getSessionId());
+    }
+
     private void onMessageReceivedLocal(int pubSubId, int requestorInstanceId, byte[] peerMac,
             byte[] message, int messageLength) {
         if (VDBG) {
             Log.v(TAG,
-                    "onMessageReceived: pubSubId=" + pubSubId + ", requestorInstanceId="
-                            + requestorInstanceId + ", peerMac="
+                    "onMessageReceivedLocal: pubSubId=" + pubSubId + ", requestorInstanceId="
+                            + requestorInstanceId + ", peerDiscoveryMac="
                             + String.valueOf(HexEncoding.encode(peerMac)) + ", messageLength="
                             + messageLength);
         }
 
-        WifiNanSessionState session = getNanSessionStateForPubSubId(pubSubId);
-        if (session == null) {
-            Log.e(TAG, "onMessageReceived: no session found for pubSubId=" + pubSubId);
+        Pair<WifiNanClientState, WifiNanSessionState> data = getClientSessionForPubSubId(pubSubId);
+        if (data == null) {
+            Log.e(TAG, "onMessageReceivedLocal: no session found for pubSubId=" + pubSubId);
             return;
         }
 
-        session.onMessageReceived(requestorInstanceId, peerMac, message, messageLength);
+        data.second.onMessageReceived(requestorInstanceId, peerMac, message, messageLength);
     }
 
-    private ConfigRequest mergeConfigRequests() {
+    private void onNanDownLocal() {
         if (VDBG) {
-            Log.v(TAG, "mergeConfigRequests(): mClients=[" + mClients + "]");
+            Log.v(TAG, "onNanDown");
         }
 
-        if (mClients.size() == 0) {
+        mClients.clear();
+        mCurrentNanConfiguration = null;
+        mSm.onNanDownCleanupSendQueueState();
+        mDataPathMgr.onNanDownCleanupDataPaths();
+        mCurrentDiscoveryInterfaceMac = ALL_ZERO_MAC;
+    }
+
+    /*
+     * Utilities
+     */
+
+    private Pair<WifiNanClientState, WifiNanSessionState> getClientSessionForPubSubId(
+            int pubSubId) {
+        for (int i = 0; i < mClients.size(); ++i) {
+            WifiNanClientState client = mClients.valueAt(i);
+            WifiNanSessionState session = client.getNanSessionStateForPubSubId(pubSubId);
+            if (session != null) {
+                return new Pair<>(client, session);
+            }
+        }
+
+        return null;
+    }
+
+    private ConfigRequest mergeConfigRequests(ConfigRequest configRequest) {
+        if (VDBG) {
+            Log.v(TAG, "mergeConfigRequests(): mClients=[" + mClients + "], configRequest="
+                    + configRequest);
+        }
+
+        if (mClients.size() == 0 && configRequest == null) {
             Log.e(TAG, "mergeConfigRequests: invalid state - called with 0 clients registered!");
             return null;
         }
 
-        if (mClients.size() == 1) {
-            return mClients.valueAt(0).getConfigRequest();
-        }
-
         // TODO: continue working on merge algorithm:
         // - if any request 5g: enable
         // - maximal master preference
         // - cluster range covering all requests: assume that [0,max] is a
         // non-request
+        // - if any request identity change: enable
         boolean support5gBand = false;
         int masterPreference = 0;
         boolean clusterIdValid = false;
         int clusterLow = 0;
         int clusterHigh = ConfigRequest.CLUSTER_ID_MAX;
+        boolean identityChange = false;
+        if (configRequest != null) {
+            support5gBand = configRequest.mSupport5gBand;
+            masterPreference = configRequest.mMasterPreference;
+            clusterIdValid = true;
+            clusterLow = configRequest.mClusterLow;
+            clusterHigh = configRequest.mClusterHigh;
+            identityChange = configRequest.mEnableIdentityChangeCallback;
+        }
         for (int i = 0; i < mClients.size(); ++i) {
             ConfigRequest cr = mClients.valueAt(i).getConfigRequest();
 
@@ -1151,22 +2533,56 @@
                 }
                 clusterIdValid = true;
             }
-        }
-        ConfigRequest.Builder builder = new ConfigRequest.Builder();
-        builder.setSupport5gBand(support5gBand).setMasterPreference(masterPreference)
-                .setClusterLow(clusterLow).setClusterHigh(clusterHigh);
 
-        return builder.build();
+            if (cr.mEnableIdentityChangeCallback) {
+                identityChange = true;
+            }
+        }
+        return new ConfigRequest.Builder().setSupport5gBand(support5gBand)
+                .setMasterPreference(masterPreference).setClusterLow(clusterLow)
+                .setClusterHigh(clusterHigh).setEnableIdentityChangeCallback(identityChange)
+                .build();
     }
 
+    private static String messageToString(Message msg) {
+        StringBuilder sb = new StringBuilder();
+
+        String s = sSmToString.get(msg.what);
+        if (s == null) {
+            s = "<unknown>";
+        }
+        sb.append(s).append("/");
+
+        if (msg.what == MESSAGE_TYPE_NOTIFICATION || msg.what == MESSAGE_TYPE_COMMAND
+                || msg.what == MESSAGE_TYPE_RESPONSE) {
+            s = sSmToString.get(msg.arg1);
+            if (s == null) {
+                s = "<unknown>";
+            }
+            sb.append(s);
+        }
+
+        if (msg.what == MESSAGE_TYPE_RESPONSE || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT) {
+            sb.append(" (Transaction ID=").append(msg.arg2).append(")");
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Dump the internal state of the class.
+     */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("NanStateManager:");
         pw.println("  mClients: [" + mClients + "]");
-        pw.println("  mPendingResponses: [" + mPendingResponses + "]");
+        pw.println("  mUsageEnabled: " + mUsageEnabled);
         pw.println("  mCapabilities: [" + mCapabilities + "]");
-        pw.println("  mNextTransactionId: " + mNextTransactionId);
+        pw.println("  mCurrentNanConfiguration: " + mCurrentNanConfiguration);
         for (int i = 0; i < mClients.size(); ++i) {
             mClients.valueAt(i).dump(fd, pw, args);
         }
+        mSm.dump(fd, pw, args);
+        mRtt.dump(fd, pw, args);
+        mDataPathMgr.dump(fd, pw, args);
     }
 }
diff --git a/service/java/com/android/server/wifi/scanner/SupplicantWifiScannerImpl.java b/service/java/com/android/server/wifi/scanner/SupplicantWifiScannerImpl.java
index 3f93c90..4d93e8f 100644
--- a/service/java/com/android/server/wifi/scanner/SupplicantWifiScannerImpl.java
+++ b/service/java/com/android/server/wifi/scanner/SupplicantWifiScannerImpl.java
@@ -68,7 +68,7 @@
     private final ChannelHelper mChannelHelper;
     private final Clock mClock;
 
-    private Object mSettingsLock = new Object();
+    private final Object mSettingsLock = new Object();
 
     // Next scan settings to apply when the previous scan completes
     private WifiNative.ScanSettings mPendingBackgroundScanSettings = null;
@@ -341,7 +341,7 @@
             ChannelCollection allFreqs = mChannelHelper.createChannelCollection();
             Set<Integer> hiddenNetworkIdSet = new HashSet<Integer>();
             final LastScanSettings newScanSettings =
-                    new LastScanSettings(mClock.elapsedRealtime());
+                    new LastScanSettings(mClock.getElapsedSinceBootMillis());
 
             // Update scan settings if there is a pending scan
             if (!mBackgroundScanPaused) {
@@ -397,7 +397,7 @@
                     mNextBackgroundScanPeriod++;
                     mBackgroundScanPeriodPending = false;
                     mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            mClock.elapsedRealtime() + mBackgroundScanSettings.base_period_ms,
+                            mClock.getElapsedSinceBootMillis() + mBackgroundScanSettings.base_period_ms,
                             BACKGROUND_PERIOD_ALARM_TAG, mScanPeriodListener, mEventHandler);
                 }
             }
@@ -443,7 +443,7 @@
                     }
                     mLastScanSettings = newScanSettings;
                     mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            mClock.elapsedRealtime() + SCAN_TIMEOUT_MS,
+                            mClock.getElapsedSinceBootMillis() + SCAN_TIMEOUT_MS,
                             TIMEOUT_ALARM_TAG, mScanTimeoutListener, mEventHandler);
                 } else {
                     Log.e(TAG, "Failed to start scan, freqs=" + freqs);
@@ -1042,7 +1042,7 @@
                 return true;
             }
 
-            mLastPnoChangeTimeStamp = mClock.elapsedRealtime();
+            mLastPnoChangeTimeStamp = mClock.getElapsedSinceBootMillis();
             if (mWifiNative.setPnoScan(enable)) {
                 Log.d(TAG, "Changed PNO state from " + mCurrentPnoState + " to " + enable);
                 mCurrentPnoState = enable;
@@ -1074,14 +1074,14 @@
             boolean isSuccess = true;
             mExpectedPnoState = enable;
             if (!mWaitForTimer) {
-                long timeDifference = mClock.elapsedRealtime() - mLastPnoChangeTimeStamp;
+                long timeDifference = mClock.getElapsedSinceBootMillis() - mLastPnoChangeTimeStamp;
                 if (timeDifference >= MINIMUM_PNO_GAP_MS) {
                     isSuccess = updatePnoState(enable);
                 } else {
                     long alarmTimeout = MINIMUM_PNO_GAP_MS - timeDifference;
                     Log.d(TAG, "Start PNO timer with delay " + alarmTimeout);
                     mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                            mClock.elapsedRealtime() + alarmTimeout, PNO_DEBOUNCER_ALARM_TAG,
+                            mClock.getElapsedSinceBootMillis() + alarmTimeout, PNO_DEBOUNCER_ALARM_TAG,
                             mAlarmListener, mEventHandler);
                     mWaitForTimer = true;
                 }
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 6ae2237..fdf3dfa 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -2284,7 +2284,7 @@
                         long unchangedDelay = settings.unchangedSampleSize * settings.periodInMs;
                         mAlarmManager.cancel(mTimeoutIntent);
                         mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                                mClock.elapsedRealtime() + unchangedDelay,
+                                mClock.getElapsedSinceBootMillis() + unchangedDelay,
                                 mTimeoutIntent);
                         break;
                     case WifiScanner.CMD_SCAN_RESULT:
@@ -2295,7 +2295,7 @@
                                     STATIONARY_SCAN_PERIOD_MS);
                             mWifiChangeDetected = false;
                             mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                                    mClock.elapsedRealtime() + MOVING_STATE_TIMEOUT_MS,
+                                    mClock.getElapsedSinceBootMillis() + MOVING_STATE_TIMEOUT_MS,
                                     mTimeoutIntent);
                             mScanResultsPending = false;
                         }
diff --git a/service/java/com/android/server/wifi/util/ScanDetailUtil.java b/service/java/com/android/server/wifi/util/ScanDetailUtil.java
deleted file mode 100644
index a83900e..0000000
--- a/service/java/com/android/server/wifi/util/ScanDetailUtil.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.util;
-
-import android.net.wifi.ScanResult;
-
-import com.android.server.wifi.ScanDetail;
-import com.android.server.wifi.hotspot2.NetworkDetail;
-
-/**
- * Utility for converting a ScanResult to a ScanDetail.
- * Only fields that are supported in ScanResult are copied.
- */
-public class ScanDetailUtil {
-    private ScanDetailUtil() { /* not constructable */ }
-
-    /**
-     * This method should only be used when the informationElements field in the provided scan
-     * result is filled in with the IEs from the beacon.
-     */
-    public static ScanDetail toScanDetail(ScanResult scanResult) {
-        NetworkDetail networkDetail = new NetworkDetail(scanResult.BSSID,
-                scanResult.informationElements, scanResult.anqpLines, scanResult.frequency);
-        return new ScanDetail(scanResult, networkDetail, null);
-    }
-}
diff --git a/service/java/com/android/server/wifi/util/ScanResultUtil.java b/service/java/com/android/server/wifi/util/ScanResultUtil.java
new file mode 100644
index 0000000..3f1e98f
--- /dev/null
+++ b/service/java/com/android/server/wifi/util/ScanResultUtil.java
@@ -0,0 +1,105 @@
+/*
+ * 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 com.android.server.wifi.util;
+
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+
+import com.android.server.wifi.ScanDetail;
+import com.android.server.wifi.WifiConfigurationUtil;
+import com.android.server.wifi.hotspot2.NetworkDetail;
+
+/**
+ * Scan result utility for any {@link ScanResult} related operations.
+ * Currently contains:
+ *   > Helper method for converting a ScanResult to a ScanDetail.
+ *     Only fields that are supported in ScanResult are copied.
+ *   > Helper methods to identify the encryption of a ScanResult.
+ */
+public class ScanResultUtil {
+    private ScanResultUtil() { /* not constructable */ }
+
+    /**
+     * This method should only be used when the informationElements field in the provided scan
+     * result is filled in with the IEs from the beacon.
+     */
+    public static ScanDetail toScanDetail(ScanResult scanResult) {
+        NetworkDetail networkDetail = new NetworkDetail(scanResult.BSSID,
+                scanResult.informationElements, scanResult.anqpLines, scanResult.frequency);
+        return new ScanDetail(scanResult, networkDetail, null);
+    }
+
+    /**
+     * Helper method to check if the provided |scanResult| corresponds to a PSK network or not.
+     * This checks if the provided capabilities string contains PSK encryption type or not.
+     */
+    public static boolean isScanResultForPskNetwork(ScanResult scanResult) {
+        return scanResult.capabilities.contains("PSK");
+    }
+
+    /**
+     * Helper method to check if the provided |scanResult| corresponds to a EAP network or not.
+     * This checks if the provided capabilities string contains EAP encryption type or not.
+     */
+    public static boolean isScanResultForEapNetwork(ScanResult scanResult) {
+        return scanResult.capabilities.contains("EAP");
+    }
+
+    /**
+     * Helper method to check if the provided |scanResult| corresponds to a WEP network or not.
+     * This checks if the provided capabilities string contains WEP encryption type or not.
+     */
+    public static boolean isScanResultForWepNetwork(ScanResult scanResult) {
+        return scanResult.capabilities.contains("WEP");
+    }
+
+    /**
+     * Helper method to check if the provided |scanResult| corresponds to an open network or not.
+     * This checks if the provided capabilities string does not contain either of WEP, PSK or EAP
+     * encryption types or not.
+     */
+    public static boolean isScanResultForOpenNetwork(ScanResult scanResult) {
+        return !(isScanResultForWepNetwork(scanResult) || isScanResultForPskNetwork(scanResult)
+                || isScanResultForEapNetwork(scanResult));
+    }
+
+    /**
+     * Helper method to check if the provided |scanResult| and |config| have the same
+     * encryption type.
+     */
+    public static boolean doesScanResultEncryptionMatchWithNetwork(
+            ScanResult scanResult, WifiConfiguration config) {
+        if (ScanResultUtil.isScanResultForPskNetwork(scanResult)
+                && WifiConfigurationUtil.isConfigForPskNetwork(config)) {
+            return true;
+        }
+        if (ScanResultUtil.isScanResultForEapNetwork(scanResult)
+                && WifiConfigurationUtil.isConfigForEapNetwork(config)) {
+            return true;
+        }
+        if (ScanResultUtil.isScanResultForWepNetwork(scanResult)
+                && WifiConfigurationUtil.isConfigForWepNetwork(config)) {
+            return true;
+        }
+        if (ScanResultUtil.isScanResultForOpenNetwork(scanResult)
+                && WifiConfigurationUtil.isConfigForOpenNetwork(config)) {
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
new file mode 100644
index 0000000..dffe602
--- /dev/null
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -0,0 +1,1027 @@
+/*
+ * 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 com.android.server.wifi.util;
+
+import android.net.IpConfiguration;
+import android.net.IpConfiguration.IpAssignment;
+import android.net.IpConfiguration.ProxySettings;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+import android.net.ProxyInfo;
+import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
+import android.net.wifi.WifiEnterpriseConfig;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.util.BitSet;
+import java.util.HashMap;
+
+/**
+ * Utils for manipulating XML data. This is essentially a wrapper over XmlUtils provided by core.
+ * The utility provides methods to write/parse section headers and write/parse values.
+ * This utility is designed for formatting the XML into the following format:
+ * <Document Header>
+ *  <Section 1 Header>
+ *   <Value 1>
+ *   <Value 2>
+ *   ...
+ *   <Sub Section 1 Header>
+ *    <Value 1>
+ *    <Value 2>
+ *    ...
+ *   </Sub Section 1 Header>
+ *  </Section 1 Header>
+ * </Document Header>
+ */
+public class XmlUtil {
+    private static final String TAG = "WifiXmlUtil";
+
+    /**
+     * Ensure that the XML stream is at a start tag or the end of document.
+     *
+     * @throws XmlPullParserException if parsing errors occur.
+     */
+    private static void gotoStartTag(XmlPullParser in)
+            throws XmlPullParserException, IOException {
+        int type = in.getEventType();
+        while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
+            type = in.next();
+        }
+    }
+
+    /**
+     * Ensure that the XML stream is at an end tag or the end of document.
+     *
+     * @throws XmlPullParserException if parsing errors occur.
+     */
+    private static void gotoEndTag(XmlPullParser in)
+            throws XmlPullParserException, IOException {
+        int type = in.getEventType();
+        while (type != XmlPullParser.END_TAG && type != XmlPullParser.END_DOCUMENT) {
+            type = in.next();
+        }
+    }
+
+    /**
+     * Start processing the XML stream at the document header.
+     *
+     * @param in         XmlPullParser instance pointing to the XML stream.
+     * @param headerName expected name for the start tag.
+     * @throws XmlPullParserException if parsing errors occur.
+     */
+    public static void gotoDocumentStart(XmlPullParser in, String headerName)
+            throws XmlPullParserException, IOException {
+        XmlUtils.beginDocument(in, headerName);
+    }
+
+    /**
+     * Move the XML stream to the next section header or indicate if there are no more sections.
+     * The provided outerDepth is used to find sub sections within that depth.
+     *
+     * Use this to move across sections if the ordering of sections are variable. The returned name
+     * can be used to decide what section is next.
+     *
+     * @param in         XmlPullParser instance pointing to the XML stream.
+     * @param headerName An array of one string, used to return the name of the next section.
+     * @param outerDepth Find section within this depth.
+     * @return {@code true} if a next section is found, {@code false} if there are no more sections.
+     * @throws XmlPullParserException if parsing errors occur.
+     */
+    public static boolean gotoNextSectionOrEnd(
+            XmlPullParser in, String[] headerName, int outerDepth)
+            throws XmlPullParserException, IOException {
+        if (XmlUtils.nextElementWithin(in, outerDepth)) {
+            headerName[0] = in.getName();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Move the XML stream to the next section header or indicate if there are no more sections.
+     * If a section, exists ensure that the name matches the provided name.
+     * The provided outerDepth is used to find sub sections within that depth.
+     *
+     * Use this to move across repeated sections until the end.
+     *
+     * @param in           XmlPullParser instance pointing to the XML stream.
+     * @param expectedName expected name for the section header.
+     * @param outerDepth   Find section within this depth.
+     * @return {@code true} if a next section is found, {@code false} if there are no more sections.
+     * @throws XmlPullParserException if the section header name does not match |expectedName|,
+     *                                or if parsing errors occur.
+     */
+    public static boolean gotoNextSectionWithNameOrEnd(
+            XmlPullParser in, String expectedName, int outerDepth)
+            throws XmlPullParserException, IOException {
+        String[] headerName = new String[1];
+        if (gotoNextSectionOrEnd(in, headerName, outerDepth)) {
+            if (headerName[0].equals(expectedName)) {
+                return true;
+            }
+            throw new XmlPullParserException(
+                    "Next section name does not match expected name: " + expectedName);
+        }
+        return false;
+    }
+
+    /**
+     * Move the XML stream to the next section header and ensure that the name matches the provided
+     * name.
+     * The provided outerDepth is used to find sub sections within that depth.
+     *
+     * Use this to move across sections if the ordering of sections are fixed.
+     *
+     * @param in           XmlPullParser instance pointing to the XML stream.
+     * @param expectedName expected name for the section header.
+     * @param outerDepth   Find section within this depth.
+     * @throws XmlPullParserException if the section header name does not match |expectedName|,
+     *                                there are no more sections or if parsing errors occur.
+     */
+    public static void gotoNextSectionWithName(
+            XmlPullParser in, String expectedName, int outerDepth)
+            throws XmlPullParserException, IOException {
+        if (!gotoNextSectionWithNameOrEnd(in, expectedName, outerDepth)) {
+            throw new XmlPullParserException("Section not found. Expected: " + expectedName);
+        }
+    }
+
+    /**
+     * Checks if the stream is at the end of a section of values. This moves the stream to next tag
+     * and checks if it finds an end tag at the specified depth.
+     *
+     * @param in           XmlPullParser instance pointing to the XML stream.
+     * @param sectionDepth depth of the start tag of this section. Used to match the end tag.
+     * @return {@code true} if a end tag at the provided depth is found, {@code false} otherwise
+     * @throws XmlPullParserException if parsing errors occur.
+     */
+    public static boolean isNextSectionEnd(XmlPullParser in, int sectionDepth)
+            throws XmlPullParserException, IOException {
+        return !XmlUtils.nextElementWithin(in, sectionDepth);
+    }
+
+    /**
+     * Read the current value in the XML stream using core XmlUtils and stores the retrieved
+     * value name in the string provided. This method reads the value contained in current start
+     * tag.
+     * Note: Because there could be genuine null values being read from the XML, this method raises
+     * an exception to indicate errors.
+     *
+     * @param in        XmlPullParser instance pointing to the XML stream.
+     * @param valueName An array of one string, used to return the name attribute
+     *                  of the value's tag.
+     * @return value retrieved from the XML stream.
+     * @throws XmlPullParserException if parsing errors occur.
+     */
+    public static Object readCurrentValue(XmlPullParser in, String[] valueName)
+            throws XmlPullParserException, IOException {
+        Object value = XmlUtils.readValueXml(in, valueName);
+        // XmlUtils.readValue does not always move the stream to the end of the tag. So, move
+        // it to the end tag before returning from here.
+        gotoEndTag(in);
+        return value;
+    }
+
+    /**
+     * Read the next value in the XML stream using core XmlUtils and ensure that it matches the
+     * provided name. This method moves the stream to the next start tag and reads the value
+     * contained in it.
+     * Note: Because there could be genuine null values being read from the XML, this method raises
+     * an exception to indicate errors.
+     *
+     * @param in XmlPullParser instance pointing to the XML stream.
+     * @return value retrieved from the XML stream.
+     * @throws XmlPullParserException if the value read does not match |expectedName|,
+     *                                or if parsing errors occur.
+     */
+    public static Object readNextValueWithName(XmlPullParser in, String expectedName)
+            throws XmlPullParserException, IOException {
+        String[] valueName = new String[1];
+        XmlUtils.nextElement(in);
+        Object value = readCurrentValue(in, valueName);
+        if (valueName[0].equals(expectedName)) {
+            return value;
+        }
+        throw new XmlPullParserException(
+                "Value not found. Expected: " + expectedName + ", but got: " + valueName[0]);
+    }
+
+    /**
+     * Write the XML document start with the provided document header name.
+     *
+     * @param out        XmlSerializer instance pointing to the XML stream.
+     * @param headerName name for the start tag.
+     */
+    public static void writeDocumentStart(XmlSerializer out, String headerName)
+            throws IOException {
+        out.startDocument(null, true);
+        out.startTag(null, headerName);
+    }
+
+    /**
+     * Write the XML document end with the provided document header name.
+     *
+     * @param out        XmlSerializer instance pointing to the XML stream.
+     * @param headerName name for the end tag.
+     */
+    public static void writeDocumentEnd(XmlSerializer out, String headerName)
+            throws IOException {
+        out.endTag(null, headerName);
+        out.endDocument();
+    }
+
+    /**
+     * Write a section start header tag with the provided section name.
+     *
+     * @param out        XmlSerializer instance pointing to the XML stream.
+     * @param headerName name for the start tag.
+     */
+    public static void writeNextSectionStart(XmlSerializer out, String headerName)
+            throws IOException {
+        out.startTag(null, headerName);
+    }
+
+    /**
+     * Write a section end header tag with the provided section name.
+     *
+     * @param out        XmlSerializer instance pointing to the XML stream.
+     * @param headerName name for the end tag.
+     */
+    public static void writeNextSectionEnd(XmlSerializer out, String headerName)
+            throws IOException {
+        out.endTag(null, headerName);
+    }
+
+    /**
+     * Write the value with the provided name in the XML stream using core XmlUtils.
+     *
+     * @param out   XmlSerializer instance pointing to the XML stream.
+     * @param name  name of the value.
+     * @param value value to be written.
+     */
+    public static void writeNextValue(XmlSerializer out, String name, Object value)
+            throws XmlPullParserException, IOException {
+        XmlUtils.writeValueXml(value, name, out);
+    }
+
+    /**
+     * Utility class to serialize and deseriaize {@link WifiConfiguration} object to XML &
+     * vice versa.
+     * This is used by both {@link com.android.server.wifi.WifiConfigStore} &
+     * {@link com.android.server.wifi.WifiBackupRestore} modules.
+     * The |writeConfigurationToXml| has 2 versions, one for backup and one for config store.
+     * There is only 1 version of |parseXmlToConfiguration| for both backup & config store.
+     * The parse method is written so that any element added/deleted in future revisions can
+     * be easily handled.
+     */
+    public static class WifiConfigurationXmlUtil {
+        /**
+         * List of XML tags corresponding to WifiConfiguration object elements.
+         */
+        public static final String XML_TAG_SSID = "SSID";
+        public static final String XML_TAG_BSSID = "BSSID";
+        public static final String XML_TAG_CONFIG_KEY = "ConfigKey";
+        public static final String XML_TAG_PRE_SHARED_KEY = "PreSharedKey";
+        public static final String XML_TAG_WEP_KEYS = "WEPKeys";
+        public static final String XML_TAG_WEP_TX_KEY_INDEX = "WEPTxKeyIndex";
+        public static final String XML_TAG_HIDDEN_SSID = "HiddenSSID";
+        public static final String XML_TAG_ALLOWED_KEY_MGMT = "AllowedKeyMgmt";
+        public static final String XML_TAG_ALLOWED_PROTOCOLS = "AllowedProtocols";
+        public static final String XML_TAG_ALLOWED_AUTH_ALGOS = "AllowedAuthAlgos";
+        public static final String XML_TAG_SHARED = "Shared";
+        public static final String XML_TAG_FQDN = "FQDN";
+        public static final String XML_TAG_PROVIDER_FRIENDLY_NAME = "ProviderFriendlyName";
+        public static final String XML_TAG_LINKED_NETWORKS_LIST = "LinkedNetworksList";
+        public static final String XML_TAG_DEFAULT_GW_MAC_ADDRESS = "DefaultGwMacAddress";
+        public static final String XML_TAG_VALIDATED_INTERNET_ACCESS = "ValidatedInternetAccess";
+        public static final String XML_TAG_NO_INTERNET_ACCESS_EXPECTED = "NoInternetAccessExpected";
+        public static final String XML_TAG_USER_APPROVED = "UserApproved";
+        public static final String XML_TAG_METERED_HINT = "MeteredHint";
+        public static final String XML_TAG_USE_EXTERNAL_SCORES = "UseExternalScores";
+        public static final String XML_TAG_NUM_ASSOCIATION = "NumAssociation";
+        public static final String XML_TAG_CREATOR_UID = "CreatorUid";
+        public static final String XML_TAG_CREATOR_NAME = "CreatorName";
+        public static final String XML_TAG_CREATION_TIME = "CreationTime";
+        public static final String XML_TAG_LAST_UPDATE_UID = "LastUpdateUid";
+        public static final String XML_TAG_LAST_UPDATE_NAME = "LastUpdateName";
+        public static final String XML_TAG_LAST_CONNECT_UID = "LastConnectUid";
+
+        /**
+         * Write WepKeys to the XML stream.
+         * WepKeys array is intialized in WifiConfiguration constructor, but all of the elements
+         * are set to null. User may chose to set any one of the key elements in WifiConfiguration.
+         * XmlUtils serialization doesn't handle this array of nulls well .
+         * So, write empty strings if some of the keys are not initialized and null if all of
+         * the elements are empty.
+         */
+        private static void writeWepKeysToXml(XmlSerializer out, String[] wepKeys)
+                throws XmlPullParserException, IOException {
+            String[] wepKeysToWrite = new String[wepKeys.length];
+            boolean hasWepKey = false;
+            for (int i = 0; i < wepKeys.length; i++) {
+                if (wepKeys[i] == null) {
+                    wepKeysToWrite[i] = new String();
+                } else {
+                    wepKeysToWrite[i] = wepKeys[i];
+                    hasWepKey = true;
+                }
+            }
+            if (hasWepKey) {
+                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, wepKeysToWrite);
+            } else {
+                XmlUtil.writeNextValue(out, XML_TAG_WEP_KEYS, null);
+            }
+        }
+
+        /**
+         * Write the Configuration data elements that are common for backup & config store to the
+         * XML stream.
+         *
+         * @param out           XmlSerializer instance pointing to the XML stream.
+         * @param configuration WifiConfiguration object to be serialized.
+         */
+        public static void writeCommonElementsToXml(
+                XmlSerializer out, WifiConfiguration configuration)
+                throws XmlPullParserException, IOException {
+            XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey());
+            XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID);
+            XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
+            XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey);
+            writeWepKeysToXml(out, configuration.wepKeys);
+            XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
+            XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID);
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_ALLOWED_KEY_MGMT,
+                    configuration.allowedKeyManagement.toByteArray());
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_ALLOWED_PROTOCOLS,
+                    configuration.allowedProtocols.toByteArray());
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_ALLOWED_AUTH_ALGOS,
+                    configuration.allowedAuthAlgorithms.toByteArray());
+            XmlUtil.writeNextValue(out, XML_TAG_SHARED, configuration.shared);
+        }
+
+        /**
+         * Write the Configuration data elements for backup from the provided Configuration to the
+         * XML stream.
+         * Note: This is a subset of the elements serialized for config store.
+         *
+         * @param out           XmlSerializer instance pointing to the XML stream.
+         * @param configuration WifiConfiguration object to be serialized.
+         */
+        public static void writeToXmlForBackup(XmlSerializer out, WifiConfiguration configuration)
+                throws XmlPullParserException, IOException {
+            writeCommonElementsToXml(out, configuration);
+        }
+
+        /**
+         * Write the Configuration data elements for config store from the provided Configuration
+         * to the XML stream.
+         *
+         * @param out           XmlSerializer instance pointing to the XML stream.
+         * @param configuration WifiConfiguration object to be serialized.
+         */
+        public static void writeToXmlForConfigStore(
+                XmlSerializer out, WifiConfiguration configuration)
+                throws XmlPullParserException, IOException {
+            writeCommonElementsToXml(out, configuration);
+            XmlUtil.writeNextValue(out, XML_TAG_FQDN, configuration.FQDN);
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_PROVIDER_FRIENDLY_NAME, configuration.providerFriendlyName);
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_LINKED_NETWORKS_LIST, configuration.linkedConfigurations);
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_DEFAULT_GW_MAC_ADDRESS, configuration.defaultGwMacAddress);
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_VALIDATED_INTERNET_ACCESS, configuration.validatedInternetAccess);
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_NO_INTERNET_ACCESS_EXPECTED,
+                    configuration.noInternetAccessExpected);
+            XmlUtil.writeNextValue(out, XML_TAG_USER_APPROVED, configuration.userApproved);
+            XmlUtil.writeNextValue(out, XML_TAG_METERED_HINT, configuration.meteredHint);
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_USE_EXTERNAL_SCORES, configuration.useExternalScores);
+            XmlUtil.writeNextValue(out, XML_TAG_NUM_ASSOCIATION, configuration.numAssociation);
+            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, configuration.creatorUid);
+            XmlUtil.writeNextValue(out, XML_TAG_CREATOR_NAME, configuration.creatorName);
+            XmlUtil.writeNextValue(out, XML_TAG_CREATION_TIME, configuration.creationTime);
+            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_UID, configuration.lastUpdateUid);
+            XmlUtil.writeNextValue(out, XML_TAG_LAST_UPDATE_NAME, configuration.lastUpdateName);
+            XmlUtil.writeNextValue(out, XML_TAG_LAST_CONNECT_UID, configuration.lastConnectUid);
+        }
+
+        /**
+         * Populate wepKeys array elements only if they were non-empty in the backup data.
+         *
+         * @throws XmlPullParserException if parsing errors occur.
+         */
+        private static void populateWepKeysFromXmlValue(Object value, String[] wepKeys)
+                throws XmlPullParserException, IOException {
+            String[] wepKeysInData = (String[]) value;
+            if (wepKeysInData == null) {
+                return;
+            }
+            if (wepKeysInData.length != wepKeys.length) {
+                throw new XmlPullParserException(
+                        "Invalid Wep Keys length: " + wepKeysInData.length);
+            }
+            for (int i = 0; i < wepKeys.length; i++) {
+                if (wepKeysInData[i].isEmpty()) {
+                    wepKeys[i] = null;
+                } else {
+                    wepKeys[i] = wepKeysInData[i];
+                }
+            }
+        }
+
+        /**
+         * Parses the configuration data elements from the provided XML stream to a
+         * WifiConfiguration object.
+         * Note: This is used for parsing both backup data and config store data. Looping through
+         * the tags make it easy to add or remove elements in the future versions if needed.
+         *
+         * @param in            XmlPullParser instance pointing to the XML stream.
+         * @param outerTagDepth depth of the outer tag in the XML document.
+         * @return Pair<Config key, WifiConfiguration object> if parsing is successful,
+         * null otherwise.
+         */
+        public static Pair<String, WifiConfiguration> parseFromXml(
+                XmlPullParser in, int outerTagDepth)
+                throws XmlPullParserException, IOException {
+            WifiConfiguration configuration = new WifiConfiguration();
+            String configKeyInData = null;
+
+            // Loop through and parse out all the elements from the stream within this section.
+            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
+                String[] valueName = new String[1];
+                Object value = XmlUtil.readCurrentValue(in, valueName);
+                if (valueName[0] == null) {
+                    throw new XmlPullParserException("Missing value name");
+                }
+                switch (valueName[0]) {
+                    case XML_TAG_CONFIG_KEY:
+                        configKeyInData = (String) value;
+                        break;
+                    case XML_TAG_SSID:
+                        configuration.SSID = (String) value;
+                        break;
+                    case XML_TAG_BSSID:
+                        configuration.BSSID = (String) value;
+                        break;
+                    case XML_TAG_PRE_SHARED_KEY:
+                        configuration.preSharedKey = (String) value;
+                        break;
+                    case XML_TAG_WEP_KEYS:
+                        populateWepKeysFromXmlValue(value, configuration.wepKeys);
+                        break;
+                    case XML_TAG_WEP_TX_KEY_INDEX:
+                        configuration.wepTxKeyIndex = (int) value;
+                        break;
+                    case XML_TAG_HIDDEN_SSID:
+                        configuration.hiddenSSID = (boolean) value;
+                        break;
+                    case XML_TAG_ALLOWED_KEY_MGMT:
+                        byte[] allowedKeyMgmt = (byte[]) value;
+                        configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
+                        break;
+                    case XML_TAG_ALLOWED_PROTOCOLS:
+                        byte[] allowedProtocols = (byte[]) value;
+                        configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
+                        break;
+                    case XML_TAG_ALLOWED_AUTH_ALGOS:
+                        byte[] allowedAuthAlgorithms = (byte[]) value;
+                        configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
+                        break;
+                    case XML_TAG_SHARED:
+                        configuration.shared = (boolean) value;
+                        break;
+                    case XML_TAG_FQDN:
+                        configuration.FQDN = (String) value;
+                        break;
+                    case XML_TAG_PROVIDER_FRIENDLY_NAME:
+                        configuration.providerFriendlyName = (String) value;
+                        break;
+                    case XML_TAG_LINKED_NETWORKS_LIST:
+                        configuration.linkedConfigurations = (HashMap<String, Integer>) value;
+                        break;
+                    case XML_TAG_DEFAULT_GW_MAC_ADDRESS:
+                        configuration.defaultGwMacAddress = (String) value;
+                        break;
+                    case XML_TAG_VALIDATED_INTERNET_ACCESS:
+                        configuration.validatedInternetAccess = (boolean) value;
+                        break;
+                    case XML_TAG_NO_INTERNET_ACCESS_EXPECTED:
+                        configuration.noInternetAccessExpected = (boolean) value;
+                        break;
+                    case XML_TAG_USER_APPROVED:
+                        configuration.userApproved = (int) value;
+                        break;
+                    case XML_TAG_METERED_HINT:
+                        configuration.meteredHint = (boolean) value;
+                        break;
+                    case XML_TAG_USE_EXTERNAL_SCORES:
+                        configuration.useExternalScores = (boolean) value;
+                        break;
+                    case XML_TAG_NUM_ASSOCIATION:
+                        configuration.numAssociation = (int) value;
+                        break;
+                    case XML_TAG_CREATOR_UID:
+                        configuration.creatorUid = (int) value;
+                        break;
+                    case XML_TAG_CREATOR_NAME:
+                        configuration.creatorName = (String) value;
+                        break;
+                    case XML_TAG_CREATION_TIME:
+                        configuration.creationTime = (String) value;
+                        break;
+                    case XML_TAG_LAST_UPDATE_UID:
+                        configuration.lastUpdateUid = (int) value;
+                        break;
+                    case XML_TAG_LAST_UPDATE_NAME:
+                        configuration.lastUpdateName = (String) value;
+                        break;
+                    case XML_TAG_LAST_CONNECT_UID:
+                        configuration.lastConnectUid = (int) value;
+                        break;
+                    default:
+                        throw new XmlPullParserException(
+                                "Unknown value name found: " + valueName[0]);
+                }
+            }
+            return Pair.create(configKeyInData, configuration);
+        }
+    }
+
+    /**
+     * Utility class to serialize and deseriaize {@link IpConfiguration} object to XML & vice versa.
+     * This is used by both {@link com.android.server.wifi.WifiConfigStore} &
+     * {@link com.android.server.wifi.WifiBackupRestore} modules.
+     */
+    public static class IpConfigurationXmlUtil {
+
+        /**
+         * List of XML tags corresponding to IpConfiguration object elements.
+         */
+        public static final String XML_TAG_IP_ASSIGNMENT = "IpAssignment";
+        public static final String XML_TAG_LINK_ADDRESS = "LinkAddress";
+        public static final String XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength";
+        public static final String XML_TAG_GATEWAY_ADDRESS = "GatewayAddress";
+        public static final String XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers";
+        public static final String XML_TAG_PROXY_SETTINGS = "ProxySettings";
+        public static final String XML_TAG_PROXY_HOST = "ProxyHost";
+        public static final String XML_TAG_PROXY_PORT = "ProxyPort";
+        public static final String XML_TAG_PROXY_PAC_FILE = "ProxyPac";
+        public static final String XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList";
+
+        /**
+         * Write the static IP configuration data elements to XML stream.
+         */
+        private static void writeStaticIpConfigurationToXml(
+                XmlSerializer out, StaticIpConfiguration staticIpConfiguration)
+                throws XmlPullParserException, IOException {
+            if (staticIpConfiguration.ipAddress != null) {
+                XmlUtil.writeNextValue(
+                        out, XML_TAG_LINK_ADDRESS,
+                        staticIpConfiguration.ipAddress.getAddress().getHostAddress());
+                XmlUtil.writeNextValue(
+                        out, XML_TAG_LINK_PREFIX_LENGTH,
+                        staticIpConfiguration.ipAddress.getPrefixLength());
+            } else {
+                XmlUtil.writeNextValue(
+                        out, XML_TAG_LINK_ADDRESS, null);
+                XmlUtil.writeNextValue(
+                        out, XML_TAG_LINK_PREFIX_LENGTH, null);
+            }
+            if (staticIpConfiguration.gateway != null) {
+                XmlUtil.writeNextValue(
+                        out, XML_TAG_GATEWAY_ADDRESS,
+                        staticIpConfiguration.gateway.getHostAddress());
+            } else {
+                XmlUtil.writeNextValue(
+                        out, XML_TAG_GATEWAY_ADDRESS, null);
+
+            }
+            if (staticIpConfiguration.dnsServers != null) {
+                // Create a string array of DNS server addresses
+                String[] dnsServers = new String[staticIpConfiguration.dnsServers.size()];
+                int dnsServerIdx = 0;
+                for (InetAddress inetAddr : staticIpConfiguration.dnsServers) {
+                    dnsServers[dnsServerIdx++] = inetAddr.getHostAddress();
+                }
+                XmlUtil.writeNextValue(
+                        out, XML_TAG_DNS_SERVER_ADDRESSES, dnsServers);
+            } else {
+                XmlUtil.writeNextValue(
+                        out, XML_TAG_DNS_SERVER_ADDRESSES, null);
+            }
+        }
+
+        /**
+         * Write the IP configuration data elements from the provided Configuration to the XML
+         * stream.
+         *
+         * @param out             XmlSerializer instance pointing to the XML stream.
+         * @param ipConfiguration IpConfiguration object to be serialized.
+         */
+        public static void writeToXml(XmlSerializer out, IpConfiguration ipConfiguration)
+                throws XmlPullParserException, IOException {
+            // Write IP assignment settings
+            XmlUtil.writeNextValue(out, XML_TAG_IP_ASSIGNMENT,
+                    ipConfiguration.ipAssignment.toString());
+            switch (ipConfiguration.ipAssignment) {
+                case STATIC:
+                    writeStaticIpConfigurationToXml(
+                            out, ipConfiguration.getStaticIpConfiguration());
+                    break;
+                default:
+                    break;
+            }
+
+            // Write proxy settings
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_PROXY_SETTINGS,
+                    ipConfiguration.proxySettings.toString());
+            switch (ipConfiguration.proxySettings) {
+                case STATIC:
+                    XmlUtil.writeNextValue(
+                            out, XML_TAG_PROXY_HOST,
+                            ipConfiguration.httpProxy.getHost());
+                    XmlUtil.writeNextValue(
+                            out, XML_TAG_PROXY_PORT,
+                            ipConfiguration.httpProxy.getPort());
+                    XmlUtil.writeNextValue(
+                            out, XML_TAG_PROXY_EXCLUSION_LIST,
+                            ipConfiguration.httpProxy.getExclusionListAsString());
+                    break;
+                case PAC:
+                    XmlUtil.writeNextValue(
+                            out, XML_TAG_PROXY_PAC_FILE,
+                            ipConfiguration.httpProxy.getPacFileUrl().toString());
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        /**
+         * Parse out the static IP configuration from the XML stream.
+         */
+        private static StaticIpConfiguration parseStaticIpConfigurationFromXml(XmlPullParser in)
+                throws XmlPullParserException, IOException {
+            StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+
+            String linkAddressString =
+                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_ADDRESS);
+            Integer linkPrefixLength =
+                    (Integer) XmlUtil.readNextValueWithName(in, XML_TAG_LINK_PREFIX_LENGTH);
+            if (linkAddressString != null && linkPrefixLength != null) {
+                LinkAddress linkAddress = new LinkAddress(
+                        NetworkUtils.numericToInetAddress(linkAddressString),
+                        linkPrefixLength);
+                if (linkAddress.getAddress() instanceof Inet4Address) {
+                    staticIpConfiguration.ipAddress = linkAddress;
+                } else {
+                    Log.w(TAG, "Non-IPv4 address: " + linkAddress);
+                }
+            }
+            String gatewayAddressString =
+                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_GATEWAY_ADDRESS);
+            if (gatewayAddressString != null) {
+                LinkAddress dest = null;
+                InetAddress gateway =
+                        NetworkUtils.numericToInetAddress(gatewayAddressString);
+                RouteInfo route = new RouteInfo(dest, gateway);
+                if (route.isIPv4Default()) {
+                    staticIpConfiguration.gateway = gateway;
+                } else {
+                    Log.w(TAG, "Non-IPv4 default route: " + route);
+                }
+            }
+            String[] dnsServerAddressesString =
+                    (String[]) XmlUtil.readNextValueWithName(in, XML_TAG_DNS_SERVER_ADDRESSES);
+            if (dnsServerAddressesString != null) {
+                for (String dnsServerAddressString : dnsServerAddressesString) {
+                    InetAddress dnsServerAddress =
+                            NetworkUtils.numericToInetAddress(dnsServerAddressString);
+                    staticIpConfiguration.dnsServers.add(dnsServerAddress);
+                }
+            }
+            return staticIpConfiguration;
+        }
+
+        /**
+         * Parses the IP configuration data elements from the provided XML stream to an
+         * IpConfiguration object.
+         *
+         * @param in            XmlPullParser instance pointing to the XML stream.
+         * @param outerTagDepth depth of the outer tag in the XML document.
+         * @return IpConfiguration object if parsing is successful, null otherwise.
+         */
+        public static IpConfiguration parseFromXml(XmlPullParser in, int outerTagDepth)
+                throws XmlPullParserException, IOException {
+            IpConfiguration ipConfiguration = new IpConfiguration();
+
+            // Parse out the IP assignment info first.
+            String ipAssignmentString =
+                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_IP_ASSIGNMENT);
+            IpAssignment ipAssignment = IpAssignment.valueOf(ipAssignmentString);
+            ipConfiguration.setIpAssignment(ipAssignment);
+            switch (ipAssignment) {
+                case STATIC:
+                    ipConfiguration.setStaticIpConfiguration(parseStaticIpConfigurationFromXml(in));
+                    break;
+                case DHCP:
+                case UNASSIGNED:
+                    break;
+                default:
+                    throw new XmlPullParserException("Unknown ip assignment type: " + ipAssignment);
+            }
+
+            // Parse out the proxy settings next.
+            String proxySettingsString =
+                    (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_SETTINGS);
+            ProxySettings proxySettings = ProxySettings.valueOf(proxySettingsString);
+            ipConfiguration.setProxySettings(proxySettings);
+            switch (proxySettings) {
+                case STATIC:
+                    String proxyHost =
+                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_HOST);
+                    int proxyPort =
+                            (int) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PORT);
+                    String proxyExclusionList =
+                            (String) XmlUtil.readNextValueWithName(
+                                    in, XML_TAG_PROXY_EXCLUSION_LIST);
+                    ipConfiguration.setHttpProxy(
+                            new ProxyInfo(proxyHost, proxyPort, proxyExclusionList));
+                    break;
+                case PAC:
+                    String proxyPacFile =
+                            (String) XmlUtil.readNextValueWithName(in, XML_TAG_PROXY_PAC_FILE);
+                    ipConfiguration.setHttpProxy(new ProxyInfo(proxyPacFile));
+                    break;
+                case NONE:
+                case UNASSIGNED:
+                    break;
+                default:
+                    throw new XmlPullParserException(
+                            "Unknown proxy settings type: " + proxySettings);
+            }
+            return ipConfiguration;
+        }
+    }
+
+    /**
+     * Utility class to serialize and deseriaize {@link NetworkSelectionStatus} object to XML &
+     * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module.
+     */
+    public static class NetworkSelectionStatusXmlUtil {
+
+        /**
+         * List of XML tags corresponding to NetworkSelectionStatus object elements.
+         */
+        public static final String XML_TAG_SELECTION_STATUS = "SelectionStatus";
+        public static final String XML_TAG_DISABLE_REASON = "DisableReason";
+        public static final String XML_TAG_CONNECT_CHOICE = "ConnectChoice";
+        public static final String XML_TAG_CONNECT_CHOICE_TIMESTAMP = "ConnectChoiceTimeStamp";
+        public static final String XML_TAG_HAS_EVER_CONNECTED = "HasEverConnected";
+
+        /**
+         * Write the NetworkSelectionStatus data elements from the provided status to the XML
+         * stream.
+         *
+         * @param out    XmlSerializer instance pointing to the XML stream.
+         * @param status NetworkSelectionStatus object to be serialized.
+         */
+        public static void writeToXml(XmlSerializer out, NetworkSelectionStatus status)
+                throws XmlPullParserException, IOException {
+            // Don't persist blacklists across reboots. So, if the status is temporarily disabled,
+            // store the status as enabled. This will ensure that when the device reboots, it is
+            // still considered for network selection.
+            int selectionStatus = status.getNetworkSelectionStatus();
+            if (selectionStatus == NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED) {
+                selectionStatus = NetworkSelectionStatus.NETWORK_SELECTION_ENABLED;
+            }
+            XmlUtil.writeNextValue(out, XML_TAG_SELECTION_STATUS, selectionStatus);
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_DISABLE_REASON, status.getNetworkSelectionDisableReason());
+            XmlUtil.writeNextValue(out, XML_TAG_CONNECT_CHOICE, status.getConnectChoice());
+            XmlUtil.writeNextValue(
+                    out, XML_TAG_CONNECT_CHOICE_TIMESTAMP, status.getConnectChoiceTimestamp());
+            XmlUtil.writeNextValue(out, XML_TAG_HAS_EVER_CONNECTED, status.getHasEverConnected());
+        }
+
+        /**
+         * Parses the NetworkSelectionStatus data elements from the provided XML stream to a
+         * NetworkSelectionStatus object.
+         *
+         * @param in            XmlPullParser instance pointing to the XML stream.
+         * @param outerTagDepth depth of the outer tag in the XML document.
+         * @return NetworkSelectionStatus object if parsing is successful, null otherwise.
+         */
+        public static NetworkSelectionStatus parseFromXml(XmlPullParser in, int outerTagDepth)
+                throws XmlPullParserException, IOException {
+            NetworkSelectionStatus status = new NetworkSelectionStatus();
+
+            // Loop through and parse out all the elements from the stream within this section.
+            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
+                String[] valueName = new String[1];
+                Object value = XmlUtil.readCurrentValue(in, valueName);
+                if (valueName[0] == null) {
+                    throw new XmlPullParserException("Missing value name");
+                }
+                switch (valueName[0]) {
+                    case XML_TAG_SELECTION_STATUS:
+                        status.setNetworkSelectionStatus((int) value);
+                        break;
+                    case XML_TAG_DISABLE_REASON:
+                        status.setNetworkSelectionDisableReason((int) value);
+                        break;
+                    case XML_TAG_CONNECT_CHOICE:
+                        status.setConnectChoice((String) value);
+                        break;
+                    case XML_TAG_CONNECT_CHOICE_TIMESTAMP:
+                        status.setConnectChoiceTimestamp((long) value);
+                        break;
+                    case XML_TAG_HAS_EVER_CONNECTED:
+                        status.setHasEverConnected((boolean) value);
+                        break;
+                    default:
+                        throw new XmlPullParserException(
+                                "Unknown value name found: " + valueName[0]);
+                }
+            }
+            return status;
+        }
+    }
+
+    /**
+     * Utility class to serialize and deseriaize {@link WifiEnterpriseConfig} object to XML &
+     * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module.
+     */
+    public static class WifiEnterpriseConfigXmlUtil {
+
+        /**
+         * List of XML tags corresponding to WifiEnterpriseConfig object elements.
+         */
+        public static final String XML_TAG_IDENTITY = "Identity";
+        public static final String XML_TAG_ANON_IDENTITY = "AnonIdentity";
+        public static final String XML_TAG_PASSWORD = "Password";
+        public static final String XML_TAG_CLIENT_CERT = "ClientCert";
+        public static final String XML_TAG_CA_CERT = "CaCert";
+        public static final String XML_TAG_SUBJECT_MATCH = "SubjectMatch";
+        public static final String XML_TAG_ENGINE = "Engine";
+        public static final String XML_TAG_ENGINE_ID = "EngineId";
+        public static final String XML_TAG_PRIVATE_KEY_ID = "PrivateKeyId";
+        public static final String XML_TAG_ALT_SUBJECT_MATCH = "AltSubjectMatch";
+        public static final String XML_TAG_DOM_SUFFIX_MATCH = "DomSuffixMatch";
+        public static final String XML_TAG_CA_PATH = "CaPath";
+        public static final String XML_TAG_EAP_METHOD = "EapMethod";
+        public static final String XML_TAG_PHASE2_METHOD = "Phase2Method";
+
+        /**
+         * Write the WifiEnterpriseConfig data elements from the provided config to the XML
+         * stream.
+         *
+         * @param out              XmlSerializer instance pointing to the XML stream.
+         * @param enterpriseConfig WifiEnterpriseConfig object to be serialized.
+         */
+        public static void writeToXml(XmlSerializer out, WifiEnterpriseConfig enterpriseConfig)
+                throws XmlPullParserException, IOException {
+            XmlUtil.writeNextValue(out, XML_TAG_IDENTITY,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_ANON_IDENTITY,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_PASSWORD,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_CLIENT_CERT,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_CA_CERT,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_SUBJECT_MATCH,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_ENGINE,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_ENGINE_ID,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_PRIVATE_KEY_ID,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_ALT_SUBJECT_MATCH,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_DOM_SUFFIX_MATCH,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_CA_PATH,
+                    enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, ""));
+            XmlUtil.writeNextValue(out, XML_TAG_EAP_METHOD, enterpriseConfig.getEapMethod());
+            XmlUtil.writeNextValue(out, XML_TAG_PHASE2_METHOD, enterpriseConfig.getPhase2Method());
+        }
+
+        /**
+         * Parses the data elements from the provided XML stream to a WifiEnterpriseConfig object.
+         *
+         * @param in            XmlPullParser instance pointing to the XML stream.
+         * @param outerTagDepth depth of the outer tag in the XML document.
+         * @return WifiEnterpriseConfig object if parsing is successful, null otherwise.
+         */
+        public static WifiEnterpriseConfig parseFromXml(XmlPullParser in, int outerTagDepth)
+                throws XmlPullParserException, IOException {
+            WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+
+            // Loop through and parse out all the elements from the stream within this section.
+            while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
+                String[] valueName = new String[1];
+                Object value = XmlUtil.readCurrentValue(in, valueName);
+                if (valueName[0] == null) {
+                    throw new XmlPullParserException("Missing value name");
+                }
+                switch (valueName[0]) {
+                    case XML_TAG_IDENTITY:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.IDENTITY_KEY, (String) value);
+                        break;
+                    case XML_TAG_ANON_IDENTITY:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.ANON_IDENTITY_KEY, (String) value);
+                        break;
+                    case XML_TAG_PASSWORD:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.PASSWORD_KEY, (String) value);
+                        break;
+                    case XML_TAG_CLIENT_CERT:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.CLIENT_CERT_KEY, (String) value);
+                        break;
+                    case XML_TAG_CA_CERT:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.CA_CERT_KEY, (String) value);
+                        break;
+                    case XML_TAG_SUBJECT_MATCH:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.SUBJECT_MATCH_KEY, (String) value);
+                        break;
+                    case XML_TAG_ENGINE:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.ENGINE_KEY, (String) value);
+                        break;
+                    case XML_TAG_ENGINE_ID:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.ENGINE_ID_KEY, (String) value);
+                        break;
+                    case XML_TAG_PRIVATE_KEY_ID:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, (String) value);
+                        break;
+                    case XML_TAG_ALT_SUBJECT_MATCH:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, (String) value);
+                        break;
+                    case XML_TAG_DOM_SUFFIX_MATCH:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, (String) value);
+                        break;
+                    case XML_TAG_CA_PATH:
+                        enterpriseConfig.setFieldValue(
+                                WifiEnterpriseConfig.CA_PATH_KEY, (String) value);
+                        break;
+                    case XML_TAG_EAP_METHOD:
+                        enterpriseConfig.setEapMethod((int) value);
+                        break;
+                    case XML_TAG_PHASE2_METHOD:
+                        enterpriseConfig.setPhase2Method((int) value);
+                        break;
+                    default:
+                        throw new XmlPullParserException(
+                                "Unknown value name found: " + valueName[0]);
+                }
+            }
+            return enterpriseConfig;
+        }
+    }
+}
+
diff --git a/service/jni/com_android_server_wifi_WifiNative.cpp b/service/jni/com_android_server_wifi_WifiNative.cpp
index 71e3971..1467503 100644
--- a/service/jni/com_android_server_wifi_WifiNative.cpp
+++ b/service/jni/com_android_server_wifi_WifiNative.cpp
@@ -16,33 +16,41 @@
 
 #define LOG_TAG "wifi"
 
-#include "jni.h"
-#include "JniConstants.h"
-#include <ScopedUtfChars.h>
-#include <ScopedBytes.h>
-#include <utils/misc.h>
-#include <utils/Log.h>
-#include <utils/String16.h>
 #include <ctype.h>
 #include <stdlib.h>
-#include <sys/socket.h>
 #include <sys/klog.h>
-#include <linux/if.h>
+#include <sys/socket.h>
+/* We need linux/if_arp.h for ARPHRD_ETHER.  Sadly, it forward declares
+   struct sockaddr and must be included after sys/socket.h. */
 #include <linux/if_arp.h>
 
 #include <algorithm>
 #include <limits>
 #include <vector>
 
-#include "wifi.h"
-#include "wifi_hal.h"
+#include <hardware_legacy/rtt.h>
+#include <hardware_legacy/wifi.h>
+#include <hardware_legacy/wifi_hal.h>
+#include <log/log.h>
+#include <nativehelper/JniConstants.h>
+#include <nativehelper/ScopedBytes.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni.h>
+#include <utils/String16.h>
+#include <utils/misc.h>
+#include <wifi_system/hal_tool.h>
+#include <wifi_system/interface_tool.h>
+#include <wifi_system/wifi.h>
+
 #include "jni_helper.h"
-#include "rtt.h"
-#include "wifi_hal_stub.h"
+
 #define REPLY_BUF_SIZE (4096 + 1)         // wpa_supplicant's maximum size + 1 for nul
 #define EVENT_BUF_SIZE 2048
 #define WAKE_REASON_TYPE_MAX 10
 
+using android::wifi_system::HalTool;
+using android::wifi_system::InterfaceTool;
+
 namespace android {
 
 extern "C"
@@ -64,7 +72,7 @@
     }
 
     --reply_len; // Ensure we have room to add NUL termination.
-    if (::wifi_command(command.c_str(), reply, &reply_len) != 0) {
+    if (wifi_system::wifi_command(command.c_str(), reply, &reply_len) != 0) {
         return false;
     }
 
@@ -124,28 +132,28 @@
 
 static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jclass, jboolean p2pSupported)
 {
-    return (::wifi_start_supplicant(p2pSupported) == 0);
+    return (wifi_system::wifi_start_supplicant(p2pSupported) == 0);
 }
 
 static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jclass, jboolean p2pSupported)
 {
-    return (::wifi_stop_supplicant(p2pSupported) == 0);
+    return (wifi_system::wifi_stop_supplicant(p2pSupported) == 0);
 }
 
 static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jclass)
 {
-    return (::wifi_connect_to_supplicant() == 0);
+    return (wifi_system::wifi_connect_to_supplicant() == 0);
 }
 
 static void android_net_wifi_closeSupplicantConnection(JNIEnv* env, jclass)
 {
-    ::wifi_close_supplicant_connection();
+    wifi_system::wifi_close_supplicant_connection();
 }
 
 static jstring android_net_wifi_waitForEvent(JNIEnv* env, jclass)
 {
     char buf[EVENT_BUF_SIZE];
-    int nread = ::wifi_wait_for_event(buf, sizeof buf);
+    int nread = wifi_system::wifi_wait_for_event(buf, sizeof buf);
     if (nread > 0) {
         return env->NewStringUTF(buf);
     } else {
@@ -237,96 +245,38 @@
     return scanResult;
 }
 
-int set_iface_flags(const char *ifname, bool dev_up) {
-    struct ifreq ifr;
-    int ret;
-    int sock = socket(PF_INET, SOCK_DGRAM, 0);
-    if (sock < 0) {
-        ALOGD("Bad socket: %d\n", sock);
-        return -errno;
-    }
-
-    //ALOGD("setting interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
-
-    memset(&ifr, 0, sizeof(ifr));
-    strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
-
-    //ALOGD("reading old value\n");
-
-    if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
-      ret = errno ? -errno : -999;
-      ALOGE("Could not read interface %s flags: %d\n", ifname, errno);
-      close(sock);
-      return ret;
-    } else {
-      //ALOGD("writing new value\n");
-    }
-
-    if (dev_up) {
-      if (ifr.ifr_flags & IFF_UP) {
-        // ALOGD("interface %s is already up\n", ifname);
-        close(sock);
-        return 0;
-      }
-      ifr.ifr_flags |= IFF_UP;
-    } else {
-      if (!(ifr.ifr_flags & IFF_UP)) {
-        // ALOGD("interface %s is already down\n", ifname);
-        close(sock);
-        return 0;
-      }
-      ifr.ifr_flags &= ~IFF_UP;
-    }
-
-    if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
-      ALOGE("Could not set interface %s flags: %d\n", ifname, errno);
-      ret = errno ? -errno : -999;
-      close(sock);
-      return ret;
-    } else {
-      ALOGD("set interface %s flags (%s)\n", ifname, dev_up ? "UP" : "DOWN");
-    }
-    close(sock);
-    return 0;
-}
-
 static jboolean android_net_wifi_set_interface_up(JNIEnv* env, jclass cls, jboolean up) {
-    return (set_iface_flags("wlan0", (bool)up) == 0);
+    InterfaceTool if_tool;
+    return if_tool.SetWifiUpState((bool)up);
 }
 
 static jboolean android_net_wifi_startHal(JNIEnv* env, jclass cls) {
+    InterfaceTool if_tool;
     JNIHelper helper(env);
     wifi_handle halHandle = getWifiHandle(helper, cls);
-    if (halHandle == NULL) {
-
-        if(init_wifi_stub_hal_func_table(&hal_fn) != 0 ) {
-            ALOGE("Can not initialize the basic function pointer table");
-            return false;
-        }
-
-        wifi_error res = init_wifi_vendor_hal_func_table(&hal_fn);
-        if (res != WIFI_SUCCESS) {
-            ALOGE("Can not initialize the vendor function pointer table");
-	    return false;
-        }
-
-        int ret = set_iface_flags("wlan0", true);
-        if(ret != 0) {
-            return false;
-        }
-
-        res = hal_fn.wifi_initialize(&halHandle);
-        if (res == WIFI_SUCCESS) {
-            helper.setStaticLongField(cls, WifiHandleVarName, (jlong)halHandle);
-            ALOGD("Did set static halHandle = %p", halHandle);
-        }
-        env->GetJavaVM(&mVM);
-        mCls = (jclass) env->NewGlobalRef(cls);
-        ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
-        return res == WIFI_SUCCESS;
-    } else {
-        return (set_iface_flags("wlan0", true) == 0);
+    if (halHandle != NULL) {
+        return if_tool.SetWifiUpState(true);
     }
+
+    HalTool hal_tool;
+    if (!hal_tool.InitFunctionTable(&hal_fn)) {
+        return false;
+    }
+
+    if(!if_tool.SetWifiUpState(true)) {
+        ALOGE("Failed to set WiFi interface up");
+        return false;
+    }
+
+    const bool was_started = hal_fn.wifi_initialize(&halHandle) == WIFI_SUCCESS;
+    if (was_started) {
+        helper.setStaticLongField(cls, WifiHandleVarName, (jlong)halHandle);
+        ALOGD("Did set static halHandle = %p", halHandle);
+    }
+    env->GetJavaVM(&mVM);
+    mCls = (jclass) env->NewGlobalRef(cls);
+    ALOGD("halHandle = %p, mVM = %p, mCls = %p", halHandle, mVM, mCls);
+    return was_started;
 }
 
 void android_net_wifi_hal_cleaned_up_handler(wifi_handle handle) {
@@ -359,7 +309,8 @@
     JNIHelper helper(env);
     wifi_handle halHandle = getWifiHandle(helper, cls);
     hal_fn.wifi_event_loop(halHandle);
-    set_iface_flags("wlan0", false);
+    InterfaceTool if_tool;
+    if_tool.SetWifiUpState(false);
 }
 
 static int android_net_wifi_getInterfaces(JNIEnv *env, jclass cls) {
@@ -1388,7 +1339,8 @@
 }
 
 static jboolean android_net_wifi_is_get_channels_for_band_supported(JNIEnv *env, jclass cls){
-    return (hal_fn.wifi_get_valid_channels == wifi_get_valid_channels_stub);
+    HalTool hal_tool;
+    return hal_tool.CanGetValidChannels(&hal_fn);
 }
 
 static jintArray android_net_wifi_getValidChannels(JNIEnv *env, jclass cls,
diff --git a/service/jni/com_android_server_wifi_nan_WifiNanNative.cpp b/service/jni/com_android_server_wifi_nan_WifiNanNative.cpp
index cae441a..83c2490 100644
--- a/service/jni/com_android_server_wifi_nan_WifiNanNative.cpp
+++ b/service/jni/com_android_server_wifi_nan_WifiNanNative.cpp
@@ -16,19 +16,20 @@
 
 #define LOG_TAG "wifinan"
 
-#include "jni.h"
-#include "JniConstants.h"
-#include <ScopedUtfChars.h>
-#include <ScopedBytes.h>
-#include <utils/misc.h>
-#include <utils/Log.h>
-#include <utils/String16.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <sys/socket.h>
-#include <linux/if.h>
-#include "wifi.h"
-#include "wifi_hal.h"
+
+#include <hardware_legacy/wifi_hal.h>
+#include <log/log.h>
+#include <nativehelper/JniConstants.h>
+#include <nativehelper/ScopedBytes.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni.h>
+#include <utils/String16.h>
+#include <utils/misc.h>
+#include <wifi_system/wifi.h>
+
 #include "jni_helper.h"
 
 namespace android {
@@ -98,6 +99,8 @@
                          (int) msg->body.nan_capabilities.max_ndp_sessions);
       helper.setIntField(data, "maxAppInfoLen",
                          (int) msg->body.nan_capabilities.max_app_info_len);
+      helper.setIntField(data, "maxQueuedTransmitMessages",
+                         (int) msg->body.nan_capabilities.max_queued_transmit_followup_msgs);
 
       helper.reportEvent(
           mCls, "onNanNotifyResponseCapabilities",
@@ -105,6 +108,11 @@
           (short) id, (int) msg->status, (int) msg->value, data.get());
       break;
     }
+    case NAN_DP_INITIATOR_RESPONSE:
+      helper.reportEvent(mCls, "onNanNotifyResponseDataPathInitiate", "(SIII)V", (short) id,
+                         (int) msg->status, (int) msg->value,
+                         msg->body.data_request_response.ndp_instance_id);
+      break;
     default:
       helper.reportEvent(mCls, "onNanNotifyResponse", "(SIII)V", (short) id,
                          (int) msg->response_type, (int) msg->status,
@@ -208,6 +216,63 @@
     ALOGD("OnNanEventSdfPayload");
 }
 
+static void OnNanEventDataRequest(NanDataPathRequestInd* event) {
+  ALOGD("OnNanEventDataRequest");
+  JNIHelper helper(mVM);
+
+  JNIObject<jbyteArray> peerBytes = helper.newByteArray(6);
+  helper.setByteArrayRegion(peerBytes, 0, 6,
+                            (jbyte *)event->peer_disc_mac_addr);
+
+  JNIObject<jbyteArray> msgBytes =
+      helper.newByteArray(event->app_info.ndp_app_info_len);
+  helper.setByteArrayRegion(msgBytes, 0, event->app_info.ndp_app_info_len,
+                            (jbyte *)event->app_info.ndp_app_info);
+
+  helper.reportEvent(mCls, "onDataPathRequest", "(I[BI[BI)V",
+                     event->service_instance_id, peerBytes.get(),
+                     event->ndp_instance_id, msgBytes.get(),
+                     event->app_info.ndp_app_info_len);
+}
+
+static void OnNanEventDataConfirm(NanDataPathConfirmInd* event) {
+  ALOGD("OnNanEventDataConfirm");
+  JNIHelper helper(mVM);
+
+  JNIObject<jbyteArray> peerBytes = helper.newByteArray(6);
+  helper.setByteArrayRegion(peerBytes, 0, 6, (jbyte *)event->peer_ndi_mac_addr);
+
+  JNIObject<jbyteArray> msgBytes =
+      helper.newByteArray(event->app_info.ndp_app_info_len);
+  helper.setByteArrayRegion(msgBytes, 0, event->app_info.ndp_app_info_len,
+                            (jbyte *)event->app_info.ndp_app_info);
+
+  helper.reportEvent(
+      mCls, "onDataPathConfirm", "(I[BZI[BI)V", event->ndp_instance_id,
+      peerBytes.get(), event->rsp_code == NAN_DP_REQUEST_ACCEPT,
+      event->reason_code, msgBytes.get(), event->app_info.ndp_app_info_len);
+}
+
+static void OnNanEventDataEnd(NanDataPathEndInd* event) {
+  ALOGD("OnNanEventDataEnd");
+  JNIHelper helper(mVM);
+
+  for (int i = 0; i < event->num_ndp_instances; ++i) {
+    helper.reportEvent(mCls, "onDataPathEnd", "(I)V",
+                       event->ndp_instance_id[i]);
+  }
+}
+
+static void OnNanEventTransmitFollowup(NanTransmitFollowupInd* event) {
+  ALOGD("OnNanEventTransmitFollowup: transaction_id=%d, reason=%d", event->id,
+        event->reason);
+
+  JNIHelper helper(mVM);
+
+  helper.reportEvent(mCls, "onTransmitFollowupEvent", "(SI)V",
+                     (short) event->id, (int) event->reason);
+}
+
 static jint android_net_wifi_nan_register_handler(JNIEnv *env, jclass cls,
                                                   jclass wifi_native_cls,
                                                   jint iface) {
@@ -217,6 +282,7 @@
     ALOGD("android_net_wifi_nan_register_handler handle=%p", handle);
 
     NanCallbackHandler handlers;
+    memset(&handlers, 0, sizeof(NanCallbackHandler));
     handlers.NotifyResponse = OnNanNotifyResponse;
     handlers.EventPublishTerminated = OnNanEventPublishTerminated;
     handlers.EventMatch = OnNanEventMatch;
@@ -227,6 +293,10 @@
     handlers.EventDisabled = OnNanEventDisabled;
     handlers.EventTca = OnNanEventTca;
     handlers.EventBeaconSdfPayload = OnNanEventBeaconSdfPayload;
+    handlers.EventDataRequest = OnNanEventDataRequest;
+    handlers.EventDataConfirm = OnNanEventDataConfirm;
+    handlers.EventDataEnd = OnNanEventDataEnd;
+    handlers.EventTransmitFollowup = OnNanEventTransmitFollowup;
 
     if (mVM == NULL) {
         env->GetJavaVM(&mVM);
@@ -260,6 +330,27 @@
     return hal_fn.wifi_nan_enable_request(transaction_id, handle, &msg);
 }
 
+static jint android_net_wifi_nan_config_request(JNIEnv *env, jclass cls,
+                                                jshort transaction_id,
+                                                jclass wifi_native_cls,
+                                                jint iface,
+                                                jobject config_request) {
+    JNIHelper helper(env);
+    wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface);
+
+    ALOGD("android_net_wifi_nan_config_request handle=%p, id=%d",
+          handle, transaction_id);
+
+    NanConfigRequest msg;
+    memset(&msg, 0, sizeof(NanConfigRequest));
+
+    /* configurable settings */
+    msg.config_master_pref = 1;
+    msg.master_pref = helper.getIntField(config_request, "mMasterPreference");
+
+    return hal_fn.wifi_nan_config_request(transaction_id, handle, &msg);
+}
+
 static jint android_net_wifi_nan_get_capabilities(JNIEnv *env, jclass cls,
                                                   jshort transaction_id,
                                                   jclass wifi_native_cls,
@@ -291,8 +382,7 @@
                                          jint publish_id,
                                          jclass wifi_native_cls,
                                          jint iface,
-                                         jobject publish_data,
-                                         jobject publish_settings) {
+                                         jobject publish_config) {
     JNIHelper helper(env);
     wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface);
 
@@ -310,47 +400,47 @@
     /* configurable settings */
     msg.publish_id = publish_id;
 
-    JNIObject<jstring> objStr1 = helper.getStringField(publish_data, "mServiceName");
-    if (objStr1 == NULL) {
-        ALOGE("Error accessing mServiceName field");
+    size_t service_name_len;
+    helper.getByteArrayField(publish_config, "mServiceName", msg.service_name,
+                             &service_name_len, NAN_MAX_SERVICE_NAME_LEN);
+    if (service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+        ALOGE("Length of service name field larger than max allowed");
         return 0;
     }
-    ScopedUtfChars chars1(env, objStr1);
-    const char *serviceName = chars1.c_str();
-    if (serviceName == NULL) {
-        ALOGE("Error getting mServiceName");
-        return 0;
-    }
-    msg.service_name_len = strlen(serviceName);
-    strcpy((char*)msg.service_name, serviceName);
+    msg.service_name_len = service_name_len;
 
-    msg.service_specific_info_len = helper.getIntField(publish_data, "mServiceSpecificInfoLength");
+    msg.service_specific_info_len = helper.getIntField(publish_config, "mServiceSpecificInfoLength");
     if (msg.service_specific_info_len != 0) {
-        helper.getByteArrayField(publish_data, "mServiceSpecificInfo",
+        helper.getByteArrayField(publish_config, "mServiceSpecificInfo",
                              msg.service_specific_info, msg.service_specific_info_len);
     }
 
 
-    msg.tx_match_filter_len = helper.getIntField(publish_data, "mTxFilterLength");
+    msg.tx_match_filter_len = helper.getIntField(publish_config, "mTxFilterLength");
     if (msg.tx_match_filter_len != 0) {
-        helper.getByteArrayField(publish_data, "mTxFilter",
+        helper.getByteArrayField(publish_config, "mTxFilter",
                              msg.tx_match_filter, msg.tx_match_filter_len);
     }
 
-    msg.rx_match_filter_len = helper.getIntField(publish_data, "mRxFilterLength");
+    msg.rx_match_filter_len = helper.getIntField(publish_config, "mRxFilterLength");
     if (msg.rx_match_filter_len != 0) {
-        helper.getByteArrayField(publish_data, "mRxFilter",
+        helper.getByteArrayField(publish_config, "mRxFilter",
                              msg.rx_match_filter, msg.rx_match_filter_len);
     }
 
-    msg.publish_type = (NanPublishType)helper.getIntField(publish_settings, "mPublishType");
-    msg.publish_count = helper.getIntField(publish_settings, "mPublishCount");
-    msg.ttl = helper.getIntField(publish_settings, "mTtlSec");
+    msg.publish_type = (NanPublishType)helper.getIntField(publish_config, "mPublishType");
+    msg.publish_count = helper.getIntField(publish_config, "mPublishCount");
+    msg.ttl = helper.getIntField(publish_config, "mTtlSec");
 
     msg.tx_type = NAN_TX_TYPE_BROADCAST;
     if (msg.publish_type != NAN_PUBLISH_TYPE_UNSOLICITED)
       msg.tx_type = NAN_TX_TYPE_UNICAST;
 
+    msg.recv_indication_cfg = 0;
+    if (!helper.getBoolField(publish_config, "mEnableTerminateNotification")) {
+      msg.recv_indication_cfg |= 0x1;
+    }
+
     return hal_fn.wifi_nan_publish_request(transaction_id, handle, &msg);
 }
 
@@ -359,8 +449,7 @@
                                            jint subscribe_id,
                                            jclass wifi_native_cls,
                                            jint iface,
-                                           jobject subscribe_data,
-                                           jobject subscribe_settings) {
+                                           jobject subscribe_config) {
     JNIHelper helper(env);
     wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface);
 
@@ -375,7 +464,6 @@
     msg.serviceResponseInclude = NAN_SRF_INCLUDE_RESPOND;
     msg.useServiceResponseFilter = NAN_DO_NOT_USE_SRF;
     msg.ssiRequiredForMatchIndication = NAN_SSI_NOT_REQUIRED_IN_MATCH_IND;
-    msg.subscribe_match_indicator = NAN_MATCH_ALG_MATCH_ONCE;
     msg.rssi_threshold_flag = 0;
     msg.connmap = 0;
     msg.num_intf_addr_present = 0;
@@ -383,41 +471,43 @@
     /* configurable settings */
     msg.subscribe_id = subscribe_id;
 
-    JNIObject<jstring> objStr1 = helper.getStringField(subscribe_data, "mServiceName");
-    if (objStr1 == NULL) {
-        ALOGE("Error accessing mServiceName field");
+    size_t service_name_len;
+    helper.getByteArrayField(subscribe_config, "mServiceName", msg.service_name,
+                             &service_name_len, NAN_MAX_SERVICE_NAME_LEN);
+    if (service_name_len > NAN_MAX_SERVICE_NAME_LEN) {
+        ALOGE("Length of service name field larger than max allowed");
         return 0;
     }
-    ScopedUtfChars chars1(env, objStr1);
-    const char *serviceName = chars1.c_str();
-    if (serviceName == NULL) {
-        ALOGE("Error getting mServiceName");
-        return 0;
-    }
-    msg.service_name_len = strlen(serviceName);
-    strcpy((char*)msg.service_name, serviceName);
+    msg.service_name_len = service_name_len;
 
-    msg.service_specific_info_len = helper.getIntField(subscribe_data, "mServiceSpecificInfoLength");
+    msg.service_specific_info_len = helper.getIntField(subscribe_config, "mServiceSpecificInfoLength");
     if (msg.service_specific_info_len != 0) {
-        helper.getByteArrayField(subscribe_data, "mServiceSpecificInfo",
+        helper.getByteArrayField(subscribe_config, "mServiceSpecificInfo",
                              msg.service_specific_info, msg.service_specific_info_len);
     }
 
-    msg.tx_match_filter_len = helper.getIntField(subscribe_data, "mTxFilterLength");
+    msg.tx_match_filter_len = helper.getIntField(subscribe_config, "mTxFilterLength");
     if (msg.tx_match_filter_len != 0) {
-        helper.getByteArrayField(subscribe_data, "mTxFilter",
+        helper.getByteArrayField(subscribe_config, "mTxFilter",
                              msg.tx_match_filter, msg.tx_match_filter_len);
     }
 
-    msg.rx_match_filter_len = helper.getIntField(subscribe_data, "mRxFilterLength");
+    msg.rx_match_filter_len = helper.getIntField(subscribe_config, "mRxFilterLength");
     if (msg.rx_match_filter_len != 0) {
-        helper.getByteArrayField(subscribe_data, "mRxFilter",
+        helper.getByteArrayField(subscribe_config, "mRxFilter",
                              msg.rx_match_filter, msg.rx_match_filter_len);
     }
 
-    msg.subscribe_type = (NanSubscribeType)helper.getIntField(subscribe_settings, "mSubscribeType");
-    msg.subscribe_count = helper.getIntField(subscribe_settings, "mSubscribeCount");
-    msg.ttl = helper.getIntField(subscribe_settings, "mTtlSec");
+    msg.subscribe_type = (NanSubscribeType)helper.getIntField(subscribe_config, "mSubscribeType");
+    msg.subscribe_count = helper.getIntField(subscribe_config, "mSubscribeCount");
+    msg.ttl = helper.getIntField(subscribe_config, "mTtlSec");
+    msg.subscribe_match_indicator = (NanMatchAlg) helper.getIntField(
+      subscribe_config, "mMatchStyle");
+
+    msg.recv_indication_cfg = 0;
+    if (!helper.getBoolField(subscribe_config, "mEnableTerminateNotification")) {
+      msg.recv_indication_cfg |= 0x1;
+    }
 
     return hal_fn.wifi_nan_subscribe_request(transaction_id, handle, &msg);
 }
@@ -493,6 +583,142 @@
     return hal_fn.wifi_nan_subscribe_cancel_request(transaction_id, handle, &msg);
 }
 
+static jint android_net_wifi_nan_create_nan_network_interface(
+    JNIEnv *env, jclass cls, jshort transaction_id, jclass wifi_native_cls,
+    jint iface, jstring interface_name) {
+  JNIHelper helper(env);
+  wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface);
+
+  ALOGD("android_net_wifi_nan_create_nan_network_interface handle=%p, id=%d",
+        handle, transaction_id);
+
+  ScopedUtfChars chars(env, interface_name);
+  if (chars.c_str() == NULL) {
+    return 0;
+  }
+
+  return hal_fn.wifi_nan_data_interface_create(transaction_id, handle,
+                                               (char*) chars.c_str());
+}
+
+static jint android_net_wifi_nan_delete_nan_network_interface(
+    JNIEnv *env, jclass cls, jshort transaction_id, jclass wifi_native_cls,
+    jint iface, jstring interface_name) {
+  JNIHelper helper(env);
+  wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface);
+
+  ALOGD("android_net_wifi_nan_delete_nan_network_interface handle=%p, id=%d",
+        handle, transaction_id);
+
+  ScopedUtfChars chars(env, interface_name);
+  if (chars.c_str() == NULL) {
+    return 0;
+  }
+
+  return hal_fn.wifi_nan_data_interface_delete(transaction_id, handle,
+                                               (char*) chars.c_str());
+}
+
+static jint android_net_wifi_nan_initiate_nan_data_path(
+    JNIEnv *env, jclass cls, jshort transaction_id, jclass wifi_native_cls,
+    jint iface, jint pub_sub_id, jint channel_request_type, jint channel,
+    jbyteArray peer, jstring interface_name, jbyteArray message,
+    jint message_length) {
+  JNIHelper helper(env);
+  wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface);
+
+  ALOGD("android_net_wifi_nan_initiate_nan_data_path handle=%p, id=%d", handle,
+        transaction_id);
+
+  NanDataPathInitiatorRequest msg;
+  memset(&msg, 0, sizeof(NanDataPathInitiatorRequest));
+
+  msg.service_instance_id = pub_sub_id;
+  msg.channel_request_type = (NanDataPathChannelCfg) channel_request_type;
+  msg.channel = channel;
+
+  ScopedBytesRO peerBytes(env, peer);
+  memcpy(msg.peer_disc_mac_addr, (byte *)peerBytes.get(), 6);
+
+  ScopedUtfChars chars(env, interface_name);
+  if (chars.c_str() == NULL) {
+    return 0;
+  }
+  strcpy(msg.ndp_iface, chars.c_str());
+
+  // TODO: b/26564544: add security configuration
+  msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
+
+  // TODO: b/29065317: add QoS configuration
+  msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
+
+  msg.app_info.ndp_app_info_len = message_length;
+
+  ScopedBytesRO messageBytes(env, message);
+  memcpy(msg.app_info.ndp_app_info, (byte *)messageBytes.get(), message_length);
+
+  return hal_fn.wifi_nan_data_request_initiator(transaction_id, handle, &msg);
+}
+
+static jint android_net_wifi_nan_respond_nan_data_path_request(
+    JNIEnv *env, jclass cls, jshort transaction_id, jclass wifi_native_cls,
+    jint iface, jboolean accept, jint ndp_id, jstring interface_name,
+    jbyteArray message, jint message_length) {
+  JNIHelper helper(env);
+  wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface);
+
+  ALOGD("android_net_wifi_nan_respond_nan_data_path_request handle=%p, id=%d",
+        handle, transaction_id);
+
+  NanDataPathIndicationResponse msg;
+  memset(&msg, 0, sizeof(NanDataPathIndicationResponse));
+
+  msg.ndp_instance_id = ndp_id;
+
+  ScopedUtfChars chars(env, interface_name);
+  if (chars.c_str() == NULL) {
+    return 0;
+  }
+  strcpy(msg.ndp_iface, chars.c_str());
+
+  // TODO: b/26564544: add security configuration
+  msg.ndp_cfg.security_cfg = NAN_DP_CONFIG_NO_SECURITY;
+
+  // TODO: b/29065317: add QoS configuration
+  msg.ndp_cfg.qos_cfg = NAN_DP_CONFIG_NO_QOS;
+
+  msg.app_info.ndp_app_info_len = message_length;
+
+  ScopedBytesRO messageBytes(env, message);
+  memcpy(msg.app_info.ndp_app_info, (byte *)messageBytes.get(), message_length);
+
+  msg.rsp_code = accept ? NAN_DP_REQUEST_ACCEPT : NAN_DP_REQUEST_REJECT;
+
+  return hal_fn.wifi_nan_data_indication_response(transaction_id, handle, &msg);
+}
+
+static jint android_net_wifi_nan_end_nan_data_path(JNIEnv *env, jclass cls,
+                                                   jshort transaction_id,
+                                                   jclass wifi_native_cls,
+                                                   jint iface, jint ndp_id) {
+  JNIHelper helper(env);
+  wifi_interface_handle handle = getIfaceHandle(helper, wifi_native_cls, iface);
+
+  ALOGD("android_net_wifi_nan_end_nan_data_path handle=%p, id=%d", handle,
+        transaction_id);
+
+  NanDataPathEndRequest* msg = (NanDataPathEndRequest*)malloc(sizeof(NanDataPathEndRequest) + sizeof(NanDataPathId));
+
+  msg->num_ndp_instances = 1;
+  msg->ndp_instance_id[0] = ndp_id;
+
+  jint status = hal_fn.wifi_nan_data_end(transaction_id, handle, msg);
+
+  free(msg);
+
+  return status;
+}
+
 // ----------------------------------------------------------------------------
 
 /*
@@ -501,16 +727,21 @@
 
 static JNINativeMethod gWifiNanMethods[] = {
     /* name, signature, funcPtr */
-
-    {"initNanHandlersNative", "(Ljava/lang/Object;I)I", (void*)android_net_wifi_nan_register_handler },
-    {"getCapabilitiesNative", "(SLjava/lang/Object;I)I", (void*)android_net_wifi_nan_get_capabilities },
-    {"enableAndConfigureNative", "(SLjava/lang/Object;ILandroid/net/wifi/nan/ConfigRequest;)I", (void*)android_net_wifi_nan_enable_request },
-    {"disableNative", "(SLjava/lang/Object;I)I", (void*)android_net_wifi_nan_disable_request },
-    {"publishNative", "(SILjava/lang/Object;ILandroid/net/wifi/nan/PublishData;Landroid/net/wifi/nan/PublishSettings;)I", (void*)android_net_wifi_nan_publish },
-    {"subscribeNative", "(SILjava/lang/Object;ILandroid/net/wifi/nan/SubscribeData;Landroid/net/wifi/nan/SubscribeSettings;)I", (void*)android_net_wifi_nan_subscribe },
-    {"sendMessageNative", "(SLjava/lang/Object;III[B[BI)I", (void*)android_net_wifi_nan_send_message },
-    {"stopPublishNative", "(SLjava/lang/Object;II)I", (void*)android_net_wifi_nan_stop_publish },
-    {"stopSubscribeNative", "(SLjava/lang/Object;II)I", (void*)android_net_wifi_nan_stop_subscribe },
+    {"initNanHandlersNative", "(Ljava/lang/Class;I)I", (void*)android_net_wifi_nan_register_handler },
+    {"getCapabilitiesNative", "(SLjava/lang/Class;I)I", (void*)android_net_wifi_nan_get_capabilities },
+    {"enableAndConfigureNative", "(SLjava/lang/Class;ILandroid/net/wifi/nan/ConfigRequest;)I", (void*)android_net_wifi_nan_enable_request },
+    {"updateConfigurationNative", "(SLjava/lang/Class;ILandroid/net/wifi/nan/ConfigRequest;)I", (void*)android_net_wifi_nan_config_request },
+    {"disableNative", "(SLjava/lang/Class;I)I", (void*)android_net_wifi_nan_disable_request },
+    {"publishNative", "(SILjava/lang/Class;ILandroid/net/wifi/nan/PublishConfig;)I", (void*)android_net_wifi_nan_publish },
+    {"subscribeNative", "(SILjava/lang/Class;ILandroid/net/wifi/nan/SubscribeConfig;)I", (void*)android_net_wifi_nan_subscribe },
+    {"sendMessageNative", "(SLjava/lang/Class;III[B[BI)I", (void*)android_net_wifi_nan_send_message },
+    {"stopPublishNative", "(SLjava/lang/Class;II)I", (void*)android_net_wifi_nan_stop_publish },
+    {"stopSubscribeNative", "(SLjava/lang/Class;II)I", (void*)android_net_wifi_nan_stop_subscribe },
+    {"createNanNetworkInterfaceNative", "(SLjava/lang/Class;ILjava/lang/String;)I", (void*)android_net_wifi_nan_create_nan_network_interface },
+    {"deleteNanNetworkInterfaceNative", "(SLjava/lang/Class;ILjava/lang/String;)I", (void*)android_net_wifi_nan_delete_nan_network_interface },
+    {"initiateDataPathNative", "(SLjava/lang/Class;IIII[BLjava/lang/String;[BI)I", (void*)android_net_wifi_nan_initiate_nan_data_path },
+    {"respondToDataPathRequestNative", "(SLjava/lang/Class;IZILjava/lang/String;[BI)I", (void*)android_net_wifi_nan_respond_nan_data_path_request },
+    {"endDataPathNative", "(SLjava/lang/Class;II)I", (void*)android_net_wifi_nan_end_nan_data_path },
 };
 
 /* User to register native functions */
diff --git a/service/jni/jni_helper.cpp b/service/jni/jni_helper.cpp
index c9b4edd..52f6bf2 100644
--- a/service/jni/jni_helper.cpp
+++ b/service/jni/jni_helper.cpp
@@ -16,15 +16,15 @@
 
 #define LOG_TAG "wifi"
 
-#include "jni.h"
-#include <ScopedUtfChars.h>
-#include <utils/misc.h>
 #include <android_runtime/AndroidRuntime.h>
+#include <hardware_legacy/wifi_hal.h>
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativehelper/jni.h>
 #include <utils/Log.h>
 #include <utils/String16.h>
+#include <utils/misc.h>
+#include <wifi_system/wifi.h>
 
-#include "wifi.h"
-#include "wifi_hal.h"
 #include "jni_helper.h"
 
 namespace android {
@@ -241,7 +241,7 @@
     return value;
 }
 
-void JNIHelper::getByteArrayField(jobject obj, const char *name, byte* buf, int size) {
+void JNIHelper::getByteArrayField(jobject obj, const char *name, byte *buf, size_t size) {
     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
     jfieldID field = mEnv->GetFieldID(cls, name, "[B");
     if (field == 0) {
@@ -265,6 +265,37 @@
     mEnv->ReleaseByteArrayElements(array, elem, 0);
 }
 
+void JNIHelper::getByteArrayField(jobject obj, const char *name, byte *buf, size_t *size, int max_size) {
+    JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
+    jfieldID field = mEnv->GetFieldID(cls, name, "[B");
+    if (field == 0) {
+        THROW(*this, "Error in accessing field definition");
+        return;
+    }
+
+    jbyteArray byteArray = (jbyteArray)mEnv->GetObjectField(obj, field);
+    JNIObject<jbyteArray> array(*this, byteArray);
+    if (array == NULL) {
+        THROW(*this, "Error in accessing array");
+        return;
+    }
+
+    *size = getArrayLength(byteArray);
+    int use_size = *size;
+    if (use_size > max_size) {
+        use_size = max_size;
+    }
+
+    jbyte *elem = mEnv->GetByteArrayElements(array, 0);
+    if (elem == NULL) {
+        THROW(*this, "Error in accessing index element");
+        return;
+    }
+
+    memcpy(buf, elem, use_size);
+    mEnv->ReleaseByteArrayElements(array, elem, 0);
+}
+
 jlong JNIHelper::getStaticLongArrayField(jobject obj, const char *name, int index)
 {
     JNIObject<jclass> cls(*this, mEnv->GetObjectClass(obj));
@@ -514,6 +545,7 @@
     jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature);
     if (methodID == 0) {
         ALOGE("Error in getting method ID");
+        va_end(params);
         return;
     }
 
@@ -535,6 +567,7 @@
     jmethodID methodID = mEnv->GetMethodID(cls, method, signature);
     if (methodID == 0) {
         ALOGE("Error in getting method ID");
+        va_end(params);
         return;
     }
 
@@ -555,6 +588,7 @@
     jmethodID methodID = mEnv->GetStaticMethodID(cls, method, signature);
     if (methodID == 0) {
         ALOGE("Error in getting method ID");
+        va_end(params);
         return false;
     }
 
@@ -562,6 +596,7 @@
     if (mEnv->ExceptionCheck()) {
         mEnv->ExceptionDescribe();
         mEnv->ExceptionClear();
+        va_end(params);
         return false;
     }
 
@@ -582,18 +617,21 @@
     JNIObject<jclass> cls(*this, mEnv->FindClass(className));
     if (cls == NULL) {
         ALOGE("Error in finding class %s", className);
+        va_end(params);
         return JNIObject<jobject>(*this, NULL);
     }
 
     jmethodID constructor = mEnv->GetMethodID(cls, "<init>", signature);
     if (constructor == 0) {
         ALOGE("Error in constructor ID for %s", className);
+        va_end(params);
         return JNIObject<jobject>(*this, NULL);
     }
 
     JNIObject<jobject> obj(*this, mEnv->NewObjectV(cls, constructor, params));
     if (obj == NULL) {
         ALOGE("Could not create new object of %s", className);
+        va_end(params);
         return JNIObject<jobject>(*this, NULL);
     }
 
diff --git a/service/jni/jni_helper.h b/service/jni/jni_helper.h
index bb65f1c..f665fa7 100644
--- a/service/jni/jni_helper.h
+++ b/service/jni/jni_helper.h
@@ -82,7 +82,8 @@
     bool getStringFieldValue(jobject obj, const char *name, char *buf, int size);
     JNIObject<jobject> getObjectField(jobject obj, const char *name, const char *type);
     JNIObject<jobjectArray> getArrayField(jobject obj, const char *name, const char *type);
-    void getByteArrayField(jobject obj, const char *name, byte* buf, int size);
+    void getByteArrayField(jobject obj, const char *name, byte *buf, size_t size);
+    void getByteArrayField(jobject obj, const char *name, byte *buf, size_t *size, int max_size);
     jlong getLongArrayField(jobject obj, const char *name, int index);
     JNIObject<jobject> getObjectArrayField(
             jobject obj, const char *name, const char *type, int index);
diff --git a/service/jni/wifi_hal_stub.h b/service/jni/wifi_hal_stub.h
deleted file mode 100644
index 6ec3d8e..0000000
--- a/service/jni/wifi_hal_stub.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __WIFI_HAL_STUB_H__
-#define __WIFI_HAL_STUB_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#include "wifi_hal.h"
-
-int init_wifi_stub_hal_func_table(wifi_hal_fn *hal_fn);
-
-/* declare all HAL stub API here*/
-wifi_error wifi_initialize_stub(wifi_handle *handle);
-void wifi_cleanup_stub(wifi_handle handle, wifi_cleaned_up_handler handler);
-void wifi_event_loop_stub(wifi_handle handle);
-void wifi_get_error_info_stub(wifi_error err, const char **msg);
-wifi_error wifi_get_supported_feature_set_stub(wifi_interface_handle handle, feature_set *set);
-wifi_error wifi_get_concurrency_matrix_stub(wifi_interface_handle handle, int set_size_max,
-        feature_set set[], int *set_size);
-wifi_error wifi_get_ifaces_stub(wifi_handle handle, int *num_ifaces, wifi_interface_handle **ifaces);
-wifi_error wifi_get_iface_name_stub(wifi_interface_handle iface, char *name, size_t size);
-wifi_error wifi_set_iface_event_handler_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_event_handler eh);
-wifi_error wifi_reset_iface_event_handler_stub(wifi_request_id id, wifi_interface_handle iface);
-wifi_error wifi_set_nodfs_flag_stub(wifi_interface_handle handle, u32 nodfs);
-wifi_error wifi_set_scanning_mac_oui_stub(wifi_interface_handle handle, unsigned char *oui);
-wifi_error wifi_get_supported_channels_stub(wifi_handle handle, int *size, wifi_channel *list);
-wifi_error wifi_is_epr_supported_stub(wifi_handle handle);
-wifi_error wifi_start_gscan_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_scan_cmd_params params, wifi_scan_result_handler handler);
-wifi_error wifi_stop_gscan_stub(wifi_request_id id, wifi_interface_handle iface);
-wifi_error wifi_get_cached_gscan_results_stub(wifi_interface_handle iface, byte flush,
-        int max, wifi_cached_scan_results *results, int *num);
-wifi_error wifi_set_bssid_hotlist_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler);
-wifi_error wifi_reset_bssid_hotlist_stub(wifi_request_id id, wifi_interface_handle iface);
-wifi_error wifi_set_significant_change_handler_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_significant_change_params params, wifi_significant_change_handler handler);
-wifi_error wifi_reset_significant_change_handler_stub(wifi_request_id id,
-        wifi_interface_handle iface);
-wifi_error wifi_get_gscan_capabilities_stub(wifi_interface_handle handle,
-        wifi_gscan_capabilities *capabilities);
-wifi_error wifi_set_link_stats_stub(wifi_interface_handle iface, wifi_link_layer_params params);
-wifi_error wifi_get_link_stats_stub(wifi_request_id id,
-         wifi_interface_handle iface, wifi_stats_result_handler handler);
-wifi_error wifi_clear_link_stats_stub(wifi_interface_handle iface,
-       u32 stats_clear_req_mask, u32 *stats_clear_rsp_mask, u8 stop_req, u8 *stop_rsp);
-wifi_error wifi_get_valid_channels_stub(wifi_interface_handle handle,
-         int band, int max_channels, wifi_channel *channels, int *num_channels);
-wifi_error wifi_rtt_range_request_stub(wifi_request_id id, wifi_interface_handle iface,
-         unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler);
-wifi_error wifi_rtt_range_cancel_stub(wifi_request_id id,  wifi_interface_handle iface,
-         unsigned num_devices, mac_addr addr[]);
-wifi_error wifi_get_rtt_capabilities_stub(wifi_interface_handle iface,
-         wifi_rtt_capabilities *capabilities);
-wifi_error wifi_rtt_get_available_channel_stub(wifi_interface_handle iface,
-        wifi_channel_info* channel);
-wifi_error wifi_enable_responder_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_channel_info channel_hint, unsigned max_duration_seconds,
-        wifi_channel_info* channel_used);
-wifi_error wifi_disable_responder_stub(wifi_request_id id, wifi_interface_handle iface);
-
-wifi_error wifi_set_nodfs_flag_stub(wifi_interface_handle iface, u32 nodfs);
-wifi_error wifi_start_logging_stub(wifi_interface_handle iface, u32 verbose_level, u32 flags,
-         u32 max_interval_sec, u32 min_data_size, char *buffer_name);
-wifi_error wifi_set_epno_list_stub(wifi_request_id id, wifi_interface_info *iface,
-        const wifi_epno_params *params, wifi_epno_handler handler);
-wifi_error wifi_reset_epno_list_stub(wifi_request_id id, wifi_interface_info *iface);
-wifi_error wifi_set_country_code_stub(wifi_interface_handle iface, const char *code);
-wifi_error wifi_get_firmware_memory_dump_stub( wifi_interface_handle iface,
-        wifi_firmware_memory_dump_handler handler);
-wifi_error wifi_set_log_handler_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_ring_buffer_data_handler handler);
-wifi_error wifi_reset_log_handler_stub(wifi_request_id id, wifi_interface_handle iface);
-wifi_error wifi_set_alert_handler_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_alert_handler handler);
-wifi_error wifi_reset_alert_handler_stub(wifi_request_id id, wifi_interface_handle iface);
-wifi_error wifi_get_firmware_version_stub(wifi_interface_handle iface, char *buffer,
-        int buffer_size);
-wifi_error wifi_get_ring_buffers_status_stub(wifi_interface_handle iface,
-        u32 *num_rings, wifi_ring_buffer_status *status);
-wifi_error wifi_get_logger_supported_feature_set_stub(wifi_interface_handle iface,
-        unsigned int *support);
-wifi_error wifi_get_ring_data_stub(wifi_interface_handle iface, char *ring_name);
-wifi_error wifi_enable_tdls_stub(wifi_interface_handle iface, mac_addr addr,
-        wifi_tdls_params *params, wifi_tdls_handler handler);
-wifi_error wifi_disable_tdls_stub(wifi_interface_handle iface, mac_addr addr);
-wifi_error wifi_get_tdls_status_stub(wifi_interface_handle iface, mac_addr addr,
-        wifi_tdls_status *status);
-wifi_error wifi_get_tdls_capabilities_stub(wifi_interface_handle iface,
-        wifi_tdls_capabilities *capabilities);
-wifi_error wifi_get_driver_version_stub(wifi_interface_handle iface, char *buffer,
-        int buffer_size);
- wifi_error wifi_set_country_code_stub(wifi_interface_handle iface, const char *code);
-wifi_error wifi_set_bssid_blacklist_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_bssid_params params);
-wifi_error wifi_start_sending_offloaded_packet_stub(wifi_request_id id,
-        wifi_interface_handle iface, u8 *ip_packet, u16 ip_packet_len,
-        u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec);
-wifi_error wifi_stop_sending_offloaded_packet_stub(wifi_request_id id, wifi_interface_handle iface);
-wifi_error wifi_get_wake_reason_stats_stub(wifi_interface_handle iface,
-                                        WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt);
-wifi_error wifi_configure_nd_offload_stub(wifi_interface_handle iface, u8 enable);
-wifi_error wifi_nan_enable_request_stub(transaction_id id,
-                              wifi_interface_handle iface,
-                              NanEnableRequest* msg);
-wifi_error wifi_nan_disable_request_stub(transaction_id id,
-                               wifi_interface_handle iface);
-wifi_error wifi_nan_publish_request_stub(transaction_id id,
-                               wifi_interface_handle iface,
-                               NanPublishRequest* msg);
-wifi_error wifi_nan_publish_cancel_request_stub(transaction_id id,
-                                      wifi_interface_handle iface,
-                                      NanPublishCancelRequest* msg);
-wifi_error wifi_nan_subscribe_request_stub(transaction_id id,
-                                 wifi_interface_handle iface,
-                                 NanSubscribeRequest* msg);
-wifi_error wifi_nan_subscribe_cancel_request_stub(transaction_id id,
-                                        wifi_interface_handle iface,
-                                        NanSubscribeCancelRequest* msg);
-wifi_error wifi_nan_transmit_followup_request_stub(transaction_id id,
-                                         wifi_interface_handle iface,
-                                         NanTransmitFollowupRequest* msg);
-wifi_error wifi_nan_stats_request_stub(transaction_id id,
-                             wifi_interface_handle iface,
-                             NanStatsRequest* msg);
-wifi_error wifi_nan_config_request_stub(transaction_id id,
-                              wifi_interface_handle iface,
-                              NanConfigRequest* msg);
-wifi_error wifi_nan_tca_request_stub(transaction_id id,
-                           wifi_interface_handle iface,
-                           NanTCARequest* msg);
-wifi_error wifi_nan_beacon_sdf_payload_request_stub(transaction_id id,
-                                         wifi_interface_handle iface,
-                                         NanBeaconSdfPayloadRequest* msg);
-wifi_error wifi_nan_register_handler_stub(wifi_interface_handle iface,
-                                NanCallbackHandler handlers);
-wifi_error wifi_nan_get_version_stub(wifi_handle handle,
-                           NanVersion* version);
-wifi_error wifi_nan_get_capabilities_stub(transaction_id id,
-                                wifi_interface_handle iface);
-wifi_error wifi_get_packet_filter_capabilities_stub(wifi_interface_handle handle,
-                                          u32 *version, u32 *max_len);
-wifi_error wifi_set_packet_filter_stub(wifi_interface_handle handle,
-                             const u8 *program, u32 len);
-
-#ifdef __cplusplus
-}
-#endif
-#endif //__WIFI_HAL_STUB_H__
diff --git a/service/lib/wifi_hal.cpp b/service/lib/wifi_hal.cpp
deleted file mode 100644
index 25bb373..0000000
--- a/service/lib/wifi_hal.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <stdint.h>
-#include "wifi_hal.h"
-
-wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
diff --git a/service/lib/wifi_hal_stub.cpp b/service/lib/wifi_hal_stub.cpp
deleted file mode 100644
index bd75b3d..0000000
--- a/service/lib/wifi_hal_stub.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#include <stdint.h>
-#include "wifi_hal.h"
-#include "wifi_hal_stub.h"
-
-wifi_error wifi_initialize_stub(wifi_handle *handle) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-void wifi_cleanup_stub(wifi_handle handle, wifi_cleaned_up_handler handler) {
-}
-
-void wifi_event_loop_stub(wifi_handle handle) {
-
-}
-
-void wifi_get_error_info_stub(wifi_error err, const char **msg) {
-    *msg = NULL;
-}
-
-wifi_error wifi_get_supported_feature_set_stub(wifi_interface_handle handle, feature_set *set) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_get_concurrency_matrix_stub(wifi_interface_handle handle, int max_size,
-        feature_set *matrix, int *size) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_set_scanning_mac_oui_stub(wifi_interface_handle handle, unsigned char *oui_data) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-/* List of all supported channels, including 5GHz channels */
-wifi_error wifi_get_supported_channels_stub(wifi_handle handle, int *size, wifi_channel *list) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-/* Enhanced power reporting */
-wifi_error wifi_is_epr_supported_stub(wifi_handle handle) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-/* multiple interface support */
-wifi_error wifi_get_ifaces_stub(wifi_handle handle, int *num_ifaces, wifi_interface_handle **ifaces) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_get_iface_name_stub(wifi_interface_handle iface, char *name, size_t size) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_set_iface_event_handler_stub(wifi_request_id id,
-            wifi_interface_handle iface, wifi_event_handler eh) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_reset_iface_event_handler_stub(wifi_request_id id, wifi_interface_handle iface) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_start_gscan_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_scan_cmd_params params, wifi_scan_result_handler handler) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_stop_gscan_stub(wifi_request_id id, wifi_interface_handle iface) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_get_cached_gscan_results_stub(wifi_interface_handle iface, byte flush,
-        int max, wifi_cached_scan_results *results, int *num) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_set_bssid_hotlist_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_bssid_hotlist_params params, wifi_hotlist_ap_found_handler handler) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_reset_bssid_hotlist_stub(wifi_request_id id, wifi_interface_handle iface) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_set_significant_change_handler_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_significant_change_params params, wifi_significant_change_handler handler) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_reset_significant_change_handler_stub(wifi_request_id id, wifi_interface_handle iface) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_get_gscan_capabilities_stub(wifi_interface_handle handle,
-        wifi_gscan_capabilities *capabilities) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_set_link_stats_stub(wifi_interface_handle iface, wifi_link_layer_params params) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_get_link_stats_stub(wifi_request_id id,
-        wifi_interface_handle iface, wifi_stats_result_handler handler) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_clear_link_stats_stub(wifi_interface_handle iface,
-      u32 stats_clear_req_mask, u32 *stats_clear_rsp_mask, u8 stop_req, u8 *stop_rsp) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-wifi_error wifi_get_valid_channels_stub(wifi_interface_handle handle,
-        int band, int max_channels, wifi_channel *channels, int *num_channels) {
-    return WIFI_ERROR_UNINITIALIZED;
-}
-
-/* API to request RTT measurement */
-wifi_error wifi_rtt_range_request_stub(wifi_request_id id, wifi_interface_handle iface,
-        unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-/* API to cancel RTT measurements */
-wifi_error wifi_rtt_range_cancel_stub(wifi_request_id id,  wifi_interface_handle iface,
-        unsigned num_devices, mac_addr addr[]) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-/* API to get RTT capability */
-wifi_error wifi_get_rtt_capabilities_stub(wifi_interface_handle iface,
-        wifi_rtt_capabilities *capabilities)
-{
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-/* API to enable RTT responder role */
-wifi_error wifi_enable_responder_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_channel_info channel_hint, unsigned max_duration_seconds,
-        wifi_channel_info* channel_used) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-/* API to disable RTT responder role */
-wifi_error wifi_disable_responder_stub(wifi_request_id id, wifi_interface_handle iface) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-/* API to get available channel for RTT responder role */
-wifi_error wifi_rtt_get_available_channel_stub(wifi_interface_handle iface, wifi_channel_info* channel) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_set_nodfs_flag_stub(wifi_interface_handle iface, u32 nodfs) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_start_logging_stub(wifi_interface_handle iface, u32 verbose_level, u32 flags,
-        u32 max_interval_sec, u32 min_data_size, char *buffer_name) {
-            return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_set_epno_list_stub(int id, wifi_interface_info *iface,
-        const wifi_epno_params *params, wifi_epno_handler handler) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_reset_epno_list_stub(int id, wifi_interface_info *iface) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_set_country_code_stub(wifi_interface_handle iface, const char *code) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_firmware_memory_dump_stub( wifi_interface_handle iface,
-        wifi_firmware_memory_dump_handler handler){
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_set_log_handler_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_ring_buffer_data_handler handler) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_reset_log_handler_stub(wifi_request_id id, wifi_interface_handle iface) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_set_alert_handler_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_alert_handler handler) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_reset_alert_handler_stub(wifi_request_id id, wifi_interface_handle iface) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_firmware_version_stub( wifi_interface_handle iface, char *buffer,
-        int buffer_size) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_ring_buffers_status_stub(wifi_interface_handle iface,
-        u32 *num_rings, wifi_ring_buffer_status *status) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_logger_supported_feature_set_stub(wifi_interface_handle iface,
-        unsigned int *support) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_ring_data_stub(wifi_interface_handle iface, char *ring_name) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_driver_version_stub(wifi_interface_handle iface, char *buffer,
-        int buffer_size) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_enable_tdls_stub(wifi_interface_handle iface, mac_addr addr,
-        wifi_tdls_params *params, wifi_tdls_handler handler) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_disable_tdls_stub(wifi_interface_handle iface, mac_addr addr) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_tdls_status_stub(wifi_interface_handle iface, mac_addr addr,
-        wifi_tdls_status *status) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_tdls_capabilities_stub(wifi_interface_handle iface,
-        wifi_tdls_capabilities *capabilities) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_set_bssid_blacklist_stub(wifi_request_id id, wifi_interface_handle iface,
-        wifi_bssid_params params) {
-      return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_start_sending_offloaded_packet_stub(wifi_request_id id,
-        wifi_interface_handle iface, u8 *ip_packet, u16 ip_packet_len,
-        u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_stop_sending_offloaded_packet_stub(wifi_request_id id, wifi_interface_handle iface) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_wake_reason_stats_stub(wifi_interface_handle iface,
-                                    WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_configure_nd_offload_stub(wifi_interface_handle iface, u8 enable) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_driver_memory_dump_stub(wifi_interface_handle iface,
-    wifi_driver_memory_dump_callbacks callbacks)  {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_start_pkt_fate_monitoring_stub(wifi_interface_handle iface) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_tx_pkt_fates_stub(wifi_interface_handle handle,
-    wifi_tx_report *tx_report_bufs, size_t n_requested_fates, size_t *n_provided_fates) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_rx_pkt_fates_stub(wifi_interface_handle handle,
-    wifi_rx_report *rx_report_bufs, size_t n_requested_fates, size_t *n_provided_fates) {
-    return WIFI_ERROR_NOT_SUPPORTED;
-}
-wifi_error wifi_nan_enable_request_stub(transaction_id id,
-                              wifi_interface_handle iface,
-                              NanEnableRequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_disable_request_stub(transaction_id id,
-                               wifi_interface_handle iface) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_publish_request_stub(transaction_id id,
-                               wifi_interface_handle iface,
-                               NanPublishRequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_publish_cancel_request_stub(transaction_id id,
-                                      wifi_interface_handle iface,
-                                      NanPublishCancelRequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_subscribe_request_stub(transaction_id id,
-                                 wifi_interface_handle iface,
-                                 NanSubscribeRequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_subscribe_cancel_request_stub(transaction_id id,
-                                        wifi_interface_handle iface,
-                                        NanSubscribeCancelRequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_transmit_followup_request_stub(transaction_id id,
-                                         wifi_interface_handle iface,
-                                         NanTransmitFollowupRequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_stats_request_stub(transaction_id id,
-                             wifi_interface_handle iface,
-                             NanStatsRequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_config_request_stub(transaction_id id,
-                              wifi_interface_handle iface,
-                              NanConfigRequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_tca_request_stub(transaction_id id,
-                           wifi_interface_handle iface,
-                           NanTCARequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_beacon_sdf_payload_request_stub(transaction_id id,
-                                         wifi_interface_handle iface,
-                                         NanBeaconSdfPayloadRequest* msg) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_register_handler_stub(wifi_interface_handle iface,
-                                NanCallbackHandler handlers) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_get_version_stub(wifi_handle handle,
-                           NanVersion* version) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_nan_get_capabilities_stub(transaction_id id,
-                                wifi_interface_handle iface) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_get_packet_filter_capabilities_stub(wifi_interface_handle handle,
-                                          u32 *version, u32 *max_len) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-wifi_error wifi_set_packet_filter_stub(wifi_interface_handle handle,
-                             const u8 *program, u32 len) {
-  return WIFI_ERROR_NOT_SUPPORTED;
-}
-
-int init_wifi_stub_hal_func_table(wifi_hal_fn *hal_fn) {
-    if (hal_fn == NULL) {
-        return -1;
-    }
-    hal_fn->wifi_initialize = wifi_initialize_stub;
-    hal_fn->wifi_cleanup = wifi_cleanup_stub;
-    hal_fn->wifi_event_loop = wifi_event_loop_stub;
-    hal_fn->wifi_get_error_info = wifi_get_error_info_stub;
-    hal_fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set_stub;
-    hal_fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix_stub;
-    hal_fn->wifi_set_scanning_mac_oui =  wifi_set_scanning_mac_oui_stub;
-    hal_fn->wifi_get_supported_channels = wifi_get_supported_channels_stub;
-    hal_fn->wifi_is_epr_supported = wifi_is_epr_supported_stub;
-    hal_fn->wifi_get_ifaces = wifi_get_ifaces_stub;
-    hal_fn->wifi_get_iface_name = wifi_get_iface_name_stub;
-    hal_fn->wifi_reset_iface_event_handler = wifi_reset_iface_event_handler_stub;
-    hal_fn->wifi_start_gscan = wifi_start_gscan_stub;
-    hal_fn->wifi_stop_gscan = wifi_stop_gscan_stub;
-    hal_fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results_stub;
-    hal_fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist_stub;
-    hal_fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist_stub;
-    hal_fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler_stub;
-    hal_fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler_stub;
-    hal_fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities_stub;
-    hal_fn->wifi_set_link_stats = wifi_set_link_stats_stub;
-    hal_fn->wifi_get_link_stats = wifi_get_link_stats_stub;
-    hal_fn->wifi_clear_link_stats = wifi_clear_link_stats_stub;
-    hal_fn->wifi_get_valid_channels = wifi_get_valid_channels_stub;
-    hal_fn->wifi_rtt_range_request = wifi_rtt_range_request_stub;
-    hal_fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel_stub;
-    hal_fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities_stub;
-    hal_fn->wifi_start_logging = wifi_start_logging_stub;
-    hal_fn->wifi_set_epno_list = wifi_set_epno_list_stub;
-    hal_fn->wifi_set_country_code = wifi_set_country_code_stub;
-    hal_fn->wifi_enable_tdls = wifi_enable_tdls_stub;
-    hal_fn->wifi_disable_tdls = wifi_disable_tdls_stub;
-    hal_fn->wifi_get_tdls_status = wifi_get_tdls_status_stub;
-    hal_fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities_stub;
-    hal_fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag_stub;
-    hal_fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump_stub;
-    hal_fn->wifi_set_log_handler = wifi_set_log_handler_stub;
-    hal_fn->wifi_reset_log_handler = wifi_reset_log_handler_stub;
-    hal_fn->wifi_set_alert_handler = wifi_set_alert_handler_stub;
-    hal_fn->wifi_reset_alert_handler = wifi_reset_alert_handler_stub;
-    hal_fn->wifi_get_firmware_version = wifi_get_firmware_version_stub;
-    hal_fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status_stub;
-    hal_fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set_stub;
-    hal_fn->wifi_get_ring_data = wifi_get_ring_data_stub;
-    hal_fn->wifi_get_driver_version = wifi_get_driver_version_stub;
-    hal_fn->wifi_set_bssid_blacklist = wifi_set_bssid_blacklist_stub;
-    hal_fn->wifi_start_sending_offloaded_packet = wifi_start_sending_offloaded_packet_stub;
-    hal_fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet_stub;
-    hal_fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats_stub;
-    hal_fn->wifi_configure_nd_offload = wifi_configure_nd_offload_stub;
-    hal_fn->wifi_get_driver_memory_dump = wifi_get_driver_memory_dump_stub;
-    hal_fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring_stub;
-    hal_fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates_stub;
-    hal_fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates_stub;
-    hal_fn->wifi_nan_enable_request = wifi_nan_enable_request_stub;
-    hal_fn->wifi_nan_disable_request = wifi_nan_disable_request_stub;
-    hal_fn->wifi_nan_publish_request = wifi_nan_publish_request_stub;
-    hal_fn->wifi_nan_publish_cancel_request = wifi_nan_publish_cancel_request_stub;
-    hal_fn->wifi_nan_subscribe_request = wifi_nan_subscribe_request_stub;
-    hal_fn->wifi_nan_subscribe_cancel_request = wifi_nan_subscribe_cancel_request_stub;
-    hal_fn->wifi_nan_transmit_followup_request = wifi_nan_transmit_followup_request_stub;
-    hal_fn->wifi_nan_stats_request = wifi_nan_stats_request_stub;
-    hal_fn->wifi_nan_config_request = wifi_nan_config_request_stub;
-    hal_fn->wifi_nan_tca_request = wifi_nan_tca_request_stub;
-    hal_fn->wifi_nan_beacon_sdf_payload_request = wifi_nan_beacon_sdf_payload_request_stub;
-    hal_fn->wifi_nan_register_handler = wifi_nan_register_handler_stub;
-    hal_fn->wifi_nan_get_version = wifi_nan_get_version_stub;
-    hal_fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities_stub;
-    hal_fn->wifi_set_packet_filter = wifi_set_packet_filter_stub;
-
-    return 0;
-}
diff --git a/tests/wifitests/Android.mk b/tests/wifitests/Android.mk
index e2489c4..c65a9d0 100644
--- a/tests/wifitests/Android.mk
+++ b/tests/wifitests/Android.mk
@@ -28,30 +28,29 @@
 	$(JNI_H_INCLUDE) \
 	$(LOCAL_PATH)/../../service/jni \
 	$(call include-path-for, libhardware)/hardware \
-	$(call include-path-for, libhardware_legacy)/hardware_legacy \
+	$(call include-path-for, libhardware_legacy) \
 	packages/apps/Test/connectivity/sl4n/rapidjson/include \
 	libcore/include
 
 LOCAL_SRC_FILES := \
 	jni/wifi_hal_mock.cpp
 
-ifdef INCLUDE_NAN_FEATURE
+ifeq ($(BOARD_HAS_NAN), true)
 LOCAL_SRC_FILES += \
 	jni/wifi_nan_hal_mock.cpp
 endif
 
 LOCAL_MODULE := libwifi-hal-mock
 
-LOCAL_STATIC_LIBRARIES += libwifi-hal
 LOCAL_SHARED_LIBRARIES += \
 	libnativehelper \
 	libcutils \
 	libutils \
 	libhardware \
-	libhardware_legacy \
 	libnl \
 	libdl \
-	libwifi-service
+	libwifi-service \
+	libwifi-system
 
 include $(BUILD_SHARED_LIBRARY)
 
@@ -63,7 +62,7 @@
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
-ifndef INCLUDE_NAN_FEATURE
+ifneq ($(BOARD_HAS_NAN), true)
 LOCAL_SRC_FILES := $(filter-out $(call all-java-files-under, \
           src/com/android/server/wifi/nan),$(LOCAL_SRC_FILES))
 endif
@@ -103,6 +102,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
 	android-support-test \
 	mockito-target \
+	frameworks-base-testutils \
 	services \
 	wifi-service \
 
@@ -114,20 +114,40 @@
 # These must be explicitly included because they are not normally accessible
 # from apps.
 LOCAL_JNI_SHARED_LIBRARIES := \
+	libcrypto \
 	libwifi-service \
-	libc++ \
-	libLLVM \
-	libutils \
-	libunwind \
-	libhardware_legacy \
-	libbase \
-	libhardware \
-	libnl \
-	libcutils \
-	libnetutils \
+	libEGL \
+	libGLESv2 \
+	libaudioutils \
 	libbacktrace \
-	libnativehelper \
+	libbase \
+	libbinder \
+	libc++ \
+	libcamera_client \
+	libcamera_metadata \
+	libcutils \
+	libexpat \
+	libgui \
+	libhardware \
+	libicui18n \
+	libicuuc \
 	liblzma \
+	libmedia \
+	libnativehelper \
+	libnbaio \
+	libnetutils \
+	libnl \
+	libpowermanager \
+	libsonivox \
+	libspeexresampler \
+	libstagefright_foundation \
+	libstdc++ \
+	libsync \
+	libwifi-hal \
+	libwifi-system \
+	libui \
+	libunwind \
+	libutils \
 
 ifdef WPA_SUPPLICANT_VERSION
 LOCAL_JNI_SHARED_LIBRARIES += libwpa_client
diff --git a/tests/wifitests/README.md b/tests/wifitests/README.md
index c68014e..8812f83 100644
--- a/tests/wifitests/README.md
+++ b/tests/wifitests/README.md
@@ -8,21 +8,22 @@
 The easiest way to run tests is simply run
 
 ```
-runtest frameworks-wifi
+frameworks/opt/net/wifi/tests/wifitests/runtests.sh
 ```
 
-`runtest` will build the test project and push the APK to the connected device. It will then run the
-tests on the device. See `runtest --help` for options to specify individual test classes or methods.
+`runtests.sh` will build the test project and all of its dependencies and push the APK to the
+connected device. It will then run the tests on the device.
 
-**WARNING:** You have to build the components under test (wifi-service, etc) first before you run
-runtest for changes there to take effect. You can use the following command from your build root to
-build the wifi service and run tests.
+See below for a few example of options to limit which tests are run.
+See the
+[AndroidJUnitRunner Documentation](https://developer.android.com/reference/android/support/test/runner/AndroidJUnitRunner.html)
+for more details on the supported options.
 
 ```
-mmma frameworks/opt/net/wifi/tests && runtest frameworks-wifi
+runtests.sh -e package com.android.server.wifi.util
+runtests.sh -e class com.android.server.wifi.WifiStateMachineTest
 ```
 
-
 If you manually build and push the test APK to the device you can run tests using
 
 ```
@@ -41,7 +42,7 @@
 ## Code Coverage
 If you would like to collect code coverage information you can run the `coverage.sh` script located
 in this directory. It will rebuild parts of your tree with coverage enabled and then run the tests,
-similar to runtest. If you have multiple devices connected to your machine make sure to set the
+similar to runtests.sh. If you have multiple devices connected to your machine make sure to set the
 `ANDROID_SERIAL` environment variable before running the script. You must supply an output directory
 for results. By default the results are generated as a set of HTML pages. For example, you can use
 the following from the root out your source tree to generate results in the wifi_coverage directory
diff --git a/tests/wifitests/jni/wifi_hal_mock.cpp b/tests/wifitests/jni/wifi_hal_mock.cpp
index 06b2d23..96c0dd5 100644
--- a/tests/wifitests/jni/wifi_hal_mock.cpp
+++ b/tests/wifitests/jni/wifi_hal_mock.cpp
@@ -25,8 +25,8 @@
 #include <ctype.h>
 #include <sys/socket.h>
 #include <linux/if.h>
-#include "wifi.h"
-#include "wifi_hal.h"
+#include "wifi_system/wifi.h"
+#include "hardware_legacy/wifi_hal.h"
 #include "jni_helper.h"
 #include "wifi_hal_mock.h"
 #include <sstream>
diff --git a/tests/wifitests/jni/wifi_hal_mock.h b/tests/wifitests/jni/wifi_hal_mock.h
index 2b9cad4..f316122 100644
--- a/tests/wifitests/jni/wifi_hal_mock.h
+++ b/tests/wifitests/jni/wifi_hal_mock.h
@@ -17,7 +17,7 @@
 #ifndef __WIFI_HAL_MOCK_H__
 #define __WIFI_HAL_MOCK_H__
 
-#include "wifi_hal.h"
+#include "hardware_legacy/wifi_hal.h"
 
 #include <rapidjson/document.h>
 #include <rapidjson/stringbuffer.h>
@@ -90,6 +90,21 @@
 wifi_error wifi_nan_get_version_mock(wifi_handle handle, NanVersion* version);
 wifi_error wifi_nan_get_capabilities_mock(transaction_id id,
                                 wifi_interface_handle iface);
+wifi_error wifi_nan_data_interface_create_mock(transaction_id id,
+                                               wifi_interface_handle iface,
+                                               char* iface_name);
+wifi_error wifi_nan_data_interface_delete_mock(transaction_id id,
+                                               wifi_interface_handle iface,
+                                               char* iface_name);
+wifi_error wifi_nan_data_request_initiator_mock(
+    transaction_id id, wifi_interface_handle iface,
+    NanDataPathInitiatorRequest* msg);
+wifi_error wifi_nan_data_indication_response_mock(
+    transaction_id id, wifi_interface_handle iface,
+    NanDataPathIndicationResponse* msg);
+wifi_error wifi_nan_data_end_mock(transaction_id id,
+                                  wifi_interface_handle iface,
+                                  NanDataPathEndRequest* msg);
 
 }  // namespace android
 
diff --git a/tests/wifitests/jni/wifi_nan_hal_mock.cpp b/tests/wifitests/jni/wifi_nan_hal_mock.cpp
index 022fadd..01da519 100644
--- a/tests/wifitests/jni/wifi_nan_hal_mock.cpp
+++ b/tests/wifitests/jni/wifi_nan_hal_mock.cpp
@@ -25,8 +25,8 @@
 #include <ctype.h>
 #include <sys/socket.h>
 #include <linux/if.h>
-#include "wifi.h"
-#include "wifi_hal.h"
+#include "wifi_system/wifi.h"
+#include "hardware_legacy/wifi_hal.h"
 #include "jni_helper.h"
 #include "wifi_hal_mock.h"
 #include <sstream>
@@ -161,6 +161,7 @@
                        msg->tx_match_filter_len);
   jsonW.put_int("rssi_threshold_flag", msg->rssi_threshold_flag);
   jsonW.put_int("connmap", msg->connmap);
+  jsonW.put_int("recv_indication_cfg", msg->recv_indication_cfg);
   std::string str = jsonW.to_string();
 
   JNIObject < jstring > json_write_string = helper.newStringUTF(str.c_str());
@@ -222,6 +223,7 @@
   jsonW.put_int("connmap", msg->connmap);
   jsonW.put_int("num_intf_addr_present", msg->num_intf_addr_present);
   // TODO: jsonW.put_byte_array("intf_addr", msg->intf_addr, NAN_MAX_SUBSCRIBE_MAX_ADDRESS * NAN_MAC_ADDR_LEN);
+  jsonW.put_int("recv_indication_cfg", msg->recv_indication_cfg);
   std::string str = jsonW.to_string();
 
   JNIObject < jstring > json_write_string = helper.newStringUTF(str.c_str());
@@ -286,8 +288,41 @@
 wifi_error wifi_nan_config_request_mock(transaction_id id,
                                         wifi_interface_handle iface,
                                         NanConfigRequest* msg) {
+  JNIHelper helper(mock_mVM);
+
   ALOGD("wifi_nan_config_request_mock");
-  return WIFI_ERROR_UNINITIALIZED;
+  HalMockJsonWriter jsonW;
+  jsonW.put_int("config_sid_beacon", msg->config_sid_beacon);
+  jsonW.put_int("sid_beacon", msg->sid_beacon);
+  jsonW.put_int("config_rssi_proximity", msg->config_rssi_proximity);
+  jsonW.put_int("rssi_proximity", msg->rssi_proximity);
+  jsonW.put_int("config_master_pref", msg->config_master_pref);
+  jsonW.put_int("master_pref", msg->master_pref);
+  jsonW.put_int("config_5g_rssi_close_proximity", msg->config_5g_rssi_close_proximity);
+  jsonW.put_int("rssi_close_proximity_5g_val", msg->rssi_close_proximity_5g_val);
+  jsonW.put_int("config_rssi_window_size", msg->config_rssi_window_size);
+  jsonW.put_int("rssi_window_size_val", msg->rssi_window_size_val);
+  jsonW.put_int("config_cluster_attribute_val", msg->config_cluster_attribute_val);
+  jsonW.put_int("config_scan_params", msg->config_scan_params);
+  // TODO: NanSocialChannelScanParams scan_params_val
+  jsonW.put_int("config_random_factor_force", msg->config_random_factor_force);
+  jsonW.put_int("random_factor_force_val", msg->random_factor_force_val);
+  jsonW.put_int("config_hop_count_force", msg->config_hop_count_force);
+  jsonW.put_int("hop_count_force_val", msg->hop_count_force_val);
+  jsonW.put_int("config_conn_capability", msg->config_conn_capability);
+  // TODO: NanTransmitPostConnectivityCapability conn_capability_val
+  jsonW.put_int("num_config_discovery_attr", msg->num_config_discovery_attr);
+  // TODO: NanTransmitPostDiscovery discovery_attr_val[NAN_MAX_POSTDISCOVERY_LEN]
+  jsonW.put_int("config_fam", msg->config_fam);
+  // TODO: NanFurtherAvailabilityMap fam_val
+  std::string str = jsonW.to_string();
+
+  JNIObject < jstring > json_write_string = helper.newStringUTF(str.c_str());
+
+  helper.callMethod(mock_mObj, "configHalMockNative", "(SLjava/lang/String;)V",
+                    (short) id, json_write_string.get());
+
+  return WIFI_SUCCESS;
 }
 
 wifi_error wifi_nan_tca_request_mock(transaction_id id,
@@ -327,6 +362,119 @@
   return WIFI_SUCCESS;
 }
 
+wifi_error wifi_nan_data_interface_create_mock(transaction_id id,
+                                               wifi_interface_handle iface,
+                                               char* iface_name) {
+  JNIHelper helper(mock_mVM);
+
+  ALOGD("wifi_nan_data_interface_create_mock");
+  HalMockJsonWriter jsonW;
+  jsonW.put_byte_array("iface_name", (u8*) iface_name, strlen(iface_name));
+  std::string str = jsonW.to_string();
+
+  JNIObject<jstring> json_write_string = helper.newStringUTF(str.c_str());
+
+  helper.callMethod(mock_mObj, "createNanNetworkInterfaceMockNative",
+                    "(SLjava/lang/String;)V", (short)id,
+                    json_write_string.get());
+
+  return WIFI_SUCCESS;
+}
+
+wifi_error wifi_nan_data_interface_delete_mock(transaction_id id,
+                                               wifi_interface_handle iface,
+                                               char* iface_name) {
+  JNIHelper helper(mock_mVM);
+
+  ALOGD("wifi_nan_data_interface_delete_mock");
+  HalMockJsonWriter jsonW;
+  jsonW.put_byte_array("iface_name", (u8*) iface_name, strlen(iface_name));
+  std::string str = jsonW.to_string();
+
+  JNIObject<jstring> json_write_string = helper.newStringUTF(str.c_str());
+
+  helper.callMethod(mock_mObj, "deleteNanNetworkInterfaceMockNative",
+                    "(SLjava/lang/String;)V", (short)id,
+                    json_write_string.get());
+
+  return WIFI_SUCCESS;
+}
+
+wifi_error wifi_nan_data_request_initiator_mock(
+    transaction_id id, wifi_interface_handle iface,
+    NanDataPathInitiatorRequest* msg) {
+  JNIHelper helper(mock_mVM);
+
+  ALOGD("wifi_nan_data_request_initiator_mock");
+  HalMockJsonWriter jsonW;
+  jsonW.put_int("service_instance_id", msg->service_instance_id);
+  jsonW.put_int("channel_request_type", (int)msg->channel_request_type);
+  jsonW.put_int("channel", (int)msg->channel);
+  jsonW.put_byte_array("peer_disc_mac_addr", msg->peer_disc_mac_addr, 6);
+  jsonW.put_byte_array("ndp_iface", (u8*) msg->ndp_iface, strlen(msg->ndp_iface));
+  jsonW.put_int("ndp_cfg.security_cfg", (int)msg->ndp_cfg.security_cfg);
+  jsonW.put_int("ndp_cfg.qos_cfg", (int)msg->ndp_cfg.qos_cfg);
+  jsonW.put_int("app_info.ndp_app_info_len", msg->app_info.ndp_app_info_len);
+  jsonW.put_byte_array("app_info.ndp_app_info", msg->app_info.ndp_app_info,
+                       msg->app_info.ndp_app_info_len);
+  std::string str = jsonW.to_string();
+
+  JNIObject<jstring> json_write_string = helper.newStringUTF(str.c_str());
+
+  helper.callMethod(mock_mObj, "initiateDataPathMockNative",
+                    "(SLjava/lang/String;)V", (short)id,
+                    json_write_string.get());
+
+  return WIFI_SUCCESS;
+}
+
+wifi_error wifi_nan_data_indication_response_mock(
+    transaction_id id, wifi_interface_handle iface,
+    NanDataPathIndicationResponse* msg) {
+  JNIHelper helper(mock_mVM);
+
+  ALOGD("wifi_nan_data_indication_response_mock");
+  HalMockJsonWriter jsonW;
+  jsonW.put_int("ndp_instance_id", msg->ndp_instance_id);
+  jsonW.put_byte_array("ndp_iface", (u8*) msg->ndp_iface, strlen(msg->ndp_iface));
+  jsonW.put_int("ndp_cfg.security_cfg", (int)msg->ndp_cfg.security_cfg);
+  jsonW.put_int("ndp_cfg.qos_cfg", (int)msg->ndp_cfg.qos_cfg);
+  jsonW.put_int("app_info.ndp_app_info_len", msg->app_info.ndp_app_info_len);
+  jsonW.put_byte_array("app_info.ndp_app_info", msg->app_info.ndp_app_info,
+                       msg->app_info.ndp_app_info_len);
+  jsonW.put_int("rsp_code", (int)msg->rsp_code);
+  std::string str = jsonW.to_string();
+
+  JNIObject<jstring> json_write_string = helper.newStringUTF(str.c_str());
+
+  helper.callMethod(mock_mObj, "respondToDataPathRequestMockNative",
+                    "(SLjava/lang/String;)V", (short)id,
+                    json_write_string.get());
+
+  return WIFI_SUCCESS;
+}
+
+wifi_error wifi_nan_data_end_mock(transaction_id id,
+                                  wifi_interface_handle iface,
+                                  NanDataPathEndRequest* msg) {
+  JNIHelper helper(mock_mVM);
+
+  ALOGD("wifi_nan_data_end_mock");
+  HalMockJsonWriter jsonW;
+  jsonW.put_int("num_ndp_instances", msg->num_ndp_instances);
+  if (msg->num_ndp_instances == 1) {
+    jsonW.put_int("ndp_instance_id", msg->ndp_instance_id[0]);
+  }
+  std::string str = jsonW.to_string();
+
+  JNIObject<jstring> json_write_string = helper.newStringUTF(str.c_str());
+
+  helper.callMethod(mock_mObj, "endDataPathMockNative", "(SLjava/lang/String;)V",
+                    (short)id, json_write_string.get());
+
+  return WIFI_SUCCESS;
+}
+
 // Callbacks
 
 extern "C" void Java_com_android_server_wifi_nan_WifiNanHalMock_callNotifyResponse(
@@ -374,6 +522,11 @@
         "body.nan_capabilities.max_ndp_sessions", &error);
     msg.body.nan_capabilities.max_app_info_len = jsonR.get_int(
         "body.nan_capabilities.max_app_info_len", &error);
+    msg.body.nan_capabilities.max_queued_transmit_followup_msgs = jsonR.get_int(
+        "body.nan_capabilities.max_queued_transmit_followup_msgs", &error);
+  } else if (msg.response_type == NAN_DP_INITIATOR_RESPONSE) {
+      msg.body.data_request_response.ndp_instance_id = jsonR.get_int(
+          "body.data_request_response.ndp_instance_id", &error);
   }
 
   if (error) {
@@ -541,8 +694,123 @@
   mCallbackHandlers.EventDisabled(&msg);
 }
 
+extern "C" void Java_com_android_server_wifi_nan_WifiNanHalMock_callTransmitFollowup(
+    JNIEnv* env, jclass clazz, jstring json_args_jstring) {
+  ScopedUtfChars chars(env, json_args_jstring);
+  HalMockJsonReader jsonR(chars.c_str());
+  bool error = false;
+
+  ALOGD("Java_com_android_server_wifi_nan_WifiNanHalMock_callTransmitFollowup: '%s'",
+        chars.c_str());
+
+  NanTransmitFollowupInd msg;
+  msg.id = (transaction_id) jsonR.get_int("id", &error);
+  msg.reason = (NanStatusType) jsonR.get_int("reason", &error);
+
+  if (error) {
+    ALOGE("Java_com_android_server_wifi_nan_WifiNanHalMock_callTransmitFollowup: "
+          "error parsing args");
+    return;
+  }
+
+  mCallbackHandlers.EventTransmitFollowup(&msg);
+}
+
+extern "C" void Java_com_android_server_wifi_nan_WifiNanHalMock_callDataPathRequest(
+    JNIEnv* env, jclass clazz, jstring json_args_jstring) {
+  ScopedUtfChars chars(env, json_args_jstring);
+  HalMockJsonReader jsonR(chars.c_str());
+  bool error = false;
+
+  ALOGD("Java_com_android_server_wifi_nan_WifiNanHalMock_callDataPathRequest: '%s'",
+        chars.c_str());
+
+  NanDataPathRequestInd msg;
+  msg.service_instance_id = jsonR.get_int("service_instance_id", &error);
+  jsonR.get_byte_array("peer_disc_mac_addr", &error, msg.peer_disc_mac_addr, 6);
+  msg.ndp_instance_id = (NanDataPathId)jsonR.get_int("ndp_instance_id", &error);
+  msg.ndp_cfg.security_cfg = (NanDataPathSecurityCfgStatus)jsonR.get_int(
+      "ndp_cfg.security_cfg", &error);
+  msg.ndp_cfg.qos_cfg =
+      (NanDataPathQosCfg)jsonR.get_int("ndp_cfg.qos_cfg", &error);
+  msg.app_info.ndp_app_info_len =
+      jsonR.get_int("app_info.ndp_app_info_len", &error);
+  jsonR.get_byte_array("app_info.ndp_app_info", &error,
+                       msg.app_info.ndp_app_info,
+                       msg.app_info.ndp_app_info_len);
+
+  if (error) {
+    ALOGE(
+        "Java_com_android_server_wifi_nan_WifiNanHalMock_callDataPathRequest: "
+        "error parsing args");
+    return;
+  }
+
+  mCallbackHandlers.EventDataRequest(&msg);
+}
+
+extern "C" void Java_com_android_server_wifi_nan_WifiNanHalMock_callDataPathConfirm(
+    JNIEnv* env, jclass clazz, jstring json_args_jstring) {
+  ScopedUtfChars chars(env, json_args_jstring);
+  HalMockJsonReader jsonR(chars.c_str());
+  bool error = false;
+
+  ALOGD("Java_com_android_server_wifi_nan_WifiNanHalMock_callDataPathConfirm: '%s'",
+        chars.c_str());
+
+  NanDataPathConfirmInd msg;
+  msg.ndp_instance_id = (NanDataPathId)jsonR.get_int("ndp_instance_id", &error);
+  jsonR.get_byte_array("peer_ndi_mac_addr", &error, msg.peer_ndi_mac_addr, 6);
+  msg.app_info.ndp_app_info_len =
+      jsonR.get_int("app_info.ndp_app_info_len", &error);
+  jsonR.get_byte_array("app_info.ndp_app_info", &error,
+                       msg.app_info.ndp_app_info,
+                       msg.app_info.ndp_app_info_len);
+  msg.rsp_code = (NanDataPathResponseCode)jsonR.get_int("rsp_code", &error);
+  msg.reason_code = (NanStatusType)jsonR.get_int("reason_code", &error);
+
+  if (error) {
+    ALOGE(
+        "Java_com_android_server_wifi_nan_WifiNanHalMock_callDataPathConfirm: "
+        "error parsing args");
+    return;
+  }
+
+  mCallbackHandlers.EventDataConfirm(&msg);
+}
+
+extern "C" void Java_com_android_server_wifi_nan_WifiNanHalMock_callDataPathEnd(
+    JNIEnv* env, jclass clazz, jstring json_args_jstring) {
+  ScopedUtfChars chars(env, json_args_jstring);
+  HalMockJsonReader jsonR(chars.c_str());
+  bool error = false;
+
+  ALOGD("Java_com_android_server_wifi_nan_WifiNanHalMock_callDataPathEnd: '%s'",
+        chars.c_str());
+
+  int num_ndp_instances = jsonR.get_int("num_ndp_instances", &error);
+
+  NanDataPathEndInd* msg = (NanDataPathEndInd*) malloc(sizeof(NanDataPathEndInd)
+                                                       + num_ndp_instances * sizeof(NanDataPathId));
+  msg->num_ndp_instances = num_ndp_instances;
+  for (int i = 0; i < num_ndp_instances; ++i) {
+    msg->ndp_instance_id[i] = jsonR.get_int("ndp_instance_id", &error) + i;
+  }
+
+  if (error) {
+    ALOGE(
+        "Java_com_android_server_wifi_nan_WifiNanHalMock_callDataPathEnd: "
+        "error parsing args");
+    return;
+  }
+
+  mCallbackHandlers.EventDataEnd(msg);
+
+  free(msg);
+}
+
 // TODO: Not currently used: add as needed
-//void (*EventUnMatch) (NanUnmatchInd* event);
+//void (*EventMatchExpired) (NanUnmatchInd* event);
 //void (*EventTca) (NanTCAInd* event);
 //void (*EventBeaconSdfPayload) (NanBeaconSdfPayloadInd* event);
 
@@ -569,6 +837,11 @@
   fn->wifi_nan_register_handler = wifi_nan_register_handler_mock;
   fn->wifi_nan_get_version = wifi_nan_get_version_mock;
   fn->wifi_nan_get_capabilities = wifi_nan_get_capabilities_mock;
+  fn->wifi_nan_data_interface_create = wifi_nan_data_interface_create_mock;
+  fn->wifi_nan_data_interface_delete = wifi_nan_data_interface_delete_mock;
+  fn->wifi_nan_data_request_initiator = wifi_nan_data_request_initiator_mock;
+  fn->wifi_nan_data_indication_response = wifi_nan_data_indication_response_mock;
+  fn->wifi_nan_data_end = wifi_nan_data_end_mock;
 
   return 0;
 }
diff --git a/tests/wifitests/runtests.sh b/tests/wifitests/runtests.sh
new file mode 100755
index 0000000..c0551a4
--- /dev/null
+++ b/tests/wifitests/runtests.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+if [ -z $ANDROID_BUILD_TOP ]; then
+  echo "You need to source and lunch before you can use this script"
+  exit 1
+fi
+
+echo "Running tests"
+
+set -e # fail early
+
+echo "+ mmma -j32 $ANDROID_BUILD_TOP/frameworks/opt/net/wifi/tests"
+# NOTE Don't actually run the command above since this shell doesn't inherit functions from the
+#      caller.
+make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk MODULES-IN-frameworks-opt-net-wifi-tests
+
+set -x # print commands
+
+adb root
+adb wait-for-device
+
+adb install -r -g "$OUT/data/app/FrameworksWifiTests/FrameworksWifiTests.apk"
+
+adb shell am instrument -w "$@" 'com.android.server.wifi.test/android.support.test.runner.AndroidJUnitRunner'
diff --git a/tests/wifitests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/tests/wifitests/src/android/net/wifi/WifiEnterpriseConfigTest.java
index 75480b5..814594d 100644
--- a/tests/wifitests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ b/tests/wifitests/src/android/net/wifi/WifiEnterpriseConfigTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
 
 import android.net.wifi.WifiEnterpriseConfig.Eap;
 import android.net.wifi.WifiEnterpriseConfig.Phase2;
@@ -50,6 +51,22 @@
     }
 
     @Test
+    public void testGetEmptyCaCertificate() {
+        // A newly-constructed WifiEnterpriseConfig object should have no CA certificate.
+        assertNull(mEnterpriseConfig.getCaCertificate());
+        assertNull(mEnterpriseConfig.getCaCertificates());
+        // Setting CA certificate to null explicitly.
+        mEnterpriseConfig.setCaCertificate(null);
+        assertNull(mEnterpriseConfig.getCaCertificate());
+        // Setting CA certificate to null using setCaCertificates().
+        mEnterpriseConfig.setCaCertificates(null);
+        assertNull(mEnterpriseConfig.getCaCertificates());
+        // Setting CA certificate to zero-length array.
+        mEnterpriseConfig.setCaCertificates(new X509Certificate[0]);
+        assertNull(mEnterpriseConfig.getCaCertificates());
+    }
+
+    @Test
     public void testSetGetSingleCaCertificate() {
         X509Certificate cert0 = FakeKeys.CA_CERT0;
         mEnterpriseConfig.setCaCertificate(cert0);
diff --git a/tests/wifitests/src/android/net/wifi/WifiScannerTest.java b/tests/wifitests/src/android/net/wifi/WifiScannerTest.java
index 5034c2a..a829eb9 100644
--- a/tests/wifitests/src/android/net/wifi/WifiScannerTest.java
+++ b/tests/wifitests/src/android/net/wifi/WifiScannerTest.java
@@ -30,10 +30,10 @@
 import android.net.wifi.WifiScanner.BssidListener;
 import android.os.Handler;
 import android.os.Message;
+import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.server.wifi.BidirectionalAsyncChannelServer;
-import com.android.server.wifi.MockLooper;
+import com.android.internal.util.test.BidirectionalAsyncChannelServer;
 
 import org.junit.After;
 import org.junit.Before;
@@ -55,7 +55,7 @@
     private BssidListener mBssidListener;
 
     private WifiScanner mWifiScanner;
-    private MockLooper mLooper;
+    private TestLooper mLooper;
     private Handler mHandler;
 
     /**
@@ -64,7 +64,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mLooper = new MockLooper();
+        mLooper = new TestLooper();
         mHandler = mock(Handler.class);
         BidirectionalAsyncChannelServer server = new BidirectionalAsyncChannelServer(
                 mContext, mLooper.getLooper(), mHandler);
diff --git a/tests/wifitests/src/com/android/server/wifi/AnqpCacheTest.java b/tests/wifitests/src/com/android/server/wifi/AnqpCacheTest.java
index 1a96831..9b06d13 100644
--- a/tests/wifitests/src/com/android/server/wifi/AnqpCacheTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/AnqpCacheTest.java
@@ -113,7 +113,7 @@
     private void advanceTimeAndTrimCache(long howManyMillis) {
         mCurrentTimeMillis += howManyMillis;
         Log.d(TAG, "Time set to " + mCurrentTimeMillis);
-        when(mClock.currentTimeMillis()).thenReturn(mCurrentTimeMillis);
+        when(mClock.getWallClockMillis()).thenReturn(mCurrentTimeMillis);
         mCache.clear(false, true);
     }
 
diff --git a/tests/wifitests/src/com/android/server/wifi/BidirectionalAsyncChannel.java b/tests/wifitests/src/com/android/server/wifi/BidirectionalAsyncChannel.java
deleted file mode 100644
index 75c0f87..0000000
--- a/tests/wifitests/src/com/android/server/wifi/BidirectionalAsyncChannel.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.wifi;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.util.Log;
-
-import com.android.internal.util.AsyncChannel;
-
-
-/**
- * Provides an AsyncChannel interface that implements the connection initiating half of a
- * bidirectional channel as described in {@link com.android.internal.util.AsyncChannel}.
- */
-public class BidirectionalAsyncChannel {
-    private static final String TAG = "BidirectionalAsyncChannel";
-
-    private AsyncChannel mChannel;
-    public enum ChannelState { DISCONNECTED, HALF_CONNECTED, CONNECTED, FAILURE };
-    private ChannelState mState = ChannelState.DISCONNECTED;
-
-    public void assertConnected() {
-        assertEquals("AsyncChannel was not fully connected", ChannelState.CONNECTED, mState);
-    }
-
-    public void connect(final Looper looper, final Messenger messenger,
-            final Handler incomingMessageHandler) {
-        assertEquals("AsyncChannel must be disconnected to connect",
-                ChannelState.DISCONNECTED, mState);
-        mChannel = new AsyncChannel();
-        Handler rawMessageHandler = new Handler(looper) {
-                @Override
-                public void handleMessage(Message msg) {
-                    switch (msg.what) {
-                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
-                        if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                            Log.d(TAG, "Successfully half connected " + this);
-                            mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
-                            mState = ChannelState.HALF_CONNECTED;
-                        } else {
-                            Log.d(TAG, "Failed to connect channel " + this);
-                            mState = ChannelState.FAILURE;
-                            mChannel = null;
-                        }
-                        break;
-                    case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
-                        mState = ChannelState.CONNECTED;
-                        Log.d(TAG, "Channel fully connected" + this);
-                        break;
-                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                        mState = ChannelState.DISCONNECTED;
-                        mChannel = null;
-                        Log.d(TAG, "Channel disconnected" + this);
-                        break;
-                    default:
-                        incomingMessageHandler.handleMessage(msg);
-                        break;
-                    }
-                }
-            };
-        mChannel.connect(null, rawMessageHandler, messenger);
-    }
-
-    public void disconnect() {
-        assertEquals("AsyncChannel must be connected to disconnect",
-                ChannelState.CONNECTED, mState);
-        mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_DISCONNECT);
-        mState = ChannelState.DISCONNECTED;
-        mChannel = null;
-    }
-
-    public void sendMessage(Message msg) {
-        assertEquals("AsyncChannel must be connected to send messages",
-                ChannelState.CONNECTED, mState);
-        mChannel.sendMessage(msg);
-    }
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/BidirectionalAsyncChannelServer.java b/tests/wifitests/src/com/android/server/wifi/BidirectionalAsyncChannelServer.java
deleted file mode 100644
index 6cc0e90..0000000
--- a/tests/wifitests/src/com/android/server/wifi/BidirectionalAsyncChannelServer.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.util.Log;
-
-import com.android.internal.util.AsyncChannel;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Provides an interface for the server side implementation of a bidirectional channel as described
- * in {@link com.android.internal.util.AsyncChannel}.
- */
-public class BidirectionalAsyncChannelServer {
-
-    private static final String TAG = "BidirectionalAsyncChannelServer";
-
-    // Keeps track of incoming clients, which are identifiable by their messengers.
-    private final Map<Messenger, AsyncChannel> mClients = new HashMap<>();
-
-    private Messenger mMessenger;
-
-    public BidirectionalAsyncChannelServer(final Context context, final Looper looper,
-            final Handler messageHandler) {
-        Handler handler = new Handler(looper) {
-            @Override
-            public void handleMessage(Message msg) {
-                AsyncChannel channel = mClients.get(msg.replyTo);
-                switch (msg.what) {
-                    case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
-                        if (channel != null) {
-                            Log.d(TAG, "duplicate client connection: " + msg.sendingUid);
-                            channel.replyToMessage(msg,
-                                    AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
-                                    AsyncChannel.STATUS_FULL_CONNECTION_REFUSED_ALREADY_CONNECTED);
-                        } else {
-                            channel = new AsyncChannel();
-                            mClients.put(msg.replyTo, channel);
-                            channel.connected(context, this, msg.replyTo);
-                            channel.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
-                                    AsyncChannel.STATUS_SUCCESSFUL);
-                        }
-                        break;
-                    case AsyncChannel.CMD_CHANNEL_DISCONNECT:
-                        channel.disconnect();
-                        break;
-
-                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                        mClients.remove(msg.replyTo);
-                        break;
-
-                    default:
-                        messageHandler.handleMessage(msg);
-                        break;
-                }
-            }
-        };
-        mMessenger = new Messenger(handler);
-    }
-
-    public Messenger getMessenger() {
-        return mMessenger;
-    }
-
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java b/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
index 328feaf..c1e333b 100644
--- a/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ConfigurationMapTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.when;
 
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
 import android.content.pm.UserInfo;
 import android.net.wifi.WifiConfiguration;
 import android.os.UserHandle;
@@ -28,8 +29,6 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.SparseArray;
 
-import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
diff --git a/tests/wifitests/src/com/android/server/wifi/HalMockUtils.java b/tests/wifitests/src/com/android/server/wifi/HalMockUtils.java
index 6e485f6..3235ff7 100644
--- a/tests/wifitests/src/com/android/server/wifi/HalMockUtils.java
+++ b/tests/wifitests/src/com/android/server/wifi/HalMockUtils.java
@@ -19,12 +19,11 @@
 import android.os.Bundle;
 import android.util.Log;
 
-import com.android.server.wifi.WifiNative;
-
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.util.Iterator;
 
@@ -43,14 +42,24 @@
 
     public static void initHalMockLibrary() throws Exception {
         /*
-         * Setting the Wi-Fi HAL handle and interface (array) to dummy
-         * values. Required to fake the init checking code to think that
-         * the HAL actually started.
-         *
-         * Note that values are not important since they are only used by
-         * the real HAL - which is mocked-out in this use-case.
+         * Setting the Wi-Fi HAL handle and interface (array) to dummy values.
+         * Need to install a default WifiNative (since another mock may have
+         * installed something else). Required to fake the init checking code to
+         * think that the HAL actually started. Note that values are not
+         * important since they are only used by the real HAL - which is
+         * mocked-out in this use-case.
          */
-        Field field = WifiNative.class.getDeclaredField("sWifiHalHandle");
+
+        Constructor<WifiNative> ctr = WifiNative.class.getDeclaredConstructor(String.class,
+                                                                              Boolean.TYPE);
+        ctr.setAccessible(true);
+        WifiNative wifiNativeInstance = ctr.newInstance("wlan0", true);
+
+        Field field = WifiNative.class.getDeclaredField("wlanNativeInterface");
+        field.setAccessible(true);
+        field.set(null, wifiNativeInstance);
+
+        field = WifiNative.class.getDeclaredField("sWifiHalHandle");
         field.setAccessible(true);
         long currentWifiHalHandle = field.getLong(null);
         if (DBG) Log.d(TAG, "currentWifiHalHandle=" + currentWifiHalHandle);
diff --git a/tests/wifitests/src/com/android/server/wifi/MockAlarmManager.java b/tests/wifitests/src/com/android/server/wifi/MockAlarmManager.java
deleted file mode 100644
index 02af281..0000000
--- a/tests/wifitests/src/com/android/server/wifi/MockAlarmManager.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-
-import android.app.AlarmManager;
-import android.os.Handler;
-
-import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Creates an AlarmManager whose alarm dispatch can be controlled
- * Currently only supports alarm listeners
- *
- * Alarm listeners will be dispatched to the handler provided or will
- * be dispatched imediatly if they would have been sent to the main
- * looper (handler was null).
- */
-public class MockAlarmManager {
-    private final AlarmManager mAlarmManager;
-    private final List<PendingAlarm> mPendingAlarms;
-
-    public MockAlarmManager() throws Exception {
-        mPendingAlarms = new ArrayList<>();
-
-        mAlarmManager = mock(AlarmManager.class);
-        doAnswer(new SetListenerAnswer()).when(mAlarmManager).set(anyInt(), anyLong(), anyString(),
-                any(AlarmManager.OnAlarmListener.class), any(Handler.class));
-        doAnswer(new SetListenerAnswer()).when(mAlarmManager).setExact(anyInt(), anyLong(),
-                anyString(), any(AlarmManager.OnAlarmListener.class), any(Handler.class));
-        doAnswer(new CancelListenerAnswer())
-                .when(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
-    }
-
-    public AlarmManager getAlarmManager() {
-        return mAlarmManager;
-    }
-
-    /**
-     * Dispatch a pending alarm with the given tag
-     * @return if any alarm was dispatched
-     */
-    public boolean dispatch(String tag) {
-        for (int i = 0; i < mPendingAlarms.size(); ++i) {
-            PendingAlarm alarm = mPendingAlarms.get(i);
-            if (Objects.equals(tag, alarm.getTag())) {
-                mPendingAlarms.remove(i);
-                alarm.dispatch();
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @return if an alarm with the given tag is pending
-     */
-    public boolean isPending(String tag) {
-        for (int i = 0; i < mPendingAlarms.size(); ++i) {
-            PendingAlarm alarm = mPendingAlarms.get(i);
-            if (Objects.equals(tag, alarm.getTag())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @return trigger time of an pending alarm with the given tag
-     *         -1 if no pending alram with the given tag
-     */
-    public long getTriggerTimeMillis(String tag) {
-        for (int i = 0; i < mPendingAlarms.size(); ++i) {
-            PendingAlarm alarm = mPendingAlarms.get(i);
-            if (Objects.equals(tag, alarm.getTag())) {
-                return alarm.getTriggerTimeMillis();
-            }
-        }
-        return -1;
-    }
-
-    private static class PendingAlarm {
-        private final int mType;
-        private final long mTriggerAtMillis;
-        private final String mTag;
-        private final Runnable mCallback;
-
-        public PendingAlarm(int type, long triggerAtMillis, String tag, Runnable callback) {
-            mType = type;
-            mTriggerAtMillis = triggerAtMillis;
-            mTag = tag;
-            mCallback = callback;
-        }
-
-        public void dispatch() {
-            if (mCallback != null) {
-                mCallback.run();
-            }
-        }
-
-        public Runnable getCallback() {
-            return mCallback;
-        }
-
-        public String getTag() {
-            return mTag;
-        }
-
-        public long getTriggerTimeMillis() {
-            return mTriggerAtMillis;
-        }
-    }
-
-    private class SetListenerAnswer extends AnswerWithArguments {
-        public void answer(int type, long triggerAtMillis, String tag,
-                AlarmManager.OnAlarmListener listener, Handler handler) {
-            mPendingAlarms.add(new PendingAlarm(type, triggerAtMillis, tag,
-                            new AlarmListenerRunnable(listener, handler)));
-        }
-    }
-
-    private class CancelListenerAnswer extends AnswerWithArguments {
-        public void answer(AlarmManager.OnAlarmListener listener) {
-            Iterator<PendingAlarm> alarmItr = mPendingAlarms.iterator();
-            while (alarmItr.hasNext()) {
-                PendingAlarm alarm = alarmItr.next();
-                if (alarm.getCallback() instanceof AlarmListenerRunnable) {
-                    AlarmListenerRunnable alarmCallback =
-                            (AlarmListenerRunnable) alarm.getCallback();
-                    if (alarmCallback.getListener() == listener) {
-                        alarmItr.remove();
-                    }
-                }
-            }
-        }
-    }
-
-    private static class AlarmListenerRunnable implements Runnable {
-        private final AlarmManager.OnAlarmListener mListener;
-        private final Handler mHandler;
-        public AlarmListenerRunnable(AlarmManager.OnAlarmListener listener, Handler handler) {
-            mListener = listener;
-            mHandler = handler;
-        }
-
-        public Handler getHandler() {
-            return mHandler;
-        }
-
-        public AlarmManager.OnAlarmListener getListener() {
-            return mListener;
-        }
-
-        public void run() {
-            if (mHandler != null) {
-                mHandler.post(new Runnable() {
-                        public void run() {
-                            mListener.onAlarm();
-                        }
-                    });
-            } else { // normally gets dispatched in main looper
-                mListener.onAlarm();
-            }
-        }
-    }
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/MockAnswerUtil.java b/tests/wifitests/src/com/android/server/wifi/MockAnswerUtil.java
deleted file mode 100644
index 1a3dfa1..0000000
--- a/tests/wifitests/src/com/android/server/wifi/MockAnswerUtil.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-
-/**
- * Utilities for creating Answers for mock objects
- */
-public class MockAnswerUtil {
-
-    /**
-     * Answer that calls the method in the Answer called "answer" that matches the type signature of
-     * the method being answered. An error will be thrown at runtime if the signature does not match
-     * exactly.
-     */
-    public static class AnswerWithArguments implements Answer<Object> {
-        @Override
-        public final Object answer(InvocationOnMock invocation) throws Throwable {
-            Method method = invocation.getMethod();
-            try {
-                Method implementation = getClass().getMethod("answer", method.getParameterTypes());
-                if (!implementation.getReturnType().equals(method.getReturnType())) {
-                    throw new RuntimeException("Found answer method does not have expected return "
-                            + "type. Expected: " + method.getReturnType() + ", got "
-                            + implementation.getReturnType());
-                }
-                Object[] args = invocation.getArguments();
-                try {
-                    return implementation.invoke(this, args);
-                } catch (IllegalAccessException e) {
-                    throw new RuntimeException("Error invoking answer method", e);
-                } catch (InvocationTargetException e) {
-                    throw e.getCause();
-                }
-            } catch (NoSuchMethodException e) {
-                throw new RuntimeException("Could not find answer method with the expected args "
-                        + Arrays.toString(method.getParameterTypes()), e);
-            }
-        }
-    }
-
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/MockLooper.java b/tests/wifitests/src/com/android/server/wifi/MockLooper.java
deleted file mode 100644
index 34d80a4..0000000
--- a/tests/wifitests/src/com/android/server/wifi/MockLooper.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import static org.junit.Assert.assertTrue;
-
-import android.os.Looper;
-import android.os.Message;
-import android.os.MessageQueue;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Creates a looper whose message queue can be manipulated
- * This allows testing code that uses a looper to dispatch messages in a deterministic manner
- * Creating a MockLooper will also install it as the looper for the current thread
- */
-public class MockLooper {
-    protected final Looper mLooper;
-
-    private static final Constructor<Looper> LOOPER_CONSTRUCTOR;
-    private static final Field THREAD_LOCAL_LOOPER_FIELD;
-    private static final Field MESSAGE_QUEUE_MESSAGES_FIELD;
-    private static final Field MESSAGE_NEXT_FIELD;
-    private static final Field MESSAGE_WHEN_FIELD;
-    private static final Method MESSAGE_MARK_IN_USE_METHOD;
-    private static final String TAG = "MockLooper";
-
-    private AutoDispatchThread mAutoDispatchThread;
-
-    static {
-        try {
-            LOOPER_CONSTRUCTOR = Looper.class.getDeclaredConstructor(Boolean.TYPE);
-            LOOPER_CONSTRUCTOR.setAccessible(true);
-            THREAD_LOCAL_LOOPER_FIELD = Looper.class.getDeclaredField("sThreadLocal");
-            THREAD_LOCAL_LOOPER_FIELD.setAccessible(true);
-            MESSAGE_QUEUE_MESSAGES_FIELD = MessageQueue.class.getDeclaredField("mMessages");
-            MESSAGE_QUEUE_MESSAGES_FIELD.setAccessible(true);
-            MESSAGE_NEXT_FIELD = Message.class.getDeclaredField("next");
-            MESSAGE_NEXT_FIELD.setAccessible(true);
-            MESSAGE_WHEN_FIELD = Message.class.getDeclaredField("when");
-            MESSAGE_WHEN_FIELD.setAccessible(true);
-            MESSAGE_MARK_IN_USE_METHOD = Message.class.getDeclaredMethod("markInUse");
-            MESSAGE_MARK_IN_USE_METHOD.setAccessible(true);
-        } catch (NoSuchFieldException | NoSuchMethodException e) {
-            throw new RuntimeException("Failed to initialize MockLooper", e);
-        }
-    }
-
-
-    public MockLooper() {
-        try {
-            mLooper = LOOPER_CONSTRUCTOR.newInstance(false);
-
-            ThreadLocal<Looper> threadLocalLooper = (ThreadLocal<Looper>) THREAD_LOCAL_LOOPER_FIELD
-                    .get(null);
-            threadLocalLooper.set(mLooper);
-        } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
-            throw new RuntimeException("Reflection error constructing or accessing looper", e);
-        }
-    }
-
-    public Looper getLooper() {
-        return mLooper;
-    }
-
-    private Message getMessageLinkedList() {
-        try {
-            MessageQueue queue = mLooper.getQueue();
-            return (Message) MESSAGE_QUEUE_MESSAGES_FIELD.get(queue);
-        } catch (IllegalAccessException e) {
-            throw new RuntimeException("Access failed in MockLooper: get - MessageQueue.mMessages",
-                    e);
-        }
-    }
-
-    public void moveTimeForward(long milliSeconds) {
-        try {
-            Message msg = getMessageLinkedList();
-            while (msg != null) {
-                long updatedWhen = msg.getWhen() - milliSeconds;
-                if (updatedWhen < 0) {
-                    updatedWhen = 0;
-                }
-                MESSAGE_WHEN_FIELD.set(msg, updatedWhen);
-                msg = (Message) MESSAGE_NEXT_FIELD.get(msg);
-            }
-        } catch (IllegalAccessException e) {
-            throw new RuntimeException("Access failed in MockLooper: set - Message.when", e);
-        }
-    }
-
-    private Message messageQueueNext() {
-        try {
-            long now = SystemClock.uptimeMillis();
-
-            Message prevMsg = null;
-            Message msg = getMessageLinkedList();
-            if (msg != null && msg.getTarget() == null) {
-                // Stalled by a barrier. Find the next asynchronous message in
-                // the queue.
-                do {
-                    prevMsg = msg;
-                    msg = (Message) MESSAGE_NEXT_FIELD.get(msg);
-                } while (msg != null && !msg.isAsynchronous());
-            }
-            if (msg != null) {
-                if (now >= msg.getWhen()) {
-                    // Got a message.
-                    if (prevMsg != null) {
-                        MESSAGE_NEXT_FIELD.set(prevMsg, MESSAGE_NEXT_FIELD.get(msg));
-                    } else {
-                        MESSAGE_QUEUE_MESSAGES_FIELD.set(mLooper.getQueue(),
-                                MESSAGE_NEXT_FIELD.get(msg));
-                    }
-                    MESSAGE_NEXT_FIELD.set(msg, null);
-                    MESSAGE_MARK_IN_USE_METHOD.invoke(msg);
-                    return msg;
-                }
-            }
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            throw new RuntimeException("Access failed in MockLooper", e);
-        }
-
-        return null;
-    }
-
-    /**
-     * @return true if there are pending messages in the message queue
-     */
-    public synchronized boolean isIdle() {
-        Message messageList = getMessageLinkedList();
-
-        return messageList != null && SystemClock.uptimeMillis() >= messageList.getWhen();
-    }
-
-    /**
-     * @return the next message in the Looper's message queue or null if there is none
-     */
-    public synchronized Message nextMessage() {
-        if (isIdle()) {
-            return messageQueueNext();
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Dispatch the next message in the queue
-     * Asserts that there is a message in the queue
-     */
-    public synchronized void dispatchNext() {
-        assertTrue(isIdle());
-        Message msg = messageQueueNext();
-        if (msg == null) {
-            return;
-        }
-        msg.getTarget().dispatchMessage(msg);
-    }
-
-    /**
-     * Dispatch all messages currently in the queue
-     * Will not fail if there are no messages pending
-     * @return the number of messages dispatched
-     */
-    public synchronized int dispatchAll() {
-        int count = 0;
-        while (isIdle()) {
-            dispatchNext();
-            ++count;
-        }
-        return count;
-    }
-
-    /**
-     * Thread used to dispatch messages when the main thread is blocked waiting for a response.
-     */
-    private class AutoDispatchThread extends Thread {
-        private static final int MAX_LOOPS = 100;
-        private static final int LOOP_SLEEP_TIME_MS = 10;
-
-        private RuntimeException mAutoDispatchException = null;
-
-        /**
-         * Run method for the auto dispatch thread.
-         * The thread loops a maximum of MAX_LOOPS times with a 10ms sleep between loops.
-         * The thread continues looping and attempting to dispatch all messages until at
-         * least one message has been dispatched.
-         */
-        @Override
-        public void run() {
-            int dispatchCount = 0;
-            for (int i = 0; i < MAX_LOOPS; i++) {
-                try {
-                    dispatchCount = dispatchAll();
-                } catch (RuntimeException e) {
-                    mAutoDispatchException = e;
-                }
-                Log.d(TAG, "dispatched " + dispatchCount + " messages");
-                if (dispatchCount > 0) {
-                    return;
-                }
-                try {
-                    Thread.sleep(LOOP_SLEEP_TIME_MS);
-                } catch (InterruptedException e) {
-                    mAutoDispatchException = new IllegalStateException(
-                            "stopAutoDispatch called before any messages were dispatched.");
-                    return;
-                }
-            }
-            Log.e(TAG, "AutoDispatchThread did not dispatch any messages.");
-            mAutoDispatchException = new IllegalStateException(
-                    "MockLooper did not dispatch any messages before exiting.");
-        }
-
-        /**
-         * Method allowing the MockLooper to pass any exceptions thrown by the thread to be passed
-         * to the main thread.
-         *
-         * @return RuntimeException Exception created by stopping without dispatching a message
-         */
-        public RuntimeException getException() {
-            return mAutoDispatchException;
-        }
-    }
-
-    /**
-     * Create and start a new AutoDispatchThread if one is not already running.
-     */
-    public void startAutoDispatch() {
-        if (mAutoDispatchThread != null) {
-            throw new IllegalStateException(
-                    "startAutoDispatch called with the AutoDispatchThread already running.");
-        }
-        mAutoDispatchThread = new AutoDispatchThread();
-        mAutoDispatchThread.start();
-    }
-
-    /**
-     * If an AutoDispatchThread is currently running, stop and clean up.
-     */
-    public void stopAutoDispatch() {
-        if (mAutoDispatchThread != null) {
-            if (mAutoDispatchThread.isAlive()) {
-                mAutoDispatchThread.interrupt();
-            }
-            try {
-                mAutoDispatchThread.join();
-            } catch (InterruptedException e) {
-                // Catch exception from join.
-            }
-
-            RuntimeException e = mAutoDispatchThread.getException();
-            mAutoDispatchThread = null;
-            if (e != null) {
-                throw e;
-            }
-        } else {
-            // stopAutoDispatch was called when startAutoDispatch has not created a new thread.
-            throw new IllegalStateException(
-                    "stopAutoDispatch called without startAutoDispatch.");
-        }
-    }
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/MockLooperTest.java b/tests/wifitests/src/com/android/server/wifi/MockLooperTest.java
deleted file mode 100644
index 74a73d6..0000000
--- a/tests/wifitests/src/com/android/server/wifi/MockLooperTest.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ErrorCollector;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Test MockLooperAbstractTime which provides control over "time". Note that
- * real-time is being used as well. Therefore small time increments are NOT
- * reliable. All tests are in "K" units (i.e. *1000).
- */
-
-@SmallTest
-public class MockLooperTest {
-    private MockLooper mMockLooper;
-    private Handler mHandler;
-    private Handler mHandlerSpy;
-
-    @Rule
-    public ErrorCollector collector = new ErrorCollector();
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        mMockLooper = new MockLooper();
-        mHandler = new Handler(mMockLooper.getLooper());
-        mHandlerSpy = spy(mHandler);
-    }
-
-    /**
-     * Basic test with no time stamps: dispatch 4 messages, check that all 4
-     * delivered (in correct order).
-     */
-    @Test
-    public void testNoTimeMovement() {
-        final int messageA = 1;
-        final int messageB = 2;
-        final int messageC = 3;
-
-        InOrder inOrder = inOrder(mHandlerSpy);
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageA));
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageA));
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageB));
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageC));
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("1: messageA", messageA, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("2: messageA", messageA, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("3: messageB", messageB, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("4: messageC", messageC, equalTo(messageCaptor.getValue().what));
-
-        inOrder.verify(mHandlerSpy, never()).handleMessage(any(Message.class));
-    }
-
-    /**
-     * Test message sequence: A, B, C@5K, A@10K. Don't move time.
-     * <p>
-     * Expected: only get A, B
-     */
-    @Test
-    public void testDelayedDispatchNoTimeMove() {
-        final int messageA = 1;
-        final int messageB = 2;
-        final int messageC = 3;
-
-        InOrder inOrder = inOrder(mHandlerSpy);
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageA));
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageB));
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageC), 5000);
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageA), 10000);
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("1: messageA", messageA, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("2: messageB", messageB, equalTo(messageCaptor.getValue().what));
-
-        inOrder.verify(mHandlerSpy, never()).handleMessage(any(Message.class));
-    }
-
-    /**
-     * Test message sequence: A, B, C@5K, A@10K, Advance time by 5K.
-     * <p>
-     * Expected: only get A, B, C
-     */
-    @Test
-    public void testDelayedDispatchAdvanceTimeOnce() {
-        final int messageA = 1;
-        final int messageB = 2;
-        final int messageC = 3;
-
-        InOrder inOrder = inOrder(mHandlerSpy);
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageA));
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageB));
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageC), 5000);
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageA), 10000);
-        mMockLooper.moveTimeForward(5000);
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("1: messageA", messageA, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("2: messageB", messageB, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("3: messageC", messageC, equalTo(messageCaptor.getValue().what));
-
-        inOrder.verify(mHandlerSpy, never()).handleMessage(any(Message.class));
-    }
-
-    /**
-     * Test message sequence: A, B, C@5K, Advance time by 4K, A@1K, B@2K Advance
-     * time by 1K.
-     * <p>
-     * Expected: get A, B, C, A
-     */
-    @Test
-    public void testDelayedDispatchAdvanceTimeTwice() {
-        final int messageA = 1;
-        final int messageB = 2;
-        final int messageC = 3;
-
-        InOrder inOrder = inOrder(mHandlerSpy);
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageA));
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageB));
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageC), 5000);
-        mMockLooper.moveTimeForward(4000);
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageA), 1000);
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageB), 2000);
-        mMockLooper.moveTimeForward(1000);
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("1: messageA", messageA, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("2: messageB", messageB, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("3: messageC", messageC, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("4: messageA", messageA, equalTo(messageCaptor.getValue().what));
-
-        inOrder.verify(mHandlerSpy, never()).handleMessage(any(Message.class));
-    }
-
-    /**
-     * Test message sequence: A, B, C@5K, Advance time by 4K, A@5K, B@2K Advance
-     * time by 3K.
-     * <p>
-     * Expected: get A, B, C, B
-     */
-    @Test
-    public void testDelayedDispatchReverseOrder() {
-        final int messageA = 1;
-        final int messageB = 2;
-        final int messageC = 3;
-
-        InOrder inOrder = inOrder(mHandlerSpy);
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageA));
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageB));
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageC), 5000);
-        mMockLooper.moveTimeForward(4000);
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageA), 5000);
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageB), 2000);
-        mMockLooper.moveTimeForward(3000);
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("1: messageA", messageA, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("2: messageB", messageB, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("3: messageC", messageC, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("4: messageB", messageB, equalTo(messageCaptor.getValue().what));
-
-        inOrder.verify(mHandlerSpy, never()).handleMessage(any(Message.class));
-    }
-
-    /**
-     * Test message sequence: A, B, C@5K, Advance time by 4K, dispatch all,
-     * A@5K, B@2K Advance time by 3K, dispatch all.
-     * <p>
-     * Expected: get A, B after first dispatch; then C, B after second dispatch
-     */
-    @Test
-    public void testDelayedDispatchAllMultipleTimes() {
-        final int messageA = 1;
-        final int messageB = 2;
-        final int messageC = 3;
-
-        InOrder inOrder = inOrder(mHandlerSpy);
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageA));
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageB));
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageC), 5000);
-        mMockLooper.moveTimeForward(4000);
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("1: messageA", messageA, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("2: messageB", messageB, equalTo(messageCaptor.getValue().what));
-
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageA), 5000);
-        mHandlerSpy.sendMessageDelayed(mHandler.obtainMessage(messageB), 2000);
-        mMockLooper.moveTimeForward(3000);
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("3: messageC", messageC, equalTo(messageCaptor.getValue().what));
-        inOrder.verify(mHandlerSpy).handleMessage(messageCaptor.capture());
-        collector.checkThat("4: messageB", messageB, equalTo(messageCaptor.getValue().what));
-
-        inOrder.verify(mHandlerSpy, never()).handleMessage(any(Message.class));
-    }
-
-    /**
-     * Test AutoDispatch for a single message.
-     * This test would ideally use the Channel sendMessageSynchronously.  At this time, the setup to
-     * get a working test channel is cumbersome.  Until this is fixed, we substitute with a
-     * sendMessage followed by a blocking call.  The main test thread blocks until the test handler
-     * receives the test message (messageA) and sets a boolean true.  Once the boolean is true, the
-     * main thread will exit the busy wait loop, stop autoDispatch and check the assert.
-     *
-     * Enable AutoDispatch, add message, block on message being handled and stop AutoDispatch.
-     * <p>
-     * Expected: handleMessage is called for messageA and stopAutoDispatch is called.
-     */
-    @Test
-    public void testAutoDispatchWithSingleMessage() {
-        final int mLoopSleepTimeMs = 5;
-
-        final int messageA = 1;
-
-        MockLooper mockLooper = new MockLooper();
-        class TestHandler extends Handler {
-            public volatile boolean handledMessage = false;
-            TestHandler(Looper looper) {
-                super(looper);
-            }
-
-            @Override
-            public void handleMessage(Message msg) {
-                if (msg.what == messageA) {
-                    handledMessage = true;
-                }
-            }
-        }
-
-        TestHandler testHandler = new TestHandler(mockLooper.getLooper());
-        mockLooper.startAutoDispatch();
-        testHandler.sendMessage(testHandler.obtainMessage(messageA));
-        while (!testHandler.handledMessage) {
-            // Block until message is handled
-            try {
-                Thread.sleep(mLoopSleepTimeMs);
-            } catch (InterruptedException e) {
-                // Interrupted while sleeping.
-            }
-        }
-        mockLooper.stopAutoDispatch();
-        assertTrue("TestHandler should have received messageA", testHandler.handledMessage);
-    }
-
-    /**
-     * Test starting AutoDispatch while already running throws IllegalStateException
-     * Enable AutoDispatch two times in a row.
-     * <p>
-     * Expected: catch IllegalStateException on second call.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testRepeatedStartAutoDispatchThrowsException() {
-        mMockLooper.startAutoDispatch();
-        mMockLooper.startAutoDispatch();
-    }
-
-    /**
-     * Test stopping AutoDispatch without previously starting throws IllegalStateException
-     * Stop AutoDispatch
-     * <p>
-     * Expected: catch IllegalStateException on second call.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testStopAutoDispatchWithoutStartThrowsException() {
-        mMockLooper.stopAutoDispatch();
-    }
-
-    /**
-     * Test AutoDispatch exits and does not dispatch a later message.
-     * Start and stop AutoDispatch then add a message.
-     * <p>
-     * Expected: After AutoDispatch is stopped, dispatchAll will return 1.
-     */
-    @Test
-    public void testAutoDispatchStopsCleanlyWithoutDispatchingAMessage() {
-        final int messageA = 1;
-
-        InOrder inOrder = inOrder(mHandlerSpy);
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-
-        mMockLooper.startAutoDispatch();
-        try {
-            mMockLooper.stopAutoDispatch();
-        } catch (IllegalStateException e) {
-            //  Stopping without a dispatch will throw an exception.
-        }
-
-        mHandlerSpy.sendMessage(mHandler.obtainMessage(messageA));
-        assertEquals("One message should be dispatched", 1, mMockLooper.dispatchAll());
-    }
-
-    /**
-     * Test AutoDispatch throws an exception when no messages are dispatched.
-     * Start and stop AutoDispatch
-     * <p>
-     * Expected: Exception is thrown with the stopAutoDispatch call.
-     */
-    @Test(expected = IllegalStateException.class)
-    public void testAutoDispatchThrowsExceptionWhenNoMessagesDispatched() {
-        mMockLooper.startAutoDispatch();
-        mMockLooper.stopAutoDispatch();
-    }
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/MockWifiMonitor.java b/tests/wifitests/src/com/android/server/wifi/MockWifiMonitor.java
index 8b68a11..6786504 100644
--- a/tests/wifitests/src/com/android/server/wifi/MockWifiMonitor.java
+++ b/tests/wifitests/src/com/android/server/wifi/MockWifiMonitor.java
@@ -23,12 +23,11 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
 import android.os.Handler;
 import android.os.Message;
 import android.util.SparseArray;
 
-import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
-
 import java.lang.reflect.Field;
 import java.util.HashMap;
 import java.util.Map;
diff --git a/tests/wifitests/src/com/android/server/wifi/RttServiceTest.java b/tests/wifitests/src/com/android/server/wifi/RttServiceTest.java
index 177705c..157164a 100644
--- a/tests/wifitests/src/com/android/server/wifi/RttServiceTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/RttServiceTest.java
@@ -36,8 +36,11 @@
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.os.Message;
+import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.internal.util.test.BidirectionalAsyncChannel;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -60,7 +63,7 @@
     Context mContext;
     @Mock
     WifiNative mWifiNative;
-    MockLooper mLooper;
+    TestLooper mLooper;
 
     RttService.RttServiceImpl mRttServiceImpl;
     ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor = ArgumentCaptor
@@ -70,7 +73,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         TestUtil.installWlanWifiNative(mWifiNative);
-        mLooper = new MockLooper();
+        mLooper = new TestLooper();
         mRttServiceImpl = new RttService.RttServiceImpl(mContext, mLooper.getLooper());
         mRttServiceImpl.startService();
     }
diff --git a/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java b/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java
index 8228118..ce77f8a 100644
--- a/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java
+++ b/tests/wifitests/src/com/android/server/wifi/ScanTestUtil.java
@@ -233,6 +233,18 @@
         return createScanDatas(freqs, new int[freqs.length] /* defaults all 0 */);
     }
 
+    private static void assertScanResultEquals(
+            String prefix, ScanResult expected, ScanResult actual) {
+        assertEquals(prefix + "SSID", expected.SSID, actual.SSID);
+        assertEquals(prefix + "wifiSsid", expected.wifiSsid.toString(), actual.wifiSsid.toString());
+        assertEquals(prefix + "BSSID", expected.BSSID, actual.BSSID);
+        assertEquals(prefix + "capabilities", expected.capabilities, actual.capabilities);
+        assertEquals(prefix + "level", expected.level, actual.level);
+        assertEquals(prefix + "frequency", expected.frequency, actual.frequency);
+        assertEquals(prefix + "timestamp", expected.timestamp, actual.timestamp);
+        assertEquals(prefix + "seen", expected.seen, actual.seen);
+    }
+
     private static void assertScanResultsEquals(String prefix, ScanResult[] expected,
             ScanResult[] actual) {
         assertNotNull(prefix + "expected ScanResults was null", expected);
@@ -241,26 +253,18 @@
         for (int j = 0; j < expected.length; ++j) {
             ScanResult expectedResult = expected[j];
             ScanResult actualResult = actual[j];
-            assertEquals(prefix + "results[" + j + "].SSID",
-                    expectedResult.SSID, actualResult.SSID);
-            assertEquals(prefix + "results[" + j + "].wifiSsid",
-                    expectedResult.wifiSsid.toString(), actualResult.wifiSsid.toString());
-            assertEquals(prefix + "results[" + j + "].BSSID",
-                    expectedResult.BSSID, actualResult.BSSID);
-            assertEquals(prefix + "results[" + j + "].capabilities",
-                    expectedResult.capabilities, actualResult.capabilities);
-            assertEquals(prefix + "results[" + j + "].level",
-                    expectedResult.level, actualResult.level);
-            assertEquals(prefix + "results[" + j + "].frequency",
-                    expectedResult.frequency, actualResult.frequency);
-            assertEquals(prefix + "results[" + j + "].timestamp",
-                    expectedResult.timestamp, actualResult.timestamp);
-            assertEquals(prefix + "results[" + j + "].seen",
-                    expectedResult.seen, actualResult.seen);
+            assertScanResultEquals(prefix + "results[" + j + "]", actualResult, expectedResult);
         }
     }
 
     /**
+     * Asserts if the provided scan results are the same.
+     */
+    public static void assertScanResultEquals(ScanResult expected, ScanResult actual) {
+        assertScanResultEquals("", expected, actual);
+    }
+
+    /**
      * Asserts if the provided scan result arrays are the same.
      */
     public static void assertScanResultsEquals(ScanResult[] expected, ScanResult[] actual) {
diff --git a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
index b91df5a..5919156 100644
--- a/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SoftApManagerTest.java
@@ -24,14 +24,14 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
 import android.net.InterfaceConfiguration;
+import android.net.wifi.IApInterface;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
 import android.os.INetworkManagementService;
+import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import org.junit.Before;
@@ -54,18 +54,19 @@
     private static final String TEST_INTERFACE_NAME = "TestInterface";
     private static final String TEST_COUNTRY_CODE = "TestCountry";
     private static final Integer[] ALLOWED_2G_CHANNELS = {1, 2, 3, 4};
-    private static final String[] AVAILABLE_DEVICES = { TEST_INTERFACE_NAME };
 
     private final ArrayList<Integer> mAllowed2GChannels =
             new ArrayList<Integer>(Arrays.asList(ALLOWED_2G_CHANNELS));
 
-    MockLooper mLooper;
-    @Mock Context mContext;
+    TestLooper mLooper;
     @Mock WifiNative mWifiNative;
     @Mock INetworkManagementService mNmService;
-    @Mock ConnectivityManager mConnectivityManager;
     @Mock SoftApManager.Listener mListener;
     @Mock InterfaceConfiguration mInterfaceConfiguration;
+    @Mock IApInterface mApInterface;
+    @Mock IBinder mApInterfaceBinder;
+    final ArgumentCaptor<DeathRecipient> mDeathListenerCaptor =
+            ArgumentCaptor.forClass(DeathRecipient.class);
 
     SoftApManager mSoftApManager;
 
@@ -73,20 +74,20 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mLooper = new MockLooper();
+        mLooper = new TestLooper();
 
         when(mWifiNative.getInterfaceName()).thenReturn(TEST_INTERFACE_NAME);
         when(mNmService.getInterfaceConfig(TEST_INTERFACE_NAME))
                 .thenReturn(mInterfaceConfiguration);
-        when(mConnectivityManager.getTetherableWifiRegexs())
-                .thenReturn(AVAILABLE_DEVICES);
+        when(mApInterface.asBinder()).thenReturn(mApInterfaceBinder);
 
         mSoftApManager = new SoftApManager(mLooper.getLooper(),
                                            mWifiNative,
                                            mNmService,
                                            TEST_COUNTRY_CODE,
                                            mAllowed2GChannels,
-                                           mListener);
+                                           mListener,
+                                           mApInterface);
 
         mLooper.dispatchAll();
     }
@@ -128,9 +129,21 @@
         order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLED, 0);
     }
 
+    @Test
+    public void handlesWificondInterfaceDeath() throws Exception {
+        startSoftApAndVerifyEnabled();
+
+        mDeathListenerCaptor.getValue().binderDied();
+        mLooper.dispatchAll();
+        InOrder order = inOrder(mListener);
+        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_DISABLING, 0);
+        order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_FAILED,
+                WifiManager.SAP_START_FAILURE_GENERAL);
+    }
+
     /** Starts soft AP and verifies that it is enabled successfully. */
     protected void startSoftApAndVerifyEnabled() throws Exception {
-        InOrder order = inOrder(mListener);
+        InOrder order = inOrder(mListener, mApInterfaceBinder);
 
         /**
          *  Only test the default configuration. Testing for different configurations
@@ -146,6 +159,7 @@
         verify(mNmService).startAccessPoint(
                 any(WifiConfiguration.class), eq(TEST_INTERFACE_NAME));
         order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLING, 0);
+        order.verify(mApInterfaceBinder).linkToDeath(mDeathListenerCaptor.capture(), eq(0));
         order.verify(mListener).onStateChanged(WifiManager.WIFI_AP_STATE_ENABLED, 0);
     }
 
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
new file mode 100644
index 0000000..c17f2ae
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/WifiBackupRestoreTest.java
@@ -0,0 +1,654 @@
+/*
+ * 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 com.android.server.wifi;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import android.net.wifi.WifiConfiguration;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.server.net.IpConfigStore;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.WifiBackupRestore}.
+ */
+@SmallTest
+public class WifiBackupRestoreTest {
+
+    private final WifiBackupRestore mWifiBackupRestore = new WifiBackupRestore();
+    private boolean mCheckDump = true;
+
+    @Before
+    public void setUp() throws Exception {
+        // Enable verbose logging before tests to check the backup data dumps.
+        mWifiBackupRestore.enableVerboseLogging(1);
+    }
+
+    @After
+    public void cleanUp() throws Exception {
+        if (mCheckDump) {
+            StringWriter stringWriter = new StringWriter();
+            mWifiBackupRestore.dump(
+                    new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
+            String dumpString = stringWriter.toString();
+            // Ensure that the SSID was dumped out.
+            assertTrue("Dump: " + dumpString,
+                    dumpString.contains(WifiConfigurationTestUtil.TEST_SSID));
+            // Ensure that the password wasn't dumped out.
+            assertFalse("Dump: " + dumpString,
+                    dumpString.contains(WifiConfigurationTestUtil.TEST_PSK));
+            assertFalse("Dump: " + dumpString,
+                    dumpString.contains(WifiConfigurationTestUtil.TEST_WEP_KEYS[0]));
+            assertFalse("Dump: " + dumpString,
+                    dumpString.contains(WifiConfigurationTestUtil.TEST_WEP_KEYS[1]));
+            assertFalse("Dump: " + dumpString,
+                    dumpString.contains(WifiConfigurationTestUtil.TEST_WEP_KEYS[2]));
+            assertFalse("Dump: " + dumpString,
+                    dumpString.contains(WifiConfigurationTestUtil.TEST_WEP_KEYS[3]));
+        }
+    }
+
+    /**
+     * Verify that a single open network configuration is serialized & deserialized correctly.
+     */
+    @Test
+    public void testSingleOpenNetworkBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createOpenNetwork());
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single open hidden network configuration is serialized & deserialized
+     * correctly.
+     */
+    @Test
+    public void testSingleOpenHiddenNetworkBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createOpenHiddenNetwork());
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single PSK network configuration is serialized & deserialized correctly.
+     */
+    @Test
+    public void testSinglePskNetworkBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createPskNetwork());
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single PSK hidden network configuration is serialized & deserialized correctly.
+     */
+    @Test
+    public void testSinglePskHiddenNetworkBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createPskHiddenNetwork());
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single WEP network configuration is serialized & deserialized correctly.
+     */
+    @Test
+    public void testSingleWepNetworkBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createWepNetwork());
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single WEP network configuration with only 1 key is serialized & deserialized
+     * correctly.
+     */
+    @Test
+    public void testSingleWepNetworkWithSingleKeyBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createWepNetworkWithSingleKey());
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single enterprise network configuration is not serialized.
+     */
+    @Test
+    public void testSingleEnterpriseNetworkNotBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createEapNetwork());
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        assertTrue(retrievedConfigurations.isEmpty());
+        // No valid data to check in dump.
+        mCheckDump = false;
+    }
+
+    /**
+     * Verify that a single PSK network configuration with static ip/proxy settings is serialized &
+     * deserialized correctly.
+     */
+    @Test
+    public void testSinglePskNetworkWithStaticIpAndStaticProxyBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        pskNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
+        configurations.add(pskNetwork);
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single PSK network configuration with static ip & PAC proxy settings is
+     * serialized & deserialized correctly.
+     */
+    @Test
+    public void testSinglePskNetworkWithStaticIpAndPACProxyBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        pskNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
+        configurations.add(pskNetwork);
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single PSK network configuration with DHCP ip & PAC proxy settings is
+     * serialized & deserialized correctly.
+     */
+    @Test
+    public void testSinglePskNetworkWithDHCPIpAndPACProxyBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        pskNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
+        configurations.add(pskNetwork);
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single PSK network configuration with partial static ip settings is serialized
+     * & deserialized correctly.
+     */
+    @Test
+    public void testSinglePskNetworkWithPartialStaticIpBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        pskNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createPartialStaticIpConfigurationWithPacProxy());
+        configurations.add(pskNetwork);
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that multiple networks of different types are serialized and deserialized correctly.
+     */
+    @Test
+    public void testMultipleNetworksAllBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createWepNetwork());
+        configurations.add(WifiConfigurationTestUtil.createWepNetwork());
+        configurations.add(WifiConfigurationTestUtil.createPskNetwork());
+        configurations.add(WifiConfigurationTestUtil.createOpenNetwork());
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that multiple networks of different types except enterprise ones are serialized and
+     * deserialized correctly
+     */
+    @Test
+    public void testMultipleNetworksNonEnterpriseBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        List<WifiConfiguration> expectedConfigurations = new ArrayList<>();
+
+        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+        configurations.add(wepNetwork);
+        expectedConfigurations.add(wepNetwork);
+
+        configurations.add(WifiConfigurationTestUtil.createEapNetwork());
+
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        configurations.add(pskNetwork);
+        expectedConfigurations.add(pskNetwork);
+
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        configurations.add(openNetwork);
+        expectedConfigurations.add(openNetwork);
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                expectedConfigurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that multiple networks with different credential types and IpConfiguration types are
+     * serialized and deserialized correctly.
+     */
+    @Test
+    public void testMultipleNetworksWithDifferentIpConfigurationsAllBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+
+        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+        wepNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
+        configurations.add(wepNetwork);
+
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        pskNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
+        configurations.add(pskNetwork);
+
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        openNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
+        configurations.add(openNetwork);
+
+        byte[] backupData = mWifiBackupRestore.retrieveBackupDataFromConfigurations(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single open network configuration is serialized & deserialized correctly from
+     * old backups.
+     */
+    @Test
+    public void testSingleOpenNetworkSupplicantBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createOpenNetwork());
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        byte[] ipConfigData = createIpConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, ipConfigData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single open hidden network configuration is serialized & deserialized
+     * correctly from old backups.
+     */
+    @Test
+    public void testSingleOpenHiddenNetworkSupplicantBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createOpenHiddenNetwork());
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        byte[] ipConfigData = createIpConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, ipConfigData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single PSK network configuration is serialized & deserialized correctly from
+     * old backups.
+     */
+    @Test
+    public void testSinglePskNetworkSupplicantBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createPskNetwork());
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        byte[] ipConfigData = createIpConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, ipConfigData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single PSK hidden network configuration is serialized & deserialized correctly
+     * from old backups.
+     */
+    @Test
+    public void testSinglePskHiddenNetworkSupplicantBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createPskHiddenNetwork());
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        byte[] ipConfigData = createIpConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, ipConfigData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single WEP network configuration is serialized & deserialized correctly from
+     * old backups.
+     */
+    @Test
+    public void testSingleWepNetworkSupplicantBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createWepNetwork());
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        byte[] ipConfigData = createIpConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, ipConfigData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single WEP network configuration with only 1 key is serialized & deserialized
+     * correctly from old backups.
+     */
+    @Test
+    public void testSingleWepNetworkWithSingleKeySupplicantBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createWepNetworkWithSingleKey());
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        byte[] ipConfigData = createIpConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, ipConfigData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single enterprise network configuration is not serialized from old backups.
+     */
+    @Test
+    public void testSingleEnterpriseNetworkNotSupplicantBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createEapNetwork());
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        byte[] ipConfigData = createIpConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, ipConfigData);
+        assertTrue(retrievedConfigurations.isEmpty());
+    }
+
+    /**
+     * Verify that multiple networks with different credential types and IpConfiguration types are
+     * serialized and deserialized correctly from old backups
+     */
+    @Test
+    public void testMultipleNetworksWithDifferentIpConfigurationsAllSupplicantBackupRestore() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+
+        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+        wepNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
+        configurations.add(wepNetwork);
+
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        pskNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
+        configurations.add(pskNetwork);
+
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        openNetwork.setIpConfiguration(
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
+        configurations.add(openNetwork);
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        byte[] ipConfigData = createIpConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, ipConfigData);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that a single open network configuration is serialized & deserialized correctly from
+     * old backups with no ipconfig data.
+     */
+    @Test
+    public void testSingleOpenNetworkSupplicantBackupRestoreWithNoIpConfigData() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createOpenNetwork());
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, null);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that multiple networks with different credential types are serialized and
+     * deserialized correctly from old backups with no ipconfig data.
+     */
+    @Test
+    public void testMultipleNetworksAllSupplicantBackupRestoreWithNoIpConfigData() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+
+        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+        configurations.add(wepNetwork);
+
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        configurations.add(pskNetwork);
+
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        configurations.add(openNetwork);
+
+        byte[] supplicantData = createWpaSupplicantConfBackupData(configurations);
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromSupplicantBackupData(
+                        supplicantData, null);
+        WifiConfigurationTestUtil.assertConfigurationsEqualForBackup(
+                configurations, retrievedConfigurations);
+    }
+
+    /**
+     * Verify that any corrupted data provided by Backup/Restore is ignored correctly.
+     */
+    @Test
+    public void testCorruptBackupRestore() {
+        Random random = new Random();
+        byte[] backupData = new byte[100];
+        random.nextBytes(backupData);
+
+        List<WifiConfiguration> retrievedConfigurations =
+                mWifiBackupRestore.retrieveConfigurationsFromBackupData(backupData);
+        assertNull(retrievedConfigurations);
+        // No valid data to check in dump.
+        mCheckDump = false;
+    }
+
+    /**
+     * Helper method to write a list of networks in wpa_supplicant.conf format to the output stream.
+     */
+    private byte[] createWpaSupplicantConfBackupData(List<WifiConfiguration> configurations) {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        OutputStreamWriter out = new OutputStreamWriter(bos);
+        try {
+            for (WifiConfiguration configuration : configurations) {
+                writeConfigurationToWpaSupplicantConf(out, configuration);
+            }
+            out.flush();
+            return bos.toByteArray();
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Helper method to write a network in wpa_supplicant.conf format to the output stream.
+     * This was created using a sample wpa_supplicant.conf file. Using the raw key strings here
+     * (instead of consts in WifiBackupRestore).
+     */
+    private void writeConfigurationToWpaSupplicantConf(
+            OutputStreamWriter out, WifiConfiguration configuration)
+            throws IOException {
+        out.write("network={\n");
+        out.write("        " + "ssid=" + configuration.SSID + "\n");
+        String allowedKeyManagement = "";
+        if (configuration.hiddenSSID) {
+            out.write("        " + "scan_ssid=1" + "\n");
+        }
+        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)) {
+            allowedKeyManagement += "NONE";
+        }
+        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
+            allowedKeyManagement += "WPA-PSK ";
+        }
+        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
+            allowedKeyManagement += "WPA-EAP ";
+        }
+        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) {
+            allowedKeyManagement += "IEEE8021X ";
+        }
+        out.write("        " + "key_mgmt=" + allowedKeyManagement + "\n");
+        if (configuration.preSharedKey != null) {
+            out.write("        " + "psk=" + configuration.preSharedKey + "\n");
+        }
+        if (configuration.wepKeys[0] != null) {
+            out.write("        " + "wep_key0=" + configuration.wepKeys[0] + "\n");
+        }
+        if (configuration.wepKeys[1] != null) {
+            out.write("        " + "wep_key1=" + configuration.wepKeys[1] + "\n");
+        }
+        if (configuration.wepKeys[2] != null) {
+            out.write("        " + "wep_key2=" + configuration.wepKeys[2] + "\n");
+        }
+        if (configuration.wepKeys[3] != null) {
+            out.write("        " + "wep_key3=" + configuration.wepKeys[3] + "\n");
+        }
+        if (configuration.wepKeys[0] != null || configuration.wepKeys[1] != null
+                || configuration.wepKeys[2] != null || configuration.wepKeys[3] != null) {
+            out.write("        " + "wep_tx_keyidx=" + configuration.wepTxKeyIndex + "\n");
+        }
+        Map<String, String> extras = new HashMap<>();
+        extras.put(WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY, configuration.configKey());
+        extras.put(WifiSupplicantControl.ID_STRING_KEY_CREATOR_UID,
+                Integer.toString(configuration.creatorUid));
+        String idString = WifiNative.createNetworkExtra(extras);
+        if (idString != null) {
+            idString = "\"" + idString + "\"";
+            out.write("        " + "id_str=" + idString + "\n");
+        }
+        out.write("}\n");
+        out.write("\n");
+    }
+
+    /**
+     * Helper method to write a list of networks in ipconfig.txt format to the output stream.
+     */
+    private byte[] createIpConfBackupData(List<WifiConfiguration> configurations) {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        DataOutputStream out = new DataOutputStream(bos);
+        try {
+            // write version first.
+            out.writeInt(2);
+            for (WifiConfiguration configuration : configurations) {
+                IpConfigStore.writeConfig(out, configuration.configKey().hashCode(),
+                        configuration.getIpConfiguration());
+            }
+            out.flush();
+            return bos.toByteArray();
+        } catch (IOException e) {
+            return null;
+        }
+    }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerNewTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerNewTest.java
new file mode 100644
index 0000000..2ff6de2
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerNewTest.java
@@ -0,0 +1,1361 @@
+/*
+ * 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 com.android.server.wifi;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.IpConfiguration;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
+import android.net.wifi.WifiEnterpriseConfig;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.WifiConfigManagerNew}.
+ */
+@SmallTest
+public class WifiConfigManagerNewTest {
+
+    private static final String TEST_BSSID = "0a:08:5c:67:89:00";
+    private static final long TEST_WALLCLOCK_CREATION_TIME_MILLIS = 9845637;
+    private static final long TEST_WALLCLOCK_UPDATE_TIME_MILLIS = 75455637;
+    private static final long TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS = 29457631;
+    private static final int TEST_CREATOR_UID = 5;
+    private static final int TEST_UPDATE_UID = 4;
+    private static final String TEST_CREATOR_NAME = "com.wificonfigmanagerNew.creator";
+    private static final String TEST_UPDATE_NAME = "com.wificonfigmanagerNew.update";
+
+    @Mock private Context mContext;
+    @Mock private FrameworkFacade mFrameworkFacade;
+    @Mock private Clock mClock;
+    @Mock private UserManager mUserManager;
+    @Mock private WifiKeyStore mWifiKeyStore;
+    @Mock private WifiConfigStoreNew mWifiConfigStore;
+    @Mock private PackageManager mPackageManager;
+
+    private InOrder mContextConfigStoreMockOrder;
+
+    private WifiConfigManagerNew mWifiConfigManager;
+
+    /**
+     * Setup the mocks and an instance of WifiConfigManagerNew before each test.
+     */
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        // Set up the inorder for verifications. This is needed to verify that the broadcasts,
+        // store writes for network updates followed by network additions are in the expected order.
+        mContextConfigStoreMockOrder = inOrder(mContext, mWifiConfigStore);
+
+        // Set up the package name stuff & permission override.
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        doAnswer(new AnswerWithArguments() {
+            public String answer(int uid) throws Exception {
+                if (uid == TEST_CREATOR_UID) {
+                    return TEST_CREATOR_NAME;
+                } else if (uid == TEST_UPDATE_UID) {
+                    return TEST_UPDATE_NAME;
+                }
+                fail("Unexpected UID: " + uid);
+                return "";
+            }
+        }).when(mPackageManager).getNameForUid(anyInt());
+
+        // Both the UID's in the test have the configuration override permission granted by
+        // default. This maybe modified for particular tests if needed.
+        doAnswer(new AnswerWithArguments() {
+            public int answer(String permName, int uid) throws Exception {
+                if (uid == TEST_CREATOR_UID || uid == TEST_UPDATE_UID) {
+                    return PackageManager.PERMISSION_GRANTED;
+                }
+                return PackageManager.PERMISSION_DENIED;
+            }
+        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
+
+        when(mWifiKeyStore
+                .updateNetworkKeys(any(WifiConfiguration.class), any(WifiConfiguration.class)))
+                .thenReturn(true);
+
+        mWifiConfigManager =
+                new WifiConfigManagerNew(
+                        mContext, mFrameworkFacade, mClock, mUserManager, mWifiKeyStore,
+                        mWifiConfigStore);
+        mWifiConfigManager.enableVerboseLogging(1);
+    }
+
+    /**
+     * Verifies the addition of a single network using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)}
+     */
+    @Test
+    public void testAddSingleOpenNetwork() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(openNetwork);
+
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        List<WifiConfiguration> retrievedNetworks =
+                mWifiConfigManager.getConfiguredNetworksWithPasswords();
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
+                networks, retrievedNetworks);
+    }
+
+    /**
+     * Verifies the modification of a single network using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)}
+     */
+    @Test
+    public void testUpdateSingleOpenNetwork() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(openNetwork);
+
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        // Now change BSSID for the network.
+        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(openNetwork);
+
+        // Now verify that the modification has been effective.
+        List<WifiConfiguration> retrievedNetworks =
+                mWifiConfigManager.getConfiguredNetworksWithPasswords();
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
+                networks, retrievedNetworks);
+    }
+
+    /**
+     * Verifies the addition of a single ephemeral network using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)} and verifies that
+     * the {@link WifiConfigManagerNew#getSavedNetworks()} does not return this network.
+     */
+    @Test
+    public void testAddSingleEphemeralNetwork() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        openNetwork.ephemeral = true;
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(openNetwork);
+
+        verifyAddEphemeralNetworkToWifiConfigManager(openNetwork);
+
+        List<WifiConfiguration> retrievedNetworks =
+                mWifiConfigManager.getConfiguredNetworksWithPasswords();
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
+                networks, retrievedNetworks);
+
+        // Ensure that this is not returned in the saved network list.
+        assertTrue(mWifiConfigManager.getSavedNetworks().isEmpty());
+    }
+
+    /**
+     * Verifies that the modification of a single open network using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)} with a UID which
+     * has no permission to modify the network fails.
+     */
+    @Test
+    public void testUpdateSingleOpenNetworkFailedDueToPermissionDenied() throws Exception {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(openNetwork);
+
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        // Now change BSSID of the network.
+        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
+
+        // Deny permission for |UPDATE_UID|.
+        doAnswer(new AnswerWithArguments() {
+            public int answer(String permName, int uid) throws Exception {
+                if (uid == TEST_CREATOR_UID) {
+                    return PackageManager.PERMISSION_GRANTED;
+                }
+                return PackageManager.PERMISSION_DENIED;
+            }
+        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
+
+        // Update the same configuration and ensure that the operation failed.
+        NetworkUpdateResult result = updateNetworkToWifiConfigManager(openNetwork);
+        assertTrue(result.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID);
+    }
+
+    /**
+     * Verifies that the modification of a single open network using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)} with the creator UID
+     * should always succeed.
+     */
+    @Test
+    public void testUpdateSingleOpenNetworkSuccessWithCreatorUID() throws Exception {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(openNetwork);
+
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        // Now change BSSID of the network.
+        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
+
+        // Deny permission for all UIDs.
+        doAnswer(new AnswerWithArguments() {
+            public int answer(String permName, int uid) throws Exception {
+                return PackageManager.PERMISSION_DENIED;
+            }
+        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
+
+        // Update the same configuration using the creator UID.
+        NetworkUpdateResult result =
+                mWifiConfigManager.addOrUpdateNetwork(openNetwork, TEST_CREATOR_UID);
+        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
+
+        // Now verify that the modification has been effective.
+        List<WifiConfiguration> retrievedNetworks =
+                mWifiConfigManager.getConfiguredNetworksWithPasswords();
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
+                networks, retrievedNetworks);
+    }
+
+    /**
+     * Verifies the addition of a single PSK network using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)} and verifies that
+     * {@link WifiConfigManagerNew#getSavedNetworks()} masks the password.
+     */
+    @Test
+    public void testAddSinglePskNetwork() {
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(pskNetwork);
+
+        verifyAddNetworkToWifiConfigManager(pskNetwork);
+
+        List<WifiConfiguration> retrievedNetworks =
+                mWifiConfigManager.getConfiguredNetworksWithPasswords();
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
+                networks, retrievedNetworks);
+
+        List<WifiConfiguration> retrievedSavedNetworks = mWifiConfigManager.getSavedNetworks();
+        assertEquals(retrievedSavedNetworks.size(), 1);
+        assertEquals(retrievedSavedNetworks.get(0).configKey(), pskNetwork.configKey());
+        assertPasswordsMaskedInWifiConfiguration(retrievedSavedNetworks.get(0));
+    }
+
+    /**
+     * Verifies the addition of a single WEP network using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)} and verifies that
+     * {@link WifiConfigManagerNew#getSavedNetworks()} masks the password.
+     */
+    @Test
+    public void testAddSingleWepNetwork() {
+        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(wepNetwork);
+
+        verifyAddNetworkToWifiConfigManager(wepNetwork);
+
+        List<WifiConfiguration> retrievedNetworks =
+                mWifiConfigManager.getConfiguredNetworksWithPasswords();
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
+                networks, retrievedNetworks);
+
+        List<WifiConfiguration> retrievedSavedNetworks = mWifiConfigManager.getSavedNetworks();
+        assertEquals(retrievedSavedNetworks.size(), 1);
+        assertEquals(retrievedSavedNetworks.get(0).configKey(), wepNetwork.configKey());
+        assertPasswordsMaskedInWifiConfiguration(retrievedSavedNetworks.get(0));
+    }
+
+    /**
+     * Verifies the modification of an IpConfiguration using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)}
+     */
+    @Test
+    public void testUpdateIpConfiguration() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(openNetwork);
+
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        // Now change BSSID of the network.
+        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
+
+        // Update the same configuration and ensure that the IP configuration change flags
+        // are not set.
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(openNetwork);
+
+        // Change the IpConfiguration now and ensure that the IP configuration flags are set now.
+        assertAndSetNetworkIpConfiguration(
+                openNetwork,
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
+        verifyUpdateNetworkToWifiConfigManagerWithIpChange(openNetwork);
+
+        // Now verify that all the modifications have been effective.
+        List<WifiConfiguration> retrievedNetworks =
+                mWifiConfigManager.getConfiguredNetworksWithPasswords();
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
+                networks, retrievedNetworks);
+    }
+
+    /**
+     * Verifies the removal of a single network using
+     * {@link WifiConfigManagerNew#removeNetwork(int)}
+     */
+    @Test
+    public void testRemoveSingleOpenNetwork() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(openNetwork);
+
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        verifyRemoveNetworkFromWifiConfigManager(openNetwork);
+
+        // Ensure that configured network list is empty now.
+        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
+    }
+
+    /**
+     * Verifies the addition & update of multiple networks using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)} and the
+     * removal of networks using
+     * {@link WifiConfigManagerNew#removeNetwork(int)}
+     */
+    @Test
+    public void testAddUpdateRemoveMultipleNetworks() {
+        List<WifiConfiguration> networks = new ArrayList<>();
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+        networks.add(openNetwork);
+        networks.add(pskNetwork);
+        networks.add(wepNetwork);
+
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+        verifyAddNetworkToWifiConfigManager(pskNetwork);
+        verifyAddNetworkToWifiConfigManager(wepNetwork);
+
+        // Now verify that all the additions has been effective.
+        List<WifiConfiguration> retrievedNetworks =
+                mWifiConfigManager.getConfiguredNetworksWithPasswords();
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
+                networks, retrievedNetworks);
+
+        // Modify all the 3 configurations and update it to WifiConfigManager.
+        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
+        assertAndSetNetworkBSSID(pskNetwork, TEST_BSSID);
+        assertAndSetNetworkIpConfiguration(
+                wepNetwork,
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
+
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(openNetwork);
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(pskNetwork);
+        verifyUpdateNetworkToWifiConfigManagerWithIpChange(wepNetwork);
+        // Now verify that all the modifications has been effective.
+        retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
+                networks, retrievedNetworks);
+
+        // Now remove all 3 networks.
+        verifyRemoveNetworkFromWifiConfigManager(openNetwork);
+        verifyRemoveNetworkFromWifiConfigManager(pskNetwork);
+        verifyRemoveNetworkFromWifiConfigManager(wepNetwork);
+
+        // Ensure that configured network list is empty now.
+        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
+    }
+
+    /**
+     * Verifies the update of network status using
+     * {@link WifiConfigManagerNew#updateNetworkSelectionStatus(int, int)}.
+     */
+    @Test
+    public void testNetworkSelectionStatus() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+
+        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        // First set it to enabled.
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
+
+        // Now set it to temporarily disabled. The threshold for association rejection is 5, so
+        // disable it 5 times to actually mark it temporarily disabled.
+        int assocRejectReason = NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION;
+        int assocRejectThreshold =
+                WifiConfigManagerNew.NETWORK_SELECTION_DISABLE_THRESHOLD[assocRejectReason];
+        for (int i = 1; i <= assocRejectThreshold; i++) {
+            verifyUpdateNetworkSelectionStatus(result.getNetworkId(), assocRejectReason, i);
+        }
+
+        // Now set it to permanently disabled.
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER, 0);
+
+        // Now set it back to enabled.
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
+    }
+
+    /**
+     * Verifies the update of network status using
+     * {@link WifiConfigManagerNew#updateNetworkSelectionStatus(int, int)} and ensures that
+     * enabling a network clears out all the temporary disable counters.
+     */
+    @Test
+    public void testNetworkSelectionStatusEnableClearsDisableCounters() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+
+        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        // First set it to enabled.
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
+
+        // Now set it to temporarily disabled 2 times for 2 different reasons.
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, 1);
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, 2);
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE, 1);
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE, 2);
+
+        // Now set it back to enabled.
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
+
+        // Ensure that the counters have all been reset now.
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, 1);
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE, 1);
+    }
+
+    /**
+     * Verifies the enabling of temporarily disabled network using
+     * {@link WifiConfigManagerNew#tryEnableNetwork(int)}.
+     */
+    @Test
+    public void testTryEnableNetwork() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+
+        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        // First set it to enabled.
+        verifyUpdateNetworkSelectionStatus(
+                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
+
+        // Now set it to temporarily disabled. The threshold for association rejection is 5, so
+        // disable it 5 times to actually mark it temporarily disabled.
+        int assocRejectReason = NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION;
+        int assocRejectThreshold =
+                WifiConfigManagerNew.NETWORK_SELECTION_DISABLE_THRESHOLD[assocRejectReason];
+        for (int i = 1; i <= assocRejectThreshold; i++) {
+            verifyUpdateNetworkSelectionStatus(result.getNetworkId(), assocRejectReason, i);
+        }
+
+        // Now let's try enabling this network without changing the time, this should fail and the
+        // status remains temporarily disabled.
+        assertFalse(mWifiConfigManager.tryEnableNetwork(result.getNetworkId()));
+        NetworkSelectionStatus retrievedStatus =
+                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId())
+                        .getNetworkSelectionStatus();
+        assertTrue(retrievedStatus.isNetworkTemporaryDisabled());
+
+        // Now advance time by the timeout for association rejection and ensure that the network
+        // is now enabled.
+        int assocRejectTimeout =
+                WifiConfigManagerNew.NETWORK_SELECTION_DISABLE_TIMEOUT_MS[assocRejectReason];
+        when(mClock.getElapsedSinceBootMillis())
+                .thenReturn(TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS + assocRejectTimeout);
+
+        assertTrue(mWifiConfigManager.tryEnableNetwork(result.getNetworkId()));
+        retrievedStatus =
+                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId())
+                        .getNetworkSelectionStatus();
+        assertTrue(retrievedStatus.isNetworkEnabled());
+    }
+
+    /**
+     * Verifies the enabling of network using
+     * {@link WifiConfigManagerNew#enableNetwork(int, int)} and
+     * {@link WifiConfigManagerNew#disableNetwork(int, int)}.
+     */
+    @Test
+    public void testEnableDisableNetwork() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+
+        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        assertTrue(mWifiConfigManager.enableNetwork(result.getNetworkId(), TEST_CREATOR_UID));
+        WifiConfiguration retrievedNetwork =
+                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+        NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
+        assertTrue(retrievedStatus.isNetworkEnabled());
+        verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.ENABLED);
+
+        // Now set it disabled.
+        assertTrue(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_CREATOR_UID));
+        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+        retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
+        assertTrue(retrievedStatus.isNetworkPermanentlyDisabled());
+        verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.DISABLED);
+    }
+
+    /**
+     * Verifies the enabling of network using
+     * {@link WifiConfigManagerNew#enableNetwork(int, int)} with a UID which
+     * has no permission to modify the network fails..
+     */
+    @Test
+    public void testEnableDisableNetworkFailedDueToPermissionDenied() throws Exception {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+
+        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        assertTrue(mWifiConfigManager.enableNetwork(result.getNetworkId(), TEST_CREATOR_UID));
+        WifiConfiguration retrievedNetwork =
+                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+        NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
+        assertTrue(retrievedStatus.isNetworkEnabled());
+        verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.ENABLED);
+
+        // Deny permission for |UPDATE_UID|.
+        doAnswer(new AnswerWithArguments() {
+            public int answer(String permName, int uid) throws Exception {
+                if (uid == TEST_CREATOR_UID) {
+                    return PackageManager.PERMISSION_GRANTED;
+                }
+                return PackageManager.PERMISSION_DENIED;
+            }
+        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
+
+        // Now try to set it disabled with |TEST_UPDATE_UID|, it should fail and the network
+        // should remain enabled.
+        assertFalse(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_UPDATE_UID));
+        retrievedStatus =
+                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId())
+                        .getNetworkSelectionStatus();
+        assertTrue(retrievedStatus.isNetworkEnabled());
+        assertEquals(WifiConfiguration.Status.ENABLED, retrievedNetwork.status);
+    }
+
+    /**
+     * Verifies the updation of network's connectUid using
+     * {@link WifiConfigManagerNew#checkAndUpdateLastConnectUid(int, int)}.
+     */
+    @Test
+    public void testUpdateLastConnectUid() throws Exception {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+
+        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        assertTrue(
+                mWifiConfigManager.checkAndUpdateLastConnectUid(result.getNetworkId(), TEST_CREATOR_UID));
+        WifiConfiguration retrievedNetwork =
+                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+        assertEquals(TEST_CREATOR_UID, retrievedNetwork.lastConnectUid);
+
+        // Deny permission for |UPDATE_UID|.
+        doAnswer(new AnswerWithArguments() {
+            public int answer(String permName, int uid) throws Exception {
+                if (uid == TEST_CREATOR_UID) {
+                    return PackageManager.PERMISSION_GRANTED;
+                }
+                return PackageManager.PERMISSION_DENIED;
+            }
+        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
+
+        // Now try to update the last connect UID with |TEST_UPDATE_UID|, it should fail and
+        // the lastConnectUid should remain the same.
+        assertFalse(
+                mWifiConfigManager.checkAndUpdateLastConnectUid(
+                        result.getNetworkId(), TEST_UPDATE_UID));
+        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
+        assertEquals(TEST_CREATOR_UID, retrievedNetwork.lastConnectUid);
+    }
+
+    /**
+     * Verifies that any configuration update attempt with an null config is gracefully
+     * handled.
+     * This invokes {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)}.
+     */
+    @Test
+    public void testAddOrUpdateNetworkWithNullConfig() {
+        NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork(null, TEST_CREATOR_UID);
+        assertFalse(result.isSuccess());
+    }
+
+    /**
+     * Verifies that any configuration removal attempt with an invalid networkID is gracefully
+     * handled.
+     * This invokes {@link WifiConfigManagerNew#removeNetwork(int)}.
+     */
+    @Test
+    public void testRemoveNetworkWithInvalidNetworkId() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        // Change the networkID to an invalid one.
+        openNetwork.networkId++;
+        assertFalse(mWifiConfigManager.removeNetwork(openNetwork.networkId));
+    }
+
+    /**
+     * Verifies that any configuration update attempt with an invalid networkID is gracefully
+     * handled.
+     * This invokes {@link WifiConfigManagerNew#enableNetwork(int, int)},
+     * {@link WifiConfigManagerNew#disableNetwork(int, int)},
+     * {@link WifiConfigManagerNew#updateNetworkSelectionStatus(int, int)} and
+     * {@link WifiConfigManagerNew#checkAndUpdateLastConnectUid(int, int)}.
+     */
+    @Test
+    public void testChangeConfigurationWithInvalidNetworkId() {
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+
+        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        assertFalse(mWifiConfigManager.enableNetwork(result.getNetworkId() + 1, TEST_CREATOR_UID));
+        assertFalse(mWifiConfigManager.disableNetwork(result.getNetworkId() + 1, TEST_CREATOR_UID));
+        assertFalse(mWifiConfigManager.updateNetworkSelectionStatus(
+                result.getNetworkId() + 1, NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER));
+        assertFalse(mWifiConfigManager.checkAndUpdateLastConnectUid(
+                result.getNetworkId() + 1, TEST_CREATOR_UID));
+    }
+
+    /**
+     * Verifies multiple modification of a single network using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)}.
+     * This test is basically checking if the apps can reset some of the fields of the config after
+     * addition. The fields being reset in this test are the |preSharedKey| and |wepKeys|.
+     * 1. Create an open network initially.
+     * 2. Modify the added network config to a WEP network config with all the 4 keys set.
+     * 3. Modify the added network config to a WEP network config with only 1 key set.
+     * 4. Modify the added network config to a PSK network config.
+     */
+    @Test
+    public void testMultipleUpdatesSingleNetwork() {
+        WifiConfiguration network = WifiConfigurationTestUtil.createOpenNetwork();
+        verifyAddNetworkToWifiConfigManager(network);
+
+        // Now add |wepKeys| to the network. We don't need to update the |allowedKeyManagement|
+        // fields for open to WEP conversion.
+        String[] wepKeys =
+                Arrays.copyOf(WifiConfigurationTestUtil.TEST_WEP_KEYS,
+                        WifiConfigurationTestUtil.TEST_WEP_KEYS.length);
+        int wepTxKeyIdx = WifiConfigurationTestUtil.TEST_WEP_TX_KEY_INDEX;
+        assertAndSetNetworkWepKeysAndTxIndex(network, wepKeys, wepTxKeyIdx);
+
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
+        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
+                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
+
+        // Now empty out 3 of the |wepKeys[]| and ensure that those keys have been reset correctly.
+        for (int i = 1; i < network.wepKeys.length; i++) {
+            wepKeys[i] = "";
+        }
+        wepTxKeyIdx = 0;
+        assertAndSetNetworkWepKeysAndTxIndex(network, wepKeys, wepTxKeyIdx);
+
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
+        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
+                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
+
+        // Now change the config to a PSK network config by resetting the remaining |wepKey[0]|
+        // field and setting the |preSharedKey| and |allowedKeyManagement| fields.
+        wepKeys[0] = "";
+        wepTxKeyIdx = -1;
+        assertAndSetNetworkWepKeysAndTxIndex(network, wepKeys, wepTxKeyIdx);
+        network.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        assertAndSetNetworkPreSharedKey(network, WifiConfigurationTestUtil.TEST_PSK);
+
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
+        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
+                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
+    }
+
+    /**
+     * Verifies the modification of a WifiEnteriseConfig using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)}.
+     */
+    @Test
+    public void testUpdateWifiEnterpriseConfig() {
+        WifiConfiguration network = WifiConfigurationTestUtil.createEapNetwork();
+        verifyAddNetworkToWifiConfigManager(network);
+
+        // Set the |password| field in WifiEnterpriseConfig and modify the config to PEAP/GTC.
+        network.enterpriseConfig =
+                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
+        assertAndSetNetworkEnterprisePassword(network, "test");
+
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
+        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
+                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
+
+        // Reset the |password| field in WifiEnterpriseConfig and modify the config to TLS/None.
+        network.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+        network.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
+        assertAndSetNetworkEnterprisePassword(network, "");
+
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
+        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
+                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
+    }
+
+    /**
+     * Verifies the modification of a single network using
+     * {@link WifiConfigManagerNew#addOrUpdateNetwork(WifiConfiguration, int)} by passing in nulls
+     * in all the publicly exposed fields.
+     */
+    @Test
+    public void testUpdateSingleNetworkWithNullValues() {
+        WifiConfiguration network = WifiConfigurationTestUtil.createEapNetwork();
+        verifyAddNetworkToWifiConfigManager(network);
+
+        // Save a copy of the original network for comparison.
+        WifiConfiguration originalNetwork = new WifiConfiguration(network);
+
+        // Now set all the public fields to null and try updating the network.
+        network.allowedAuthAlgorithms = null;
+        network.allowedProtocols = null;
+        network.allowedKeyManagement = null;
+        network.allowedPairwiseCiphers = null;
+        network.allowedGroupCiphers = null;
+        network.setIpConfiguration(null);
+        network.enterpriseConfig = null;
+
+        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
+
+        // Copy over the updated debug params to the original network config before comparison.
+        originalNetwork.lastUpdateUid = network.lastUpdateUid;
+        originalNetwork.lastUpdateName = network.lastUpdateName;
+        originalNetwork.updateTime = network.updateTime;
+
+        // Now verify that there was no change to the network configurations.
+        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
+                originalNetwork,
+                mWifiConfigManager.getConfiguredNetworkWithPassword(originalNetwork.networkId));
+    }
+
+    /**
+     * Verifies the matching of networks with different encryption types with the
+     * corresponding scan detail using
+     * {@link WifiConfigManagerNew#getSavedNetworkForScanDetailAndCache(ScanDetail)}.
+     * The test also verifies that the provided scan detail was cached,
+     */
+    @Test
+    public void testMatchScanDetailToNetworksAndCache() {
+        // Create networks of different types and ensure that they're all matched using
+        // the corresponding ScanDetail correctly.
+        verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
+                WifiConfigurationTestUtil.createOpenNetwork());
+        verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
+                WifiConfigurationTestUtil.createWepNetwork());
+        verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
+                WifiConfigurationTestUtil.createPskNetwork());
+        verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
+                WifiConfigurationTestUtil.createEapNetwork());
+    }
+
+    /**
+     * Verifies that scan details with wrong SSID/authentication types are not matched using
+     * {@link WifiConfigManagerNew#getSavedNetworkForScanDetailAndCache(ScanDetail)}
+     * to the added networks.
+     */
+    @Test
+    public void testNoMatchScanDetailToNetwork() {
+        // First create networks of different types.
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
+
+        // Now add them to WifiConfigManager.
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+        verifyAddNetworkToWifiConfigManager(wepNetwork);
+        verifyAddNetworkToWifiConfigManager(pskNetwork);
+        verifyAddNetworkToWifiConfigManager(eapNetwork);
+
+        // Now create dummy scan detail corresponding to the networks.
+        ScanDetail openNetworkScanDetail = createScanDetailForNetwork(openNetwork);
+        ScanDetail wepNetworkScanDetail = createScanDetailForNetwork(wepNetwork);
+        ScanDetail pskNetworkScanDetail = createScanDetailForNetwork(pskNetwork);
+        ScanDetail eapNetworkScanDetail = createScanDetailForNetwork(eapNetwork);
+
+        // Now mix and match parameters from different scan details.
+        openNetworkScanDetail.getScanResult().SSID =
+                wepNetworkScanDetail.getScanResult().SSID;
+        wepNetworkScanDetail.getScanResult().capabilities =
+                pskNetworkScanDetail.getScanResult().capabilities;
+        pskNetworkScanDetail.getScanResult().capabilities =
+                eapNetworkScanDetail.getScanResult().capabilities;
+        eapNetworkScanDetail.getScanResult().capabilities =
+                openNetworkScanDetail.getScanResult().capabilities;
+
+        // Try to lookup a saved network using the modified scan details. All of these should fail.
+        assertNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(openNetworkScanDetail));
+        assertNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(wepNetworkScanDetail));
+        assertNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(pskNetworkScanDetail));
+        assertNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(eapNetworkScanDetail));
+
+        // All the cache's should be empty as well.
+        assertNull(mWifiConfigManager.getScanDetailCacheForNetwork(openNetwork.networkId));
+        assertNull(mWifiConfigManager.getScanDetailCacheForNetwork(wepNetwork.networkId));
+        assertNull(mWifiConfigManager.getScanDetailCacheForNetwork(pskNetwork.networkId));
+        assertNull(mWifiConfigManager.getScanDetailCacheForNetwork(eapNetwork.networkId));
+    }
+
+    /**
+     * Verifies that scan detail cache is trimmed down when the size of the cache for a network
+     * exceeds {@link WifiConfigManagerNew#SCAN_CACHE_ENTRIES_MAX_SIZE}.
+     */
+    @Test
+    public void testScanDetailCacheTrimForNetwork() {
+        // Add a single network.
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        verifyAddNetworkToWifiConfigManager(openNetwork);
+
+        ScanDetailCache scanDetailCache;
+        String testBssidPrefix = "00:a5:b8:c9:45:";
+
+        // Modify |BSSID| field in the scan result and add copies of scan detail
+        // |SCAN_CACHE_ENTRIES_MAX_SIZE| times.
+        int scanDetailNum = 1;
+        for (; scanDetailNum <= WifiConfigManagerNew.SCAN_CACHE_ENTRIES_MAX_SIZE; scanDetailNum++) {
+            // Create dummy scan detail caches with different BSSID for the network.
+            ScanDetail scanDetail =
+                    createScanDetailForNetwork(
+                            openNetwork, String.format("%s%02x", testBssidPrefix, scanDetailNum));
+            assertNotNull(
+                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail));
+
+            // The size of scan detail cache should keep growing until it hits
+            // |SCAN_CACHE_ENTRIES_MAX_SIZE|.
+            scanDetailCache =
+                    mWifiConfigManager.getScanDetailCacheForNetwork(openNetwork.networkId);
+            assertEquals(scanDetailNum, scanDetailCache.size());
+        }
+
+        // Now add the |SCAN_CACHE_ENTRIES_MAX_SIZE + 1| entry. This should trigger the trim.
+        ScanDetail scanDetail =
+                createScanDetailForNetwork(
+                        openNetwork, String.format("%s%02x", testBssidPrefix, scanDetailNum));
+        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail));
+
+        // Retrieve the scan detail cache and ensure that the size was trimmed down to
+        // |SCAN_CACHE_ENTRIES_TRIM_SIZE + 1|. The "+1" is to account for the new entry that
+        // was added after the trim.
+        scanDetailCache = mWifiConfigManager.getScanDetailCacheForNetwork(openNetwork.networkId);
+        assertEquals(WifiConfigManagerNew.SCAN_CACHE_ENTRIES_TRIM_SIZE + 1, scanDetailCache.size());
+    }
+
+    /**
+     * This method sets defaults in the provided WifiConfiguration object if not set
+     * so that it can be used for comparison with the configuration retrieved from
+     * WifiConfigManager.
+     */
+    private void setDefaults(WifiConfiguration configuration) {
+        if (configuration.allowedAuthAlgorithms.isEmpty()) {
+            configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+            configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
+        }
+        if (configuration.allowedProtocols.isEmpty()) {
+            configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+            configuration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
+        }
+        if (configuration.allowedKeyManagement.isEmpty()) {
+            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+        }
+        if (configuration.allowedPairwiseCiphers.isEmpty()) {
+            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
+        }
+        if (configuration.allowedGroupCiphers.isEmpty()) {
+            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
+            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
+        }
+        if (configuration.getIpAssignment() == IpConfiguration.IpAssignment.UNASSIGNED) {
+            configuration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
+        }
+        if (configuration.getProxySettings() == IpConfiguration.ProxySettings.UNASSIGNED) {
+            configuration.setProxySettings(IpConfiguration.ProxySettings.NONE);
+        }
+    }
+
+    /**
+     * Modifies the provided configuration with creator uid, package name
+     * and time.
+     */
+    private void setCreationDebugParams(WifiConfiguration configuration) {
+        configuration.creatorUid = configuration.lastUpdateUid = TEST_CREATOR_UID;
+        configuration.creatorName = configuration.lastUpdateName = TEST_CREATOR_NAME;
+        configuration.creationTime = configuration.updateTime =
+                WifiConfigManagerNew.createDebugTimeStampString(
+                        TEST_WALLCLOCK_CREATION_TIME_MILLIS);
+    }
+
+    /**
+     * Modifies the provided configuration with update uid, package name
+     * and time.
+     */
+    private void setUpdateDebugParams(WifiConfiguration configuration) {
+        configuration.lastUpdateUid = TEST_UPDATE_UID;
+        configuration.lastUpdateName = TEST_UPDATE_NAME;
+        configuration.updateTime =
+                WifiConfigManagerNew.createDebugTimeStampString(TEST_WALLCLOCK_UPDATE_TIME_MILLIS);
+    }
+
+    private void assertNotEquals(Object expected, Object actual) {
+        if (actual != null) {
+            assertFalse(actual.equals(expected));
+        } else {
+            assertNotNull(expected);
+        }
+    }
+
+    /**
+     * Modifies the provided WifiConfiguration with the specified bssid value. Also, asserts that
+     * the existing |BSSID| field is not the same value as the one being set
+     */
+    private void assertAndSetNetworkBSSID(WifiConfiguration configuration, String bssid) {
+        assertNotEquals(bssid, configuration.BSSID);
+        configuration.BSSID = bssid;
+    }
+
+    /**
+     * Modifies the provided WifiConfiguration with the specified |IpConfiguration| object. Also,
+     * asserts that the existing |mIpConfiguration| field is not the same value as the one being set
+     */
+    private void assertAndSetNetworkIpConfiguration(
+            WifiConfiguration configuration, IpConfiguration ipConfiguration) {
+        assertNotEquals(ipConfiguration, configuration.getIpConfiguration());
+        configuration.setIpConfiguration(ipConfiguration);
+    }
+
+    /**
+     * Modifies the provided WifiConfiguration with the specified |wepKeys| value and
+     * |wepTxKeyIndex|.
+     */
+    private void assertAndSetNetworkWepKeysAndTxIndex(
+            WifiConfiguration configuration, String[] wepKeys, int wepTxKeyIdx) {
+        assertNotEquals(wepKeys, configuration.wepKeys);
+        assertNotEquals(wepTxKeyIdx, configuration.wepTxKeyIndex);
+        configuration.wepKeys = Arrays.copyOf(wepKeys, wepKeys.length);
+        configuration.wepTxKeyIndex = wepTxKeyIdx;
+    }
+
+    /**
+     * Modifies the provided WifiConfiguration with the specified |preSharedKey| value.
+     */
+    private void assertAndSetNetworkPreSharedKey(
+            WifiConfiguration configuration, String preSharedKey) {
+        assertNotEquals(preSharedKey, configuration.preSharedKey);
+        configuration.preSharedKey = preSharedKey;
+    }
+
+    /**
+     * Modifies the provided WifiConfiguration with the specified enteprise |password| value.
+     */
+    private void assertAndSetNetworkEnterprisePassword(
+            WifiConfiguration configuration, String password) {
+        assertNotEquals(password, configuration.enterpriseConfig.getPassword());
+        configuration.enterpriseConfig.setPassword(password);
+    }
+
+    /**
+     * Returns whether the provided network was in the store data or not.
+     */
+    private boolean isNetworkInConfigStoreData(WifiConfiguration configuration) {
+        try {
+            ArgumentCaptor<WifiConfigStoreData> storeDataCaptor =
+                    ArgumentCaptor.forClass(WifiConfigStoreData.class);
+            mContextConfigStoreMockOrder.verify(mWifiConfigStore)
+                    .write(anyBoolean(), storeDataCaptor.capture());
+
+            WifiConfigStoreData storeData = storeDataCaptor.getValue();
+
+            boolean foundNetworkInStoreData = false;
+            for (WifiConfiguration retrievedConfig : storeData.configurations) {
+                if (retrievedConfig.configKey().equals(configuration.configKey())) {
+                    foundNetworkInStoreData = true;
+                }
+            }
+            return foundNetworkInStoreData;
+        } catch (Exception e) {
+            fail("Exception encountered during write " + e);
+        }
+        return false;
+    }
+
+    /**
+     * Verifies that the provided network was not present in the last config store write.
+     */
+    private void verifyNetworkNotInConfigStoreData(WifiConfiguration configuration) {
+        assertFalse(isNetworkInConfigStoreData(configuration));
+    }
+
+    /**
+     * Verifies that the provided network was present in the last config store write.
+     */
+    private void verifyNetworkInConfigStoreData(WifiConfiguration configuration) {
+        assertTrue(isNetworkInConfigStoreData(configuration));
+    }
+
+    private void assertPasswordsMaskedInWifiConfiguration(WifiConfiguration configuration) {
+        if (!TextUtils.isEmpty(configuration.preSharedKey)) {
+            assertEquals(WifiConfigManagerNew.PASSWORD_MASK, configuration.preSharedKey);
+        }
+        if (configuration.wepKeys != null) {
+            for (int i = 0; i < configuration.wepKeys.length; i++) {
+                if (!TextUtils.isEmpty(configuration.wepKeys[i])) {
+                    assertEquals(WifiConfigManagerNew.PASSWORD_MASK, configuration.wepKeys[i]);
+                }
+            }
+        }
+        if (!TextUtils.isEmpty(configuration.enterpriseConfig.getPassword())) {
+            assertEquals(
+                    WifiConfigManagerNew.PASSWORD_MASK,
+                    configuration.enterpriseConfig.getPassword());
+        }
+    }
+
+    /**
+     * Verifies that the network was present in the network change broadcast and returns the
+     * change reason.
+     */
+    private int verifyNetworkInBroadcastAndReturnReason(WifiConfiguration configuration) {
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        ArgumentCaptor<UserHandle> userHandleCaptor = ArgumentCaptor.forClass(UserHandle.class);
+        mContextConfigStoreMockOrder.verify(mContext)
+                .sendBroadcastAsUser(intentCaptor.capture(), userHandleCaptor.capture());
+
+        assertEquals(userHandleCaptor.getValue(), UserHandle.ALL);
+        Intent intent = intentCaptor.getValue();
+
+        int changeReason = intent.getIntExtra(WifiManager.EXTRA_CHANGE_REASON, -1);
+        WifiConfiguration retrievedConfig =
+                (WifiConfiguration) intent.getExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
+        assertEquals(retrievedConfig.configKey(), configuration.configKey());
+
+        // Verify that all the passwords are masked in the broadcast configuration.
+        assertPasswordsMaskedInWifiConfiguration(retrievedConfig);
+
+        return changeReason;
+    }
+
+    /**
+     * Verifies that we sent out an add broadcast with the provided network.
+     */
+    private void verifyNetworkAddBroadcast(WifiConfiguration configuration) {
+        assertEquals(
+                verifyNetworkInBroadcastAndReturnReason(configuration),
+                WifiManager.CHANGE_REASON_ADDED);
+    }
+
+    /**
+     * Verifies that we sent out an update broadcast with the provided network.
+     */
+    private void verifyNetworkUpdateBroadcast(WifiConfiguration configuration) {
+        assertEquals(
+                verifyNetworkInBroadcastAndReturnReason(configuration),
+                WifiManager.CHANGE_REASON_CONFIG_CHANGE);
+    }
+
+    /**
+     * Verifies that we sent out a remove broadcast with the provided network.
+     */
+    private void verifyNetworkRemoveBroadcast(WifiConfiguration configuration) {
+        assertEquals(
+                verifyNetworkInBroadcastAndReturnReason(configuration),
+                WifiManager.CHANGE_REASON_REMOVED);
+    }
+
+    /**
+     * Adds the provided configuration to WifiConfigManager and modifies the provided configuration
+     * with creator/update uid, package name and time. This also sets defaults for fields not
+     * populated.
+     * These fields are populated internally by WifiConfigManager and hence we need
+     * to modify the configuration before we compare the added network with the retrieved network.
+     */
+    private NetworkUpdateResult addNetworkToWifiConfigManager(WifiConfiguration configuration) {
+        when(mClock.getWallClockMillis()).thenReturn(TEST_WALLCLOCK_CREATION_TIME_MILLIS);
+        NetworkUpdateResult result =
+                mWifiConfigManager.addOrUpdateNetwork(configuration, TEST_CREATOR_UID);
+        setDefaults(configuration);
+        setCreationDebugParams(configuration);
+        configuration.networkId = result.getNetworkId();
+        return result;
+    }
+
+    /**
+     * Add network to WifiConfigManager and ensure that it was successful.
+     */
+    private NetworkUpdateResult verifyAddNetworkToWifiConfigManager(
+            WifiConfiguration configuration) {
+        NetworkUpdateResult result = addNetworkToWifiConfigManager(configuration);
+        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
+        assertTrue(result.isNewNetwork());
+        assertTrue(result.hasIpChanged());
+        assertTrue(result.hasProxyChanged());
+
+        verifyNetworkAddBroadcast(configuration);
+        // Verify that the config store write was triggered with this new configuration.
+        verifyNetworkInConfigStoreData(configuration);
+        return result;
+    }
+
+    /**
+     * Add ephemeral network to WifiConfigManager and ensure that it was successful.
+     */
+    private NetworkUpdateResult verifyAddEphemeralNetworkToWifiConfigManager(
+            WifiConfiguration configuration) {
+        NetworkUpdateResult result = addNetworkToWifiConfigManager(configuration);
+        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
+        assertTrue(result.isNewNetwork());
+        assertTrue(result.hasIpChanged());
+        assertTrue(result.hasProxyChanged());
+
+        verifyNetworkAddBroadcast(configuration);
+        // Ephemeral networks should not be persisted.
+        verifyNetworkNotInConfigStoreData(configuration);
+        return result;
+    }
+
+    /**
+     * Updates the provided configuration to WifiConfigManager and modifies the provided
+     * configuration with update uid, package name and time.
+     * These fields are populated internally by WifiConfigManager and hence we need
+     * to modify the configuration before we compare the added network with the retrieved network.
+     */
+    private NetworkUpdateResult updateNetworkToWifiConfigManager(WifiConfiguration configuration) {
+        when(mClock.getWallClockMillis()).thenReturn(TEST_WALLCLOCK_UPDATE_TIME_MILLIS);
+        NetworkUpdateResult result =
+                mWifiConfigManager.addOrUpdateNetwork(configuration, TEST_UPDATE_UID);
+        setUpdateDebugParams(configuration);
+        return result;
+    }
+
+    /**
+     * Update network to WifiConfigManager config change and ensure that it was successful.
+     */
+    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManager(
+            WifiConfiguration configuration) {
+        NetworkUpdateResult result = updateNetworkToWifiConfigManager(configuration);
+        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
+        assertFalse(result.isNewNetwork());
+
+        verifyNetworkUpdateBroadcast(configuration);
+        // Verify that the config store write was triggered with this new configuration.
+        verifyNetworkInConfigStoreData(configuration);
+        return result;
+    }
+
+    /**
+     * Update network to WifiConfigManager without IP config change and ensure that it was
+     * successful.
+     */
+    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(
+            WifiConfiguration configuration) {
+        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManager(configuration);
+        assertFalse(result.hasIpChanged());
+        assertFalse(result.hasProxyChanged());
+        return result;
+    }
+
+    /**
+     * Update network to WifiConfigManager with IP config change and ensure that it was
+     * successful.
+     */
+    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManagerWithIpChange(
+            WifiConfiguration configuration) {
+        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManager(configuration);
+        assertTrue(result.hasIpChanged());
+        assertTrue(result.hasProxyChanged());
+        return result;
+    }
+
+    /**
+     * Removes network from WifiConfigManager and ensure that it was successful.
+     */
+    private void verifyRemoveNetworkFromWifiConfigManager(
+            WifiConfiguration configuration) {
+        assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId));
+
+        verifyNetworkRemoveBroadcast(configuration);
+        // Verify if the config store write was triggered without this new configuration.
+        verifyNetworkNotInConfigStoreData(configuration);
+    }
+
+    /**
+     * Verifies the provided network's public status and ensures that the network change broadcast
+     * has been sent out.
+     */
+    private void verifyUpdateNetworkStatus(WifiConfiguration configuration, int status) {
+        assertEquals(status, configuration.status);
+        verifyNetworkUpdateBroadcast(configuration);
+    }
+
+    /**
+     * Verifies the network's selection status update.
+     *
+     * For temporarily disabled reasons, the method ensures that the status has changed only if
+     * disable reason counter has exceeded the threshold.
+     *
+     * For permanently disabled/enabled reasons, the method ensures that the public status has
+     * changed and the network change broadcast has been sent out.
+     */
+    private void verifyUpdateNetworkSelectionStatus(
+            int networkId, int reason, int temporaryDisableReasonCounter) {
+        when(mClock.getElapsedSinceBootMillis())
+                .thenReturn(TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS);
+
+        // Fetch the current status of the network before we try to update the status.
+        WifiConfiguration retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
+        NetworkSelectionStatus currentStatus = retrievedNetwork.getNetworkSelectionStatus();
+        int currentDisableReason = currentStatus.getNetworkSelectionDisableReason();
+
+        // First set the status to the provided reason.
+        assertTrue(mWifiConfigManager.updateNetworkSelectionStatus(networkId, reason));
+
+        // Now fetch the network configuration and verify the new status of the network.
+        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
+
+        NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
+        int retrievedDisableReason = retrievedStatus.getNetworkSelectionDisableReason();
+        long retrievedDisableTime = retrievedStatus.getDisableTime();
+        int retrievedDisableReasonCounter = retrievedStatus.getDisableReasonCounter(reason);
+        int disableReasonThreshold =
+                WifiConfigManagerNew.NETWORK_SELECTION_DISABLE_THRESHOLD[reason];
+
+        if (reason == NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) {
+            assertEquals(reason, retrievedDisableReason);
+            assertTrue(retrievedStatus.isNetworkEnabled());
+            assertEquals(
+                    NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP,
+                    retrievedDisableTime);
+            verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.ENABLED);
+        } else if (reason < NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) {
+            // For temporarily disabled networks, we need to ensure that the current status remains
+            // until the threshold is crossed.
+            assertEquals(temporaryDisableReasonCounter, retrievedDisableReasonCounter);
+            if (retrievedDisableReasonCounter < disableReasonThreshold) {
+                assertEquals(currentDisableReason, retrievedDisableReason);
+                assertEquals(
+                        currentStatus.getNetworkSelectionStatus(),
+                        retrievedStatus.getNetworkSelectionStatus());
+            } else {
+                assertEquals(reason, retrievedDisableReason);
+                assertTrue(retrievedStatus.isNetworkTemporaryDisabled());
+                assertEquals(
+                        TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS, retrievedDisableTime);
+            }
+        } else if (reason < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX) {
+            assertEquals(reason, retrievedDisableReason);
+            assertTrue(retrievedStatus.isNetworkPermanentlyDisabled());
+            assertEquals(
+                    NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP,
+                    retrievedDisableTime);
+            verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.DISABLED);
+        }
+    }
+
+    /**
+     * Creates a scan detail corresponding to the provided network and BSSID value.
+     */
+    private ScanDetail createScanDetailForNetwork(WifiConfiguration configuration, String bssid) {
+        String caps;
+        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
+            caps = "[WPA2-PSK-CCMP]";
+        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)
+                || configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) {
+            caps = "[WPA2-EAP-CCMP]";
+        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)
+                && WifiConfigurationUtil.hasAnyValidWepKey(configuration.wepKeys)) {
+            caps = "[WEP]";
+        } else {
+            caps = "[]";
+        }
+        WifiSsid ssid = WifiSsid.createFromAsciiEncoded(configuration.getPrintableSsid());
+        // Fill in 0's in the fields we don't care about.
+        return new ScanDetail(
+                ssid, bssid, caps, 0, 0, SystemClock.uptimeMillis(), System.currentTimeMillis());
+    }
+
+    /**
+     * Creates a scan detail corresponding to the provided network and fixed BSSID value.
+     */
+    private ScanDetail createScanDetailForNetwork(WifiConfiguration configuration) {
+        return createScanDetailForNetwork(configuration, TEST_BSSID);
+    }
+
+    /**
+     * Adds the provided network and then creates a scan detail corresponding to the network. The
+     * method then creates a ScanDetail corresponding to the network and ensures that the network
+     * is properly matched using
+     * {@link WifiConfigManagerNew#getSavedNetworkForScanDetailAndCache(ScanDetail)} and also
+     * verifies that the provided scan detail was cached,
+     */
+    private void verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
+            WifiConfiguration network) {
+        // First add the provided network.
+        verifyAddNetworkToWifiConfigManager(network);
+
+        // Now create a dummy scan detail corresponding to the network.
+        ScanDetail scanDetail = createScanDetailForNetwork(network);
+        ScanResult scanResult = scanDetail.getScanResult();
+
+        WifiConfiguration retrievedNetwork =
+                mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail);
+
+        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
+                network, retrievedNetwork);
+
+        // Now retrieve the scan detail cache and ensure that the new scan detail is in cache.
+        ScanDetailCache retrievedScanDetailCache =
+                mWifiConfigManager.getScanDetailCacheForNetwork(network.networkId);
+        assertEquals(1, retrievedScanDetailCache.size());
+        ScanResult retrievedScanResult = retrievedScanDetailCache.get(scanResult.BSSID);
+
+        ScanTestUtil.assertScanResultEquals(scanResult, retrievedScanResult);
+    }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index a585000..fd1d66d 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
 import android.content.Context;
 import android.content.pm.UserInfo;
 import android.net.wifi.FakeKeys;
@@ -45,7 +46,6 @@
 import android.util.SparseArray;
 
 import com.android.server.net.DelayedDiskWrite;
-import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
 import com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager;
 import com.android.server.wifi.hotspot2.pps.Credential;
 import com.android.server.wifi.hotspot2.pps.HomeSP;
@@ -420,23 +420,15 @@
                         assertEquals(WifiConfiguration.Status.ENABLED, config2.status);
                     }
                 } else {
-                    // If the network configuration is visible to the current user, verify that it
-                    // was enabled and all other network configurations visible to the user were
-                    // disabled.
+                    // If the network configuration is visible to the current user, verify that
+                    // a connection attempt was made to it. This does not modify the status of
+                    // other networks.
                     assertTrue(success);
                     verify(mWifiNative).selectNetwork(config.networkId);
                     verify(mWifiNative, never()).selectNetwork(intThat(not(config.networkId)));
                     verify(mWifiNative, never()).enableNetwork(config.networkId);
                     verify(mWifiNative, never()).enableNetwork(intThat(not(config.networkId)));
-                    for (WifiConfiguration config2 : mConfiguredNetworks.valuesForAllUsers()) {
-                        if (WifiConfigurationUtil.isVisibleToAnyProfile(config2,
-                                USER_PROFILES.get(userId))
-                                && config2.networkId != config.networkId) {
-                            assertEquals(WifiConfiguration.Status.DISABLED, config2.status);
-                        } else {
-                            assertEquals(WifiConfiguration.Status.ENABLED, config2.status);
-                        }
-                    }
+                    assertEquals(WifiConfiguration.Status.ENABLED, config.status);
                 }
             }
         }
@@ -471,12 +463,13 @@
         // configuration.
         final Map<String, String> metadata = new HashMap<String, String>();
         if (CONFIGS.get(network).FQDN != null) {
-            metadata.put(WifiConfigStore.ID_STRING_KEY_FQDN, CONFIGS.get(network).FQDN);
+            metadata.put(WifiSupplicantControl.ID_STRING_KEY_FQDN, CONFIGS.get(network).FQDN);
         }
-        metadata.put(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(network).configKey());
-        metadata.put(WifiConfigStore.ID_STRING_KEY_CREATOR_UID,
+        metadata.put(
+                WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(network).configKey());
+        metadata.put(WifiSupplicantControl.ID_STRING_KEY_CREATOR_UID,
                 Integer.toString(CONFIGS.get(network).creatorUid));
-        verify(mWifiNative).setNetworkExtra(network, WifiConfigStore.ID_STRING_VAR_NAME,
+        verify(mWifiNative).setNetworkExtra(network, WifiSupplicantControl.ID_STRING_VAR_NAME,
                 metadata);
 
         // Verify that an attempt to read back the requirePMF variable was made.
@@ -576,27 +569,27 @@
                 .thenReturn(encodeConfigSSID(CONFIGS.get(i)));
         }
         // Legacy regular network configuration: No "id_str".
-        when(mWifiNative.getNetworkExtra(0, WifiConfigStore.ID_STRING_VAR_NAME))
+        when(mWifiNative.getNetworkExtra(0, WifiSupplicantControl.ID_STRING_VAR_NAME))
             .thenReturn(null);
         // Legacy Hotspot 2.0 network configuration: Quoted FQDN in "id_str".
-        when(mWifiNative.getNetworkExtra(1, WifiConfigStore.ID_STRING_VAR_NAME))
+        when(mWifiNative.getNetworkExtra(1, WifiSupplicantControl.ID_STRING_VAR_NAME))
             .thenReturn(null);
-        when(mWifiNative.getNetworkVariable(1, WifiConfigStore.ID_STRING_VAR_NAME))
+        when(mWifiNative.getNetworkVariable(1, WifiSupplicantControl.ID_STRING_VAR_NAME))
             .thenReturn('"' + CONFIGS.get(1).FQDN + '"');
         // Up-to-date Hotspot 2.0 network configuration: Metadata in "id_str".
         Map<String, String> metadata = new HashMap<String, String>();
-        metadata.put(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(2).configKey());
-        metadata.put(WifiConfigStore.ID_STRING_KEY_CREATOR_UID,
+        metadata.put(WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(2).configKey());
+        metadata.put(WifiSupplicantControl.ID_STRING_KEY_CREATOR_UID,
                 Integer.toString(CONFIGS.get(2).creatorUid));
-        metadata.put(WifiConfigStore.ID_STRING_KEY_FQDN, CONFIGS.get(2).FQDN);
-        when(mWifiNative.getNetworkExtra(2, WifiConfigStore.ID_STRING_VAR_NAME))
+        metadata.put(WifiSupplicantControl.ID_STRING_KEY_FQDN, CONFIGS.get(2).FQDN);
+        when(mWifiNative.getNetworkExtra(2, WifiSupplicantControl.ID_STRING_VAR_NAME))
             .thenReturn(metadata);
         // Up-to-date regular network configuration: Metadata in "id_str".
         metadata = new HashMap<String, String>();
-        metadata.put(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(3).configKey());
-        metadata.put(WifiConfigStore.ID_STRING_KEY_CREATOR_UID,
+        metadata.put(WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY, CONFIGS.get(3).configKey());
+        metadata.put(WifiSupplicantControl.ID_STRING_KEY_CREATOR_UID,
                 Integer.toString(CONFIGS.get(3).creatorUid));
-        when(mWifiNative.getNetworkExtra(3, WifiConfigStore.ID_STRING_VAR_NAME))
+        when(mWifiNative.getNetworkExtra(3, WifiSupplicantControl.ID_STRING_VAR_NAME))
             .thenReturn(metadata);
 
         // Set up networkHistory.txt file.
@@ -661,10 +654,10 @@
         when(mWifiNative.getNetworkVariable(anyInt(), eq(WifiConfiguration.ssidVarName)))
             .thenReturn(encodeConfigSSID(config));
         final Map<String, String> metadata = new HashMap<String, String>();
-        metadata.put(WifiConfigStore.ID_STRING_KEY_CONFIG_KEY, config.configKey());
-        metadata.put(WifiConfigStore.ID_STRING_KEY_CREATOR_UID,
+        metadata.put(WifiSupplicantControl.ID_STRING_KEY_CONFIG_KEY, config.configKey());
+        metadata.put(WifiSupplicantControl.ID_STRING_KEY_CREATOR_UID,
                 Integer.toString(config.creatorUid));
-        when(mWifiNative.getNetworkExtra(anyInt(), eq(WifiConfigStore.ID_STRING_VAR_NAME)))
+        when(mWifiNative.getNetworkExtra(anyInt(), eq(WifiSupplicantControl.ID_STRING_VAR_NAME)))
             .thenReturn(metadata);
 
         // Load network configurations.
@@ -741,16 +734,20 @@
         for (WifiConfiguration config : newConfigs) {
             if (oldUserOnlyConfigs.contains(config)) {
                 verify(mWifiNative).disableNetwork(config.networkId);
-                assertEquals(WifiConfiguration.Status.DISABLED, config.status);
+                assertNetworkStatus(
+                        config,
+                        WifiConfiguration.NetworkSelectionStatus.DISABLED_DUE_TO_USER_SWITCH);
             } else {
                 verify(mWifiNative, never()).disableNetwork(config.networkId);
                 if (neitherUserConfigs.contains(config)) {
-                    assertEquals(WifiConfiguration.Status.DISABLED, config.status);
+                    assertNetworkStatus(
+                            config,
+                            WifiConfiguration.NetworkSelectionStatus.DISABLED_DUE_TO_USER_SWITCH);
                 } else {
-                    // Only enabled in networkSelection.
-                    assertTrue(config.getNetworkSelectionStatus().isNetworkEnabled());
+                    assertNetworkStatus(
+                            config,
+                            WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
                 }
-
             }
         }
     }
@@ -1463,8 +1460,8 @@
         updateRequirePMFConfig.requirePMF = true;
 
         // Set up mock to allow the new value to be read back into the config
-        // TODO: please see b/28088226  - this test is implemented as if WifiConfigStore correctly
-        // read back the boolean value.  When fixed, uncomment the following line and the
+        // TODO: please see b/28088226  - this test is implemented as if WifiSupplicantControl
+        // correctly read back the boolean value. When fixed, uncomment the following line and the
         // checkHasEverConnectedFalse below.
         //when(mWifiNative.getNetworkVariable(BASE_HAS_EVER_CONNECTED_CONFIG.networkId,
         //        WifiConfiguration.pmfVarName)).thenReturn("2");
@@ -1591,7 +1588,6 @@
                 eapConfigSame.enterpriseConfig));
     }
 
-
     private void checkHasEverConnectedTrue(int networkId) {
         WifiConfiguration checkConfig = mWifiConfigManager.getWifiConfiguration(networkId);
         assertTrue("hasEverConnected expected to be true.",
@@ -1627,5 +1623,80 @@
         return buf.toString();
     }
 
+    /**
+     * Test whether enableNetwork with the disableOthers flag set to false enables the
+     * input network, but does not attempt a connection.
+     */
+    @Test
+    public void testEnableNetworkWithoutDisableOthers() throws Exception {
+        addNetworks();
 
+        for (Map.Entry<Integer, List<WifiConfiguration>> entry : VISIBLE_CONFIGS.entrySet()) {
+            switchUser(entry.getKey());
+            // Iterate through all the configs for the current user and invoke |enableNetwork|
+            // on the corresponding config retrieved from WifiConfigManager.
+            for (WifiConfiguration config : entry.getValue()) {
+                WifiConfiguration retrievedConfig =
+                        mWifiConfigManager.getWifiConfiguration(config.networkId);
+                assertTrue(mWifiConfigManager.enableNetwork(retrievedConfig, false, 0));
+                assertNetworkStatus(retrievedConfig,
+                        WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
+                verify(mWifiNative, never()).selectNetwork(anyInt());
+            }
+        }
+    }
+
+    /**
+     * Test whether enableNetwork without the disableOthers flag set to true enables the input
+     * network and attempts a connection to it immediately. It also checks if all the other
+     * networks are disabled.
+     */
+    @Test
+    public void testEnableNetworkWithDisableOthers() throws Exception {
+        addNetworks();
+
+        for (Map.Entry<Integer, List<WifiConfiguration>> entry : VISIBLE_CONFIGS.entrySet()) {
+            switchUser(entry.getKey());
+            // Iterate through all the configs for the current user and invoke |enableNetwork|
+            // on the corresponding config retrieved from WifiConfigManager.
+            for (WifiConfiguration config : entry.getValue()) {
+                reset(mWifiNative);
+                when(mWifiNative.selectNetwork(anyInt())).thenReturn(true);
+                WifiConfiguration retrievedConfig =
+                        mWifiConfigManager.getWifiConfiguration(config.networkId);
+                assertTrue(mWifiConfigManager.enableNetwork(retrievedConfig, true, 0));
+                assertNetworkStatus(retrievedConfig,
+                        WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
+                assertAllNetworksDisabledExcept(retrievedConfig.networkId,
+                        WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER);
+                verify(mWifiNative).selectNetwork(retrievedConfig.networkId);
+                verify(mWifiNative, never()).selectNetwork(intThat(not(retrievedConfig.networkId)));
+            }
+        }
+    }
+
+    private void assertNetworkStatus(WifiConfiguration config, int disableReason) {
+        final WifiConfiguration.NetworkSelectionStatus status = config.getNetworkSelectionStatus();
+        assertEquals(disableReason, status.getNetworkSelectionDisableReason());
+        if (disableReason
+                == WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) {
+            assertEquals(WifiConfiguration.Status.ENABLED, config.status);
+            assertTrue(config.getNetworkSelectionStatus().isNetworkEnabled());
+        } else if (disableReason
+                < WifiConfiguration.NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) {
+            assertEquals(WifiConfiguration.Status.ENABLED, config.status);
+            assertTrue(config.getNetworkSelectionStatus().isNetworkTemporaryDisabled());
+        } else {
+            assertEquals(WifiConfiguration.Status.DISABLED, config.status);
+            assertTrue(config.getNetworkSelectionStatus().isNetworkPermanentlyDisabled());
+        }
+    }
+
+    private void assertAllNetworksDisabledExcept(int netId, int disableReason) {
+        for (WifiConfiguration config : mWifiConfigManager.getSavedNetworks()) {
+            if (config.networkId != netId) {
+                assertNetworkStatus(config, disableReason);
+            }
+        }
+    }
 }
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreDataTest.java
new file mode 100644
index 0000000..7bed17a
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreDataTest.java
@@ -0,0 +1,419 @@
+/*
+ * 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 com.android.server.wifi;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.WifiConfigStoreData}.
+ */
+@SmallTest
+public class WifiConfigStoreDataTest {
+
+    private static final String TEST_SSID = "WifiConfigStoreDataSSID_";
+    private static final String TEST_CONNECT_CHOICE = "XmlUtilConnectChoice";
+    private static final long TEST_CONNECT_CHOICE_TIMESTAMP = 0x4566;
+    private static final Set<String> TEST_DELETED_EPHEMERAL_LIST = new HashSet<String>() {
+        {
+            add("\"" + TEST_SSID + "1\"");
+            add("\"" + TEST_SSID + "2\"");
+        }
+    };
+    private static final String SINGLE_OPEN_NETWORK_LIST_XML_STRING_FORMAT =
+            "<NetworkList>\n"
+                    + "<Network>\n"
+                    + "<WifiConfiguration>\n"
+                    + "<string name=\"ConfigKey\">%s</string>\n"
+                    + "<string name=\"SSID\">%s</string>\n"
+                    + "<null name=\"BSSID\" />\n"
+                    + "<null name=\"PreSharedKey\" />\n"
+                    + "<null name=\"WEPKeys\" />\n"
+                    + "<int name=\"WEPTxKeyIndex\" value=\"0\" />\n"
+                    + "<boolean name=\"HiddenSSID\" value=\"false\" />\n"
+                    + "<byte-array name=\"AllowedKeyMgmt\" num=\"1\">01</byte-array>\n"
+                    + "<byte-array name=\"AllowedProtocols\" num=\"0\"></byte-array>\n"
+                    + "<byte-array name=\"AllowedAuthAlgos\" num=\"0\"></byte-array>\n"
+                    + "<boolean name=\"Shared\" value=\"%s\" />\n"
+                    + "<null name=\"FQDN\" />\n"
+                    + "<null name=\"ProviderFriendlyName\" />\n"
+                    + "<null name=\"LinkedNetworksList\" />\n"
+                    + "<null name=\"DefaultGwMacAddress\" />\n"
+                    + "<boolean name=\"ValidatedInternetAccess\" value=\"false\" />\n"
+                    + "<boolean name=\"NoInternetAccessExpected\" value=\"false\" />\n"
+                    + "<int name=\"UserApproved\" value=\"0\" />\n"
+                    + "<boolean name=\"MeteredHint\" value=\"false\" />\n"
+                    + "<boolean name=\"UseExternalScores\" value=\"false\" />\n"
+                    + "<int name=\"NumAssociation\" value=\"0\" />\n"
+                    + "<int name=\"CreatorUid\" value=\"%d\" />\n"
+                    + "<null name=\"CreatorName\" />\n"
+                    + "<null name=\"CreationTime\" />\n"
+                    + "<int name=\"LastUpdateUid\" value=\"-1\" />\n"
+                    + "<null name=\"LastUpdateName\" />\n"
+                    + "<int name=\"LastConnectUid\" value=\"0\" />\n"
+                    + "</WifiConfiguration>\n"
+                    + "<NetworkStatus>\n"
+                    + "<int name=\"SelectionStatus\" value=\"0\" />\n"
+                    + "<int name=\"DisableReason\" value=\"0\" />\n"
+                    + "<null name=\"ConnectChoice\" />\n"
+                    + "<long name=\"ConnectChoiceTimeStamp\" value=\"-1\" />\n"
+                    + "<boolean name=\"HasEverConnected\" value=\"false\" />\n"
+                    + "</NetworkStatus>\n"
+                    + "<IpConfiguration>\n"
+                    + "<string name=\"IpAssignment\">DHCP</string>\n"
+                    + "<string name=\"ProxySettings\">NONE</string>\n"
+                    + "</IpConfiguration>\n"
+                    + "</Network>\n"
+                    + "</NetworkList>\n";
+    private static final String SINGLE_OPEN_NETWORK_SHARED_DATA_XML_STRING_FORMAT =
+            "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                    + "<WifiConfigStoreData>\n"
+                    + "<int name=\"Version\" value=\"1\" />\n"
+                    + SINGLE_OPEN_NETWORK_LIST_XML_STRING_FORMAT
+                    + "</WifiConfigStoreData>\n";
+    private static final String SINGLE_OPEN_NETWORK_USER_DATA_XML_STRING_FORMAT =
+            "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                    + "<WifiConfigStoreData>\n"
+                    + "<int name=\"Version\" value=\"1\" />\n"
+                    + SINGLE_OPEN_NETWORK_LIST_XML_STRING_FORMAT
+                    + "<DeletedEphemeralSSIDList>\n"
+                    + "<set name=\"SSIDList\" />\n"
+                    + "</DeletedEphemeralSSIDList>\n"
+                    + "</WifiConfigStoreData>\n";
+
+    /**
+     * Asserts that the 2 config store data are equal.
+     */
+    public static void assertConfigStoreDataEqual(
+            WifiConfigStoreData expected, WifiConfigStoreData actual) {
+        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigStore(
+                expected.configurations, actual.configurations);
+        assertEquals(expected.deletedEphemeralSSIDs, actual.deletedEphemeralSSIDs);
+    }
+
+    /**
+     * Verify that multiple shared networks with different credential types and IpConfiguration
+     * types are serialized and deserialized correctly.
+     */
+    @Test
+    public void testMultipleNetworkAllShared()
+            throws XmlPullParserException, IOException {
+        List<WifiConfiguration> configurations = createNetworks(true);
+        serializeDeserializeConfigStoreData(configurations);
+    }
+
+    /**
+     * Verify that multiple user networks with different credential types and IpConfiguration
+     * types are serialized and deserialized correctly.
+     */
+    @Test
+    public void testMultipleNetworksAllUser()
+            throws XmlPullParserException, IOException {
+        List<WifiConfiguration> configurations = createNetworks(false);
+        serializeDeserializeConfigStoreData(configurations);
+    }
+
+    /**
+     * Verify that multiple networks with different credential types and IpConfiguration
+     * types are serialized and deserialized correctly when both user & shared networks are present.
+     */
+    @Test
+    public void testMultipleNetworksSharedAndUserNetworks()
+            throws XmlPullParserException, IOException {
+        List<WifiConfiguration> configurations = createNetworks();
+        // Let's split the list of networks into 2 and make all the networks in the first list
+        // shared and the second list all user networks.
+        int listSize = configurations.size();
+        List<WifiConfiguration> sharedConfigurations = configurations.subList(0, listSize / 2);
+        List<WifiConfiguration> userConfigurations = configurations.subList(listSize / 2, listSize);
+        for (WifiConfiguration config : sharedConfigurations) {
+            config.shared = true;
+        }
+        for (WifiConfiguration config : userConfigurations) {
+            config.shared = false;
+        }
+        serializeDeserializeConfigStoreData(configurations);
+    }
+
+    /**
+     * Verify that multiple shared networks with different credential types and IpConfiguration
+     * types are serialized and deserialized correctly when the shared data bytes are null in
+     * |parseRawData| method.
+     */
+    @Test
+    public void testMultipleNetworksSharedDataNullInParseRawData()
+            throws XmlPullParserException, IOException {
+        List<WifiConfiguration> configurations = createNetworks(false);
+        serializeDeserializeConfigStoreData(configurations, true, false);
+    }
+
+    /**
+     * Verify that multiple shared networks with different credential types and IpConfiguration
+     * types are serialized and deserialized correctly when the user data bytes are null in
+     * |parseRawData| method.
+     */
+    @Test
+    public void testMultipleNetworksUserDataNullInParseRawData()
+            throws XmlPullParserException, IOException {
+        List<WifiConfiguration> configurations = createNetworks(true);
+        serializeDeserializeConfigStoreData(configurations, false, true);
+    }
+
+    /**
+     * Verify that the manually populated xml string for is deserialized/serialized correctly.
+     * This generates a store data corresponding to the XML string and verifies that the string
+     * is indeed parsed correctly to the store data.
+     */
+    @Test
+    public void testManualConfigStoreDataParse() {
+        WifiConfiguration sharedNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        sharedNetwork.shared = true;
+        sharedNetwork.setIpConfiguration(WifiConfigurationTestUtil.createDHCPIpConfigurationWithNoProxy());
+        WifiConfiguration userNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        userNetwork.setIpConfiguration(WifiConfigurationTestUtil.createDHCPIpConfigurationWithNoProxy());
+        userNetwork.shared = false;
+
+        // Create the store data for comparison.
+        List<WifiConfiguration> networks = new ArrayList<>();
+        networks.add(sharedNetwork);
+        networks.add(userNetwork);
+        WifiConfigStoreData storeData =
+                new WifiConfigStoreData(networks, new HashSet<String>());
+
+        String sharedStoreXmlString =
+                String.format(SINGLE_OPEN_NETWORK_SHARED_DATA_XML_STRING_FORMAT,
+                        sharedNetwork.configKey().replaceAll("\"", "&quot;"),
+                        sharedNetwork.SSID.replaceAll("\"", "&quot;"),
+                        sharedNetwork.shared, sharedNetwork.creatorUid);
+        String userStoreXmlString =
+                String.format(SINGLE_OPEN_NETWORK_USER_DATA_XML_STRING_FORMAT,
+                        userNetwork.configKey().replaceAll("\"", "&quot;"),
+                        userNetwork.SSID.replaceAll("\"", "&quot;"),
+                        userNetwork.shared, userNetwork.creatorUid);
+        byte[] rawSharedData = sharedStoreXmlString.getBytes();
+        byte[] rawUserData = userStoreXmlString.getBytes();
+        WifiConfigStoreData retrievedStoreData = null;
+        try {
+            retrievedStoreData = WifiConfigStoreData.parseRawData(rawSharedData, rawUserData);
+        } catch (Exception e) {
+            // Assert if an exception was raised.
+            fail("Error in parsing the xml data: " + e
+                    + ". Shared data: " + sharedStoreXmlString
+                    + ", User data: " + userStoreXmlString);
+        }
+        // Compare the retrieved config store data with the original.
+        assertConfigStoreDataEqual(storeData, retrievedStoreData);
+
+        // Now convert the store data to XML bytes and compare the output with the expected string.
+        byte[] retrievedSharedStoreXmlBytes = null;
+        byte[] retrievedUserStoreXmlBytes = null;
+        try {
+            retrievedSharedStoreXmlBytes = retrievedStoreData.createSharedRawData();
+            retrievedUserStoreXmlBytes = retrievedStoreData.createUserRawData();
+        } catch (Exception e) {
+            // Assert if an exception was raised.
+            fail("Error in writing the xml data: " + e);
+        }
+        String retrievedSharedStoreXmlString =
+                new String(retrievedSharedStoreXmlBytes, StandardCharsets.UTF_8);
+        String retrievedUserStoreXmlString =
+                new String(retrievedUserStoreXmlBytes, StandardCharsets.UTF_8);
+        assertEquals("Retrieved: " + retrievedSharedStoreXmlString
+                + ", Expected: " + sharedStoreXmlString,
+                sharedStoreXmlString, retrievedSharedStoreXmlString);
+        assertEquals("Retrieved: " + retrievedUserStoreXmlString
+                + ", Expected: " + userStoreXmlString,
+                userStoreXmlString, retrievedUserStoreXmlString);
+    }
+
+    /**
+     * Verify that XML with corrupted version provided to WifiConfigStoreData is ignored correctly.
+     */
+    @Test
+    public void testCorruptVersionConfigStoreData() {
+        String storeDataAsString =
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                        + "<WifiConfigStoreData>\n"
+                        + "<int name=\"Version\" value=\"200\" />\n"
+                        + "</WifiConfigStoreData>\n";
+        byte[] rawData = storeDataAsString.getBytes();
+        try {
+            WifiConfigStoreData storeData = WifiConfigStoreData.parseRawData(rawData, rawData);
+        } catch (Exception e) {
+            return;
+        }
+        // Assert if there was no exception was raised.
+        fail();
+    }
+
+    /**
+     * Verify that XML with no network list provided to WifiConfigStoreData is ignored correctly.
+     */
+    @Test
+    public void testCorruptNetworkListConfigStoreData() {
+        String storeDataAsString =
+                "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                        + "<WifiConfigStoreData>\n"
+                        + "<int name=\"Version\" value=\"1\" />\n"
+                        + "</WifiConfigStoreData>\n";
+        byte[] rawData = storeDataAsString.getBytes();
+        try {
+            WifiConfigStoreData storeData = WifiConfigStoreData.parseRawData(rawData, rawData);
+        } catch (Exception e) {
+            return;
+        }
+        // Assert if there was no exception was raised.
+        fail();
+    }
+
+    /**
+     * Verify that any corrupted data provided to WifiConfigStoreData is ignored correctly.
+     */
+    @Test
+    public void testRandomCorruptConfigStoreData() {
+        Random random = new Random();
+        byte[] rawData = new byte[100];
+        random.nextBytes(rawData);
+        try {
+            WifiConfigStoreData storeData = WifiConfigStoreData.parseRawData(rawData, rawData);
+        } catch (Exception e) {
+            return;
+        }
+        // Assert if there was no exception was raised.
+        fail();
+    }
+
+    /**
+     * Helper method to add 4 networks with different credential types, IpConfiguration
+     * types for all tests in the class.
+     *
+     * @return
+     */
+    private List<WifiConfiguration> createNetworks() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+
+        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
+        wepNetwork.setIpConfiguration(WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
+        wepNetwork.getNetworkSelectionStatus().setNetworkSelectionStatus(
+                NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
+        configurations.add(wepNetwork);
+
+        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+        pskNetwork.setIpConfiguration(WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
+        pskNetwork.getNetworkSelectionStatus().setNetworkSelectionStatus(
+                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
+        pskNetwork.getNetworkSelectionStatus().setNetworkSelectionDisableReason(
+                NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION);
+        configurations.add(pskNetwork);
+
+        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
+        openNetwork.setIpConfiguration(WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
+        openNetwork.getNetworkSelectionStatus().setNetworkSelectionStatus(
+                NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
+        openNetwork.getNetworkSelectionStatus().setNetworkSelectionDisableReason(
+                NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER);
+        configurations.add(openNetwork);
+
+        WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
+        eapNetwork.setIpConfiguration(WifiConfigurationTestUtil.createPartialStaticIpConfigurationWithPacProxy());
+        eapNetwork.getNetworkSelectionStatus().setConnectChoice(TEST_CONNECT_CHOICE);
+        eapNetwork.getNetworkSelectionStatus().setConnectChoiceTimestamp(
+                TEST_CONNECT_CHOICE_TIMESTAMP);
+        eapNetwork.getNetworkSelectionStatus().setHasEverConnected(true);
+        configurations.add(eapNetwork);
+
+        return configurations;
+    }
+
+    private List<WifiConfiguration> createNetworks(boolean shared) {
+        List<WifiConfiguration> configurations = createNetworks();
+        for (WifiConfiguration config : configurations) {
+            config.shared = shared;
+        }
+        return configurations;
+    }
+
+    /**
+     * Helper method to serialize/deserialize store data.
+     */
+    private void serializeDeserializeConfigStoreData(List<WifiConfiguration> configurations)
+            throws XmlPullParserException, IOException {
+        serializeDeserializeConfigStoreData(configurations, false, false);
+    }
+
+    /**
+     * Helper method to ensure the the provided config store data is serialized/deserialized
+     * correctly.
+     * This method serialize the provided config store data instance to raw bytes in XML format
+     * and then deserialzes the raw bytes back to a config store data instance. It then
+     * compares that the original config store data matches with the deserialzed instance.
+     *
+     * @param configurations list of configurations to be added in the store data instance.
+     * @param setSharedDataNull whether to set the shared data to null to simulate the non-existence
+     *                          of the shared store file.
+     * @param setUserDataNull whether to set the user data to null to simulate the non-existence
+     *                        of the user store file.
+     */
+    private void serializeDeserializeConfigStoreData(
+            List<WifiConfiguration> configurations, boolean setSharedDataNull,
+            boolean setUserDataNull)
+            throws XmlPullParserException, IOException {
+        // Will not work if both the flags are set because then we need to ignore the configuration
+        // list as well.
+        assertFalse(setSharedDataNull & setUserDataNull);
+
+        Set<String> deletedEphemeralList;
+        if (setUserDataNull) {
+            deletedEphemeralList = new HashSet<>();
+        } else {
+            deletedEphemeralList = TEST_DELETED_EPHEMERAL_LIST;
+        }
+
+        // Serialize the data.
+        WifiConfigStoreData storeData =
+                new WifiConfigStoreData(configurations, deletedEphemeralList);
+
+        byte[] sharedDataBytes = null;
+        byte[] userDataBytes = null;
+        if (!setSharedDataNull) {
+            sharedDataBytes = storeData.createSharedRawData();
+        }
+        if (!setUserDataNull) {
+            userDataBytes = storeData.createUserRawData();
+        }
+
+        // Deserialize the data.
+        WifiConfigStoreData retrievedStoreData =
+                WifiConfigStoreData.parseRawData(sharedDataBytes, userDataBytes);
+        assertConfigStoreDataEqual(storeData, retrievedStoreData);
+    }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreNewTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreNewTest.java
new file mode 100644
index 0000000..462a229
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreNewTest.java
@@ -0,0 +1,248 @@
+/*
+ * 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 com.android.server.wifi;
+
+import static com.android.server.wifi.WifiConfigStoreDataTest.assertConfigStoreDataEqual;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import android.app.test.TestAlarmManager;
+import android.content.Context;
+import android.net.wifi.WifiConfiguration;
+import android.os.test.TestLooper;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.server.wifi.WifiConfigStoreNew.StoreFile;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.WifiConfigStoreNew}.
+ */
+@SmallTest
+public class WifiConfigStoreNewTest {
+    // Test mocks
+    @Mock private Context mContext;
+    private TestAlarmManager mAlarmManager;
+    private TestLooper mLooper;
+    @Mock private Clock mClock;
+    private MockStoreFile mSharedStore;
+    private MockStoreFile mUserStore;
+
+    /**
+     * Test instance of WifiConfigStore.
+     */
+    private WifiConfigStoreNew mWifiConfigStore;
+
+    /**
+     * Setup mocks before the test starts.
+     */
+    private void setupMocks() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mAlarmManager = new TestAlarmManager();
+        mLooper = new TestLooper();
+        when(mContext.getSystemService(Context.ALARM_SERVICE))
+                .thenReturn(mAlarmManager.getAlarmManager());
+        mUserStore = new MockStoreFile();
+        mSharedStore = new MockStoreFile();
+    }
+
+    /**
+     * Setup the test environment.
+     */
+    @Before
+    public void setUp() throws Exception {
+        setupMocks();
+
+        mWifiConfigStore =
+                new WifiConfigStoreNew(
+                        mContext, mLooper.getLooper(), mClock, mSharedStore, mUserStore);
+
+        // Enable verbose logging before tests.
+        mWifiConfigStore.enableVerboseLogging(true);
+    }
+
+    /**
+     * Called after each test
+     */
+    @After
+    public void cleanup() {
+        validateMockitoUsage();
+    }
+
+    /**
+     * Tests the write API with the force flag set to true.
+     * Expected behavior: This should trigger an immediate write to the store files and no alarms
+     * should be started.
+     */
+    @Test
+    public void testForceWrite() throws Exception {
+        mWifiConfigStore.write(true, getEmptyStoreData());
+
+        assertFalse(mAlarmManager.isPending(WifiConfigStoreNew.BUFFERED_WRITE_ALARM_TAG));
+        assertTrue(mSharedStore.isStoreWritten());
+        assertTrue(mUserStore.isStoreWritten());
+    }
+
+    /**
+     * Tests the write API with the force flag set to false.
+     * Expected behavior: This should set an alarm to write to the store files.
+     */
+    @Test
+    public void testBufferedWrite() throws Exception {
+        mWifiConfigStore.write(false, getEmptyStoreData());
+
+        assertTrue(mAlarmManager.isPending(WifiConfigStoreNew.BUFFERED_WRITE_ALARM_TAG));
+        assertFalse(mSharedStore.isStoreWritten());
+        assertFalse(mUserStore.isStoreWritten());
+
+        // Now send the alarm and ensure that the writes happen.
+        mAlarmManager.dispatch(WifiConfigStoreNew.BUFFERED_WRITE_ALARM_TAG);
+        mLooper.dispatchAll();
+        assertTrue(mSharedStore.isStoreWritten());
+        assertTrue(mUserStore.isStoreWritten());
+    }
+
+    /**
+     * Tests the force write after a buffered write.
+     * Expected behaviour: The force write should override the previous buffered write and stop the
+     * buffer write alarms.
+     */
+    @Test
+    public void testForceWriteAfterBufferedWrite() throws Exception {
+        WifiConfigStoreData bufferedStoreData = createSingleOpenNetworkStoreData();
+        mWifiConfigStore.write(false, bufferedStoreData);
+
+        assertTrue(mAlarmManager.isPending(WifiConfigStoreNew.BUFFERED_WRITE_ALARM_TAG));
+        assertFalse(mSharedStore.isStoreWritten());
+        assertFalse(mUserStore.isStoreWritten());
+
+        // Now send a force write and ensure that the writes have been performed and alarms have
+        // been stopped.
+        WifiConfigStoreData forcedStoreData = createSinglePskNetworkStoreData();
+        mWifiConfigStore.write(true, forcedStoreData);
+
+        assertFalse(mAlarmManager.isPending(WifiConfigStoreNew.BUFFERED_WRITE_ALARM_TAG));
+        assertTrue(mSharedStore.isStoreWritten());
+        assertTrue(mUserStore.isStoreWritten());
+
+        // Now deserialize the data and ensure that the configuration retrieved matches the force
+        // write data.
+        WifiConfigStoreData retrievedStoreData =
+                WifiConfigStoreData.parseRawData(
+                        mSharedStore.getStoreBytes(), mUserStore.getStoreBytes());
+
+        assertConfigStoreDataEqual(forcedStoreData, retrievedStoreData);
+    }
+
+    /**
+     * Tests the read API behaviour when there is no file on the device.
+     * Expected behaviour: The read should return an empty store data instance when the file not
+     * found exception is raised.
+     */
+    @Test
+    public void testReadWithNoStoreFile() throws Exception {
+        // Reading the mock store without a write should simulate the file not found case because
+        // |readRawData| would return null.
+        WifiConfigStoreData readData = mWifiConfigStore.read();
+        assertConfigStoreDataEqual(getEmptyStoreData(), readData);
+    }
+
+    /**
+     * Tests the read API behaviour after a write to the store file.
+     * Expected behaviour: The read should return the same data that was last written.
+     */
+    @Test
+    public void testReadAfterWrite() throws Exception {
+        WifiConfigStoreData writeData = createSingleOpenNetworkStoreData();
+        mWifiConfigStore.write(true, writeData);
+        WifiConfigStoreData readData = mWifiConfigStore.read();
+
+        assertConfigStoreDataEqual(writeData, readData);
+    }
+
+    /**
+     * Returns an empty store data object.
+     */
+    private WifiConfigStoreData getEmptyStoreData() {
+        return new WifiConfigStoreData(new ArrayList<WifiConfiguration>(), new HashSet<String>());
+    }
+
+    /**
+     * Returns an store data object with a single open network.
+     */
+    private WifiConfigStoreData createSingleOpenNetworkStoreData() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createOpenNetwork());
+        return new WifiConfigStoreData(configurations, new HashSet<String>());
+    }
+
+    /**
+     * Returns an store data object with a single psk network.
+     */
+    private WifiConfigStoreData createSinglePskNetworkStoreData() {
+        List<WifiConfiguration> configurations = new ArrayList<>();
+        configurations.add(WifiConfigurationTestUtil.createPskNetwork());
+        return new WifiConfigStoreData(configurations, new HashSet<String>());
+    }
+
+    /**
+     * Mock Store File to redirect all file writes from WifiConfigStoreNew to local buffers.
+     * This can be used to examine the data output by WifiConfigStoreNew.
+     */
+    private class MockStoreFile extends StoreFile {
+        private byte[] mStoreBytes;
+        private boolean mStoreWritten;
+
+        public MockStoreFile() {
+            super(new File("MockStoreFile"));
+        }
+
+        @Override
+        public byte[] readRawData() {
+            return mStoreBytes;
+        }
+
+        @Override
+        public void storeRawDataToWrite(byte[] data) {
+            mStoreBytes = data;
+            mStoreWritten = false;
+        }
+
+        @Override
+        public void writeBufferedRawData() {
+            mStoreWritten = true;
+        }
+
+        public byte[] getStoreBytes() {
+            return mStoreBytes;
+        }
+
+        public boolean isStoreWritten() {
+            return mStoreWritten;
+        }
+    }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
index 7117c2a..39bfd16 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java
@@ -16,8 +16,22 @@
 
 package com.android.server.wifi;
 
+import static org.junit.Assert.*;
+
+import android.net.IpConfiguration;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+import android.net.ProxyInfo;
+import android.net.StaticIpConfiguration;
+import android.net.wifi.FakeKeys;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
 import android.net.wifi.WifiEnterpriseConfig;
+import android.text.TextUtils;
+
+import java.net.InetAddress;
+import java.security.cert.X509Certificate;
+import java.util.List;
 
 /**
  * Helper for creating and populating WifiConfigurations in unit tests.
@@ -33,6 +47,45 @@
     public static final int SECURITY_EAP =  1 << 2;
 
     /**
+     * These values are used to describe ip configuration parameters for a network.
+     */
+    public static final int STATIC_IP_ASSIGNMENT = 0;
+    public static final int DHCP_IP_ASSIGNMENT = 1;
+    public static final int STATIC_PROXY_SETTING = 0;
+    public static final int PAC_PROXY_SETTING = 1;
+    public static final int NONE_PROXY_SETTING = 2;
+
+    /**
+     * These are constants used to generate predefined WifiConfiguration objects.
+     */
+    public static final int TEST_NETWORK_ID = -1;
+    public static final int TEST_UID = 1;
+    public static final String TEST_SSID = "WifiConfigurationTestUtilSSID_";
+    public static final String TEST_PSK = "WifiConfigurationTestUtilPsk";
+    public static final String[] TEST_WEP_KEYS =
+            {"WifiConfigurationTestUtilWep1", "WifiConfigurationTestUtilWep2",
+                    "WifiConfigurationTestUtilWep3", "WifiConfigurationTestUtilWep3"};
+    public static final int TEST_WEP_TX_KEY_INDEX = 1;
+    public static final String TEST_FQDN = "WifiConfigurationTestUtilFQDN";
+    public static final String TEST_PROVIDER_FRIENDLY_NAME =
+            "WifiConfigurationTestUtilFriendlyName";
+    public static final String TEST_STATIC_IP_LINK_ADDRESS = "192.168.48.2";
+    public static final int TEST_STATIC_IP_LINK_PREFIX_LENGTH = 8;
+    public static final String TEST_STATIC_IP_GATEWAY_ADDRESS = "192.168.48.1";
+    public static final String[] TEST_STATIC_IP_DNS_SERVER_ADDRESSES =
+            new String[]{"192.168.48.1", "192.168.48.10"};
+    public static final String TEST_STATIC_PROXY_HOST = "192.168.48.1";
+    public static final int TEST_STATIC_PROXY_PORT = 8000;
+    public static final String TEST_STATIC_PROXY_EXCLUSION_LIST = "";
+    public static final String TEST_PAC_PROXY_LOCATION = "http://";
+    public static final String TEST_CA_CERT_ALIAS = "WifiConfigurationTestUtilCaCertAlias";
+
+    /**
+     * Index used to assign unique SSIDs for the generation of predefined WifiConfiguration objects.
+     */
+    private static int sNetworkIndex = 0;
+
+    /**
      * Construct a {@link android.net.wifi.WifiConfiguration}.
      * @param networkId the configuration's networkId
      * @param uid the configuration's creator uid
@@ -78,10 +131,10 @@
         WifiConfiguration config = generateWifiConfig(networkId, uid, ssid, shared, enabled, fqdn,
                 providerFriendlyName);
 
-        if (security == SECURITY_NONE) {
+        if ((security == SECURITY_NONE) || ((security & SECURITY_WEP) != 0)) {
             config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
         } else {
-            if (((security & SECURITY_WEP) != 0) || ((security & SECURITY_PSK) != 0)) {
+            if ((security & SECURITY_PSK) != 0) {
                 config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
             }
 
@@ -92,4 +145,416 @@
         }
         return config;
     }
+
+    /**
+     * Construct a {@link android.net.IpConfiguration }.
+     * @param ipAssignmentType One of {@link #STATIC_IP_ASSIGNMENT} or {@link #DHCP_IP_ASSIGNMENT}.
+     * @param proxySettingType One of {@link #STATIC_PROXY_SETTING} or {@link #PAC_PROXY_SETTING} or
+     *                        {@link #NONE_PROXY_SETTING}.
+     * @param linkAddress static ip address string.
+     * @param linkPrefixLength static ip address prefix length.
+     * @param gatewayAddress static gateway address.
+     * @param dnsServerAddresses list of dns servers for static ip configuration.
+     * @param proxyHost Static proxy server address.
+     * @param proxyPort Static proxy server port.
+     * @param proxyExclusionList Static proxy exclusion list.
+     * @param pacProxyPath Pac proxy server path.
+     * @return the constructed {@link android.net.IpConfiguration}
+     */
+    public static IpConfiguration generateIpConfig(
+            int ipAssignmentType, int proxySettingType, String linkAddress, int linkPrefixLength,
+            String gatewayAddress, String[] dnsServerAddresses, String proxyHost,
+            int proxyPort, String proxyExclusionList, String pacProxyPath) {
+        StaticIpConfiguration staticIpConfiguration = null;
+        ProxyInfo proxyInfo = null;
+        IpConfiguration.IpAssignment ipAssignment = IpConfiguration.IpAssignment.UNASSIGNED;
+        IpConfiguration.ProxySettings proxySettings = IpConfiguration.ProxySettings.UNASSIGNED;
+
+        if (ipAssignmentType == STATIC_IP_ASSIGNMENT) {
+            staticIpConfiguration = new StaticIpConfiguration();
+            if (!TextUtils.isEmpty(linkAddress)) {
+                LinkAddress linkAddr =
+                        new LinkAddress(
+                                NetworkUtils.numericToInetAddress(linkAddress), linkPrefixLength);
+                staticIpConfiguration.ipAddress = linkAddr;
+            }
+
+            if (!TextUtils.isEmpty(gatewayAddress)) {
+                InetAddress gatewayAddr =
+                        NetworkUtils.numericToInetAddress(gatewayAddress);
+                staticIpConfiguration.gateway = gatewayAddr;
+            }
+            if (dnsServerAddresses != null) {
+                for (String dnsServerAddress : dnsServerAddresses) {
+                    if (!TextUtils.isEmpty(dnsServerAddress)) {
+                        staticIpConfiguration.dnsServers.add(
+                                NetworkUtils.numericToInetAddress(dnsServerAddress));
+                    }
+
+                }
+            }
+            ipAssignment = IpConfiguration.IpAssignment.STATIC;
+        } else if (ipAssignmentType == DHCP_IP_ASSIGNMENT) {
+            ipAssignment = IpConfiguration.IpAssignment.DHCP;
+        }
+
+        if (proxySettingType == STATIC_PROXY_SETTING) {
+            proxyInfo = new ProxyInfo(proxyHost, proxyPort, proxyExclusionList);
+            proxySettings = IpConfiguration.ProxySettings.STATIC;
+        } else if (proxySettingType == PAC_PROXY_SETTING) {
+            proxyInfo = new ProxyInfo(pacProxyPath);
+            proxySettings = IpConfiguration.ProxySettings.PAC;
+        } else if (proxySettingType == NONE_PROXY_SETTING) {
+            proxySettings = IpConfiguration.ProxySettings.NONE;
+        }
+        return new IpConfiguration(ipAssignment, proxySettings, staticIpConfiguration, proxyInfo);
+    }
+
+    /**
+     * Create a new SSID for the the network being created.
+     */
+    private static String createNewSSID() {
+        return "\"" + TEST_SSID + sNetworkIndex++ + "\"";
+    }
+
+    /**
+     * Helper methods to generate predefined WifiConfiguration objects of the required type. These
+     * use a static index to avoid duplicate configurations.
+     */
+    public static WifiConfiguration createOpenNetwork() {
+        return generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true, null,
+                null, SECURITY_NONE);
+    }
+
+    public static WifiConfiguration createOpenHiddenNetwork() {
+        WifiConfiguration configuration = createOpenNetwork();
+        configuration.hiddenSSID = true;
+        return configuration;
+    }
+
+    public static WifiConfiguration createPskNetwork() {
+        WifiConfiguration configuration =
+                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true, null,
+                        null, SECURITY_PSK);
+        configuration.preSharedKey = TEST_PSK;
+        return configuration;
+    }
+
+    public static WifiConfiguration createPskHiddenNetwork() {
+        WifiConfiguration configuration = createPskNetwork();
+        configuration.hiddenSSID = true;
+        return configuration;
+    }
+
+    public static WifiConfiguration createWepNetwork() {
+        WifiConfiguration configuration =
+                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true, null,
+                        null, SECURITY_WEP);
+        configuration.wepKeys = TEST_WEP_KEYS;
+        configuration.wepTxKeyIndex = TEST_WEP_TX_KEY_INDEX;
+        return configuration;
+    }
+
+    public static WifiConfiguration createWepHiddenNetwork() {
+        WifiConfiguration configuration = createWepNetwork();
+        configuration.hiddenSSID = true;
+        return configuration;
+    }
+
+
+    public static WifiConfiguration createWepNetworkWithSingleKey() {
+        WifiConfiguration configuration =
+                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true, null,
+                        null, SECURITY_WEP);
+        configuration.wepKeys[0] = TEST_WEP_KEYS[0];
+        configuration.wepTxKeyIndex = 0;
+        return configuration;
+    }
+
+
+    public static WifiConfiguration createEapNetwork() {
+        WifiConfiguration configuration =
+                generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true,
+                        TEST_FQDN, TEST_PROVIDER_FRIENDLY_NAME, SECURITY_EAP);
+        return configuration;
+    }
+
+    public static IpConfiguration createStaticIpConfigurationWithPacProxy() {
+        return generateIpConfig(
+                STATIC_IP_ASSIGNMENT, PAC_PROXY_SETTING,
+                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
+                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
+                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
+                TEST_PAC_PROXY_LOCATION);
+    }
+
+    public static IpConfiguration createStaticIpConfigurationWithStaticProxy() {
+        return generateIpConfig(
+                STATIC_IP_ASSIGNMENT, STATIC_PROXY_SETTING,
+                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
+                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
+                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
+                TEST_PAC_PROXY_LOCATION);
+    }
+
+    public static IpConfiguration createPartialStaticIpConfigurationWithPacProxy() {
+        return generateIpConfig(
+                STATIC_IP_ASSIGNMENT, PAC_PROXY_SETTING,
+                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
+                null, null,
+                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
+                TEST_PAC_PROXY_LOCATION);
+    }
+
+    public static IpConfiguration createDHCPIpConfigurationWithPacProxy() {
+        return generateIpConfig(
+                DHCP_IP_ASSIGNMENT, PAC_PROXY_SETTING,
+                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
+                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
+                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
+                TEST_PAC_PROXY_LOCATION);
+    }
+
+    public static IpConfiguration createDHCPIpConfigurationWithStaticProxy() {
+        return generateIpConfig(
+                DHCP_IP_ASSIGNMENT, STATIC_PROXY_SETTING,
+                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
+                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
+                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
+                TEST_PAC_PROXY_LOCATION);
+    }
+
+    public static IpConfiguration createDHCPIpConfigurationWithNoProxy() {
+        return generateIpConfig(
+                DHCP_IP_ASSIGNMENT, NONE_PROXY_SETTING,
+                TEST_STATIC_IP_LINK_ADDRESS, TEST_STATIC_IP_LINK_PREFIX_LENGTH,
+                TEST_STATIC_IP_GATEWAY_ADDRESS, TEST_STATIC_IP_DNS_SERVER_ADDRESSES,
+                TEST_STATIC_PROXY_HOST, TEST_STATIC_PROXY_PORT, TEST_STATIC_PROXY_EXCLUSION_LIST,
+                TEST_PAC_PROXY_LOCATION);
+    }
+
+    // TODO: These enterprise configurations may need more parameters set.
+    public static WifiEnterpriseConfig createPEAPWifiEnterpriseConfigWithGTCPhase2() {
+        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+        config.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
+        config.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
+        config.setCaCertificateAliases(new String[] {TEST_CA_CERT_ALIAS + "PEAP"});
+        config.setCaCertificates(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
+        return config;
+    }
+
+    public static WifiEnterpriseConfig createTLSWifiEnterpriseConfigWithNonePhase2() {
+        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+        config.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+        config.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
+        config.setCaCertificateAliases(new String[] {TEST_CA_CERT_ALIAS + "TLS"});
+        config.setCaCertificates(new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
+        return config;
+    }
+
+    /**
+     * Asserts that the 2 WifiConfigurations are equal in the elements saved for both backup/restore
+     * and config store.
+     */
+    private static void assertCommonConfigurationElementsEqual(
+            WifiConfiguration expected, WifiConfiguration actual) {
+        assertEquals(expected.SSID, actual.SSID);
+        assertEquals(expected.BSSID, actual.BSSID);
+        assertEquals(expected.preSharedKey, actual.preSharedKey);
+        assertEquals(expected.wepKeys, actual.wepKeys);
+        assertEquals(expected.wepTxKeyIndex, actual.wepTxKeyIndex);
+        assertEquals(expected.hiddenSSID, actual.hiddenSSID);
+        assertEquals(expected.allowedKeyManagement, actual.allowedKeyManagement);
+        assertEquals(expected.allowedProtocols, actual.allowedProtocols);
+        assertEquals(expected.allowedAuthAlgorithms, actual.allowedAuthAlgorithms);
+        assertEquals(expected.shared, actual.shared);
+        assertEquals(expected.getIpConfiguration(), actual.getIpConfiguration());
+    }
+
+    /**
+     * Asserts that the 2 WifiConfigurations are equal. This only compares the elements saved
+     * fpr backup/restore.
+     */
+    public static void assertConfigurationEqualForBackup(
+            WifiConfiguration expected, WifiConfiguration actual) {
+        assertCommonConfigurationElementsEqual(expected, actual);
+    }
+
+    /**
+     * Asserts that the 2 WifiConfigurations are equal. This compares all the elements saved for
+     * config store.
+     */
+    public static void assertConfigurationEqualForConfigStore(
+            WifiConfiguration expected, WifiConfiguration actual) {
+        assertCommonConfigurationElementsEqual(expected, actual);
+        assertEquals(expected.FQDN, actual.FQDN);
+        assertEquals(expected.providerFriendlyName, actual.providerFriendlyName);
+        assertEquals(expected.linkedConfigurations, actual.linkedConfigurations);
+        assertEquals(expected.defaultGwMacAddress, actual.defaultGwMacAddress);
+        assertEquals(expected.validatedInternetAccess, actual.validatedInternetAccess);
+        assertEquals(expected.noInternetAccessExpected, actual.noInternetAccessExpected);
+        assertEquals(expected.userApproved, actual.userApproved);
+        assertEquals(expected.meteredHint, actual.meteredHint);
+        assertEquals(expected.useExternalScores, actual.useExternalScores);
+        assertEquals(expected.numAssociation, actual.numAssociation);
+        assertEquals(expected.creatorUid, actual.creatorUid);
+        assertEquals(expected.creatorName, actual.creatorName);
+        assertEquals(expected.creationTime, actual.creationTime);
+        assertEquals(expected.lastUpdateUid, actual.lastUpdateUid);
+        assertEquals(expected.lastUpdateName, actual.lastUpdateName);
+        assertEquals(expected.lastConnectUid, actual.lastConnectUid);
+        assertEquals(expected.updateTime, actual.updateTime);
+        assertNetworkSelectionStatusEqualForConfigStore(
+                expected.getNetworkSelectionStatus(), actual.getNetworkSelectionStatus());
+        assertWifiEnterpriseConfigEqualForConfigStore(
+                expected.enterpriseConfig, actual.enterpriseConfig);
+    }
+
+    /**
+     * Asserts that the 2 WifiConfigurations are equal. This compares all the elements that are
+     * saved into internal database by WifiConfigurationManager for network additions/updates.
+     */
+    public static void assertConfigurationEqualForConfigManagerAddOrUpdate(
+            WifiConfiguration expected, WifiConfiguration actual) {
+        assertCommonConfigurationElementsEqual(expected, actual);
+        assertEquals(expected.FQDN, actual.FQDN);
+        assertEquals(expected.providerFriendlyName, actual.providerFriendlyName);
+        assertEquals(expected.noInternetAccessExpected, actual.noInternetAccessExpected);
+        assertEquals(expected.meteredHint, actual.meteredHint);
+        assertEquals(expected.useExternalScores, actual.useExternalScores);
+        assertEquals(expected.ephemeral, actual.ephemeral);
+        assertEquals(expected.creatorUid, actual.creatorUid);
+        assertEquals(expected.creatorName, actual.creatorName);
+        assertEquals(expected.creationTime, actual.creationTime);
+        assertEquals(expected.lastUpdateUid, actual.lastUpdateUid);
+        assertEquals(expected.lastUpdateName, actual.lastUpdateName);
+        assertEquals(expected.updateTime, actual.updateTime);
+        assertNetworkSelectionStatusEqualForConfigStore(
+                expected.getNetworkSelectionStatus(), actual.getNetworkSelectionStatus());
+        assertWifiEnterpriseConfigEqualForConfigStore(
+                expected.enterpriseConfig, actual.enterpriseConfig);
+    }
+
+    /**
+     * Assert that the 2 NetworkSelectionStatus's are equal. This compares all the elements saved
+     * for config store.
+     */
+    public static void assertNetworkSelectionStatusEqualForConfigStore(
+            NetworkSelectionStatus expected, NetworkSelectionStatus actual) {
+        if (expected.isNetworkTemporaryDisabled()) {
+            // Temporarily disabled networks are enabled when persisted.
+            assertEquals(
+                    NetworkSelectionStatus.NETWORK_SELECTION_ENABLED,
+                    actual.getNetworkSelectionStatus());
+        } else {
+            assertEquals(expected.getNetworkSelectionStatus(), actual.getNetworkSelectionStatus());
+        }
+        assertEquals(
+                expected.getNetworkSelectionDisableReason(),
+                actual.getNetworkSelectionDisableReason());
+        assertEquals(expected.getConnectChoice(), actual.getConnectChoice());
+        assertEquals(expected.getConnectChoiceTimestamp(), actual.getConnectChoiceTimestamp());
+        assertEquals(expected.getHasEverConnected(), actual.getHasEverConnected());
+    }
+
+    /**
+     * Assert that the 2 WifiEnterpriseConfig's are equal. This compares all the elements saved
+     * for config store.
+     */
+    public static void assertWifiEnterpriseConfigEqualForConfigStore(
+            WifiEnterpriseConfig expected, WifiEnterpriseConfig actual) {
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, ""));
+        assertEquals(expected.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, ""),
+                actual.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, ""));
+        assertEquals(expected.getEapMethod(), actual.getEapMethod());
+        assertEquals(expected.getPhase2Method(), actual.getPhase2Method());
+    }
+
+    /**
+     * Asserts that the 2 lists of WifiConfigurations are equal. This compares all the elements
+     * saved for backup/restore.
+     */
+    public static void assertConfigurationsEqualForBackup(
+            List<WifiConfiguration> expected, List<WifiConfiguration> actual) {
+        assertEquals(expected.size(), actual.size());
+        for (WifiConfiguration expectedConfiguration : expected) {
+            String expectedConfigKey = expectedConfiguration.configKey();
+            boolean didCompare = false;
+            for (WifiConfiguration actualConfiguration : actual) {
+                String actualConfigKey = actualConfiguration.configKey();
+                if (actualConfigKey.equals(expectedConfigKey)) {
+                    assertConfigurationEqualForBackup(
+                            expectedConfiguration, actualConfiguration);
+                    didCompare = true;
+                }
+            }
+            assertTrue(didCompare);
+        }
+    }
+
+    /**
+     * Asserts that the 2 lists of WifiConfigurations are equal. This compares all the elements
+     * that are saved into internal database by WifiConfigurationManager for network
+     * additions/updates.
+     */
+    public static void assertConfigurationsEqualForConfigManagerAddOrUpdate(
+            List<WifiConfiguration> expected, List<WifiConfiguration> actual) {
+        assertEquals(expected.size(), actual.size());
+        for (WifiConfiguration expectedConfiguration : expected) {
+            String expectedConfigKey = expectedConfiguration.configKey();
+            boolean didCompare = false;
+            for (WifiConfiguration actualConfiguration : actual) {
+                String actualConfigKey = actualConfiguration.configKey();
+                if (actualConfigKey.equals(expectedConfigKey)) {
+                    assertConfigurationEqualForConfigManagerAddOrUpdate(
+                            expectedConfiguration, actualConfiguration);
+                    didCompare = true;
+                }
+            }
+            assertTrue(didCompare);
+        }
+    }
+
+    /**
+     * Asserts that the 2 lists of WifiConfigurations are equal. This compares all the elements
+     * saved for config store.
+     */
+    public static void assertConfigurationsEqualForConfigStore(
+            List<WifiConfiguration> expected, List<WifiConfiguration> actual) {
+        assertEquals(expected.size(), actual.size());
+        for (WifiConfiguration expectedConfiguration : expected) {
+            String expectedConfigKey = expectedConfiguration.configKey();
+            boolean didCompare = false;
+            for (WifiConfiguration actualConfiguration : actual) {
+                String actualConfigKey = actualConfiguration.configKey();
+                if (actualConfigKey.equals(expectedConfigKey)) {
+                    assertConfigurationEqualForConfigStore(
+                            expectedConfiguration, actualConfiguration);
+                    didCompare = true;
+                }
+            }
+            assertTrue(didCompare);
+        }
+    }
 }
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
index 022997d..fbf1255 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConnectivityManagerTest.java
@@ -22,6 +22,8 @@
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
+import android.app.test.TestAlarmManager;
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.wifi.ScanResult;
@@ -38,10 +40,10 @@
 import android.net.wifi.WifiSsid;
 import android.os.SystemClock;
 import android.os.WorkSource;
+import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.R;
-import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
 
 import org.junit.After;
 import org.junit.Before;
@@ -66,7 +68,7 @@
     public void setUp() throws Exception {
         mWifiInjector = mockWifiInjector();
         mResource = mockResource();
-        mAlarmManager = new MockAlarmManager();
+        mAlarmManager = new TestAlarmManager();
         mContext = mockContext();
         mWifiStateMachine = mockWifiStateMachine();
         mWifiConfigManager = mockWifiConfigManager();
@@ -77,7 +79,7 @@
                 mWifiScanner, mWifiConfigManager, mWifiInfo, mWifiQNS, mWifiInjector,
                 mLooper.getLooper());
         mWifiConnectivityManager.setWifiEnabled(true);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime());
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
     }
 
     /**
@@ -90,8 +92,8 @@
 
     private Resources mResource;
     private Context mContext;
-    private MockAlarmManager mAlarmManager;
-    private MockLooper mLooper = new MockLooper();
+    private TestAlarmManager mAlarmManager;
+    private TestLooper mLooper = new TestLooper();
     private WifiConnectivityManager mWifiConnectivityManager;
     private WifiQualifiedNetworkSelector mWifiQNS;
     private WifiStateMachine mWifiStateMachine;
@@ -203,8 +205,8 @@
         candidateScanResult.BSSID = CANDIDATE_BSSID;
         candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult);
 
-        when(qns.selectQualifiedNetwork(anyBoolean(), anyBoolean(), anyObject(),
-              anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean())).thenReturn(candidate);
+        when(qns.selectQualifiedNetwork(anyBoolean(), anyBoolean(), anyBoolean(),
+              anyBoolean(), anyBoolean(), anyBoolean(), anyObject())).thenReturn(candidate);
         return qns;
     }
 
@@ -372,7 +374,7 @@
         long currentTimeStamp = 0;
         for (int attempt = 0; attempt < maxAttemptRate; attempt++) {
             currentTimeStamp += connectionAttemptIntervals;
-            when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+            when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
             // Set WiFi to disconnected state to trigger PNO scan
             mWifiConnectivityManager.handleConnectionStateChanged(
                     WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
@@ -380,7 +382,7 @@
         }
         // Now trigger another connection attempt before the rate interval, this should be
         // skipped because we've crossed rate limit.
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
         // Set WiFi to disconnected state to trigger PNO scan
         mWifiConnectivityManager.handleConnectionStateChanged(
                 WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
@@ -411,7 +413,7 @@
         long currentTimeStamp = 0;
         for (int attempt = 0; attempt < maxAttemptRate; attempt++) {
             currentTimeStamp += connectionAttemptIntervals;
-            when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+            when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
             // Set WiFi to disconnected state to trigger PNO scan
             mWifiConnectivityManager.handleConnectionStateChanged(
                     WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
@@ -419,7 +421,7 @@
         }
         // Now trigger another connection attempt after the rate interval, this should not be
         // skipped because we should've evicted the older attempt.
-        when(mClock.elapsedRealtime()).thenReturn(
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(
                 currentTimeStamp + connectionAttemptIntervals * 2);
         // Set WiFi to disconnected state to trigger PNO scan
         mWifiConnectivityManager.handleConnectionStateChanged(
@@ -451,7 +453,7 @@
         long currentTimeStamp = 0;
         for (int attempt = 0; attempt < maxAttemptRate; attempt++) {
             currentTimeStamp += connectionAttemptIntervals;
-            when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+            when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
             // Set WiFi to disconnected state to trigger PNO scan
             mWifiConnectivityManager.handleConnectionStateChanged(
                     WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
@@ -462,7 +464,7 @@
 
         for (int attempt = 0; attempt < maxAttemptRate; attempt++) {
             currentTimeStamp += connectionAttemptIntervals;
-            when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+            when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
             // Set WiFi to disconnected state to trigger PNO scan
             mWifiConnectivityManager.handleConnectionStateChanged(
                     WifiConnectivityManager.WIFI_STATE_DISCONNECTED);
@@ -483,8 +485,8 @@
      */
     @Test
     public void PnoRetryForLowRssiNetwork() {
-        when(mWifiQNS.selectQualifiedNetwork(anyBoolean(), anyBoolean(), anyObject(),
-              anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean())).thenReturn(null);
+        when(mWifiQNS.selectQualifiedNetwork(anyBoolean(), anyBoolean(), anyBoolean(),
+              anyBoolean(), anyBoolean(), anyBoolean(), anyObject())).thenReturn(null);
 
         // Set screen to off
         mWifiConnectivityManager.handleScreenStateChanged(false);
@@ -538,8 +540,8 @@
     @Test
     public void watchdogBitePnoGoodIncrementsMetrics() {
         // Qns returns no candidate after watchdog single scan.
-        when(mWifiQNS.selectQualifiedNetwork(anyBoolean(), anyBoolean(), anyObject(),
-                anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean())).thenReturn(null);
+        when(mWifiQNS.selectQualifiedNetwork(anyBoolean(), anyBoolean(), anyBoolean(),
+                anyBoolean(), anyBoolean(), anyBoolean(), anyObject())).thenReturn(null);
 
         // Set screen to off
         mWifiConnectivityManager.handleScreenStateChanged(false);
@@ -566,7 +568,7 @@
     @Test
     public void checkPeriodicScanIntervalWhenDisconnected() {
         long currentTimeStamp = CURRENT_SYSTEM_TIME_MS;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Set screen to ON
         mWifiConnectivityManager.handleScreenStateChanged(true);
@@ -574,7 +576,7 @@
         // Wait for MAX_PERIODIC_SCAN_INTERVAL_MS so that any impact triggered
         // by screen state change can settle
         currentTimeStamp += WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Set WiFi to disconnected state to trigger periodic scan
         mWifiConnectivityManager.handleConnectionStateChanged(
@@ -587,7 +589,7 @@
         assertEquals(firstIntervalMs, WifiConnectivityManager.PERIODIC_SCAN_INTERVAL_MS);
 
         currentTimeStamp += firstIntervalMs;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Now fire the first periodic scan alarm timer
         mAlarmManager.dispatch(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG);
@@ -602,7 +604,7 @@
         assertEquals(firstIntervalMs * 2, secondIntervalMs);
 
         currentTimeStamp += secondIntervalMs;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Make sure we eventually stay at the maximum scan interval.
         long intervalMs = 0;
@@ -613,7 +615,7 @@
                     .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG)
                     - currentTimeStamp;
             currentTimeStamp += intervalMs;
-            when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+            when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
         }
 
         assertEquals(intervalMs, WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS);
@@ -629,7 +631,7 @@
     @Test
     public void checkPeriodicScanIntervalWhenConnected() {
         long currentTimeStamp = CURRENT_SYSTEM_TIME_MS;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Set screen to ON
         mWifiConnectivityManager.handleScreenStateChanged(true);
@@ -637,7 +639,7 @@
         // Wait for MAX_PERIODIC_SCAN_INTERVAL_MS so that any impact triggered
         // by screen state change can settle
         currentTimeStamp += WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Set WiFi to connected state to trigger periodic scan
         mWifiConnectivityManager.handleConnectionStateChanged(
@@ -650,7 +652,7 @@
         assertEquals(firstIntervalMs, WifiConnectivityManager.PERIODIC_SCAN_INTERVAL_MS);
 
         currentTimeStamp += firstIntervalMs;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Now fire the first periodic scan alarm timer
         mAlarmManager.dispatch(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG);
@@ -665,7 +667,7 @@
         assertEquals(firstIntervalMs * 2, secondIntervalMs);
 
         currentTimeStamp += secondIntervalMs;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Make sure we eventually stay at the maximum scan interval.
         long intervalMs = 0;
@@ -676,7 +678,7 @@
                     .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG)
                     - currentTimeStamp;
             currentTimeStamp += intervalMs;
-            when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+            when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
         }
 
         assertEquals(intervalMs, WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS);
@@ -692,7 +694,7 @@
     @Test
     public void checkMinimumPeriodicScanIntervalWhenScreenOn() {
         long currentTimeStamp = CURRENT_SYSTEM_TIME_MS;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Set screen to ON
         mWifiConnectivityManager.handleScreenStateChanged(true);
@@ -701,7 +703,7 @@
         // by screen state change can settle
         currentTimeStamp += WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS;
         long firstScanTimeStamp = currentTimeStamp;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Set WiFi to connected state to trigger the periodic scan
         mWifiConnectivityManager.handleConnectionStateChanged(
@@ -709,7 +711,7 @@
 
         // Set the second scan attempt time stamp.
         currentTimeStamp += 2000;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Set WiFi to disconnected state to trigger another periodic scan
         mWifiConnectivityManager.handleConnectionStateChanged(
@@ -737,7 +739,7 @@
     @Test
     public void checkMinimumPeriodicScanIntervalNotEnforced() {
         long currentTimeStamp = CURRENT_SYSTEM_TIME_MS;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Set screen to ON
         mWifiConnectivityManager.handleScreenStateChanged(true);
@@ -746,7 +748,7 @@
         // by screen state change can settle
         currentTimeStamp += WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS;
         long firstScanTimeStamp = currentTimeStamp;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Set WiFi to connected state to trigger the periodic scan
         mWifiConnectivityManager.handleConnectionStateChanged(
@@ -754,7 +756,7 @@
 
         // Set the second scan attempt time stamp
         currentTimeStamp += 2000;
-        when(mClock.elapsedRealtime()).thenReturn(currentTimeStamp);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp);
 
         // Force a connectivity scan
         mWifiConnectivityManager.forceConnectivityScan();
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java
index 8f1b23e..b10266e 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiControllerTest.java
@@ -33,6 +33,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.os.WorkSource;
+import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
@@ -78,7 +79,7 @@
         when(mSettingsStore.isScanAlwaysAvailable()).thenReturn(true);
     }
 
-    MockLooper mLooper;
+    TestLooper mLooper;
     @Mock Context mContext;
     @Mock WifiServiceImpl mService;
     @Mock FrameworkFacade mFacade;
@@ -92,7 +93,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        mLooper = new MockLooper();
+        mLooper = new TestLooper();
 
         initializeSettingsStore();
 
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java
new file mode 100644
index 0000000..a0a1832
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/WifiInjectorTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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 com.android.server.wifi;
+
+import static org.mockito.Mockito.*;
+
+import android.content.Context;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Unit tests for {@link WifiInjector}. */
+@SmallTest
+public class WifiInjectorTest {
+
+    @Mock private Context mContext;
+    private WifiInjector mInjector;
+
+    /**
+     * Method to initialize mocks for tests.
+     */
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    /**
+     * Test that attempting to get the instance of the WifiInjector throws an IllegalStateException
+     * if it is not initialized.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testGetInstanceWithUninitializedWifiInjector() {
+        WifiInjector.getInstance();
+    }
+
+    /**
+     * Test that attempting to call the WifiInjector a second time throws an exception.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testShouldNotBeAbleToCreateMoreThanOneWifiInjector() {
+        try {
+            WifiInjector willThrowNullPointerException = new WifiInjector(mContext);
+        } catch (NullPointerException e) {
+        }
+        WifiInjector shouldThrowIllegalStateException = new WifiInjector(mContext);
+    }
+
+    /**
+     * Test that a WifiInjector cannot be created with a null Context.
+     */
+    @Test(expected = IllegalStateException.class)
+    public void testShouldNotCreateWifiInjectorWithNullContext() {
+        new WifiInjector(null);
+    }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java b/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java
index 237fc66..a8b1614 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiLastResortWatchdogTest.java
@@ -55,8 +55,7 @@
     @Before
     public void setUp() throws Exception {
         initMocks(this);
-        mLastResortWatchdog = new WifiLastResortWatchdog(mWifiMetrics);
-        mLastResortWatchdog.setWifiController(mWifiController);
+        mLastResortWatchdog = new WifiLastResortWatchdog(mWifiController, mWifiMetrics);
     }
 
     private List<Pair<ScanDetail, WifiConfiguration>> createFilteredQnsCandidates(String[] ssids,
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiLoggerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiLoggerTest.java
index d915ff3..b70e1dd 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiLoggerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiLoggerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wifi;
 
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
 import android.content.Context;
 import android.test.suitebuilder.annotation.SmallTest;
 import com.android.internal.R;
@@ -33,8 +34,6 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 011682b..d011c54 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -50,7 +50,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mDeserializedWifiMetrics = null;
-        when(mClock.elapsedRealtime()).thenReturn((long) 0);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn((long) 0);
         mWifiMetrics = new WifiMetrics(mClock);
     }
 
@@ -89,7 +89,7 @@
         PrintWriter writer = new PrintWriter(stream);
         String[] args = new String[0];
 
-        when(mClock.elapsedRealtime()).thenReturn(TEST_RECORD_DURATION_MILLIS);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_RECORD_DURATION_MILLIS);
         //Test proto dump, by passing in proto arg option
         args = new String[]{WifiMetrics.PROTO_DUMP_ARG};
         mWifiMetrics.dump(null, writer, args);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMulticastLockManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMulticastLockManagerTest.java
new file mode 100644
index 0000000..02150d7
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMulticastLockManagerTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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 com.android.server.wifi;
+
+import static org.mockito.Mockito.*;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.internal.app.IBatteryStats;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.WifiConfigStoreData}.
+ */
+@SmallTest
+public class WifiMulticastLockManagerTest {
+    @Mock WifiMulticastLockManager.FilterController mHandler;
+    @Mock IBatteryStats mBatteryStats;
+    WifiMulticastLockManager mManager;
+
+    /**
+     * Initialize |WifiMulticastLockManager| instance before each test.
+     */
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mManager = new WifiMulticastLockManager(mHandler, mBatteryStats);
+    }
+
+    /**
+     * Test behavior when no locks are held.
+     */
+    @Test
+    public void noLocks() {
+        assertFalse(mManager.isMulticastEnabled());
+        mManager.initializeFiltering();
+        verify(mHandler, times(1)).startFilteringMulticastPackets();
+    }
+
+    /**
+     * Test behavior when one lock is aquired then released.
+     */
+    @Test
+    public void oneLock() throws RemoteException {
+        IBinder binder = mock(IBinder.class);
+        mManager.acquireLock(binder, "Test");
+        assertTrue(mManager.isMulticastEnabled());
+        verify(mHandler).stopFilteringMulticastPackets();
+        mManager.initializeFiltering();
+        verify(mHandler, times(0)).startFilteringMulticastPackets();
+        verify(mBatteryStats).noteWifiMulticastEnabled(anyInt());
+        verify(mBatteryStats, times(0)).noteWifiMulticastDisabled(anyInt());
+
+        mManager.releaseLock();
+        verify(mBatteryStats).noteWifiMulticastDisabled(anyInt());
+        assertFalse(mManager.isMulticastEnabled());
+    }
+}
+
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNotificationControllerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNotificationControllerTest.java
index 41e4e46..c3fcc96 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNotificationControllerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNotificationControllerTest.java
@@ -34,6 +34,7 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiManager;
 import android.os.UserHandle;
+import android.os.test.TestLooper;
 import android.provider.Settings;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -79,7 +80,7 @@
         when(mFrameworkFacade.getIntegerSetting(mContext,
                 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 1)).thenReturn(1);
 
-        MockLooper mock_looper = new MockLooper();
+        TestLooper mock_looper = new TestLooper();
         mWifiNotificationController = new WifiNotificationController(
                 mContext, mock_looper.getLooper(), mWifiStateMachine, mFrameworkFacade,
                 mock(Notification.Builder.class));
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiQualifiedNetworkSelectorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiQualifiedNetworkSelectorTest.java
index 64fee84..79dfffa 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiQualifiedNetworkSelectorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiQualifiedNetworkSelectorTest.java
@@ -32,6 +32,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
 import android.content.Context;
 import android.content.res.Resources;
 import android.net.NetworkScoreManager;
@@ -39,13 +40,13 @@
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiEnterpriseConfig;
 import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
 import android.net.wifi.WifiSsid;
 import android.os.SystemClock;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.LocalLog;
 
 import com.android.internal.R;
-import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
 
 import org.junit.After;
 import org.junit.Before;
@@ -76,9 +77,9 @@
         mWifiQualifiedNetworkSelector = new WifiQualifiedNetworkSelector(mWifiConfigManager,
                 mContext, mWifiInfo, mClock);
         mWifiQualifiedNetworkSelector.enableVerboseLogging(1);
-        mWifiQualifiedNetworkSelector.setUserPreferredBand(1);
+        mWifiQualifiedNetworkSelector.setUserPreferredBand(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
         mWifiQualifiedNetworkSelector.setWifiNetworkScoreCache(mScoreCache);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime());
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
     }
 
     @After
@@ -102,7 +103,7 @@
     private List<ScanDetail> getScanDetails(String[] ssids, String[] bssids, int[] frequencies,
                                             String[] caps, int[] levels) {
         List<ScanDetail> scanDetailList = new ArrayList<ScanDetail>();
-        long timeStamp = mClock.elapsedRealtime();
+        long timeStamp = mClock.getElapsedSinceBootMillis();
         for (int index = 0; index < ssids.length; index++) {
             ScanDetail scanDetail = new ScanDetail(WifiSsid.createFromAsciiEncoded(ssids[index]),
                     bssids[index], caps[index], levels[index], frequencies[index], timeStamp, 0);
@@ -342,7 +343,7 @@
         ScanResult chosenScanResult = scanDetails.get(scanDetails.size() - 1).getScanResult();
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -379,7 +380,7 @@
         ScanResult chosenScanResult = scanDetails.get(scanDetails.size() - 1).getScanResult();
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -415,7 +416,7 @@
         ScanResult chosenScanResult = scanDetails.get(scanDetails.size() - 1).getScanResult();
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -451,8 +452,9 @@
         scanResultLinkConfiguration(savedConfigs, scanDetails);
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
 
+        mWifiQualifiedNetworkSelector.setUserPreferredBand(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -489,7 +491,7 @@
         ScanResult chosenScanResult = scanDetails.get(scanDetails.size() - 1).getScanResult();
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -525,7 +527,7 @@
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         assertEquals("choose the wrong SSID", null, candidate);
     }
@@ -561,7 +563,7 @@
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -597,7 +599,7 @@
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -632,7 +634,7 @@
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -717,7 +719,7 @@
                 .thenReturn(configs[2]);
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -798,7 +800,7 @@
         mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
         mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], false);
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -840,7 +842,7 @@
         //re-enable it
         mWifiQualifiedNetworkSelector.enableBssidForQualityNetworkSelection(bssids[1], true);
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -884,10 +886,10 @@
         }
 
         //re-enable it
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime()
-                + WifiQualifiedNetworkSelector.BSSID_BLACKLIST_EXPIRE_TIME);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()
+                + WifiQualifiedNetworkSelector.BSSID_BLACKLIST_EXPIRE_TIME_MS);
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -926,7 +928,7 @@
         savedConfigs[1].getNetworkSelectionStatus().setNetworkSelectionStatus(
                 WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
     }
@@ -962,7 +964,7 @@
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, true, false, true, false);
+                false, true, false, true, false, scanDetails);
 
         assertEquals("choose the wrong network", null, candidate);
     }
@@ -994,11 +996,11 @@
         when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
         //first QNS
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
         //immediately second QNS
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, false, true, false);
+                false, false, false, true, false, scanDetails);
         ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
 
         verifySelectedResult(chosenScanResult, candidate);
@@ -1032,11 +1034,11 @@
         when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
         //first QNS
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
         //immediately second QNS
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
         assertEquals("choose the wrong BSSID", null, candidate);
     }
@@ -1068,11 +1070,11 @@
         when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
         //first QNS
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
         //immediately second QNS
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(true,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
 
         verifySelectedResult(chosenScanResult, candidate);
@@ -1105,7 +1107,7 @@
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         assertEquals("choose the wrong BSSID", null, candidate);
         assertEquals("Should receive zero filteredScanDetails", 0,
                 mWifiQualifiedNetworkSelector.getFilteredScanDetails().size());
@@ -1140,20 +1142,20 @@
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         //first time, connect to test2 due to 5GHz bonus
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
         when(mWifiInfo.is24GHz()).thenReturn(false);
         when(mWifiConfigManager.getEnableAutoJoinWhenAssociated()).thenReturn(true);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
 
         levels[0] = -50; // if there is QNS, test1 will be chosen
         scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         assertEquals("choose the wrong BSSID", null, candidate);
     }
 
@@ -1184,16 +1186,16 @@
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         //first connect to test2 due to 5GHz bonus
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
         when(mWifiInfo.is24GHz()).thenReturn(false);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
         when(mWifiConfigManager.getEnableAutoJoinWhenAssociated()).thenReturn(true);
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, true, true, false, false);
+                false, true, true, false, false, scanDetails);
         assertEquals("choose the wrong BSSID", null, candidate);
     }
 
@@ -1226,15 +1228,15 @@
         when(mWifiInfo.getBSSID()).thenReturn(bssids[0]);
         when(mWifiInfo.is24GHz()).thenReturn(true);
         //connect to config2 first
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
 
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
         when(mWifiConfigManager.getEnableAutoJoinWhenAssociated()).thenReturn(true);
 
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -1266,14 +1268,14 @@
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         //first connect to test2 because of RSSI
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
         when(mWifiInfo.is24GHz()).thenReturn(false);
         when(mWifiInfo.is5GHz()).thenReturn(true);
         when(mWifiConfigManager.isOpenNetwork(savedConfigs[1])).thenReturn(true);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
         when(mWifiConfigManager.getEnableAutoJoinWhenAssociated()).thenReturn(true);
         levels[0] = -60;
         scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
@@ -1281,7 +1283,7 @@
 
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -1314,8 +1316,8 @@
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         //first connect to test2 since test1's RSSI is negligible
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
         when(mWifiInfo.is24GHz()).thenReturn(false);
@@ -1324,11 +1326,11 @@
         scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
         when(mWifiConfigManager.getEnableAutoJoinWhenAssociated()).thenReturn(true);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
 
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -1359,8 +1361,8 @@
         when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
         when(mWifiInfo.getRssi()).thenReturn(levels[1]);
@@ -1368,14 +1370,14 @@
         when(mWifiInfo.is5GHz()).thenReturn(true);
 
         when(mWifiConfigManager.getEnableAutoJoinWhenAssociated()).thenReturn(true);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
         levels[0] = -60;
         scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
 
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -1405,8 +1407,8 @@
         when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
 
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
@@ -1417,12 +1419,12 @@
         when(mWifiConfigManager.getEnableAutoJoinWhenAssociated()).thenReturn(true);
         levels[0] = -60;
         scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -1454,8 +1456,8 @@
         when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
         when(mWifiInfo.is24GHz()).thenReturn(true);
@@ -1464,12 +1466,12 @@
         levels[0] = -80 + WifiQualifiedNetworkSelector.SAME_BSSID_AWARD / 4
                 + WifiQualifiedNetworkSelector.SAME_NETWORK_AWARD / 4 - 1;
         scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -1499,8 +1501,8 @@
         final List<WifiConfiguration> savedNetwork = Arrays.asList(savedConfigs);
         when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
 
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
@@ -1510,12 +1512,12 @@
         levels[0] = -80 + WifiQualifiedNetworkSelector.SAME_BSSID_AWARD / 4
                 + WifiQualifiedNetworkSelector.SAME_NETWORK_AWARD / 4 + 1;
         scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -1551,8 +1553,8 @@
         final List<WifiConfiguration> savedNetwork = Arrays.asList(savedConfigs);
         when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
 
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
@@ -1561,12 +1563,12 @@
         when(mWifiConfigManager.getEnableAutoJoinWhenAssociated()).thenReturn(true);
         levels[0] = -80 + WifiQualifiedNetworkSelector.SAME_NETWORK_AWARD / 4 - 1;
         scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -1602,8 +1604,8 @@
         final List<WifiConfiguration> savedNetwork = Arrays.asList(savedConfigs);
         when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
-        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, scanDetails, false,
-                false, true, false);
+        mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false, false, false,
+                false, true, false, scanDetails);
 
         when(mWifiInfo.getNetworkId()).thenReturn(1);
         when(mWifiInfo.getBSSID()).thenReturn(bssids[1]);
@@ -1612,12 +1614,12 @@
         when(mWifiConfigManager.getEnableAutoJoinWhenAssociated()).thenReturn(true);
         levels[0] = -80 + WifiQualifiedNetworkSelector.SAME_BSSID_AWARD / 4 + 1;
         scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() + 11 * 1000);
         scanResultLinkConfiguration(savedConfigs, scanDetails);
 
         ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
-                false, scanDetails, false, true, false, false);
+                false, false, true, false, false, scanDetails);
         verifySelectedResult(chosenScanResult, candidate);
     }
 
@@ -1671,11 +1673,11 @@
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(
                 false /* forceSelectNetwork */,
                 true /* isUntrustedConnectionsAllowed */,
-                scanDetails,
                 false, /* isLinkDebouncing */
                 false, /* isConnected */
                 true, /* isDisconnected */
-                false /* isSupplicantTransient */);
+                false, /* isSupplicantTransient */
+                scanDetails);
         verify(selectionStatus).setCandidate(untrustedScanResult);
         assertSame(unTrustedNetworkCandidate, candidate);
         assertEquals(meteredHints[1], candidate.meteredHint);
@@ -1744,11 +1746,11 @@
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(
                 false /* forceSelectNetwork */,
                 true /* isUntrustedConnectionsAllowed */,
-                scanDetails,
                 false, /* isLinkDebouncing */
                 false, /* isConnected */
                 true, /* isDisconnected */
-                false /* isSupplicantTransient */);
+                false, /* isSupplicantTransient */
+                scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
         //Verify two scanDetails returned in the filteredScanDetails
@@ -1823,11 +1825,11 @@
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(
                 false /* forceSelectNetwork */,
                 false /* isUntrustedConnectionsAllowed */,
-                scanDetails,
                 false, /* isLinkDebouncing */
                 false, /* isConnected */
                 true, /* isDisconnected */
-                false /* isSupplicantTransient */);
+                false, /* isSupplicantTransient */
+                scanDetails);
 
         verifySelectedResult(chosenScanResult, candidate);
         //Verify two scanDetails returned in the filteredScanDetails
@@ -1893,11 +1895,11 @@
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(
                 false /* forceSelectNetwork */,
                 true /* isUntrustedConnectionsAllowed */,
-                scanDetails,
                 false, /* isLinkDebouncing */
                 false, /* isConnected */
                 true, /* isDisconnected */
-                false /* isSupplicantTransient */);
+                false, /* isSupplicantTransient */
+                scanDetails);
         verify(selectionStatus).setCandidate(untrustedScanResult);
         assertSame(candidate, unTrustedNetworkCandidate);
         assertEquals(meteredHints[0], candidate.meteredHint);
@@ -1938,11 +1940,11 @@
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(
                 false /* forceSelectNetwork */,
                 false /* isUntrustedConnectionsAllowed */,
-                scanDetails,
                 false, /* isLinkDebouncing */
                 false, /* isConnected */
                 true, /* isDisconnected */
-                false /* isSupplicantTransient */);
+                false, /* isSupplicantTransient */
+                scanDetails);
         verifySelectedResult(scanDetails.get(0).getScanResult(), candidate);
         assertSame(candidate, savedConfigs[0]);
     }
@@ -1984,11 +1986,11 @@
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(
                 false /* forceSelectNetwork */,
                 false /* isUntrustedConnectionsAllowed */,
-                scanDetails,
                 false, /* isLinkDebouncing */
                 false, /* isConnected */
                 true, /* isDisconnected */
-                false /* isSupplicantTransient */);
+                false, /* isSupplicantTransient */
+                scanDetails);
         verifySelectedResult(scanDetails.get(0).getScanResult(), candidate);
         assertSame(candidate, savedConfigs[0]);
     }
@@ -2035,11 +2037,11 @@
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(
                 false /* forceSelectNetwork */,
                 true /* isUntrustedConnectionsAllowed */,
-                scanDetails,
                 false, /* isLinkDebouncing */
                 false, /* isConnected */
                 true, /* isDisconnected */
-                false /* isSupplicantTransient */);
+                false, /* isSupplicantTransient */
+                scanDetails);
         verifySelectedResult(scanDetails.get(0).getScanResult(), candidate);
         assertSame(candidate, savedConfigs[0]);
     }
@@ -2093,11 +2095,11 @@
         WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(
                 false /* forceSelectNetwork */,
                 true /* isUntrustedConnectionsAllowed */,
-                scanDetails,
                 false, /* isLinkDebouncing */
                 false, /* isConnected */
                 true, /* isDisconnected */
-                false /* isSupplicantTransient */);
+                false, /* isSupplicantTransient */
+                scanDetails);
         verify(selectionStatus).setCandidate(untrustedScanResult);
         assertSame(unTrustedNetworkCandidate, candidate);
     }
@@ -2233,4 +2235,119 @@
         assertEquals(WifiQualifiedNetworkSelector.ExternalScoreEvaluator
                 .BestCandidateType.NONE, evaluator.getBestCandidateType());
     }
+
+    /**
+     * Case #46   5GHz due to user band preference is set to 5GHz only
+     *
+     * In this test. we simulate following scenario
+     * WifiStateMachine is under disconnected state
+     * User band preference is set to 5GHz only
+     * Two networks test1, test2 are secured network
+     * Both network are enabled
+     * test1 is @ 2GHz with RSSI -50
+     * test2 is @ 5Ghz with RSSI -75
+     *
+     * Expected behavior: test2 is chosen due to user band preference
+     */
+    @Test
+    public void chooseNetworkDisconnectUserPrefer5GTest() {
+        String[] ssids = DEFAULT_SSIDS;
+        String[] bssids = DEFAULT_BSSIDS;
+        int[] frequencies = {2437, 5180};
+        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
+        int[] levels = {-50, -75};
+        int[] security = {SECURITY_PSK, SECURITY_PSK};
+
+        List<ScanDetail> scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
+        WifiConfiguration[] savedConfigs = generateWifiConfigurations(ssids, security);
+        prepareConfigStore(savedConfigs);
+
+        final List<WifiConfiguration> savedNetwork = Arrays.asList(savedConfigs);
+        when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
+        scanResultLinkConfiguration(savedConfigs, scanDetails);
+        ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
+
+        mWifiQualifiedNetworkSelector.setUserPreferredBand(WifiManager.WIFI_FREQUENCY_BAND_5GHZ);
+        WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
+                false, false, false, true, false, scanDetails);
+
+        verifySelectedResult(chosenScanResult, candidate);
+    }
+
+    /**
+     * Case #47   2GHz due to user band preference is set to 2GHz only
+     *
+     * In this test. we simulate following scenario
+     * WifiStateMachine is under disconnected state
+     * User band preference is set to 2.4GHz only
+     * Two networks test1, test2 are secured network
+     * Both network are enabled
+     * test1 is @ 2GHz with RSSI -75
+     * test2 is @ 5Ghz with RSSI -50
+     *
+     * Expected behavior: test1 is chosen due to user band preference
+     */
+    @Test
+    public void chooseNetworkDisconnectUserPrefer2GTest() {
+        String[] ssids = DEFAULT_SSIDS;
+        String[] bssids = DEFAULT_BSSIDS;
+        int[] frequencies = {2437, 5180};
+        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
+        int[] levels = {-75, -50};
+        int[] security = {SECURITY_PSK, SECURITY_PSK};
+
+        List<ScanDetail> scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
+        WifiConfiguration[] savedConfigs = generateWifiConfigurations(ssids, security);
+        prepareConfigStore(savedConfigs);
+
+        final List<WifiConfiguration> savedNetwork = Arrays.asList(savedConfigs);
+        when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
+        scanResultLinkConfiguration(savedConfigs, scanDetails);
+        ScanResult chosenScanResult = scanDetails.get(0).getScanResult();
+
+        mWifiQualifiedNetworkSelector.setUserPreferredBand(WifiManager.WIFI_FREQUENCY_BAND_2GHZ);
+        WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
+                false, false, false, true, false, scanDetails);
+
+        verifySelectedResult(chosenScanResult, candidate);
+    }
+
+    /**
+     * Case #48  5GHz due to user band preference is set to AUTO
+     *
+     * In this test. we simulate following scenario
+     * WifiStateMachine is under disconnected state
+     * User band preference is set to AUTO
+     * Two networks test1, test2 are secured network
+     * Both network are enabled
+     * test1 is @ 2GHz with RSSI -50
+     * test2 is @ 5Ghz with RSSI -50
+     *
+     * Expected behavior: test2 is chosen due to 5G bonus and user band preference
+     * is set to AUTO.
+     */
+    @Test
+    public void chooseNetworkDisconnectUserPreferAutoBandTest() {
+        String[] ssids = DEFAULT_SSIDS;
+        String[] bssids = DEFAULT_BSSIDS;
+        int[] frequencies = {2437, 5180};
+        String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"};
+        int[] levels = {-50, -50};
+        int[] security = {SECURITY_PSK, SECURITY_PSK};
+
+        List<ScanDetail> scanDetails = getScanDetails(ssids, bssids, frequencies, caps, levels);
+        WifiConfiguration[] savedConfigs = generateWifiConfigurations(ssids, security);
+        prepareConfigStore(savedConfigs);
+
+        final List<WifiConfiguration> savedNetwork = Arrays.asList(savedConfigs);
+        when(mWifiConfigManager.getSavedNetworks()).thenReturn(savedNetwork);
+        scanResultLinkConfiguration(savedConfigs, scanDetails);
+        ScanResult chosenScanResult = scanDetails.get(1).getScanResult();
+
+        mWifiQualifiedNetworkSelector.setUserPreferredBand(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
+        WifiConfiguration candidate = mWifiQualifiedNetworkSelector.selectQualifiedNetwork(false,
+                false, false, false, true, false, scanDetails);
+
+        verifySelectedResult(chosenScanResult, candidate);
+    }
 }
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index e0f94ad..be19084 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -22,6 +22,8 @@
 import static org.mockito.Mockito.*;
 
 import android.app.ActivityManager;
+import android.app.test.TestAlarmManager;
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -53,6 +55,7 @@
 import android.os.PowerManager;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.test.TestLooper;
 import android.provider.Settings;
 import android.security.KeyStore;
 import android.telephony.TelephonyManager;
@@ -65,7 +68,6 @@
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.IState;
 import com.android.internal.util.StateMachine;
-import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
 import com.android.server.wifi.hotspot2.NetworkDetail;
 import com.android.server.wifi.hotspot2.Utils;
 import com.android.server.wifi.p2p.WifiP2pServiceImpl;
@@ -84,6 +86,7 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -165,20 +168,16 @@
         WifiP2pServiceImpl p2pm = (WifiP2pServiceImpl) p2pBinder.queryLocalInterface(
                 IWifiP2pManager.class.getCanonicalName());
 
-        final Object sync = new Object();
-        synchronized (sync) {
-            mP2pThread = new HandlerThread("WifiP2pMockThread") {
-                @Override
-                protected void onLooperPrepared() {
-                    synchronized (sync) {
-                        sync.notifyAll();
-                    }
-                }
-            };
+        final CountDownLatch untilDone = new CountDownLatch(1);
+        mP2pThread = new HandlerThread("WifiP2pMockThread") {
+            @Override
+            protected void onLooperPrepared() {
+                untilDone.countDown();
+            }
+        };
 
-            mP2pThread.start();
-            sync.wait();
-        }
+        mP2pThread.start();
+        untilDone.await();
 
         Handler handler = new Handler(mP2pThread.getLooper());
         when(p2pm.getP2pStateMachineMessenger()).thenReturn(new Messenger(handler));
@@ -229,7 +228,7 @@
         when(context.getSystemService(Context.POWER_SERVICE)).thenReturn(
                 new PowerManager(context, mock(IPowerManager.class), new Handler()));
 
-        mAlarmManager = new MockAlarmManager();
+        mAlarmManager = new TestAlarmManager();
         when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn(
                 mAlarmManager.getAlarmManager());
 
@@ -307,10 +306,10 @@
     HandlerThread mP2pThread;
     HandlerThread mSyncThread;
     AsyncChannel  mWsmAsyncChannel;
-    MockAlarmManager mAlarmManager;
+    TestAlarmManager mAlarmManager;
     MockWifiMonitor mWifiMonitor;
     TestIpManager mTestIpManager;
-    MockLooper mLooper;
+    TestLooper mLooper;
     WifiConfigManager mWifiConfigManager;
 
     @Mock WifiNative mWifiNative;
@@ -334,7 +333,7 @@
         Log.d(TAG, "Setting up ...");
 
         // Ensure looper exists
-        mLooper = new MockLooper();
+        mLooper = new TestLooper();
 
         MockitoAnnotations.initMocks(this);
 
@@ -349,6 +348,7 @@
         when(mWifiInjector.getPropertyService()).thenReturn(mPropertyService);
         when(mWifiInjector.getBuildProperties()).thenReturn(mBuildProperties);
         when(mWifiInjector.getKeyStore()).thenReturn(mock(KeyStore.class));
+        when(mWifiInjector.getWifiBackupRestore()).thenReturn(mock(WifiBackupRestore.class));
         FrameworkFacade factory = getFrameworkFacade();
         Context context = getContext();
 
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiSupplicantControlTest.java
similarity index 93%
rename from tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
rename to tests/wifitests/src/com/android/server/wifi/WifiSupplicantControlTest.java
index 3993fe5..ceb4b42 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiSupplicantControlTest.java
@@ -11,7 +11,7 @@
  * 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
+ * limitations under the License.
  */
 
 package com.android.server.wifi;
@@ -35,10 +35,10 @@
 import java.util.Map;
 
 /**
- * Unit tests for {@link com.android.server.wifi.WifiConfigStore}.
+ * Unit tests for {@link com.android.server.wifi.WifiSupplicantControl}.
  */
 @SmallTest
-public class WifiConfigStoreTest {
+public class WifiSupplicantControlTest {
     private static final String KEY_SSID = "ssid";
     private static final String KEY_PSK = "psk";
     private static final String KEY_KEY_MGMT = "key_mgmt";
@@ -97,7 +97,7 @@
         NETWORK_3_VARS.put(CONFIG_KEY, "\"testwpa2psk\"WPA_PSK");
     }
 
-    private static final ArrayList<HashMap<String, String>> NETWORK_VARS = new ArrayList<HashMap<String, String>>();
+    private static final ArrayList<HashMap<String, String>> NETWORK_VARS = new ArrayList<>();
     static {
         NETWORK_VARS.add(NETWORK_0_VARS);
         NETWORK_VARS.add(NETWORK_1_VARS);
@@ -105,7 +105,8 @@
         NETWORK_VARS.add(NETWORK_3_VARS);
     }
 
-    // Taken from wpa_supplicant.conf actual test device Some fields modified for privacy.
+    // Taken from wpa_supplicant.conf of an actual test device. Some fields modified for privacy
+    // reasons.
     private static final String TEST_WPA_SUPPLICANT_CONF = ""
             + "ctrl_interface=/data/misc/wifi/sockets\n"
             + "disable_scan_offload=1\n"
@@ -157,16 +158,15 @@
 
     @Mock private WifiNative mWifiNative;
     @Mock private Context mContext;
-    private MockKeyStore mMockKeyStore;
-    private WifiConfigStore mWifiConfigStore;
+    private WifiSupplicantControl mWifiSupplicantControl;
 
+    /**
+     * Initialize |WifiSupplicantControl| instance before each test.
+     */
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-
-        mMockKeyStore = new MockKeyStore();
-        mWifiConfigStore = new WifiConfigStore(mContext, mWifiNative, mMockKeyStore.createMock(),
-                null, false, true);
+        mWifiSupplicantControl = new WifiSupplicantControl(mContext, mWifiNative, null);
     }
 
     /**
@@ -226,7 +226,7 @@
         BufferedReader reader = null;
         try {
             reader = new BufferedReader(new StringReader(TEST_WPA_SUPPLICANT_CONF));
-            result = mWifiConfigStore.readNetworkVariablesFromReader(reader, key);
+            result = mWifiSupplicantControl.readNetworkVariablesFromReader(reader, key);
         } catch (IOException e) {
             fail("Error reading test supplicant conf string");
         } finally {
diff --git a/tests/wifitests/src/com/android/server/wifi/nan/TlvBufferUtilsTest.java b/tests/wifitests/src/com/android/server/wifi/nan/TlvBufferUtilsTest.java
index 5c83185..9141841 100644
--- a/tests/wifitests/src/com/android/server/wifi/nan/TlvBufferUtilsTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/nan/TlvBufferUtilsTest.java
@@ -24,7 +24,6 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ErrorCollector;
-import org.junit.rules.ExpectedException;
 
 /**
  * Unit test harness for WifiNanManager class.
@@ -34,9 +33,6 @@
     @Rule
     public ErrorCollector collector = new ErrorCollector();
 
-    @Rule
-    public ExpectedException thrown = ExpectedException.none();
-
     /*
      * TlvBufferUtils Tests
      */
@@ -64,10 +60,20 @@
                 utilAreArraysEqual(tlv01.getArray(), tlv01.getActualLength(), new byte[] {
                         1, 2, 3, 0, 1, 2 }, 6),
                 equalTo(true));
+
+        collector.checkThat("tlv11-valid",
+                TlvBufferUtils.isValid(tlv11.getArray(), tlv11.getActualLength(), 1, 1),
+                equalTo(true));
+        collector.checkThat("tlv01-valid",
+                TlvBufferUtils.isValid(tlv01.getArray(), tlv01.getActualLength(), 0, 1),
+                equalTo(true));
     }
 
     @Test
     public void testTlvIterate() {
+        final String ascii = "ABC";
+        final String nonAscii = "何かもっと複雑な";
+
         TlvBufferUtils.TlvConstructor tlv22 = new TlvBufferUtils.TlvConstructor(2, 2);
         tlv22.allocate(18);
         tlv22.putInt(0, 2);
@@ -102,9 +108,10 @@
         }
 
         TlvBufferUtils.TlvConstructor tlv02 = new TlvBufferUtils.TlvConstructor(0, 2);
-        tlv02.allocate(15);
+        tlv02.allocate(100);
         tlv02.putByte(0, (byte) 2);
-        tlv02.putString(0, "ABC");
+        tlv02.putString(0, ascii);
+        tlv02.putString(0, nonAscii);
 
         TlvBufferUtils.TlvIterable tlv02It = new TlvBufferUtils.TlvIterable(0, 2, tlv02.getArray(),
                 tlv02.getActualLength());
@@ -115,101 +122,119 @@
                 collector.checkThat("tlv02-correct-iteration-DATA", (int) tlv.getByte(),
                         equalTo(2));
             } else if (count == 1) {
-                collector.checkThat("tlv02-correct-iteration-mLength", tlv.mLength, equalTo(3));
-                collector.checkThat("tlv02-correct-iteration-DATA", tlv.getString().equals("ABC"),
+                collector.checkThat("tlv02-correct-iteration-mLength", tlv.mLength,
+                        equalTo(ascii.length()));
+                collector.checkThat("tlv02-correct-iteration-DATA", tlv.getString().equals(ascii),
                         equalTo(true));
+            } else if (count == 2) {
+                collector.checkThat("tlv02-correct-iteration-mLength", tlv.mLength,
+                        equalTo(nonAscii.getBytes().length));
+                collector.checkThat("tlv02-correct-iteration-DATA",
+                        tlv.getString().equals(nonAscii), equalTo(true));
             } else {
                 collector.checkThat("Invalid number of iterations in loop - tlv02", true,
                         equalTo(false));
             }
             ++count;
         }
-        if (count != 2) {
-            collector.checkThat("Invalid number of iterations outside loop - tlv02", true,
-                    equalTo(false));
-        }
+        collector.checkThat("Invalid number of iterations outside loop - tlv02", count,
+                equalTo(3));
+
+        collector.checkThat("tlv22-valid",
+                TlvBufferUtils.isValid(tlv22.getArray(), tlv22.getActualLength(), 2, 2),
+                equalTo(true));
+        collector.checkThat("tlv02-valid",
+                TlvBufferUtils.isValid(tlv02.getArray(), tlv02.getActualLength(), 0, 2),
+                equalTo(true));
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvInvalidSizeT1L0() {
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 0);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvInvalidSizeTm3L2() {
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(-3, 2);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvInvalidSizeT1Lm2() {
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, -2);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvInvalidSizeT1L3() {
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 3);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvInvalidSizeT3L1() {
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(3, 1);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvItInvalidSizeT1L0() {
         final byte[] dummy = {
                 0, 1, 2 };
         final int dummyLength = 3;
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 0, dummy,
                 dummyLength);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvItInvalidSizeTm3L2() {
         final byte[] dummy = {
                 0, 1, 2 };
         final int dummyLength = 3;
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(-3, 2, dummy,
                 dummyLength);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvItInvalidSizeT1Lm2() {
         final byte[] dummy = {
                 0, 1, 2 };
         final int dummyLength = 3;
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, -2, dummy,
                 dummyLength);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvItInvalidSizeT1L3() {
         final byte[] dummy = {
                 0, 1, 2 };
         final int dummyLength = 3;
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 3, dummy,
                 dummyLength);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testTlvItInvalidSizeT3L1() {
         final byte[] dummy = {
                 0, 1, 2 };
         final int dummyLength = 3;
-        thrown.expect(IllegalArgumentException.class);
         TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(3, 1, dummy,
                 dummyLength);
     }
 
+    /**
+     * Validate that a malformed byte array fails the TLV validity test.
+     */
+    @Test
+    public void testTlvInvalidByteArray() {
+        TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
+        tlv01.allocate(15);
+        tlv01.putByte(0, (byte) 2);
+        tlv01.putByteArray(2, new byte[]{0, 1, 2});
+
+        byte[] array = tlv01.getArray();
+        array[0] = 10;
+
+        collector.checkThat("tlv01-invalid",
+                TlvBufferUtils.isValid(array, tlv01.getActualLength(), 0, 1), equalTo(false));
+    }
+
     /*
      * Utilities
      */
diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanDataPathStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanDataPathStateManagerTest.java
new file mode 100644
index 0000000..e4f714a
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanDataPathStateManagerTest.java
@@ -0,0 +1,735 @@
+/*
+ * 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 com.android.server.wifi.nan;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyShort;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.app.test.TestAlarmManager;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
+import android.net.NetworkCapabilities;
+import android.net.NetworkFactory;
+import android.net.NetworkInfo;
+import android.net.NetworkMisc;
+import android.net.NetworkRequest;
+import android.net.wifi.RttManager;
+import android.net.wifi.nan.ConfigRequest;
+import android.net.wifi.nan.IWifiNanEventCallback;
+import android.net.wifi.nan.IWifiNanManager;
+import android.net.wifi.nan.IWifiNanSessionCallback;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
+import android.net.wifi.nan.WifiNanEventCallback;
+import android.net.wifi.nan.WifiNanManager;
+import android.net.wifi.nan.WifiNanPublishSession;
+import android.net.wifi.nan.WifiNanSessionCallback;
+import android.net.wifi.nan.WifiNanSubscribeSession;
+import android.os.IBinder;
+import android.os.INetworkManagementService;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.test.TestLooper;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Pair;
+
+import com.android.internal.util.AsyncChannel;
+
+import libcore.util.HexEncoding;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ErrorCollector;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+
+/**
+ * Unit test harness for WifiNanDataPathStateManager class.
+ */
+@SmallTest
+public class WifiNanDataPathStateManagerTest {
+    private static final String sNanInterfacePrefix = "nan";
+
+    private TestLooper mMockLooper;
+    private WifiNanStateManager mDut;
+    @Mock private WifiNanNative mMockNative;
+    @Mock private Context mMockContext;
+    @Mock private IWifiNanManager mMockNanService;
+    @Mock private WifiNanPublishSession mMockPublishSession;
+    @Mock private WifiNanSubscribeSession mMockSubscribeSession;
+    @Mock private RttManager.RttListener mMockRttListener;
+    @Mock private ConnectivityManager mMockCm;
+    @Mock private INetworkManagementService mMockNwMgt;
+    @Mock private WifiNanDataPathStateManager.NetworkInterfaceWrapper mMockNetworkInterface;
+    @Mock private IWifiNanEventCallback mMockCallback;
+    @Mock IWifiNanSessionCallback mMockSessionCallback;
+    TestAlarmManager mAlarmManager;
+
+    @Rule
+    public ErrorCollector collector = new ErrorCollector();
+
+    /**
+     * Initialize mocks.
+     */
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mAlarmManager = new TestAlarmManager();
+        when(mMockContext.getSystemService(Context.ALARM_SERVICE))
+                .thenReturn(mAlarmManager.getAlarmManager());
+
+        when(mMockContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(mMockCm);
+
+        mMockLooper = new TestLooper();
+
+        mDut = installNewNanStateManager();
+        mDut.start(mMockContext, mMockLooper.getLooper());
+        mDut.startLate();
+
+        when(mMockNative.getCapabilities(anyShort())).thenReturn(true);
+        when(mMockNative.enableAndConfigure(anyShort(), any(ConfigRequest.class), anyBoolean()))
+                .thenReturn(true);
+        when(mMockNative.disable(anyShort())).thenReturn(true);
+        when(mMockNative.publish(anyShort(), anyInt(), any(PublishConfig.class))).thenReturn(true);
+        when(mMockNative.subscribe(anyShort(), anyInt(), any(SubscribeConfig.class)))
+                .thenReturn(true);
+        when(mMockNative.sendMessage(anyShort(), anyInt(), anyInt(), any(byte[].class),
+                any(byte[].class), anyInt(), anyInt())).thenReturn(true);
+        when(mMockNative.stopPublish(anyShort(), anyInt())).thenReturn(true);
+        when(mMockNative.stopSubscribe(anyShort(), anyInt())).thenReturn(true);
+        when(mMockNative.createNanNetworkInterface(anyShort(), anyString())).thenReturn(true);
+        when(mMockNative.deleteNanNetworkInterface(anyShort(), anyString())).thenReturn(true);
+        when(mMockNative.initiateDataPath(anyShort(), anyInt(), anyInt(), anyInt(),
+                any(byte[].class), anyString(), any(byte[].class), anyInt())).thenReturn(true);
+        when(mMockNative.respondToDataPathRequest(anyShort(), anyBoolean(), anyInt(), anyString(),
+                any(byte[].class), anyInt())).thenReturn(true);
+        when(mMockNative.endDataPath(anyShort(), anyInt())).thenReturn(true);
+
+        when(mMockNetworkInterface.configureAgentProperties(
+                any(WifiNanDataPathStateManager.NanNetworkRequestInformation.class), anyString(),
+                anyInt(), any(NetworkInfo.class), any(NetworkCapabilities.class),
+                any(LinkProperties.class))).thenReturn(true);
+
+        installMockWifiNanNative(mMockNative);
+        installDataPathStateManagerMocks();
+    }
+
+    /**
+     * Validates that creating and deleting all interfaces works based on capabilities.
+     */
+    @Test
+    public void testCreateDeleteAllInterfaces() throws Exception {
+        final int numNdis = 3;
+        final int failCreateInterfaceIndex = 1;
+
+        WifiNanNative.Capabilities capabilities = new WifiNanNative.Capabilities();
+        capabilities.maxNdiInterfaces = numNdis;
+
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<String> interfaceName = ArgumentCaptor.forClass(String.class);
+        InOrder inOrder = inOrder(mMockNative);
+
+        // (1) get capabilities
+        mDut.getCapabilities();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), capabilities);
+        mMockLooper.dispatchAll();
+
+        // (2) create all interfaces
+        mDut.createAllDataPathInterfaces();
+        mMockLooper.dispatchAll();
+        for (int i = 0; i < numNdis; ++i) {
+            inOrder.verify(mMockNative).createNanNetworkInterface(transactionId.capture(),
+                    interfaceName.capture());
+            collector.checkThat("interface created -- " + i, sNanInterfacePrefix + i,
+                    equalTo(interfaceName.getValue()));
+            mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0);
+            mMockLooper.dispatchAll();
+        }
+
+        // (3) delete all interfaces [one unsuccessfully] - note that will not necessarily be
+        // done sequentially
+        boolean[] done = new boolean[numNdis];
+        Arrays.fill(done, false);
+        mDut.deleteAllDataPathInterfaces();
+        mMockLooper.dispatchAll();
+        for (int i = 0; i < numNdis; ++i) {
+            inOrder.verify(mMockNative).deleteNanNetworkInterface(transactionId.capture(),
+                    interfaceName.capture());
+            int interfaceIndex = Integer.valueOf(
+                    interfaceName.getValue().substring(sNanInterfacePrefix.length()));
+            done[interfaceIndex] = true;
+            if (interfaceIndex == failCreateInterfaceIndex) {
+                mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), false, 0);
+            } else {
+                mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0);
+            }
+            mMockLooper.dispatchAll();
+        }
+        for (int i = 0; i < numNdis; ++i) {
+            collector.checkThat("interface deleted -- " + i, done[i], equalTo(true));
+        }
+
+        // (4) create all interfaces (should get a delete for the one which couldn't delete earlier)
+        mDut.createAllDataPathInterfaces();
+        mMockLooper.dispatchAll();
+        for (int i = 0; i < numNdis; ++i) {
+            if (i == failCreateInterfaceIndex) {
+                inOrder.verify(mMockNative).deleteNanNetworkInterface(transactionId.capture(),
+                        interfaceName.capture());
+                collector.checkThat("interface delete pre-create -- " + i, sNanInterfacePrefix + i,
+                        equalTo(interfaceName.getValue()));
+                mDut.onDeleteDataPathInterfaceResponse(transactionId.getValue(), true, 0);
+                mMockLooper.dispatchAll();
+            }
+            inOrder.verify(mMockNative).createNanNetworkInterface(transactionId.capture(),
+                    interfaceName.capture());
+            collector.checkThat("interface created -- " + i, sNanInterfacePrefix + i,
+                    equalTo(interfaceName.getValue()));
+            mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0);
+            mMockLooper.dispatchAll();
+        }
+
+        verifyNoMoreInteractions(mMockNative);
+    }
+
+    /*
+     * Initiator tests
+     */
+
+    /**
+     * Validate the success flow of the Initiator: using session network specifier with a non-null
+     * token.
+     */
+    @Test
+    public void testDataPathInitiatorMacTokenSuccess() throws Exception {
+        testDataPathInitiatorUtility(false, true, true, true);
+    }
+
+    /**
+     * Validate the fail flow of the Initiator: using session network specifier with a null
+     * token.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testDataPathInitiatorMacNoTokenFail() throws Exception {
+        testDataPathInitiatorUtility(false, true, false, true);
+    }
+
+    /**
+     * Validate the fail flow of the Initiator: using session network specifier with a 0
+     * peer ID.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testDataPathInitiatorNoMacFail() throws Exception {
+        testDataPathInitiatorUtility(false, false, true, true);
+    }
+
+    /**
+     * Validate the success flow of the Initiator: using a direct network specifier with a non-null
+     * peer mac and non-null token.
+     */
+    @Test
+    public void testDataPathInitiatorDirectMacTokenSuccess() throws Exception {
+        testDataPathInitiatorUtility(true, true, true, true);
+    }
+
+    /**
+     * Validate the fail flow of the Initiator: using a direct network specifier with a non-null
+     * peer mac and null token.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testDataPathInitiatorDirectMacNoTokenFail() throws Exception {
+        testDataPathInitiatorUtility(true, true, false, true);
+    }
+
+    /**
+     * Validate the fail flow of the Initiator: using a direct network specifier with a null peer
+     * mac and non-null token.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testDataPathInitiatorDirectNoMacTokenFail() throws Exception {
+        testDataPathInitiatorUtility(true, false, true, true);
+    }
+
+    /**
+     * Validate the fail flow of the Initiator: using a direct network specifier with a null peer
+     * mac and null token.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testDataPathInitiatorDirectNoMacNoTokenFail() throws Exception {
+        testDataPathInitiatorUtility(true, false, false, true);
+    }
+
+    /**
+     * Validate the fail flow of the Initiator: use a session network specifier with a non-null
+     * token, but don't get a confirmation.
+     */
+    @Test
+    public void testDataPathInitiatorNoConfirmationTimeoutFail() throws Exception {
+        testDataPathInitiatorUtility(false, true, true, false);
+    }
+
+    /*
+     * Responder tests
+     */
+
+    /**
+     * Validate the success flow of the Responder: using session network specifier with a non-null
+     * token.
+     */
+    @Test
+    public void testDataPathResonderMacTokenSuccess() throws Exception {
+        testDataPathResponderUtility(false, true, true, true);
+    }
+
+    /**
+     * Validate the success flow of the Responder: using session network specifier with a null
+     * token.
+     */
+    @Test
+    public void testDataPathResonderMacNoTokenSuccess() throws Exception {
+        testDataPathResponderUtility(false, true, false, true);
+    }
+
+    /**
+     * Validate the success flow of the Responder: using session network specifier with a
+     * token and no peer ID (i.e. 0).
+     */
+    @Test
+    public void testDataPathResonderMacTokenNoPeerIdSuccess() throws Exception {
+        testDataPathResponderUtility(false, false, true, true);
+    }
+
+    /**
+     * Validate the success flow of the Responder: using session network specifier with a null
+     * token and no peer ID (i.e. 0).
+     */
+    @Test
+    public void testDataPathResonderMacTokenNoPeerIdNoTokenSuccess() throws Exception {
+        testDataPathResponderUtility(false, false, false, true);
+    }
+
+    /**
+     * Validate the success flow of the Responder: using a direct network specifier with a non-null
+     * peer mac and non-null token.
+     */
+    @Test
+    public void testDataPathResonderDirectMacTokenSuccess() throws Exception {
+        testDataPathResponderUtility(true, true, true, true);
+    }
+
+    /**
+     * Validate the success flow of the Responder: using a direct network specifier with a non-null
+     * peer mac and null token.
+     */
+    @Test
+    public void testDataPathResonderDirectMacNoTokenSuccess() throws Exception {
+        testDataPathResponderUtility(true, true, false, true);
+    }
+
+    /**
+     * Validate the success flow of the Responder: using a direct network specifier with a null peer
+     * mac and non-null token.
+     */
+    @Test
+    public void testDataPathResonderDirectNoMacTokenSuccess() throws Exception {
+        testDataPathResponderUtility(true, false, true, true);
+    }
+
+    /**
+     * Validate the success flow of the Responder: using a direct network specifier with a null peer
+     * mac and null token.
+     */
+    @Test
+    public void testDataPathResonderDirectNoMacNoTokenSuccess() throws Exception {
+        testDataPathResponderUtility(true, false, false, true);
+    }
+
+    /**
+     * Validate the fail flow of the Responder: use a session network specifier with a non-null
+     * token, but don't get a confirmation.
+     */
+    @Test
+    public void testDataPathResponderNoConfirmationTimeoutFail() throws Exception {
+        testDataPathInitiatorUtility(false, true, true, false);
+    }
+
+    /*
+     * Utilities
+     */
+
+    private void testDataPathInitiatorUtility(boolean useDirect, boolean provideMac,
+            boolean provideToken, boolean getConfirmation) throws Exception {
+        final int clientId = 123;
+        final int pubSubId = 11234;
+        final int peerId = 1341234;
+        final int ndpId = 2;
+        final String token = "some token";
+        final String peerToken = "let's go!";
+        final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
+        final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
+
+        ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
+
+        // (0) initialize
+        Pair<Integer, Messenger> res = initDataPathEndPoint(clientId, pubSubId, peerId,
+                peerDiscoveryMac, inOrder);
+
+        // (1) request network
+        NetworkRequest nr;
+        if (useDirect) {
+            nr = getDirectNetworkRequest(clientId, WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR,
+                    provideMac ? peerDiscoveryMac : null, provideToken ? token : null);
+        } else {
+            nr = getSessionNetworkRequest(clientId, res.first, provideMac ? peerId : 0,
+                    WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR, provideToken ? token : null);
+        }
+
+        Message reqNetworkMsg = Message.obtain();
+        reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK;
+        reqNetworkMsg.obj = nr;
+        reqNetworkMsg.arg1 = 0;
+        res.second.send(reqNetworkMsg);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(),
+                eq(useDirect ? 0 : peerId), eq(WifiNanNative.CHANNEL_REQUEST_TYPE_REQUESTED),
+                eq(2437), eq(peerDiscoveryMac), eq("nan0"), eq(token.getBytes()),
+                eq(token.length()));
+        mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId);
+        mMockLooper.dispatchAll();
+
+        // (2) get confirmation OR timeout
+        if (getConfirmation) {
+            mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0,
+                    peerToken.getBytes(),
+                    peerToken.length());
+            mMockLooper.dispatchAll();
+            inOrder.verify(mMockCm).registerNetworkAgent(messengerCaptor.capture(),
+                    any(NetworkInfo.class), any(LinkProperties.class),
+                    any(NetworkCapabilities.class),
+                    anyInt(), any(NetworkMisc.class));
+        } else {
+            assertTrue(
+                    mAlarmManager.dispatch(WifiNanStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG));
+            mMockLooper.dispatchAll();
+            inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
+            mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
+            mMockLooper.dispatchAll();
+        }
+
+        // (3) end data-path (unless didn't get confirmation)
+        if (getConfirmation) {
+            Message endNetworkReqMsg = Message.obtain();
+            endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
+            endNetworkReqMsg.obj = nr;
+            res.second.send(endNetworkReqMsg);
+
+            Message endNetworkUsageMsg = Message.obtain();
+            endNetworkUsageMsg.what = AsyncChannel.CMD_CHANNEL_DISCONNECTED;
+            messengerCaptor.getValue().send(endNetworkUsageMsg);
+
+            mMockLooper.dispatchAll();
+            inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
+            mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
+            mMockLooper.dispatchAll();
+        }
+
+        verifyNoMoreInteractions(mMockNative, mMockCm);
+    }
+
+    private void testDataPathResponderUtility(boolean useDirect, boolean provideMac,
+            boolean provideToken, boolean getConfirmation) throws Exception {
+        final int clientId = 123;
+        final int pubSubId = 11234;
+        final int peerId = 1341234;
+        final int ndpId = 2;
+        final String token = "some token";
+        final String peerToken = "let's go!";
+        final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false);
+        final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
+
+        ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback);
+
+        // (0) initialize
+        Pair<Integer, Messenger> res = initDataPathEndPoint(clientId, pubSubId, peerId,
+                peerDiscoveryMac, inOrder);
+
+        // (1) request network
+        NetworkRequest nr;
+        if (useDirect) {
+            nr = getDirectNetworkRequest(clientId, WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_RESPONDER,
+                    provideMac ? peerDiscoveryMac : null, provideToken ? token : null);
+        } else {
+            nr = getSessionNetworkRequest(clientId, res.first, provideMac ? peerId : 0,
+                    WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_RESPONDER, provideToken ? token : null);
+        }
+
+        Message reqNetworkMsg = Message.obtain();
+        reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK;
+        reqNetworkMsg.obj = nr;
+        reqNetworkMsg.arg1 = 0;
+        res.second.send(reqNetworkMsg);
+        mMockLooper.dispatchAll();
+
+        // (2) get request & respond
+        mDut.onDataPathRequestNotification(pubSubId, peerDiscoveryMac, ndpId, token.getBytes(),
+                token.length());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).respondToDataPathRequest(transactionId.capture(), eq(true),
+                eq(ndpId), eq("nan0"), eq(new byte[0]), eq(0));
+        mDut.onRespondToDataPathSetupRequestResponse(transactionId.getValue(), true, 0);
+        mMockLooper.dispatchAll();
+
+        // (3) get confirmation OR timeout
+        if (getConfirmation) {
+            mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0,
+                    peerToken.getBytes(),
+                    peerToken.length());
+            mMockLooper.dispatchAll();
+            inOrder.verify(mMockCm).registerNetworkAgent(messengerCaptor.capture(),
+                    any(NetworkInfo.class), any(LinkProperties.class),
+                    any(NetworkCapabilities.class),
+                    anyInt(), any(NetworkMisc.class));
+        } else {
+            assertTrue(
+                    mAlarmManager.dispatch(WifiNanStateManager.HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG));
+            mMockLooper.dispatchAll();
+            inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
+            mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
+            mMockLooper.dispatchAll();
+        }
+
+        // (4) end data-path (unless didn't get confirmation)
+        if (getConfirmation) {
+            Message endNetworkMsg = Message.obtain();
+            endNetworkMsg.what = NetworkFactory.CMD_CANCEL_REQUEST;
+            endNetworkMsg.obj = nr;
+            res.second.send(endNetworkMsg);
+
+            Message endNetworkUsageMsg = Message.obtain();
+            endNetworkUsageMsg.what = AsyncChannel.CMD_CHANNEL_DISCONNECTED;
+            messengerCaptor.getValue().send(endNetworkUsageMsg);
+
+            mMockLooper.dispatchAll();
+            inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId));
+            mDut.onEndDataPathResponse(transactionId.getValue(), true, 0);
+            mMockLooper.dispatchAll();
+        }
+
+        verifyNoMoreInteractions(mMockNative, mMockCm);
+    }
+
+
+    private static WifiNanStateManager installNewNanStateManager()
+            throws Exception {
+        Constructor<WifiNanStateManager> ctr = WifiNanStateManager.class.getDeclaredConstructor();
+        ctr.setAccessible(true);
+        WifiNanStateManager nanStateManager = ctr.newInstance();
+
+        Field field = WifiNanStateManager.class.getDeclaredField("sNanStateManagerSingleton");
+        field.setAccessible(true);
+        field.set(null, nanStateManager);
+
+        return WifiNanStateManager.getInstance();
+    }
+
+    private static void installMockWifiNanNative(WifiNanNative obj) throws Exception {
+        Field field = WifiNanNative.class.getDeclaredField("sWifiNanNativeSingleton");
+        field.setAccessible(true);
+        field.set(null, obj);
+    }
+
+    private void installDataPathStateManagerMocks() throws Exception {
+        Field field = WifiNanStateManager.class.getDeclaredField("mDataPathMgr");
+        field.setAccessible(true);
+        Object mDataPathMgr = field.get(mDut);
+
+        field = WifiNanDataPathStateManager.class.getDeclaredField("mNwService");
+        field.setAccessible(true);
+        field.set(mDataPathMgr, mMockNwMgt);
+
+        field = WifiNanDataPathStateManager.class.getDeclaredField("mNiWrapper");
+        field.setAccessible(true);
+        field.set(mDataPathMgr, mMockNetworkInterface);
+    }
+
+    private NetworkRequest getSessionNetworkRequest(int clientId, int sessionId, int peerId,
+            int role, String token) throws Exception {
+        final WifiNanManager mgr = new WifiNanManager(mMockNanService);
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final PublishConfig publishConfig = new PublishConfig.Builder().build();
+
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+        ArgumentCaptor<IWifiNanSessionCallback> sessionProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanSessionCallback.class);
+        ArgumentCaptor<WifiNanPublishSession> publishSession = ArgumentCaptor
+                .forClass(WifiNanPublishSession.class);
+
+        WifiNanEventCallback mockCallback = mock(WifiNanEventCallback.class);
+        WifiNanSessionCallback mockSessionCallback = mock(WifiNanSessionCallback.class);
+
+        when(mMockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                any(ConfigRequest.class))).thenReturn(clientId);
+
+        mgr.connect(mMockLooper.getLooper(), mockCallback, configRequest);
+        verify(mMockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                eq(configRequest));
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        mgr.publish(publishConfig, mockSessionCallback);
+        verify(mMockNanService).publish(eq(clientId), eq(publishConfig),
+                sessionProxyCallback.capture());
+        sessionProxyCallback.getValue().onSessionStarted(sessionId);
+        mMockLooper.dispatchAll();
+        verify(mockSessionCallback).onPublishStarted(publishSession.capture());
+
+        String ns = publishSession.getValue().createNetworkSpecifier(role, peerId,
+                (token == null) ? null : token.getBytes(), (token == null) ? 0 : token.length());
+
+        NetworkCapabilities nc = new NetworkCapabilities();
+        nc.clearAll();
+        nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_NAN);
+        nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN).addCapability(
+                NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+        nc.setNetworkSpecifier(ns);
+        nc.setLinkUpstreamBandwidthKbps(1);
+        nc.setLinkDownstreamBandwidthKbps(1);
+        nc.setSignalStrength(1);
+
+        return new NetworkRequest(nc, 0, 0, NetworkRequest.Type.NONE);
+    }
+
+    private NetworkRequest getDirectNetworkRequest(int clientId, int role, byte[] peer,
+            String token) throws Exception {
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final WifiNanManager mgr = new WifiNanManager(mMockNanService);
+
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+
+        WifiNanEventCallback mockCallback = mock(WifiNanEventCallback.class);
+
+        when(mMockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                any(ConfigRequest.class))).thenReturn(clientId);
+
+        mgr.connect(mMockLooper.getLooper(), mockCallback, configRequest);
+        verify(mMockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                eq(configRequest));
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+
+        String ns = mgr.createNetworkSpecifier(role, peer,
+                (token == null) ? null : token.getBytes(), (token == null) ? 0 : token.length());
+        NetworkCapabilities nc = new NetworkCapabilities();
+        nc.clearAll();
+        nc.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_NAN);
+        nc.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN).addCapability(
+                NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+        nc.setNetworkSpecifier(ns);
+        nc.setLinkUpstreamBandwidthKbps(1);
+        nc.setLinkDownstreamBandwidthKbps(1);
+        nc.setSignalStrength(1);
+
+        return new NetworkRequest(nc, 0, 0, NetworkRequest.Type.REQUEST);
+    }
+
+    private Pair<Integer, Messenger> initDataPathEndPoint(int clientId, int pubSubId, int peerId,
+            byte[] peerDiscoveryMac, InOrder inOrder) throws Exception {
+        final int uid = 1000;
+        final String someMsg = "some arbitrary message from peer";
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final PublishConfig publishConfig = new PublishConfig.Builder().build();
+
+        WifiNanNative.Capabilities capabilities = new WifiNanNative.Capabilities();
+        capabilities.maxNdiInterfaces = 1;
+
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class);
+        ArgumentCaptor<String> strCaptor = ArgumentCaptor.forClass(String.class);
+
+        // (0) start/registrations
+        inOrder.verify(mMockCm).registerNetworkFactory(messengerCaptor.capture(),
+                strCaptor.capture());
+        collector.checkThat("factory name", "WIFI_NAN_FACTORY", equalTo(strCaptor.getValue()));
+
+        // (1) get capabilities
+        mDut.getCapabilities();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), capabilities);
+        mMockLooper.dispatchAll();
+
+        // (2) enable usage (creates interfaces)
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).createNanNetworkInterface(transactionId.capture(),
+                strCaptor.capture());
+        collector.checkThat("interface created -- 0", sNanInterfacePrefix + 0,
+                equalTo(strCaptor.getValue()));
+        mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0);
+        mMockLooper.dispatchAll();
+
+        // (3) create client & session & rx message
+        mDut.connect(clientId, uid, mMockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+                eq(configRequest), eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockCallback).onConnectSuccess();
+        mDut.publish(clientId, publishConfig, mMockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, pubSubId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockSessionCallback).onSessionStarted(sessionId.capture());
+        mDut.onMessageReceivedNotification(pubSubId, peerId, peerDiscoveryMac, someMsg.getBytes(),
+                someMsg.length());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockSessionCallback).onMessageReceived(peerId, someMsg.getBytes(),
+                someMsg.length());
+
+        return new Pair<>(sessionId.getValue(), messengerCaptor.getValue());
+    }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalMock.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalMock.java
index 4f3ba4d..694187e 100644
--- a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalMock.java
+++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalMock.java
@@ -39,6 +39,10 @@
         throw new IllegalStateException("Please mock this class!");
     }
 
+    public void configHalMockNative(short transactionId, String jsonArgs) {
+        throw new IllegalStateException("Please mock this class!");
+    }
+
     public void disableHalMockNative(short transactionId) {
         throw new IllegalStateException("Please mock this class!");
     }
@@ -63,6 +67,26 @@
         throw new IllegalStateException("Please mock this class!");
     }
 
+    public void createNanNetworkInterfaceMockNative(short transactionId, String jsonArgs) {
+        throw new IllegalStateException("Please mock this class!");
+    }
+
+    public void deleteNanNetworkInterfaceMockNative(short transactionId, String jsonArgs) {
+        throw new IllegalStateException("Please mock this class!");
+    }
+
+    public void initiateDataPathMockNative(short transactionId, String jsonArgs) {
+        throw new IllegalStateException("Please mock this class!");
+    }
+
+    public void respondToDataPathRequestMockNative(short transactionId, String jsonArgs) {
+        throw new IllegalStateException("Please mock this class!");
+    }
+
+    public void endDataPathMockNative(short transactionId, String jsonArgs) {
+        throw new IllegalStateException("Please mock this class!");
+    }
+
     /*
      * trigger callbacks - called by test harness with arguments passed by JSON
      * string.
@@ -82,15 +106,23 @@
 
     public static native void callDisabled(String jsonArgs);
 
+    public static native void callTransmitFollowup(String jsonArgs);
+
+    public static native void callDataPathRequest(String jsonArgs);
+
+    public static native void callDataPathConfirm(String jsonArgs);
+
+    public static native void callDataPathEnd(String jsonArgs);
+
     /**
      * initialize NAN mock
      */
     private static native int initNanHalMock();
 
-    public static void initNanHalMockLibrary() throws Exception {
-        Field field = WifiNanNative.class.getDeclaredField("sNanNativeInit");
+    public static void initNanHalMockLibrary(WifiNanNative instance) throws Exception {
+        Field field = WifiNanNative.class.getDeclaredField("mNativeHandlersIsInitialized");
         field.setAccessible(true);
-        field.setBoolean(null, true);
+        field.setBoolean(instance, true);
 
         initNanHalMock();
     }
diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalTest.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalTest.java
index 536c924..2fef83c 100644
--- a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalTest.java
@@ -18,16 +18,16 @@
 
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.PublishData;
-import android.net.wifi.nan.PublishSettings;
-import android.net.wifi.nan.SubscribeData;
-import android.net.wifi.nan.SubscribeSettings;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
 import android.net.wifi.nan.TlvBufferUtils;
-import android.net.wifi.nan.WifiNanSessionListener;
+import android.net.wifi.nan.WifiNanEventCallback;
+import android.net.wifi.nan.WifiNanSessionCallback;
 import android.os.Bundle;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -67,8 +67,10 @@
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
 
+        resetWifiNanNative();
+
         HalMockUtils.initHalMockLibrary();
-        WifiNanHalMock.initNanHalMockLibrary();
+        WifiNanHalMock.initNanHalMockLibrary(mDut);
         WifiNanNative.initNanHandlersNative(WifiNative.class, WifiNative.sWlan0Index);
         HalMockUtils.setHalMockObject(mNanHalMock);
         installMockNanStateManager(mNanStateManager);
@@ -97,6 +99,14 @@
     }
 
     @Test
+    public void testConfigCall() throws JSONException {
+        final short transactionId = 31235;
+        final short masterPref = 157;
+
+        testConfig(transactionId, masterPref);
+    }
+
+    @Test
     public void testDisable() {
         final short transactionId = 5478;
 
@@ -113,6 +123,7 @@
         final String ssi = "some much longer and more arbitrary data";
         final int publishCount = 7;
         final int publishTtl = 66;
+        final boolean enableTerminateNotification = true;
 
         TlvBufferUtils.TlvConstructor tlvTx = new TlvBufferUtils.TlvConstructor(0, 1);
         tlvTx.allocate(150).putByte(0, (byte) 10).putInt(0, 100).putString(0, "some string")
@@ -122,8 +133,8 @@
         tlvRx.allocate(150).putByte(0, (byte) 66).putInt(0, 127).putString(0, "some other string")
                 .putZeroLengthElement(0).putByteArray(0, serviceName.getBytes());
 
-        testPublish(transactionId, publishId, PublishSettings.PUBLISH_TYPE_UNSOLICITED, serviceName,
-                ssi, tlvTx, tlvRx, publishCount, publishTtl);
+        testPublish(transactionId, publishId, PublishConfig.PUBLISH_TYPE_UNSOLICITED, serviceName,
+                ssi, tlvTx, tlvRx, publishCount, publishTtl, enableTerminateNotification);
     }
 
     @Test
@@ -134,6 +145,7 @@
         final String ssi = "some much longer arbitrary data";
         final int publishCount = 32;
         final int publishTtl = 33;
+        final boolean enableTerminateNotification = false;
 
         TlvBufferUtils.TlvConstructor tlvTx = new TlvBufferUtils.TlvConstructor(0, 1);
         tlvTx.allocate(150).putByte(0, (byte) 10).putInt(0, 100).putString(0, "some string")
@@ -143,8 +155,8 @@
         tlvRx.allocate(150).putByte(0, (byte) 66).putInt(0, 127).putString(0, "some other string")
                 .putZeroLengthElement(0).putByteArray(0, serviceName.getBytes());
 
-        testPublish(transactionId, publishId, PublishSettings.PUBLISH_TYPE_SOLICITED, serviceName,
-                ssi, tlvTx, tlvRx, publishCount, publishTtl);
+        testPublish(transactionId, publishId, PublishConfig.PUBLISH_TYPE_SOLICITED, serviceName,
+                ssi, tlvTx, tlvRx, publishCount, publishTtl, enableTerminateNotification);
     }
 
     @Test
@@ -169,6 +181,8 @@
         final String ssi = "some much longer arbitrary data";
         final int subscribeCount = 32;
         final int subscribeTtl = 33;
+        final int matchStyle = SubscribeConfig.MATCH_STYLE_ALL;
+        final boolean enableTerminateNotification = true;
 
         TlvBufferUtils.TlvConstructor tlvTx = new TlvBufferUtils.TlvConstructor(0, 1);
         tlvTx.allocate(150).putByte(0, (byte) 10).putInt(0, 100).putString(0, "some string")
@@ -178,8 +192,9 @@
         tlvRx.allocate(150).putByte(0, (byte) 66).putInt(0, 127).putString(0, "some other string")
                 .putZeroLengthElement(0).putByteArray(0, serviceName.getBytes());
 
-        testSubscribe(transactionId, subscribeId, SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE,
-                serviceName, ssi, tlvTx, tlvRx, subscribeCount, subscribeTtl);
+        testSubscribe(transactionId, subscribeId, SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE,
+                serviceName, ssi, tlvTx, tlvRx, subscribeCount, subscribeTtl, matchStyle,
+                enableTerminateNotification);
     }
 
     @Test
@@ -190,6 +205,8 @@
         final String ssi = "some much longer arbitrary data";
         final int subscribeCount = 32;
         final int subscribeTtl = 33;
+        final int matchStyle = SubscribeConfig.MATCH_STYLE_FIRST_ONLY;
+        final boolean enableTerminateNotification = false;
 
         TlvBufferUtils.TlvConstructor tlvTx = new TlvBufferUtils.TlvConstructor(0, 1);
         tlvTx.allocate(150).putByte(0, (byte) 10).putInt(0, 100).putString(0, "some string")
@@ -199,8 +216,9 @@
         tlvRx.allocate(150).putByte(0, (byte) 66).putInt(0, 127).putString(0, "some other string")
                 .putZeroLengthElement(0).putByteArray(0, serviceName.getBytes());
 
-        testSubscribe(transactionId, subscribeId, SubscribeSettings.SUBSCRIBE_TYPE_ACTIVE,
-                serviceName, ssi, tlvTx, tlvRx, subscribeCount, subscribeTtl);
+        testSubscribe(transactionId, subscribeId, SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE,
+                serviceName, ssi, tlvTx, tlvRx, subscribeCount, subscribeTtl, matchStyle,
+                enableTerminateNotification);
     }
 
     @Test
@@ -224,9 +242,10 @@
         final int reqInstanceId = 11;
         final byte[] peer = HexEncoding.decode("000102030405".toCharArray(), false);
         final String msg = "Hello there - how are you doing?";
+        final int messageId = 10; /* garbage - not used by HAL */
 
         mDut.sendMessage(transactionId, pubSubId, reqInstanceId, peer, msg.getBytes(),
-                msg.length());
+                msg.length(), messageId);
 
         verify(mNanHalMock).transmitFollowupHalMockNative(eq(transactionId), mArgs.capture());
 
@@ -246,7 +265,7 @@
     }
 
     @Test
-    public void testNotifyCapabilities() throws JSONException {
+    public void testRespondWithCapabilities() throws JSONException {
         final short transactionId = 23;
         final int max_concurrent_nan_clusters = 1;
         final int max_publishes = 2;
@@ -260,6 +279,7 @@
         final int max_ndi_interfaces = 10;
         final int max_ndp_sessions = 11;
         final int max_app_info_len = 12;
+        final int max_queued_transmit_followup_msgs = 7;
 
         ArgumentCaptor<WifiNanNative.Capabilities> capabilitiesCapture = ArgumentCaptor
                 .forClass(WifiNanNative.Capabilities.class);
@@ -283,11 +303,13 @@
         args.putInt("body.nan_capabilities.max_ndi_interfaces", max_ndi_interfaces);
         args.putInt("body.nan_capabilities.max_ndp_sessions", max_ndp_sessions);
         args.putInt("body.nan_capabilities.max_app_info_len", max_app_info_len);
+        args.putInt("body.nan_capabilities.max_queued_transmit_followup_msgs",
+                max_queued_transmit_followup_msgs);
 
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onCapabilitiesUpdate(eq(transactionId),
+        verify(mNanStateManager).onCapabilitiesUpdateResponse(eq(transactionId),
                 capabilitiesCapture.capture());
         WifiNanNative.Capabilities capabilities = capabilitiesCapture.getValue();
         collector.checkThat("max_concurrent_nan_clusters", capabilities.maxConcurrentNanClusters,
@@ -312,6 +334,9 @@
                 equalTo(max_ndp_sessions));
         collector.checkThat("max_app_info_len", capabilities.maxAppInfoLen,
                 equalTo(max_app_info_len));
+        collector.checkThat("max_queued_transmit_followup_msgs",
+                capabilities.maxQueuedTransmitMessages, equalTo(max_queued_transmit_followup_msgs));
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -326,7 +351,8 @@
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onConfigCompleted(transactionId);
+        verify(mNanStateManager).onConfigSuccessResponse(transactionId);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -341,8 +367,9 @@
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onConfigFailed(transactionId,
-                WifiNanSessionListener.FAIL_REASON_INVALID_ARGS);
+        verify(mNanStateManager).onConfigFailedResponse(transactionId,
+                WifiNanEventCallback.REASON_INVALID_ARGS);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -359,7 +386,8 @@
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onPublishSuccess(transactionId, publishId);
+        verify(mNanStateManager).onSessionConfigSuccessResponse(transactionId, true, publishId);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -376,14 +404,14 @@
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onPublishFail(transactionId,
-                WifiNanSessionListener.FAIL_REASON_NO_RESOURCES);
+        verify(mNanStateManager).onSessionConfigFailResponse(transactionId, true,
+                WifiNanSessionCallback.REASON_NO_RESOURCES);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
     public void testNotifyResponsePublishCancel() throws JSONException {
         final short transactionId = 23;
-        final int publishId = 127;
 
         Bundle args = new Bundle();
         args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
@@ -393,7 +421,7 @@
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verifyZeroInteractions(mNanStateManager);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -410,7 +438,8 @@
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onSubscribeSuccess(transactionId, subscribeId);
+        verify(mNanStateManager).onSessionConfigSuccessResponse(transactionId, false, subscribeId);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -427,24 +456,24 @@
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onSubscribeFail(transactionId,
-                WifiNanSessionListener.FAIL_REASON_OTHER);
+        verify(mNanStateManager).onSessionConfigFailResponse(transactionId, false,
+                WifiNanSessionCallback.REASON_OTHER);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
     public void testNotifyResponseSubscribeCancel() throws JSONException {
         final short transactionId = 23;
-        final int subscribeId = 127;
 
         Bundle args = new Bundle();
-        args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
+        args.putInt("status", WifiNanNative.NAN_STATUS_DE_FAILURE);
         args.putInt("value", 0);
         args.putInt("response_type", WifiNanNative.NAN_RESPONSE_SUBSCRIBE_CANCEL);
 
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verifyZeroInteractions(mNanStateManager);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -459,7 +488,8 @@
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onMessageSendSuccess(transactionId);
+        verify(mNanStateManager).onMessageSendQueuedSuccessResponse(transactionId);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -474,8 +504,130 @@
         WifiNanHalMock.callNotifyResponse(transactionId,
                 HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onMessageSendFail(transactionId,
-                WifiNanSessionListener.FAIL_REASON_OTHER);
+        verify(mNanStateManager).onMessageSendQueuedFailResponse(transactionId,
+                WifiNanSessionCallback.REASON_OTHER);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testNotifyResponseCreateDataPath() throws JSONException {
+        final short transactionId = 48;
+        final int reason  = WifiNanNative.NAN_STATUS_TIMEOUT;
+
+        Bundle args = new Bundle();
+        args.putInt("status", reason);
+        args.putInt("value", 0);
+        args.putInt("response_type", WifiNanNative.NAN_RESPONSE_DP_INTERFACE_CREATE);
+
+        WifiNanHalMock.callNotifyResponse(transactionId,
+                HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onCreateDataPathInterfaceResponse(transactionId, false, reason);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testNotifyResponseDeleteDataPath() throws JSONException {
+        final short transactionId = 49;
+        final int reason  = WifiNanNative.NAN_STATUS_DE_FAILURE;
+
+        Bundle args = new Bundle();
+        args.putInt("status", reason);
+        args.putInt("value", 0);
+        args.putInt("response_type", WifiNanNative.NAN_RESPONSE_DP_INTERFACE_DELETE);
+
+        WifiNanHalMock.callNotifyResponse(transactionId,
+                HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onDeleteDataPathInterfaceResponse(transactionId, false, reason);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testNotifyResponseInitiateDataPathSuccess() throws JSONException {
+        final short transactionId = 49;
+        final int ndpId = 1234;
+
+        Bundle args = new Bundle();
+        args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
+        args.putInt("value", 0);
+        args.putInt("response_type", WifiNanNative.NAN_RESPONSE_DP_INITIATOR_RESPONSE);
+        args.putInt("body.data_request_response.ndp_instance_id", ndpId);
+
+        WifiNanHalMock.callNotifyResponse(transactionId,
+                HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onInitiateDataPathResponseSuccess(transactionId, ndpId);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testNotifyResponseInitiateDataPathFail() throws JSONException {
+        final short transactionId = 49;
+        final int reason  = WifiNanNative.NAN_STATUS_NDP_DATA_INITIATOR_REQUEST_FAILED;
+
+        Bundle args = new Bundle();
+        args.putInt("status", reason);
+        args.putInt("value", 0);
+        args.putInt("response_type", WifiNanNative.NAN_RESPONSE_DP_INITIATOR_RESPONSE);
+        args.putInt("body.data_request_response.ndp_instance_id", 5555); // NOP
+
+        WifiNanHalMock.callNotifyResponse(transactionId,
+                HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onInitiateDataPathResponseFail(transactionId, reason);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testNotifyResponseRespondToDataPathSetupRequest() throws JSONException {
+        final short transactionId = 50;
+        final int reason  = WifiNanNative.NAN_STATUS_DISABLE_IN_PROGRESS;
+
+        Bundle args = new Bundle();
+        args.putInt("status", reason);
+        args.putInt("value", 0);
+        args.putInt("response_type", WifiNanNative.NAN_RESPONSE_DP_RESPONDER_RESPONSE);
+
+        WifiNanHalMock.callNotifyResponse(transactionId,
+                HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onRespondToDataPathSetupRequestResponse(transactionId, false,
+                reason);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testNotifyResponseEndDataPath() throws JSONException {
+        final short transactionId = 50;
+        final int reason  = WifiNanNative.NAN_STATUS_NDP_END_FAILED;
+
+        Bundle args = new Bundle();
+        args.putInt("status", reason);
+        args.putInt("value", 0);
+        args.putInt("response_type", WifiNanNative.NAN_RESPONSE_DP_END);
+
+        WifiNanHalMock.callNotifyResponse(transactionId,
+                HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onEndDataPathResponse(transactionId, false, reason);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testNotifyResponseUnknown() throws JSONException {
+        final int invalidTransactionId = 99999;
+        final short transactionId = 46;
+
+        Bundle args = new Bundle();
+        args.putInt("status", WifiNanNative.NAN_STATUS_SUCCESS);
+        args.putInt("value", 0);
+        args.putInt("response_type", invalidTransactionId);
+
+        WifiNanHalMock.callNotifyResponse(transactionId,
+                HalMockUtils.convertBundleToJson(args).toString());
+
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -488,8 +640,9 @@
 
         WifiNanHalMock.callPublishTerminated(HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onPublishTerminated(publishId,
-                WifiNanSessionListener.TERMINATE_REASON_DONE);
+        verify(mNanStateManager).onSessionTerminatedNotification(publishId,
+                WifiNanSessionCallback.TERMINATE_REASON_DONE, true);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -502,8 +655,9 @@
 
         WifiNanHalMock.callSubscribeTerminated(HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onSubscribeTerminated(subscribeId,
-                WifiNanSessionListener.TERMINATE_REASON_FAIL);
+        verify(mNanStateManager).onSessionTerminatedNotification(subscribeId,
+                WifiNanSessionCallback.TERMINATE_REASON_FAIL, false);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -523,8 +677,9 @@
 
         WifiNanHalMock.callFollowup(HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onMessageReceived(pubSubId, reqInstanceId, peer,
+        verify(mNanStateManager).onMessageReceivedNotification(pubSubId, reqInstanceId, peer,
                 message.getBytes(), message.length());
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -546,8 +701,9 @@
 
         WifiNanHalMock.callMatch(HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onMatch(pubSubId, reqInstanceId, peer, ssi.getBytes(),
+        verify(mNanStateManager).onMatchNotification(pubSubId, reqInstanceId, peer, ssi.getBytes(),
                 ssi.length(), filter.getBytes(), filter.length());
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -560,11 +716,12 @@
 
         WifiNanHalMock.callDiscEngEvent(HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onInterfaceAddressChange(mac);
+        verify(mNanStateManager).onInterfaceAddressChangeNotification(mac);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
-    public void testClusterChange() throws JSONException {
+    public void testClusterJoined() throws JSONException {
         final byte[] mac = HexEncoding.decode("060504030201".toCharArray(), false);
 
         Bundle args = new Bundle();
@@ -573,8 +730,24 @@
 
         WifiNanHalMock.callDiscEngEvent(HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_JOINED,
-                mac);
+        verify(mNanStateManager)
+                .onClusterChangeNotification(WifiNanClientState.CLUSTER_CHANGE_EVENT_JOINED, mac);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testClusterStarted() throws JSONException {
+        final byte[] mac = HexEncoding.decode("0A0B0C0B0A00".toCharArray(), false);
+
+        Bundle args = new Bundle();
+        args.putInt("event_type", WifiNanNative.NAN_EVENT_ID_STARTED_CLUSTER);
+        args.putByteArray("data", mac);
+
+        WifiNanHalMock.callDiscEngEvent(HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager)
+                .onClusterChangeNotification(WifiNanClientState.CLUSTER_CHANGE_EVENT_STARTED, mac);
+        verifyNoMoreInteractions(mNanStateManager);
     }
 
     @Test
@@ -584,7 +757,206 @@
 
         WifiNanHalMock.callDisabled(HalMockUtils.convertBundleToJson(args).toString());
 
-        verify(mNanStateManager).onNanDown(WifiNanSessionListener.FAIL_REASON_OTHER);
+        verify(mNanStateManager).onNanDownNotification(WifiNanEventCallback.REASON_OTHER);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testTransmitFollowupSuccess() throws JSONException {
+        final short transactionId = 123;
+
+        Bundle args = new Bundle();
+        args.putInt("id", transactionId);
+        args.putInt("reason", WifiNanNative.NAN_STATUS_SUCCESS);
+
+        WifiNanHalMock.callTransmitFollowup(HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onMessageSendSuccessNotification(transactionId);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testTransmitFollowupFail() throws JSONException {
+        final short transactionId = 5689;
+
+        Bundle args = new Bundle();
+        args.putInt("id", transactionId);
+        args.putInt("reason", WifiNanNative.NAN_STATUS_TX_FAIL);
+
+        WifiNanHalMock.callTransmitFollowup(HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onMessageSendFailNotification(transactionId,
+                WifiNanSessionCallback.REASON_TX_FAIL);
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testCreateNanNetworkInterface() throws JSONException {
+        final short transactionId = 10;
+        final String interfaceName = "nan0";
+
+        mDut.createNanNetworkInterface(transactionId, interfaceName);
+
+        verify(mNanHalMock).createNanNetworkInterfaceMockNative(eq(transactionId), mArgs.capture());
+
+        Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
+
+        collector.checkThat("iface_name", new String(argsData
+                .getByteArray("iface_name")), equalTo(interfaceName));
+    }
+
+    @Test
+    public void testDeleteNanNetworkInterface() throws JSONException {
+        final short transactionId = 10;
+        final String interfaceName = "nan0";
+
+        mDut.deleteNanNetworkInterface(transactionId, interfaceName);
+
+        verify(mNanHalMock).deleteNanNetworkInterfaceMockNative(eq(transactionId), mArgs.capture());
+
+        Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
+
+        collector.checkThat("iface_name", new String(argsData.getByteArray("iface_name")),
+                equalTo(interfaceName));
+    }
+
+    @Test
+    public void testInitiateDataPath() throws JSONException {
+        final short transactionId = 123;
+        final int pubSubId = 55;
+        final int channelRequestType = 0;
+        final int channel = 2437;
+        final byte[] peer = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
+        final String interfaceName = "nan1";
+        final String msg = "let me talk!";
+
+        mDut.initiateDataPath(transactionId, pubSubId, channelRequestType, channel, peer,
+                interfaceName, msg.getBytes(), msg.length());
+
+        verify(mNanHalMock).initiateDataPathMockNative(eq(transactionId), mArgs.capture());
+
+        Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
+
+        collector.checkThat("service_instance_id", argsData.getInt("service_instance_id"),
+                equalTo(pubSubId));
+        collector.checkThat("channel_request_type", argsData.getInt("channel_request_type"),
+                equalTo(channelRequestType));
+        collector.checkThat("channel", argsData.getInt("channel"), equalTo(channel));
+        collector.checkThat("peer_disc_mac_addr", argsData.getByteArray("peer_disc_mac_addr"),
+                equalTo(peer));
+        collector.checkThat("ndp_iface", new String(argsData.getByteArray("ndp_iface")),
+                equalTo(interfaceName));
+        collector.checkThat("ndp_cfg.security_cfg", argsData.getInt("ndp_cfg.security_cfg"),
+                equalTo(0));
+        collector.checkThat("ndp_cfg.qos_cfg", argsData.getInt("ndp_cfg.qos_cfg"), equalTo(0));
+        collector.checkThat("app_info.ndp_app_info_len",
+                argsData.getInt("app_info.ndp_app_info_len"), equalTo(msg.length()));
+        collector.checkThat("app_info.ndp_app_info", argsData.getByteArray("app_info.ndp_app_info"),
+                equalTo(msg.getBytes()));
+    }
+
+    @Test
+    public void testRespondToDataPathRequest() throws JSONException {
+        final short transactionId = 123;
+        final boolean accept = true;
+        final int ndpId = 523;
+        final String interfaceName = "nan1";
+        final String msg = "fine - you can talk ...";
+
+        mDut.respondToDataPathRequest(transactionId, accept, ndpId, interfaceName, msg
+                .getBytes(), msg.length());
+
+        verify(mNanHalMock).respondToDataPathRequestMockNative(eq(transactionId), mArgs.capture());
+
+        Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
+
+        collector.checkThat("ndp_instance_id", argsData.getInt("ndp_instance_id"), equalTo(ndpId));
+        collector.checkThat("ndp_iface", new String(argsData
+                .getByteArray("ndp_iface")), equalTo(interfaceName));
+        collector.checkThat("ndp_cfg.security_cfg", argsData
+                .getInt("ndp_cfg.security_cfg"), equalTo(0));
+        collector.checkThat("ndp_cfg.qos_cfg", argsData.getInt("ndp_cfg.qos_cfg"), equalTo(0));
+        collector.checkThat("app_info.ndp_app_info_len", argsData
+                .getInt("app_info.ndp_app_info_len"), equalTo(msg.length()));
+        collector.checkThat("app_info.ndp_app_info", argsData
+                .getByteArray("app_info.ndp_app_info"), equalTo(msg.getBytes()));
+        collector.checkThat("rsp_code", argsData.getInt("rsp_code"), equalTo(accept ? 0 : 1));
+    }
+
+    @Test
+    public void testEndDataPath() throws JSONException {
+        final short transactionId = 123;
+        final int ndpId = 523;
+
+        mDut.endDataPath(transactionId, ndpId);
+
+        verify(mNanHalMock).endDataPathMockNative(eq(transactionId), mArgs.capture());
+
+        Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
+
+        collector.checkThat("num_ndp_instances", argsData.getInt("num_ndp_instances"), equalTo(1));
+        collector.checkThat("ndp_instance_id", argsData.getInt("ndp_instance_id"), equalTo(ndpId));
+    }
+
+    @Test
+    public void testOnDataRequest() throws JSONException {
+        final int pubSubId = 1234;
+        final byte[] peer = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
+        final int ndpId = 752;
+        final String msg = "some request or other - doesn't have to be a String!";
+
+        Bundle args = new Bundle();
+        args.putInt("service_instance_id", pubSubId);
+        args.putByteArray("peer_disc_mac_addr", peer);
+        args.putInt("ndp_instance_id", ndpId);
+        args.putInt("ndp_cfg.security_cfg", 0);
+        args.putInt("ndp_cfg.qos_cfg", 0);
+        args.putInt("app_info.ndp_app_info_len", msg.length());
+        args.putByteArray("app_info.ndp_app_info", msg.getBytes());
+
+        WifiNanHalMock.callDataPathRequest(HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onDataPathRequestNotification(pubSubId, peer, ndpId,
+                msg.getBytes(), msg.length());
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testOnDataConfirm() throws JSONException {
+        final int ndpId = 752;
+        final byte[] peer = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false);
+        final String msg = "some request or other - doesn't have to be a String!";
+        final boolean accept = true;
+        final int reason = 13412;
+
+        Bundle args = new Bundle();
+        args.putInt("ndp_instance_id", ndpId);
+        args.putByteArray("peer_ndi_mac_addr", peer);
+        args.putInt("app_info.ndp_app_info_len", msg.length());
+        args.putByteArray("app_info.ndp_app_info", msg.getBytes());
+        args.putInt("rsp_code", accept ? 0 : 1);
+        args.putInt("reason_code", reason);
+
+        WifiNanHalMock.callDataPathConfirm(HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager).onDataPathConfirmNotification(ndpId, peer, accept, reason,
+                msg.getBytes(), msg.length());
+        verifyNoMoreInteractions(mNanStateManager);
+    }
+
+    @Test
+    public void testOnDataEnd() throws JSONException {
+        testOnDataEndMultiples(1, 752);
+    }
+
+    @Test
+    public void testOnDataEndMultiples() throws JSONException {
+        testOnDataEndMultiples(5, 842);
+    }
+
+    @Test
+    public void testOnDataEndZero() throws JSONException {
+        testOnDataEndMultiples(0, 2134);
     }
 
     /*
@@ -597,7 +969,7 @@
                 .setClusterHigh(clusterHigh).setMasterPreference(masterPref)
                 .setSupport5gBand(enable5g).build();
 
-        mDut.enableAndConfigure(transactionId, configRequest);
+        mDut.enableAndConfigure(transactionId, configRequest, true);
 
         verify(mNanHalMock).enableHalMockNative(eq(transactionId), mArgs.capture());
 
@@ -646,19 +1018,63 @@
                 equalTo(0));
     }
 
+    private void testConfig(short transactionId, int masterPref) throws JSONException {
+        ConfigRequest configRequest = new ConfigRequest.Builder().setMasterPreference(masterPref)
+                .build();
+
+        mDut.enableAndConfigure(transactionId, configRequest, false);
+
+        verify(mNanHalMock).configHalMockNative(eq(transactionId), mArgs.capture());
+
+        Bundle argsData = HalMockUtils.convertJsonToBundle(mArgs.getValue());
+
+        collector.checkThat("config_master_pref", argsData.getInt("config_master_pref"),
+                equalTo(1));
+        collector.checkThat("master_pref", argsData.getInt("master_pref"), equalTo(masterPref));
+
+        collector.checkThat("config_sid_beacon", argsData.getInt("config_sid_beacon"), equalTo(0));
+        collector.checkThat("sid_beacon", argsData.getInt("sid_beacon"), equalTo(0));
+        collector.checkThat("config_rssi_proximity", argsData.getInt("config_rssi_proximity"),
+                equalTo(0));
+        collector.checkThat("rssi_proximity", argsData.getInt("rssi_proximity"), equalTo(0));
+        collector.checkThat("config_5g_rssi_close_proximity",
+                argsData.getInt("config_5g_rssi_close_proximity"), equalTo(0));
+        collector.checkThat("rssi_close_proximity_5g_val",
+                argsData.getInt("rssi_close_proximity_5g_val"), equalTo(0));
+        collector.checkThat("config_rssi_window_size", argsData.getInt("config_rssi_window_size"),
+                equalTo(0));
+        collector.checkThat("rssi_window_size_val", argsData.getInt("rssi_window_size_val"),
+                equalTo(0));
+        collector.checkThat("config_cluster_attribute_val",
+                argsData.getInt("config_cluster_attribute_val"), equalTo(0));
+        collector.checkThat("config_scan_params", argsData.getInt("config_scan_params"),
+                equalTo(0));
+        collector.checkThat("config_random_factor_force",
+                argsData.getInt("config_random_factor_force"), equalTo(0));
+        collector.checkThat("random_factor_force_val", argsData.getInt("random_factor_force_val"),
+                equalTo(0));
+        collector.checkThat("config_hop_count_force", argsData.getInt("config_hop_count_force"),
+                equalTo(0));
+        collector.checkThat("hop_count_force_val", argsData.getInt("hop_count_force_val"),
+                equalTo(0));
+        collector.checkThat("config_conn_capability", argsData.getInt("config_conn_capability"),
+                equalTo(0));
+        collector.checkThat("num_config_discovery_attr",
+                argsData.getInt("num_config_discovery_attr"), equalTo(0));
+        collector.checkThat("config_fam", argsData.getInt("config_fam"), equalTo(0));
+    }
+
     private void testPublish(short transactionId, int publishId, int publishType,
             String serviceName, String ssi, TlvBufferUtils.TlvConstructor tlvTx,
-            TlvBufferUtils.TlvConstructor tlvRx, int publishCount, int publishTtl)
-                    throws JSONException {
-        PublishData publishData = new PublishData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(ssi)
-                .setTxFilter(tlvTx.getArray(), tlvTx.getActualLength())
-                .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength()).build();
+            TlvBufferUtils.TlvConstructor tlvRx, int publishCount, int publishTtl,
+            boolean enableTerminateNotification) throws JSONException {
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
+                .setServiceSpecificInfo(ssi).setTxFilter(tlvTx.getArray(), tlvTx.getActualLength())
+                .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength()).setPublishType(publishType)
+                .setPublishCount(publishCount).setTtlSec(publishTtl)
+                .setEnableTerminateNotification(enableTerminateNotification).build();
 
-        PublishSettings publishSettings = new PublishSettings.Builder().setPublishType(publishType)
-                .setPublishCount(publishCount).setTtlSec(publishTtl).build();
-
-        mDut.publish(transactionId, publishId, publishData, publishSettings);
+        mDut.publish(transactionId, publishId, publishConfig);
 
         verify(mNanHalMock).publishHalMockNative(eq(transactionId), mArgs.capture());
 
@@ -668,7 +1084,7 @@
         collector.checkThat("ttl", argsData.getInt("ttl"), equalTo(publishTtl));
         collector.checkThat("publish_type", argsData.getInt("publish_type"), equalTo(publishType));
         collector.checkThat("tx_type", argsData.getInt("tx_type"),
-                equalTo(publishType == PublishSettings.PUBLISH_TYPE_UNSOLICITED ? 0 : 1));
+                equalTo(publishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED ? 0 : 1));
         collector.checkThat("publish_count", argsData.getInt("publish_count"),
                 equalTo(publishCount));
         collector.checkThat("service_name_len", argsData.getInt("service_name_len"),
@@ -692,22 +1108,23 @@
         collector.checkThat("rssi_threshold_flag", argsData.getInt("rssi_threshold_flag"),
                 equalTo(0));
         collector.checkThat("connmap", argsData.getInt("connmap"), equalTo(0));
+        collector.checkThat("recv_indication_cfg", argsData.getInt("recv_indication_cfg"),
+                equalTo(enableTerminateNotification ? 0x0 : 0x1));
     }
 
     private void testSubscribe(short transactionId, int subscribeId, int subscribeType,
             String serviceName, String ssi, TlvBufferUtils.TlvConstructor tlvTx,
-            TlvBufferUtils.TlvConstructor tlvRx, int subscribeCount, int subscribeTtl)
-                    throws JSONException {
-        SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName)
+            TlvBufferUtils.TlvConstructor tlvRx, int subscribeCount, int subscribeTtl,
+            int matchStyle, boolean enableTerminateNotification) throws JSONException {
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
                 .setServiceSpecificInfo(ssi)
                 .setTxFilter(tlvTx.getArray(), tlvTx.getActualLength())
-                .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength()).build();
-
-        SubscribeSettings subscribeSettings = new SubscribeSettings.Builder()
+                .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength())
                 .setSubscribeType(subscribeType).setSubscribeCount(subscribeCount)
-                .setTtlSec(subscribeTtl).build();
+                .setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
+                .setEnableTerminateNotification(enableTerminateNotification).build();
 
-        mDut.subscribe(transactionId, subscribeId, subscribeData, subscribeSettings);
+        mDut.subscribe(transactionId, subscribeId, subscribeConfig);
 
         verify(mNanHalMock).subscribeHalMockNative(eq(transactionId), mArgs.capture());
 
@@ -727,7 +1144,7 @@
         collector.checkThat("ssiRequiredForMatchIndication",
                 argsData.getInt("ssiRequiredForMatchIndication"), equalTo(0));
         collector.checkThat("subscribe_match_indicator",
-                argsData.getInt("subscribe_match_indicator"), equalTo(0));
+                argsData.getInt("subscribe_match_indicator"), equalTo(matchStyle));
         collector.checkThat("subscribe_count", argsData.getInt("subscribe_count"),
                 equalTo(subscribeCount));
         collector.checkThat("service_name_len", argsData.getInt("service_name_len"),
@@ -751,6 +1168,27 @@
         collector.checkThat("connmap", argsData.getInt("connmap"), equalTo(0));
         collector.checkThat("num_intf_addr_present", argsData.getInt("num_intf_addr_present"),
                 equalTo(0));
+        collector.checkThat("recv_indication_cfg", argsData.getInt("recv_indication_cfg"),
+                equalTo(enableTerminateNotification ? 0x0 : 0x1));
+    }
+
+    private void testOnDataEndMultiples(int numInstances, int ndpIdBase) throws JSONException {
+        ArgumentCaptor<Integer> ndpIdsCaptor = ArgumentCaptor.forClass(Integer.class);
+
+        Bundle args = new Bundle();
+        args.putInt("num_ndp_instances", numInstances);
+        args.putInt("ndp_instance_id", ndpIdBase);
+
+        WifiNanHalMock.callDataPathEnd(HalMockUtils.convertBundleToJson(args).toString());
+
+        verify(mNanStateManager, times(numInstances)).onDataPathEndNotification(
+                ndpIdsCaptor.capture());
+        verifyNoMoreInteractions(mNanStateManager);
+
+        for (int i = 0; i < numInstances; ++i) {
+            collector.checkThat("ndp id #" + i, ndpIdsCaptor.getAllValues().get(i),
+                    equalTo(ndpIdBase + i));
+        }
     }
 
     private static void installMockNanStateManager(WifiNanStateManager nanStateManager)
@@ -759,4 +1197,10 @@
         field.setAccessible(true);
         field.set(null, nanStateManager);
     }
+
+    private static void resetWifiNanNative() throws Exception {
+        Field field = WifiNanNative.class.getDeclaredField("sWifiNanNativeSingleton");
+        field.setAccessible(true);
+        field.set(null, null);
+    }
 }
diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanManagerTest.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanManagerTest.java
index bd4d43b..e143fd8 100644
--- a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanManagerTest.java
@@ -18,107 +18,609 @@
 
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
 
+import android.net.wifi.RttManager;
 import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.PublishData;
-import android.net.wifi.nan.PublishSettings;
-import android.net.wifi.nan.SubscribeData;
-import android.net.wifi.nan.SubscribeSettings;
+import android.net.wifi.nan.IWifiNanEventCallback;
+import android.net.wifi.nan.IWifiNanManager;
+import android.net.wifi.nan.IWifiNanSessionCallback;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
+import android.net.wifi.nan.WifiNanEventCallback;
+import android.net.wifi.nan.WifiNanManager;
+import android.net.wifi.nan.WifiNanPublishSession;
+import android.net.wifi.nan.WifiNanSessionCallback;
+import android.net.wifi.nan.WifiNanSubscribeSession;
+import android.os.IBinder;
 import android.os.Parcel;
+import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Base64;
 
+import libcore.util.HexEncoding;
+
+import org.json.JSONObject;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ErrorCollector;
-import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 /**
  * Unit test harness for WifiNanManager class.
  */
 @SmallTest
 public class WifiNanManagerTest {
+    private WifiNanManager mDut;
+    private TestLooper mMockLooper;
+
     @Rule
     public ErrorCollector collector = new ErrorCollector();
 
-    @Rule
-    public ExpectedException thrown = ExpectedException.none();
+    @Mock
+    public WifiNanEventCallback mockCallback;
+
+    @Mock
+    public WifiNanSessionCallback mockSessionCallback;
+
+    @Mock
+    public IWifiNanManager mockNanService;
+
+    @Mock
+    public WifiNanPublishSession mockPublishSession;
+
+    @Mock
+    public WifiNanSubscribeSession mockSubscribeSession;
+
+    @Mock
+    public RttManager.RttListener mockRttListener;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mDut = new WifiNanManager(mockNanService);
+        mMockLooper = new TestLooper();
+    }
+
+    /*
+     * Straight pass-through tests
+     */
+
+    /**
+     * Validate pass-through of enableUsage() API.
+     */
+    @Test
+    public void testEnableUsage() throws Exception {
+        mDut.enableUsage();
+
+        verify(mockNanService).enableUsage();
+    }
+
+    /**
+     * Validate pass-through of disableUsage() API.
+     */
+    @Test
+    public void testDisableUsage() throws Exception {
+        mDut.disableUsage();
+
+        verify(mockNanService).disableUsage();
+    }
+
+    /**
+     * Validate pass-through of isUsageEnabled() API.
+     */
+    @Test
+    public void testIsUsageEnable() throws Exception {
+        mDut.isUsageEnabled();
+
+        verify(mockNanService).isUsageEnabled();
+    }
+
+    /*
+     * WifiNanEventCallbackProxy Tests
+     */
+
+    /**
+     * Validate the successful connect flow: (1) try subscribing (2) connect +
+     * success (3) publish, (4) disconnect (5) try publishing (6) connect again
+     */
+    @Test
+    public void testConnectFlow() throws Exception {
+        final int clientId = 4565;
+
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                any(ConfigRequest.class))).thenReturn(clientId);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService);
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+        ArgumentCaptor<IBinder> binder = ArgumentCaptor.forClass(IBinder.class);
+
+        // (1) try subscribing on an unconnected manager: fails silently
+        mDut.subscribe(new SubscribeConfig.Builder().build(), mockSessionCallback);
+
+        // (2) connect + success
+        mDut.connect(mMockLooper.getLooper(), mockCallback);
+        inOrder.verify(mockNanService).connect(binder.capture(),
+                clientProxyCallback.capture(), (ConfigRequest) isNull());
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (3) publish - should succeed
+        PublishConfig publishConfig = new PublishConfig.Builder().build();
+        mDut.publish(publishConfig, mockSessionCallback);
+        inOrder.verify(mockNanService).publish(eq(clientId), eq(publishConfig),
+                any(IWifiNanSessionCallback.class));
+
+        // (4) disconnect
+        mDut.disconnect();
+        inOrder.verify(mockNanService).disconnect(eq(clientId), eq(binder.getValue()));
+
+        // (5) try publishing again - fails silently
+        mDut.publish(new PublishConfig.Builder().build(), mockSessionCallback);
+
+        // (6) connect
+        mDut.connect(mMockLooper.getLooper(), mockCallback);
+        inOrder.verify(mockNanService).connect(binder.capture(), any(IWifiNanEventCallback.class),
+                (ConfigRequest) isNull());
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService);
+    }
+
+    /**
+     * Validate the failed connect flow: (1) connect + failure, (2) try
+     * publishing (3) connect + success (4) subscribe
+     */
+    @Test
+    public void testConnectFailure() throws Exception {
+        final int clientId = 4565;
+        final int reason = WifiNanEventCallback.REASON_OTHER;
+
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                any(ConfigRequest.class))).thenReturn(clientId);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService);
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+
+        // (1) connect + failure
+        mDut.connect(mMockLooper.getLooper(), mockCallback);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                (ConfigRequest) isNull());
+        clientProxyCallback.getValue().onConnectFail(reason);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectFail(reason);
+
+        // (2) try publishing - silent failure (since already know that no
+        // connection)
+        mDut.publish(new PublishConfig.Builder().build(), mockSessionCallback);
+
+        // (3) connect + success
+        mDut.connect(mMockLooper.getLooper(), mockCallback);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                (ConfigRequest) isNull());
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (4) subscribe: should succeed
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+        mDut.subscribe(subscribeConfig, mockSessionCallback);
+        inOrder.verify(mockNanService).subscribe(eq(clientId), eq(subscribeConfig),
+                any(IWifiNanSessionCallback.class));
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService);
+    }
+
+    /**
+     * Validate that cannot call connect on an existing connection: (1) connect
+     * + success, (2) try connect again
+     */
+    @Test
+    public void testInvalidConnectSequence() throws Exception {
+        final int clientId = 4565;
+
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                any(ConfigRequest.class))).thenReturn(clientId);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService);
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+
+        // (1) connect + success
+        mDut.connect(mMockLooper.getLooper(), mockCallback);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                (ConfigRequest) isNull());
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) connect - forward to service (though will fail silently)
+        mDut.connect(mMockLooper.getLooper(), mockCallback);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                (ConfigRequest) isNull());
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService);
+    }
+
+    /*
+     * WifiNanSessionCallbackProxy Tests
+     */
+
+    /**
+     * Validate the publish flow: (0) connect + success, (1) publish, (2)
+     * success creates session, (3) pass through everything, (4) update publish
+     * through session, (5) terminate locally, (6) try another command -
+     * ignored.
+     */
+    @Test
+    public void testPublishFlow() throws Exception {
+        final int clientId = 4565;
+        final int sessionId = 123;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final PublishConfig publishConfig = new PublishConfig.Builder().build();
+        final int peerId = 873;
+        final String string1 = "hey from here...";
+        final String string2 = "some other arbitrary string...";
+        final int messageId = 2123;
+        final int reason = WifiNanSessionCallback.REASON_OTHER;
+
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                eq(configRequest))).thenReturn(clientId);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession);
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+        ArgumentCaptor<IWifiNanSessionCallback> sessionProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanSessionCallback.class);
+        ArgumentCaptor<WifiNanPublishSession> publishSession = ArgumentCaptor
+                .forClass(WifiNanPublishSession.class);
+
+        // (0) connect + success
+        mDut.connect(mMockLooper.getLooper(), mockCallback, configRequest);
+        inOrder.verify(mockNanService).connect(any(IBinder.class),
+                clientProxyCallback.capture(), eq(configRequest));
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (1) publish
+        mDut.publish(publishConfig, mockSessionCallback);
+        inOrder.verify(mockNanService).publish(eq(clientId), eq(publishConfig),
+                sessionProxyCallback.capture());
+
+        // (2) publish session created
+        sessionProxyCallback.getValue().onSessionStarted(sessionId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
+
+        // (3) ...
+        publishSession.getValue().sendMessage(peerId, string1.getBytes(), string1.length(),
+                messageId);
+        sessionProxyCallback.getValue().onMatch(peerId, string1.getBytes(),
+                string1.length(), string2.getBytes(), string2.length());
+        sessionProxyCallback.getValue().onMessageReceived(peerId, string1.getBytes(),
+                string1.length());
+        sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
+        sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
+        mMockLooper.dispatchAll();
+
+        inOrder.verify(mockNanService).sendMessage(eq(clientId), eq(sessionId), eq(peerId),
+                eq(string1.getBytes()), eq(string1.length()), eq(messageId), eq(0));
+        inOrder.verify(mockSessionCallback).onMatch(eq(peerId), eq(string1.getBytes()),
+                eq(string1.length()), eq(string2.getBytes()), eq(string2.length()));
+        inOrder.verify(mockSessionCallback).onMessageReceived(eq(peerId), eq(string1.getBytes()),
+                eq(string1.length()));
+        inOrder.verify(mockSessionCallback).onMessageSendFail(eq(messageId), eq(reason));
+        inOrder.verify(mockSessionCallback).onMessageSendSuccess(eq(messageId));
+
+        // (4) update publish
+        publishSession.getValue().updatePublish(publishConfig);
+        sessionProxyCallback.getValue().onSessionConfigFail(reason);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockNanService).updatePublish(eq(clientId), eq(sessionId),
+                eq(publishConfig));
+        inOrder.verify(mockSessionCallback).onSessionConfigFail(eq(reason));
+
+        // (5) terminate
+        publishSession.getValue().terminate();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockNanService).terminateSession(clientId, sessionId);
+
+        // (6) try an update (nothing)
+        publishSession.getValue().updatePublish(publishConfig);
+        mMockLooper.dispatchAll();
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession);
+    }
+
+    /**
+     * Validate race condition of session terminate and session action: (1)
+     * connect, (2) publish success + terminate, (3) update.
+     */
+    @Test
+    public void testPublishRemoteTerminate() throws Exception {
+        final int clientId = 4565;
+        final int sessionId = 123;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final PublishConfig publishConfig = new PublishConfig.Builder().build();
+        final int reason = WifiNanSessionCallback.TERMINATE_REASON_DONE;
+
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                eq(configRequest))).thenReturn(clientId);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession);
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+        ArgumentCaptor<IWifiNanSessionCallback> sessionProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanSessionCallback.class);
+        ArgumentCaptor<WifiNanPublishSession> publishSession = ArgumentCaptor
+                .forClass(WifiNanPublishSession.class);
+
+        // (1) connect successfully
+        mDut.connect(mMockLooper.getLooper(), mockCallback, configRequest);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                eq(configRequest));
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) publish: successfully - then terminated
+        mDut.publish(publishConfig, mockSessionCallback);
+        inOrder.verify(mockNanService).publish(eq(clientId), eq(publishConfig),
+                sessionProxyCallback.capture());
+        sessionProxyCallback.getValue().onSessionStarted(sessionId);
+        sessionProxyCallback.getValue().onSessionTerminated(reason);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
+        inOrder.verify(mockSessionCallback).onSessionTerminated(reason);
+
+        // (3) failure when trying to update: NOP
+        publishSession.getValue().updatePublish(publishConfig);
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession);
+    }
+
+    /**
+     * Validate the subscribe flow: (0) connect + success, (1) subscribe, (2)
+     * success creates session, (3) pass through everything, (4) update
+     * subscribe through session, (5) terminate locally, (6) try another command
+     * - ignored.
+     */
+    @Test
+    public void testSubscribeFlow() throws Exception {
+        final int clientId = 4565;
+        final int sessionId = 123;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+        final int peerId = 873;
+        final String string1 = "hey from here...";
+        final String string2 = "some other arbitrary string...";
+        final int messageId = 2123;
+        final int reason = WifiNanSessionCallback.REASON_OTHER;
+
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                eq(configRequest))).thenReturn(clientId);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService,
+                mockSubscribeSession);
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+        ArgumentCaptor<IWifiNanSessionCallback> sessionProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanSessionCallback.class);
+        ArgumentCaptor<WifiNanSubscribeSession> subscribeSession = ArgumentCaptor
+                .forClass(WifiNanSubscribeSession.class);
+
+        // (0) connect + success
+        mDut.connect(mMockLooper.getLooper(), mockCallback, configRequest);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                eq(configRequest));
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (1) subscribe
+        mDut.subscribe(subscribeConfig, mockSessionCallback);
+        inOrder.verify(mockNanService).subscribe(eq(clientId), eq(subscribeConfig),
+                sessionProxyCallback.capture());
+
+        // (2) subscribe session created
+        sessionProxyCallback.getValue().onSessionStarted(sessionId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
+
+        // (3) ...
+        subscribeSession.getValue().sendMessage(peerId, string1.getBytes(), string1.length(),
+                messageId);
+        sessionProxyCallback.getValue().onMatch(peerId, string1.getBytes(), string1.length(),
+                string2.getBytes(), string2.length());
+        sessionProxyCallback.getValue().onMessageReceived(peerId, string1.getBytes(),
+                string1.length());
+        sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
+        sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
+        mMockLooper.dispatchAll();
+
+        inOrder.verify(mockNanService).sendMessage(eq(clientId), eq(sessionId), eq(peerId),
+                eq(string1.getBytes()), eq(string1.length()), eq(messageId), eq(0));
+        inOrder.verify(mockSessionCallback).onMatch(eq(peerId), eq(string1.getBytes()),
+                eq(string1.length()), eq(string2.getBytes()), eq(string2.length()));
+        inOrder.verify(mockSessionCallback).onMessageReceived(eq(peerId), eq(string1.getBytes()),
+                eq(string1.length()));
+        inOrder.verify(mockSessionCallback).onMessageSendFail(eq(messageId), eq(reason));
+        inOrder.verify(mockSessionCallback).onMessageSendSuccess(eq(messageId));
+
+        // (4) update subscribe
+        subscribeSession.getValue().updateSubscribe(subscribeConfig);
+        sessionProxyCallback.getValue().onSessionConfigFail(reason);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockNanService).updateSubscribe(eq(clientId), eq(sessionId),
+                eq(subscribeConfig));
+        inOrder.verify(mockSessionCallback).onSessionConfigFail(eq(reason));
+
+        // (5) terminate
+        subscribeSession.getValue().terminate();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockNanService).terminateSession(clientId, sessionId);
+
+        // (6) try an update (nothing)
+        subscribeSession.getValue().updateSubscribe(subscribeConfig);
+        mMockLooper.dispatchAll();
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService,
+                mockSubscribeSession);
+    }
+
+    /**
+     * Validate race condition of session terminate and session action: (1)
+     * connect, (2) subscribe success + terminate, (3) update.
+     */
+    @Test
+    public void testSubscribeRemoteTerminate() throws Exception {
+        final int clientId = 4565;
+        final int sessionId = 123;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+        final int reason = WifiNanSessionCallback.TERMINATE_REASON_DONE;
+
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                eq(configRequest))).thenReturn(clientId);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService,
+                mockSubscribeSession);
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+        ArgumentCaptor<IWifiNanSessionCallback> sessionProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanSessionCallback.class);
+        ArgumentCaptor<WifiNanSubscribeSession> subscribeSession = ArgumentCaptor
+                .forClass(WifiNanSubscribeSession.class);
+
+        // (1) connect successfully
+        mDut.connect(mMockLooper.getLooper(), mockCallback, configRequest);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                eq(configRequest));
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) subscribe: successfully - then terminated
+        mDut.subscribe(subscribeConfig, mockSessionCallback);
+        inOrder.verify(mockNanService).subscribe(eq(clientId), eq(subscribeConfig),
+                sessionProxyCallback.capture());
+        sessionProxyCallback.getValue().onSessionStarted(sessionId);
+        sessionProxyCallback.getValue().onSessionTerminated(reason);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSubscribeStarted(subscribeSession.capture());
+        inOrder.verify(mockSessionCallback).onSessionTerminated(reason);
+
+        // (3) failure when trying to update: NOP
+        subscribeSession.getValue().updateSubscribe(subscribeConfig);
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService,
+                mockSubscribeSession);
+    }
 
     /*
      * ConfigRequest Tests
      */
 
     @Test
+    public void testConfigRequestBuilderDefaults() {
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+
+        collector.checkThat("mClusterHigh", ConfigRequest.CLUSTER_ID_MAX,
+                equalTo(configRequest.mClusterHigh));
+        collector.checkThat("mClusterLow", ConfigRequest.CLUSTER_ID_MIN,
+                equalTo(configRequest.mClusterLow));
+        collector.checkThat("mMasterPreference", 0,
+                equalTo(configRequest.mMasterPreference));
+        collector.checkThat("mSupport5gBand", false, equalTo(configRequest.mSupport5gBand));
+        collector.checkThat("mEnableIdentityChangeCallback", false,
+                equalTo(configRequest.mEnableIdentityChangeCallback));
+    }
+
+    @Test
     public void testConfigRequestBuilder() {
         final int clusterHigh = 100;
         final int clusterLow = 5;
         final int masterPreference = 55;
         final boolean supportBand5g = true;
+        final boolean enableIdentityChangeCallback = true;
 
         ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
                 .setClusterLow(clusterLow).setMasterPreference(masterPreference)
-                .setSupport5gBand(supportBand5g).build();
+                .setSupport5gBand(supportBand5g)
+                .setEnableIdentityChangeCallback(enableIdentityChangeCallback).build();
 
         collector.checkThat("mClusterHigh", clusterHigh, equalTo(configRequest.mClusterHigh));
         collector.checkThat("mClusterLow", clusterLow, equalTo(configRequest.mClusterLow));
         collector.checkThat("mMasterPreference", masterPreference,
                 equalTo(configRequest.mMasterPreference));
         collector.checkThat("mSupport5gBand", supportBand5g, equalTo(configRequest.mSupport5gBand));
+        collector.checkThat("mEnableIdentityChangeCallback", enableIdentityChangeCallback,
+                equalTo(configRequest.mEnableIdentityChangeCallback));
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testConfigRequestBuilderMasterPrefNegative() {
-        thrown.expect(IllegalArgumentException.class);
         ConfigRequest.Builder builder = new ConfigRequest.Builder();
         builder.setMasterPreference(-1);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testConfigRequestBuilderMasterPrefReserved1() {
-        thrown.expect(IllegalArgumentException.class);
         new ConfigRequest.Builder().setMasterPreference(1);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testConfigRequestBuilderMasterPrefReserved255() {
-        thrown.expect(IllegalArgumentException.class);
         new ConfigRequest.Builder().setMasterPreference(255);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testConfigRequestBuilderMasterPrefTooLarge() {
-        thrown.expect(IllegalArgumentException.class);
         new ConfigRequest.Builder().setMasterPreference(256);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testConfigRequestBuilderClusterLowNegative() {
-        thrown.expect(IllegalArgumentException.class);
         new ConfigRequest.Builder().setClusterLow(-1);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testConfigRequestBuilderClusterHighNegative() {
-        thrown.expect(IllegalArgumentException.class);
         new ConfigRequest.Builder().setClusterHigh(-1);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testConfigRequestBuilderClusterLowAboveMax() {
-        thrown.expect(IllegalArgumentException.class);
         new ConfigRequest.Builder().setClusterLow(ConfigRequest.CLUSTER_ID_MAX + 1);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testConfigRequestBuilderClusterHighAboveMax() {
-        thrown.expect(IllegalArgumentException.class);
         new ConfigRequest.Builder().setClusterHigh(ConfigRequest.CLUSTER_ID_MAX + 1);
     }
 
-    @Test
+    @Test(expected = IllegalArgumentException.class)
     public void testConfigRequestBuilderClusterLowLargerThanHigh() {
-        thrown.expect(IllegalArgumentException.class);
-        ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(100)
-                .setClusterHigh(5).build();
+        new ConfigRequest.Builder().setClusterLow(100).setClusterHigh(5).build();
     }
 
     @Test
@@ -127,10 +629,12 @@
         final int clusterLow = 25;
         final int masterPreference = 177;
         final boolean supportBand5g = true;
+        final boolean enableIdentityChangeCallback = true;
 
         ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
                 .setClusterLow(clusterLow).setMasterPreference(masterPreference)
-                .setSupport5gBand(supportBand5g).build();
+                .setSupport5gBand(supportBand5g)
+                .setEnableIdentityChangeCallback(enableIdentityChangeCallback).build();
 
         Parcel parcelW = Parcel.obtain();
         configRequest.writeToParcel(parcelW, 0);
@@ -146,237 +650,430 @@
     }
 
     /*
-     * SubscribeData Tests
+     * SubscribeConfig Tests
      */
 
     @Test
-    public void testSubscribeDataBuilder() {
+    public void testSubscribeConfigBuilderDefaults() {
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        collector.checkThat("mServiceName", subscribeConfig.mServiceName, equalTo(null));
+        collector.checkThat("mServiceSpecificInfoLength",
+                subscribeConfig.mServiceSpecificInfoLength, equalTo(0));
+        collector.checkThat("mTxFilterLength", subscribeConfig.mTxFilterLength, equalTo(0));
+        collector.checkThat("mRxFilterLength", subscribeConfig.mRxFilterLength, equalTo(0));
+        collector.checkThat("mSubscribeType", subscribeConfig.mSubscribeType,
+                equalTo(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE));
+        collector.checkThat("mSubscribeCount", subscribeConfig.mSubscribeCount, equalTo(0));
+        collector.checkThat("mTtlSec", subscribeConfig.mTtlSec, equalTo(0));
+        collector.checkThat("mMatchStyle", subscribeConfig.mMatchStyle,
+                equalTo(SubscribeConfig.MATCH_STYLE_ALL));
+        collector.checkThat("mEnableTerminateNotification",
+                subscribeConfig.mEnableTerminateNotification, equalTo(true));
+    }
+
+    @Test
+    public void testSubscribeConfigBuilder() {
         final String serviceName = "some_service_or_other";
         final String serviceSpecificInfo = "long arbitrary string with some info";
         final byte[] txFilter = {
                 0, 1, 16, 1, 22 };
         final byte[] rxFilter = {
                 1, 127, 0, 1, -5, 1, 22 };
-
-        SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length)
-                .setRxFilter(rxFilter, rxFilter.length).build();
-
-        collector.checkThat("mServiceName", serviceName, equalTo(subscribeData.mServiceName));
-        String mServiceSpecificInfo = new String(subscribeData.mServiceSpecificInfo, 0,
-                subscribeData.mServiceSpecificInfoLength);
-        collector.checkThat("mServiceSpecificInfo",
-                utilAreArraysEqual(serviceSpecificInfo.getBytes(), serviceSpecificInfo.length(),
-                        subscribeData.mServiceSpecificInfo,
-                        subscribeData.mServiceSpecificInfoLength),
-                equalTo(true));
-        collector.checkThat("mTxFilter", utilAreArraysEqual(txFilter, txFilter.length,
-                subscribeData.mTxFilter, subscribeData.mTxFilterLength), equalTo(true));
-        collector.checkThat("mRxFilter", utilAreArraysEqual(rxFilter, rxFilter.length,
-                subscribeData.mRxFilter, subscribeData.mRxFilterLength), equalTo(true));
-    }
-
-    @Test
-    public void testSubscribeDataParcel() {
-        final String serviceName = "some_service_or_other";
-        final String serviceSpecificInfo = "long arbitrary string with some info";
-        final byte[] txFilter = {
-                0, 1, 16, 1, 22 };
-        final byte[] rxFilter = {
-                1, 127, 0, 1, -5, 1, 22 };
-
-        SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length)
-                .setTxFilter(rxFilter, rxFilter.length).build();
-
-        Parcel parcelW = Parcel.obtain();
-        subscribeData.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
-
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        SubscribeData rereadSubscribeData = SubscribeData.CREATOR.createFromParcel(parcelR);
-
-        assertEquals(subscribeData, rereadSubscribeData);
-    }
-
-    /*
-     * SubscribeSettings Tests
-     */
-
-    @Test
-    public void testSubscribeSettingsBuilder() {
-        final int subscribeType = SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE;
+        final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
         final int subscribeCount = 10;
         final int subscribeTtl = 15;
+        final int matchStyle = SubscribeConfig.MATCH_STYLE_FIRST_ONLY;
+        final boolean enableTerminateNotification = false;
 
-        SubscribeSettings subscribeSetting = new SubscribeSettings.Builder()
-                .setSubscribeType(subscribeType).setSubscribeCount(subscribeCount)
-                .setTtlSec(subscribeTtl).build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
+                .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length)
+                .setRxFilter(rxFilter, rxFilter.length).setSubscribeType(subscribeType)
+                .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
+                .setEnableTerminateNotification(enableTerminateNotification).build();
 
+        collector.checkThat("mServiceName", serviceName.getBytes(),
+                equalTo(subscribeConfig.mServiceName));
+        collector.checkThat("mServiceSpecificInfo",
+                utilAreArraysEqual(serviceSpecificInfo.getBytes(), serviceSpecificInfo.length(),
+                        subscribeConfig.mServiceSpecificInfo,
+                        subscribeConfig.mServiceSpecificInfoLength),
+                equalTo(true));
+        collector.checkThat("mTxFilter", utilAreArraysEqual(txFilter, txFilter.length,
+                subscribeConfig.mTxFilter, subscribeConfig.mTxFilterLength), equalTo(true));
+        collector.checkThat("mRxFilter", utilAreArraysEqual(rxFilter, rxFilter.length,
+                subscribeConfig.mRxFilter, subscribeConfig.mRxFilterLength), equalTo(true));
         collector.checkThat("mSubscribeType", subscribeType,
-                equalTo(subscribeSetting.mSubscribeType));
+                equalTo(subscribeConfig.mSubscribeType));
         collector.checkThat("mSubscribeCount", subscribeCount,
-                equalTo(subscribeSetting.mSubscribeCount));
-        collector.checkThat("mTtlSec", subscribeTtl, equalTo(subscribeSetting.mTtlSec));
+                equalTo(subscribeConfig.mSubscribeCount));
+        collector.checkThat("mTtlSec", subscribeTtl, equalTo(subscribeConfig.mTtlSec));
+        collector.checkThat("mMatchStyle", matchStyle, equalTo(subscribeConfig.mMatchStyle));
+        collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
+                equalTo(subscribeConfig.mEnableTerminateNotification));
     }
 
     @Test
-    public void testSubscribeSettingsBuilderBadSubscribeType() {
-        thrown.expect(IllegalArgumentException.class);
-        new SubscribeSettings.Builder().setSubscribeType(10);
-    }
-
-    @Test
-    public void testSubscribeSettingsBuilderNegativeCount() {
-        thrown.expect(IllegalArgumentException.class);
-        new SubscribeSettings.Builder().setSubscribeCount(-1);
-    }
-
-    @Test
-    public void testSubscribeSettingsBuilderNegativeTtl() {
-        thrown.expect(IllegalArgumentException.class);
-        new SubscribeSettings.Builder().setTtlSec(-100);
-    }
-
-    @Test
-    public void testSubscribeSettingsParcel() {
-        final int subscribeType = SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE;
+    public void testSubscribeConfigParcel() {
+        final String serviceName = "some_service_or_other";
+        final String serviceSpecificInfo = "long arbitrary string with some info";
+        final byte[] txFilter = {
+                0, 1, 16, 1, 22 };
+        final byte[] rxFilter = {
+                1, 127, 0, 1, -5, 1, 22 };
+        final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
         final int subscribeCount = 10;
         final int subscribeTtl = 15;
+        final int matchStyle = SubscribeConfig.MATCH_STYLE_FIRST_ONLY;
+        final boolean enableTerminateNotification = true;
 
-        SubscribeSettings subscribeSetting = new SubscribeSettings.Builder()
-                .setSubscribeType(subscribeType).setSubscribeCount(subscribeCount)
-                .setTtlSec(subscribeTtl).build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
+                .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length)
+                .setTxFilter(rxFilter, rxFilter.length).setSubscribeType(subscribeType)
+                .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
+                .setEnableTerminateNotification(enableTerminateNotification).build();
 
         Parcel parcelW = Parcel.obtain();
-        subscribeSetting.writeToParcel(parcelW, 0);
+        subscribeConfig.writeToParcel(parcelW, 0);
         byte[] bytes = parcelW.marshall();
         parcelW.recycle();
 
         Parcel parcelR = Parcel.obtain();
         parcelR.unmarshall(bytes, 0, bytes.length);
         parcelR.setDataPosition(0);
-        SubscribeSettings rereadSubscribeSettings = SubscribeSettings.CREATOR
-                .createFromParcel(parcelR);
+        SubscribeConfig rereadSubscribeConfig = SubscribeConfig.CREATOR.createFromParcel(parcelR);
 
-        assertEquals(subscribeSetting, rereadSubscribeSettings);
+        assertEquals(subscribeConfig, rereadSubscribeConfig);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSubscribeConfigBuilderBadSubscribeType() {
+        new SubscribeConfig.Builder().setSubscribeType(10);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSubscribeConfigBuilderNegativeCount() {
+        new SubscribeConfig.Builder().setSubscribeCount(-1);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testSubscribeConfigBuilderNegativeTtl() {
+        new SubscribeConfig.Builder().setTtlSec(-100);
+    }
+
+    /**
+     * Validate that a bad match style configuration throws an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testSubscribeConfigBuilderBadMatchStyle() {
+        new SubscribeConfig.Builder().setMatchStyle(10);
     }
 
     /*
-     * PublishData Tests
+     * PublishConfig Tests
      */
 
     @Test
-    public void testPublishDataBuilder() {
+    public void testPublishConfigBuilderDefaults() {
+        PublishConfig publishConfig = new PublishConfig.Builder().build();
+
+        collector.checkThat("mServiceName", publishConfig.mServiceName, equalTo(null));
+        collector.checkThat("mServiceSpecificInfoLength", publishConfig.mServiceSpecificInfoLength,
+                equalTo(0));
+        collector.checkThat("mTxFilterLength", publishConfig.mTxFilterLength, equalTo(0));
+        collector.checkThat("mRxFilterLength", publishConfig.mRxFilterLength, equalTo(0));
+        collector.checkThat("mPublishType", publishConfig.mPublishType,
+                equalTo(PublishConfig.PUBLISH_TYPE_UNSOLICITED));
+        collector.checkThat("mPublishCount", publishConfig.mPublishCount, equalTo(0));
+        collector.checkThat("mTtlSec", publishConfig.mTtlSec, equalTo(0));
+        collector.checkThat("mEnableTerminateNotification",
+                publishConfig.mEnableTerminateNotification, equalTo(true));
+    }
+
+    @Test
+    public void testPublishConfigBuilder() {
         final String serviceName = "some_service_or_other";
         final String serviceSpecificInfo = "long arbitrary string with some info";
         final byte[] txFilter = {
                 0, 1, 16, 1, 22 };
         final byte[] rxFilter = {
                 1, 127, 0, 1, -5, 1, 22 };
+        final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
+        final int publishCount = 10;
+        final int publishTtl = 15;
+        final boolean enableTerminateNotification = false;
 
-        PublishData publishData = new PublishData.Builder().setServiceName(serviceName)
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
                 .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length)
-                .setRxFilter(rxFilter, rxFilter.length).build();
+                .setRxFilter(rxFilter, rxFilter.length).setPublishType(publishType)
+                .setPublishCount(publishCount).setTtlSec(publishTtl)
+                .setEnableTerminateNotification(enableTerminateNotification).build();
 
-        collector.checkThat("mServiceName", serviceName, equalTo(publishData.mServiceName));
-        String mServiceSpecificInfo = new String(publishData.mServiceSpecificInfo, 0,
-                publishData.mServiceSpecificInfoLength);
+        collector.checkThat("mServiceName", serviceName.getBytes(),
+                equalTo(publishConfig.mServiceName));
         collector.checkThat("mServiceSpecificInfo",
                 utilAreArraysEqual(serviceSpecificInfo.getBytes(), serviceSpecificInfo.length(),
-                        publishData.mServiceSpecificInfo, publishData.mServiceSpecificInfoLength),
+                        publishConfig.mServiceSpecificInfo,
+                        publishConfig.mServiceSpecificInfoLength),
                 equalTo(true));
         collector.checkThat("mTxFilter", utilAreArraysEqual(txFilter, txFilter.length,
-                publishData.mTxFilter, publishData.mTxFilterLength), equalTo(true));
+                publishConfig.mTxFilter, publishConfig.mTxFilterLength), equalTo(true));
         collector.checkThat("mRxFilter", utilAreArraysEqual(rxFilter, rxFilter.length,
-                publishData.mRxFilter, publishData.mRxFilterLength), equalTo(true));
+                publishConfig.mRxFilter, publishConfig.mRxFilterLength), equalTo(true));
+        collector.checkThat("mPublishType", publishType, equalTo(publishConfig.mPublishType));
+        collector.checkThat("mPublishCount", publishCount, equalTo(publishConfig.mPublishCount));
+        collector.checkThat("mTtlSec", publishTtl, equalTo(publishConfig.mTtlSec));
+        collector.checkThat("mEnableTerminateNotification", enableTerminateNotification,
+                equalTo(publishConfig.mEnableTerminateNotification));
     }
 
     @Test
-    public void testPublishDataParcel() {
+    public void testPublishConfigParcel() {
         final String serviceName = "some_service_or_other";
         final String serviceSpecificInfo = "long arbitrary string with some info";
         final byte[] txFilter = {
                 0, 1, 16, 1, 22 };
         final byte[] rxFilter = {
                 1, 127, 0, 1, -5, 1, 22 };
+        final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
+        final int publishCount = 10;
+        final int publishTtl = 15;
+        final boolean enableTerminateNotification = false;
 
-        PublishData publishData = new PublishData.Builder().setServiceName(serviceName)
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
                 .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length)
-                .setTxFilter(rxFilter, rxFilter.length).build();
+                .setTxFilter(rxFilter, rxFilter.length).setPublishType(publishType)
+                .setPublishCount(publishCount).setTtlSec(publishTtl)
+                .setEnableTerminateNotification(enableTerminateNotification).build();
 
         Parcel parcelW = Parcel.obtain();
-        publishData.writeToParcel(parcelW, 0);
+        publishConfig.writeToParcel(parcelW, 0);
         byte[] bytes = parcelW.marshall();
         parcelW.recycle();
 
         Parcel parcelR = Parcel.obtain();
         parcelR.unmarshall(bytes, 0, bytes.length);
         parcelR.setDataPosition(0);
-        PublishData rereadPublishData = PublishData.CREATOR.createFromParcel(parcelR);
+        PublishConfig rereadPublishConfig = PublishConfig.CREATOR.createFromParcel(parcelR);
 
-        assertEquals(publishData, rereadPublishData);
+        assertEquals(publishConfig, rereadPublishConfig);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testPublishConfigBuilderBadPublishType() {
+        new PublishConfig.Builder().setPublishType(5);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testPublishConfigBuilderNegativeCount() {
+        new PublishConfig.Builder().setPublishCount(-4);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testPublishConfigBuilderNegativeTtl() {
+        new PublishConfig.Builder().setTtlSec(-10);
     }
 
     /*
-     * PublishSettings Tests
+     * Ranging tests
      */
 
+    /**
+     * Validate ranging + success flow: (1) connect, (2) create a (publish) session, (3) start
+     * ranging, (4) ranging success callback, (5) ranging aborted callback ignored (since
+     * listener removed).
+     */
     @Test
-    public void testPublishSettingsBuilder() {
-        final int publishType = PublishSettings.PUBLISH_TYPE_SOLICITED;
-        final int publishCount = 10;
-        final int publishTtl = 15;
+    public void testRangingCallbacks() throws Exception {
+        final int clientId = 4565;
+        final int sessionId = 123;
+        final int rangingId = 3482;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final PublishConfig publishConfig = new PublishConfig.Builder().build();
+        final RttManager.RttParams rttParams = new RttManager.RttParams();
+        rttParams.deviceType = RttManager.RTT_PEER_NAN;
+        rttParams.bssid = Integer.toString(1234);
+        final RttManager.RttResult rttResults = new RttManager.RttResult();
+        rttResults.distance = 10;
 
-        PublishSettings publishSetting = new PublishSettings.Builder().setPublishType(publishType)
-                .setPublishCount(publishCount).setTtlSec(publishTtl).build();
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                eq(configRequest))).thenReturn(clientId);
+        when(mockNanService.startRanging(anyInt(), anyInt(),
+                any(RttManager.ParcelableRttParams.class))).thenReturn(rangingId);
 
-        collector.checkThat("mPublishType", publishType, equalTo(publishSetting.mPublishType));
-        collector.checkThat("mPublishCount", publishCount, equalTo(publishSetting.mPublishCount));
-        collector.checkThat("mTtlSec", publishTtl, equalTo(publishSetting.mTtlSec));
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession, mockRttListener);
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+        ArgumentCaptor<IWifiNanSessionCallback> sessionProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanSessionCallback.class);
+        ArgumentCaptor<WifiNanPublishSession> publishSession = ArgumentCaptor
+                .forClass(WifiNanPublishSession.class);
+        ArgumentCaptor<RttManager.ParcelableRttParams> rttParamCaptor = ArgumentCaptor
+                .forClass(RttManager.ParcelableRttParams.class);
+        ArgumentCaptor<RttManager.RttResult[]> rttResultsCaptor = ArgumentCaptor
+                .forClass(RttManager.RttResult[].class);
+
+        // (1) connect successfully
+        mDut.connect(mMockLooper.getLooper(), mockCallback, configRequest);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                eq(configRequest));
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) publish successfully
+        mDut.publish(publishConfig, mockSessionCallback);
+        inOrder.verify(mockNanService).publish(eq(clientId), eq(publishConfig),
+                sessionProxyCallback.capture());
+        sessionProxyCallback.getValue().onSessionStarted(sessionId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
+
+        // (3) start ranging
+        publishSession.getValue().startRanging(new RttManager.RttParams[]{rttParams},
+                mockRttListener);
+        inOrder.verify(mockNanService).startRanging(eq(clientId), eq(sessionId),
+                rttParamCaptor.capture());
+        collector.checkThat("RttParams.deviceType", rttParams.deviceType,
+                equalTo(rttParamCaptor.getValue().mParams[0].deviceType));
+        collector.checkThat("RttParams.bssid", rttParams.bssid,
+                equalTo(rttParamCaptor.getValue().mParams[0].bssid));
+
+        // (4) ranging success callback
+        clientProxyCallback.getValue().onRangingSuccess(rangingId,
+                new RttManager.ParcelableRttResults(new RttManager.RttResult[] { rttResults }));
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockRttListener).onSuccess(rttResultsCaptor.capture());
+        collector.checkThat("RttResult.distance", rttResults.distance,
+                equalTo(rttResultsCaptor.getValue()[0].distance));
+
+        // (5) ranging aborted callback (should be ignored since listener cleared on first callback)
+        clientProxyCallback.getValue().onRangingAborted(rangingId);
+        mMockLooper.dispatchAll();
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession, mockRttListener);
     }
 
+    /*
+     * Data-path tests
+     */
+
+    /**
+     * Validate that correct network specifier is generated for client-based data-path.
+     */
     @Test
-    public void testPublishSettingsBuilderBadPublishType() {
-        thrown.expect(IllegalArgumentException.class);
-        new PublishSettings.Builder().setPublishType(5);
+    public void testNetworkSpecifierWithClient() throws Exception {
+        final int clientId = 4565;
+        final int sessionId = 123;
+        final int peerId = 123412;
+        final int role = WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR;
+        final String token = "Some arbitrary token string - can really be anything";
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final PublishConfig publishConfig = new PublishConfig.Builder().build();
+
+        String tokenB64 = Base64.encodeToString(token.getBytes(), Base64.DEFAULT);
+
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
+        ArgumentCaptor<IWifiNanSessionCallback> sessionProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanSessionCallback.class);
+        ArgumentCaptor<WifiNanPublishSession> publishSession = ArgumentCaptor
+                .forClass(WifiNanPublishSession.class);
+
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                any(ConfigRequest.class))).thenReturn(clientId);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession, mockRttListener);
+
+        // (1) connect successfully
+        mDut.connect(mMockLooper.getLooper(), mockCallback, configRequest);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                eq(configRequest));
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) publish successfully
+        mDut.publish(publishConfig, mockSessionCallback);
+        inOrder.verify(mockNanService).publish(eq(clientId), eq(publishConfig),
+                sessionProxyCallback.capture());
+        sessionProxyCallback.getValue().onSessionStarted(sessionId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
+
+        // (3) request a network specifier from the session
+        String networkSpecifier = publishSession.getValue().createNetworkSpecifier(role, peerId,
+                token.getBytes(), token.length());
+
+        // validate format
+        JSONObject jsonObject = new JSONObject(networkSpecifier);
+        collector.checkThat("role", role,
+                equalTo(jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_ROLE)));
+        collector.checkThat("client_id", clientId,
+                equalTo(jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
+        collector.checkThat("session_id", sessionId,
+                equalTo(jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
+        collector.checkThat("peer_id", peerId,
+                equalTo(jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
+        collector.checkThat("token", tokenB64,
+                equalTo(jsonObject.getString(WifiNanManager.NETWORK_SPECIFIER_KEY_TOKEN)));
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession, mockRttListener);
     }
 
+    /**
+     * Validate that correct network specifier is generated for a direct data-path (i.e.
+     * specifying MAC address as opposed to a client-based oqaque specification).
+     */
     @Test
-    public void testPublishSettingsBuilderNegativeCount() {
-        thrown.expect(IllegalArgumentException.class);
-        new PublishSettings.Builder().setPublishCount(-4);
-    }
+    public void testNetworkSpecifierDirect() throws Exception {
+        final int clientId = 134;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
+        final int role = WifiNanManager.WIFI_NAN_DATA_PATH_ROLE_INITIATOR;
+        final String token = "Some arbitrary token string - can really be anything";
 
-    @Test
-    public void testPublishSettingsBuilderNegativeTtl() {
-        thrown.expect(IllegalArgumentException.class);
-        new PublishSettings.Builder().setTtlSec(-10);
-    }
+        String tokenB64 = Base64.encodeToString(token.getBytes(), Base64.DEFAULT);
 
-    @Test
-    public void testPublishSettingsParcel() {
-        final int publishType = PublishSettings.PUBLISH_TYPE_SOLICITED;
-        final int publishCount = 10;
-        final int publishTtl = 15;
+        ArgumentCaptor<IWifiNanEventCallback> clientProxyCallback = ArgumentCaptor
+                .forClass(IWifiNanEventCallback.class);
 
-        PublishSettings configSetting = new PublishSettings.Builder().setPublishType(publishType)
-                .setPublishCount(publishCount).setTtlSec(publishTtl).build();
+        when(mockNanService.connect(any(IBinder.class), any(IWifiNanEventCallback.class),
+                any(ConfigRequest.class))).thenReturn(clientId);
 
-        Parcel parcelW = Parcel.obtain();
-        configSetting.writeToParcel(parcelW, 0);
-        byte[] bytes = parcelW.marshall();
-        parcelW.recycle();
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession, mockRttListener);
 
-        Parcel parcelR = Parcel.obtain();
-        parcelR.unmarshall(bytes, 0, bytes.length);
-        parcelR.setDataPosition(0);
-        PublishSettings rereadPublishSettings = PublishSettings.CREATOR.createFromParcel(parcelR);
+        // (1) connect successfully
+        mDut.connect(mMockLooper.getLooper(), mockCallback, configRequest);
+        inOrder.verify(mockNanService).connect(any(IBinder.class), clientProxyCallback.capture(),
+                eq(configRequest));
+        clientProxyCallback.getValue().onConnectSuccess();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        assertEquals(configSetting, rereadPublishSettings);
+        /* (2) request a direct network specifier*/
+        String networkSpecifier = mDut.createNetworkSpecifier(role, someMac, token.getBytes(),
+                token.length());
+
+        /* validate format*/
+        JSONObject jsonObject = new JSONObject(networkSpecifier);
+        collector.checkThat("role", role,
+                equalTo(jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_ROLE)));
+        collector.checkThat("client_id", clientId,
+                equalTo(jsonObject.getInt(WifiNanManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
+        collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
+                jsonObject.getString(WifiNanManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
+                false)));
+        collector.checkThat("token", tokenB64,
+                equalTo(jsonObject.getString(WifiNanManager.NETWORK_SPECIFIER_KEY_TOKEN)));
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockNanService,
+                mockPublishSession, mockRttListener);
     }
 
     /*
diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanRttStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanRttStateManagerTest.java
new file mode 100644
index 0000000..35a600a
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanRttStateManagerTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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 com.android.server.wifi.nan;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsNull.nullValue;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.wifi.IRttManager;
+import android.net.wifi.RttManager;
+import android.os.Handler;
+import android.os.Message;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.internal.util.test.BidirectionalAsyncChannelServer;
+import android.os.test.TestLooper;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ErrorCollector;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit test harness for WifiNanManager class.
+ */
+@SmallTest
+public class WifiNanRttStateManagerTest {
+    private WifiNanRttStateManager mDut;
+    private TestLooper mTestLooper;
+
+    @Mock
+    private Context mMockContext;
+
+    @Mock
+    private Handler mMockHandler;
+
+    @Mock
+    private IRttManager mMockRttService;
+
+    @Rule
+    public ErrorCollector collector = new ErrorCollector();
+
+    /**
+     * Initialize mocks.
+     */
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        mDut = new WifiNanRttStateManager();
+        mTestLooper = new TestLooper();
+        BidirectionalAsyncChannelServer server = new BidirectionalAsyncChannelServer(
+                mMockContext, mTestLooper.getLooper(), mMockHandler);
+        when(mMockRttService.getMessenger()).thenReturn(server.getMessenger());
+
+        mDut.startWithRttService(mMockContext, mTestLooper.getLooper(), mMockRttService);
+    }
+
+    /**
+     * Validates that startRanging flow works: (1) start ranging, (2) get success callback - pass
+     * to client (while nulling BSSID info), (3) get fail callback - ignored (since client
+     * cleaned-out after first callback).
+     */
+    @Test
+    public void testStartRanging() throws Exception {
+        final int rangingId = 1234;
+        WifiNanClientState mockClient = mock(WifiNanClientState.class);
+        RttManager.RttParams[] params = new RttManager.RttParams[1];
+        params[0] = new RttManager.RttParams();
+        RttManager.ParcelableRttResults results =
+                new RttManager.ParcelableRttResults(new RttManager.RttResult[2]);
+        results.mResults[0] = new RttManager.RttResult();
+        results.mResults[0].bssid = "something non-null";
+        results.mResults[1] = new RttManager.RttResult();
+        results.mResults[1].bssid = "really really non-null";
+
+        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+        ArgumentCaptor<RttManager.ParcelableRttResults> rttResultsCaptor =
+                ArgumentCaptor.forClass(RttManager.ParcelableRttResults.class);
+
+        InOrder inOrder = inOrder(mMockHandler, mockClient);
+
+        // (1) start ranging
+        mDut.startRanging(rangingId, mockClient, params);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mMockHandler).handleMessage(messageCaptor.capture());
+        Message msg = messageCaptor.getValue();
+        collector.checkThat("msg.what=RttManager.CMD_OP_START_RANGING", msg.what,
+                equalTo(RttManager.CMD_OP_START_RANGING));
+        collector.checkThat("rangingId", msg.arg2, equalTo(rangingId));
+        collector.checkThat("RTT params", ((RttManager.ParcelableRttParams) msg.obj).mParams,
+                equalTo(params));
+
+        // (2) get success callback - pass to client
+        Message successMessage = Message.obtain();
+        successMessage.what = RttManager.CMD_OP_SUCCEEDED;
+        successMessage.arg2 = rangingId;
+        successMessage.obj = results;
+        msg.replyTo.send(successMessage);
+        mTestLooper.dispatchAll();
+        inOrder.verify(mockClient).onRangingSuccess(eq(rangingId), rttResultsCaptor.capture());
+        collector.checkThat("ParcelableRttResults object", results,
+                equalTo(rttResultsCaptor.getValue()));
+        collector.checkThat("RttResults[0].bssid null",
+                rttResultsCaptor.getValue().mResults[0].bssid, nullValue());
+        collector.checkThat("RttResults[1].bssid null",
+                rttResultsCaptor.getValue().mResults[1].bssid, nullValue());
+
+        // (3) get fail callback - ignored
+        Message failMessage = Message.obtain();
+        failMessage.what = RttManager.CMD_OP_ABORTED;
+        failMessage.arg2 = rangingId;
+        msg.replyTo.send(failMessage);
+        mTestLooper.dispatchAll();
+
+        verifyNoMoreInteractions(mMockHandler, mockClient);
+    }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanServiceImplTest.java
new file mode 100644
index 0000000..3fb2abb
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanServiceImplTest.java
@@ -0,0 +1,518 @@
+/*
+ * 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 com.android.server.wifi.nan;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.wifi.RttManager;
+import android.net.wifi.nan.ConfigRequest;
+import android.net.wifi.nan.IWifiNanEventCallback;
+import android.net.wifi.nan.IWifiNanSessionCallback;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
+import android.os.IBinder;
+import android.os.Looper;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.lang.reflect.Field;
+
+/**
+ * Unit test harness for WifiNanStateManager.
+ */
+@SmallTest
+public class WifiNanServiceImplTest {
+    private WifiNanServiceImplSpy mDut;
+    private int mDefaultUid = 1500;
+
+    @Mock
+    private Context mContextMock;
+    @Mock
+    private PackageManager mPackageManagerMock;
+    @Mock
+    private WifiNanStateManager mNanStateManagerMock;
+    @Mock
+    private IBinder mBinderMock;
+    @Mock
+    private IWifiNanEventCallback mCallbackMock;
+    @Mock
+    private IWifiNanSessionCallback mSessionCallbackMock;
+
+    /**
+     * Using instead of spy to avoid native crash failures - possibly due to
+     * spy's copying of state.
+     */
+    private class WifiNanServiceImplSpy extends WifiNanServiceImpl {
+        public int fakeUid;
+
+        WifiNanServiceImplSpy(Context context) {
+            super(context);
+        }
+
+        /**
+         * Return the fake UID instead of the real one: pseudo-spy
+         * implementation.
+         */
+        @Override
+        public int getMockableCallingUid() {
+            return fakeUid;
+        }
+    }
+
+    /**
+     * Initializes mocks.
+     */
+    @Before
+    public void setup() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        when(mContextMock.getApplicationContext()).thenReturn(mContextMock);
+        when(mContextMock.getPackageManager()).thenReturn(mPackageManagerMock);
+        when(mPackageManagerMock.hasSystemFeature(PackageManager.FEATURE_WIFI_NAN))
+                .thenReturn(true);
+
+        installMockNanStateManager();
+
+        mDut = new WifiNanServiceImplSpy(mContextMock);
+        mDut.fakeUid = mDefaultUid;
+    }
+
+    /**
+     * Validate start() function: passes a valid looper.
+     */
+    @Test
+    public void testStart() {
+        mDut.start();
+
+        verify(mNanStateManagerMock).start(eq(mContextMock), any(Looper.class));
+    }
+
+    /**
+     * Validate enableUsage() function
+     */
+    @Test
+    public void testEnableUsage() {
+        mDut.enableUsage();
+
+        verify(mNanStateManagerMock).enableUsage();
+    }
+
+    /**
+     * Validate disableUsage() function
+     */
+    @Test
+    public void testDisableUsage() throws Exception {
+        mDut.enableUsage();
+        doConnect();
+        mDut.disableUsage();
+
+        verify(mNanStateManagerMock).disableUsage();
+    }
+
+    /**
+     * Validate isUsageEnabled() function
+     */
+    @Test
+    public void testIsUsageEnabled() {
+        mDut.isUsageEnabled();
+
+        verify(mNanStateManagerMock).isUsageEnabled();
+    }
+
+
+    /**
+     * Validate connect() - returns and uses a client ID.
+     */
+    @Test
+    public void testConnect() {
+        doConnect();
+    }
+
+    /**
+     * Validate connect() when a non-null config is passed.
+     */
+    @Test
+    public void testConnectWithConfig() {
+        ConfigRequest configRequest = new ConfigRequest.Builder().setMasterPreference(55).build();
+
+        int returnedClientId = mDut.connect(mBinderMock, mCallbackMock, configRequest);
+
+        ArgumentCaptor<Integer> clientId = ArgumentCaptor.forClass(Integer.class);
+        verify(mNanStateManagerMock).connect(clientId.capture(), anyInt(), eq(mCallbackMock),
+                eq(configRequest));
+        assertEquals(returnedClientId, (int) clientId.getValue());
+    }
+
+    /**
+     * Validate disconnect() - correct pass-through args.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testDisconnect() throws Exception {
+        int clientId = doConnect();
+
+        mDut.disconnect(clientId, mBinderMock);
+
+        verify(mNanStateManagerMock).disconnect(clientId);
+        validateInternalStateCleanedUp(clientId);
+    }
+
+    /**
+     * Validate that security exception thrown when attempting operation using
+     * an invalid client ID.
+     */
+    @Test(expected = SecurityException.class)
+    public void testFailOnInvalidClientId() {
+        mDut.disconnect(-1, mBinderMock);
+    }
+
+    /**
+     * Validate that security exception thrown when attempting operation using a
+     * client ID which was already cleared-up.
+     */
+    @Test(expected = SecurityException.class)
+    public void testFailOnClearedUpClientId() throws Exception {
+        int clientId = doConnect();
+
+        mDut.disconnect(clientId, mBinderMock);
+
+        verify(mNanStateManagerMock).disconnect(clientId);
+        validateInternalStateCleanedUp(clientId);
+
+        mDut.disconnect(clientId, mBinderMock);
+    }
+
+    /**
+     * Validate that trying to use a client ID from a UID which is different
+     * from the one that created it fails - and that the internal state is not
+     * modified so that a valid call (from the correct UID) will subsequently
+     * succeed.
+     */
+    @Test
+    public void testFailOnAccessClientIdFromWrongUid() throws Exception {
+        int clientId = doConnect();
+
+        mDut.fakeUid = mDefaultUid + 1;
+
+        /*
+         * Not using thrown.expect(...) since want to test that subsequent
+         * access works.
+         */
+        boolean failsAsExpected = false;
+        try {
+            mDut.disconnect(clientId, mBinderMock);
+        } catch (SecurityException e) {
+            failsAsExpected = true;
+        }
+
+        mDut.fakeUid = mDefaultUid;
+
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("valid.value")
+                .build();
+        mDut.publish(clientId, publishConfig, mSessionCallbackMock);
+
+        verify(mNanStateManagerMock).publish(clientId, publishConfig, mSessionCallbackMock);
+        assertTrue("SecurityException for invalid access from wrong UID thrown", failsAsExpected);
+    }
+
+    /**
+     * Validates that on binder death we get a disconnect().
+     */
+    @Test
+    public void testBinderDeath() throws Exception {
+        ArgumentCaptor<IBinder.DeathRecipient> deathRecipient = ArgumentCaptor
+                .forClass(IBinder.DeathRecipient.class);
+
+        int clientId = doConnect();
+
+        verify(mBinderMock).linkToDeath(deathRecipient.capture(), eq(0));
+        deathRecipient.getValue().binderDied();
+        verify(mNanStateManagerMock).disconnect(clientId);
+        validateInternalStateCleanedUp(clientId);
+    }
+
+    /**
+     * Validates that sequential connect() calls return increasing client IDs.
+     */
+    @Test
+    public void testClientIdIncrementing() {
+        int loopCount = 100;
+
+        int prevId = 0;
+        for (int i = 0; i < loopCount; ++i) {
+            int id = mDut.connect(mBinderMock, mCallbackMock, null);
+            if (i != 0) {
+                assertTrue("Client ID incrementing", id > prevId);
+            }
+            prevId = id;
+        }
+    }
+
+    /**
+     * Validate terminateSession() - correct pass-through args.
+     */
+    @Test
+    public void testTerminateSession() {
+        int sessionId = 1024;
+        int clientId = doConnect();
+
+        mDut.terminateSession(clientId, sessionId);
+
+        verify(mNanStateManagerMock).terminateSession(clientId, sessionId);
+    }
+
+    /**
+     * Validate publish() - correct pass-through args.
+     */
+    @Test
+    public void testPublish() {
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("something.valid")
+                .build();
+        int clientId = doConnect();
+        IWifiNanSessionCallback mockCallback = mock(IWifiNanSessionCallback.class);
+
+        mDut.publish(clientId, publishConfig, mockCallback);
+
+        verify(mNanStateManagerMock).publish(clientId, publishConfig, mockCallback);
+    }
+
+    /**
+     * Validate that publish() verifies the input PublishConfig and fails on an invalid service
+     * name.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testPublishBadServiceName() {
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
+                "Including invalid characters - spaces").build();
+        int clientId = doConnect();
+        IWifiNanSessionCallback mockCallback = mock(IWifiNanSessionCallback.class);
+
+        mDut.publish(clientId, publishConfig, mockCallback);
+
+        verify(mNanStateManagerMock).publish(clientId, publishConfig, mockCallback);
+    }
+
+    /**
+     * Validate updatePublish() - correct pass-through args.
+     */
+    @Test
+    public void testUpdatePublish() {
+        int sessionId = 1232;
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName("something.valid")
+                .build();
+        int clientId = doConnect();
+
+        mDut.updatePublish(clientId, sessionId, publishConfig);
+
+        verify(mNanStateManagerMock).updatePublish(clientId, sessionId, publishConfig);
+    }
+
+    /**
+     * Validate subscribe() - correct pass-through args.
+     */
+    @Test
+    public void testSubscribe() {
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
+                .setServiceName("something.valid").build();
+        int clientId = doConnect();
+        IWifiNanSessionCallback mockCallback = mock(IWifiNanSessionCallback.class);
+
+        mDut.subscribe(clientId, subscribeConfig, mockCallback);
+
+        verify(mNanStateManagerMock).subscribe(clientId, subscribeConfig, mockCallback);
+    }
+
+    /**
+     * Validate that subscribe() verifies the input SubscribeConfig and fails on an invalid service
+     * name.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testSubscribeBadServiceName() {
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(
+                "InvalidServiceCharacters__").build();
+        int clientId = doConnect();
+        IWifiNanSessionCallback mockCallback = mock(IWifiNanSessionCallback.class);
+
+        mDut.subscribe(clientId, subscribeConfig, mockCallback);
+
+        verify(mNanStateManagerMock).subscribe(clientId, subscribeConfig, mockCallback);
+    }
+
+    /**
+     * Validate updateSubscribe() - correct pass-through args.
+     */
+    @Test
+    public void testUpdateSubscribe() {
+        int sessionId = 1232;
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
+                .setServiceName("something.valid").build();
+        int clientId = doConnect();
+
+        mDut.updateSubscribe(clientId, sessionId, subscribeConfig);
+
+        verify(mNanStateManagerMock).updateSubscribe(clientId, sessionId, subscribeConfig);
+    }
+
+    /**
+     * Validate sendMessage() - correct pass-through args.
+     */
+    @Test
+    public void testSendMessage() {
+        int sessionId = 2394;
+        int peerId = 2032;
+        byte[] message = new byte[23];
+        int messageId = 2043;
+        int clientId = doConnect();
+
+        mDut.sendMessage(clientId, sessionId, peerId, message, message.length, messageId, 0);
+
+        verify(mNanStateManagerMock).sendMessage(clientId, sessionId, peerId, message,
+                message.length, messageId, 0);
+    }
+
+    /**
+     * Validate startRanging() - correct pass-through args
+     */
+    @Test
+    public void testStartRanging() {
+        int clientId = doConnect();
+        int sessionId = 65345;
+        RttManager.ParcelableRttParams params =
+                new RttManager.ParcelableRttParams(new RttManager.RttParams[1]);
+
+        ArgumentCaptor<RttManager.RttParams[]> paramsCaptor =
+                ArgumentCaptor.forClass(RttManager.RttParams[].class);
+
+        int rangingId = mDut.startRanging(clientId, sessionId, params);
+
+        verify(mNanStateManagerMock).startRanging(eq(clientId), eq(sessionId),
+                paramsCaptor.capture(), eq(rangingId));
+
+        assertArrayEquals(paramsCaptor.getValue(), params.mParams);
+    }
+
+    /**
+     * Validates that sequential startRanging() calls return increasing ranging IDs.
+     */
+    @Test
+    public void testRangingIdIncrementing() {
+        int loopCount = 100;
+        int clientId = doConnect();
+        int sessionId = 65345;
+        RttManager.ParcelableRttParams params =
+                new RttManager.ParcelableRttParams(new RttManager.RttParams[1]);
+
+        int prevRangingId = 0;
+        for (int i = 0; i < loopCount; ++i) {
+            int rangingId = mDut.startRanging(clientId, sessionId, params);
+            if (i != 0) {
+                assertTrue("Client ID incrementing", rangingId > prevRangingId);
+            }
+            prevRangingId = rangingId;
+        }
+    }
+
+    /**
+     * Validates that startRanging() requires a non-empty list
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testStartRangingZeroArgs() {
+        int clientId = doConnect();
+        int sessionId = 65345;
+        RttManager.ParcelableRttParams params =
+                new RttManager.ParcelableRttParams(new RttManager.RttParams[0]);
+
+        ArgumentCaptor<RttManager.RttParams[]> paramsCaptor =
+                ArgumentCaptor.forClass(RttManager.RttParams[].class);
+
+        int rangingId = mDut.startRanging(clientId, sessionId, params);
+    }
+
+    /*
+     * Tests of internal state of WifiNanServiceImpl: very limited (not usually
+     * a good idea). However, these test that the internal state is cleaned-up
+     * appropriately. Alternatively would cause issues with memory leaks or
+     * information leak between sessions.
+     */
+
+    private void validateInternalStateCleanedUp(int clientId) throws Exception {
+        int uidEntry = getInternalStateUid(clientId);
+        assertEquals(-1, uidEntry);
+
+        IBinder.DeathRecipient dr = getInternalStateDeathRecipient(clientId);
+        assertEquals(null, dr);
+    }
+
+    /*
+     * Utilities
+     */
+
+    private int doConnect() {
+        int returnedClientId = mDut.connect(mBinderMock, mCallbackMock, null);
+
+        ArgumentCaptor<Integer> clientId = ArgumentCaptor.forClass(Integer.class);
+        verify(mNanStateManagerMock).connect(clientId.capture(), anyInt(), eq(mCallbackMock),
+                eq(new ConfigRequest.Builder().build()));
+        assertEquals(returnedClientId, (int) clientId.getValue());
+
+        return returnedClientId;
+    }
+
+    private void installMockNanStateManager()
+            throws Exception {
+        Field field = WifiNanStateManager.class.getDeclaredField("sNanStateManagerSingleton");
+        field.setAccessible(true);
+        field.set(null, mNanStateManagerMock);
+    }
+
+    private int getInternalStateUid(int clientId) throws Exception {
+        Field field = WifiNanServiceImpl.class.getDeclaredField("mUidByClientId");
+        field.setAccessible(true);
+        @SuppressWarnings("unchecked")
+        SparseIntArray uidByClientId = (SparseIntArray) field.get(mDut);
+
+        return uidByClientId.get(clientId, -1);
+    }
+
+    private IBinder.DeathRecipient getInternalStateDeathRecipient(int clientId) throws Exception {
+        Field field = WifiNanServiceImpl.class.getDeclaredField("mDeathRecipientsByClientId");
+        field.setAccessible(true);
+        @SuppressWarnings("unchecked")
+        SparseArray<IBinder.DeathRecipient> deathRecipientsByClientId =
+                            (SparseArray<IBinder.DeathRecipient>) field.get(mDut);
+
+        return deathRecipientsByClientId.get(clientId);
+    }
+}
diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanStateManagerTest.java
index 49abd27..f21ee62 100644
--- a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanStateManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanStateManagerTest.java
@@ -17,28 +17,42 @@
 package com.android.server.wifi.nan;
 
 import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsNull.notNullValue;
 import static org.hamcrest.core.IsNull.nullValue;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyShort;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
+import android.app.test.MockAnswerUtil;
+import android.app.test.TestAlarmManager;
+import android.content.Context;
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.wifi.RttManager;
 import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.IWifiNanEventListener;
-import android.net.wifi.nan.IWifiNanSessionListener;
-import android.net.wifi.nan.PublishData;
-import android.net.wifi.nan.PublishSettings;
-import android.net.wifi.nan.SubscribeData;
-import android.net.wifi.nan.SubscribeSettings;
-import android.net.wifi.nan.WifiNanEventListener;
-import android.net.wifi.nan.WifiNanSessionListener;
+import android.net.wifi.nan.IWifiNanEventCallback;
+import android.net.wifi.nan.IWifiNanSessionCallback;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
+import android.net.wifi.nan.WifiNanEventCallback;
+import android.net.wifi.nan.WifiNanManager;
+import android.net.wifi.nan.WifiNanSessionCallback;
+import android.os.Message;
+import android.os.UserHandle;
+import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
 import android.util.SparseArray;
-
-import com.android.server.wifi.MockLooper;
+import android.util.SparseIntArray;
 
 import libcore.util.HexEncoding;
 
@@ -53,436 +67,825 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Random;
 
 /**
  * Unit test harness for WifiNanStateManager.
  */
 @SmallTest
 public class WifiNanStateManagerTest {
-    private MockLooper mMockLooper;
+    private TestLooper mMockLooper;
+    private Random mRandomNg = new Random(15687);
     private WifiNanStateManager mDut;
     @Mock private WifiNanNative mMockNative;
+    @Mock private Context mMockContext;
+    @Mock private WifiNanRttStateManager mMockNanRttStateManager;
+    TestAlarmManager mAlarmManager;
+    @Mock private WifiNanDataPathStateManager mMockNanDataPathStatemanager;
 
     @Rule
     public ErrorCollector collector = new ErrorCollector();
 
+    /**
+     * Pre-test configuration. Initialize and install mocks.
+     */
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        mMockLooper = new MockLooper();
+        mAlarmManager = new TestAlarmManager();
+        when(mMockContext.getSystemService(Context.ALARM_SERVICE))
+                .thenReturn(mAlarmManager.getAlarmManager());
 
-        mDut = installNewNanStateManagerAndResetState();
-        mDut.start(mMockLooper.getLooper());
+        when(mMockContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
+                mock(ConnectivityManager.class));
+
+        mMockLooper = new TestLooper();
+
+        mDut = installNewNanStateManager();
+        mDut.start(mMockContext, mMockLooper.getLooper());
+        installMocksInStateManager(mDut, mMockNanRttStateManager, mMockNanDataPathStatemanager);
+
+        when(mMockNative.enableAndConfigure(anyShort(), any(ConfigRequest.class), anyBoolean()))
+                .thenReturn(true);
+        when(mMockNative.disable(anyShort())).thenReturn(true);
+        when(mMockNative.publish(anyShort(), anyInt(), any(PublishConfig.class))).thenReturn(true);
+        when(mMockNative.subscribe(anyShort(), anyInt(), any(SubscribeConfig.class)))
+                .thenReturn(true);
+        when(mMockNative.sendMessage(anyShort(), anyInt(), anyInt(), any(byte[].class),
+                any(byte[].class), anyInt(), anyInt())).thenReturn(true);
+        when(mMockNative.stopPublish(anyShort(), anyInt())).thenReturn(true);
+        when(mMockNative.stopSubscribe(anyShort(), anyInt())).thenReturn(true);
+        when(mMockNative.getCapabilities(anyShort())).thenReturn(true);
 
         installMockWifiNanNative(mMockNative);
     }
 
+    /**
+     * Validate that NAN data-path interfaces are brought up and down correctly.
+     */
     @Test
-    public void testNanEventsDelivered() throws Exception {
-        final int uid = 1005;
-        final int clusterLow1 = 5;
-        final int clusterHigh1 = 100;
-        final int masterPref1 = 111;
-        final int clusterLow2 = 7;
-        final int clusterHigh2 = 155;
-        final int masterPref2 = 0;
-        final int reason = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES;
+    public void testNanDataPathInterfaceUpDown() throws Exception {
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        InOrder inOrder = inOrder(mMockContext, mMockNative, mMockNanDataPathStatemanager);
+
+        // (1) enable usage
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        validateCorrectNanStatusChangeBroadcast(inOrder, true);
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNanDataPathStatemanager).createAllInterfaces();
+        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
+
+        // (2) disable usage
+        mDut.disableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).disable((short) 0);
+        inOrder.verify(mMockNative).deInitNan();
+        inOrder.verify(mMockNanDataPathStatemanager).onNanDownCleanupDataPaths();
+        validateCorrectNanStatusChangeBroadcast(inOrder, false);
+        inOrder.verify(mMockNanDataPathStatemanager).deleteAllInterfaces();
+        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
+
+        verifyNoMoreInteractions(mMockNative, mMockNanDataPathStatemanager);
+    }
+
+    /**
+     * Validate that APIs aren't functional when usage is disabled.
+     */
+    @Test
+    public void testDisableUsageDisablesApis() throws Exception {
+        final int clientId = 12314;
+        final int uid = 1000;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        InOrder inOrder = inOrder(mMockContext, mMockNative, mockCallback);
+
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+
+        // (1) check initial state
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        validateCorrectNanStatusChangeBroadcast(inOrder, true);
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
+
+        // (2) disable usage and validate state
+        mDut.disableUsage();
+        mMockLooper.dispatchAll();
+        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
+        inOrder.verify(mMockNative).disable((short) 0);
+        inOrder.verify(mMockNative).deInitNan();
+        validateCorrectNanStatusChangeBroadcast(inOrder, false);
+
+        // (3) try connecting and validate that get nothing (app should be aware of non-availability
+        // through state change broadcast and/or query API)
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+
+        verifyNoMoreInteractions(mMockNative, mockCallback);
+    }
+
+    /**
+     * Validate that when API usage is disabled while in the middle of a connection that internal
+     * state is cleaned-up, and that all subsequent operations are NOP. Then enable usage again and
+     * validate that operates correctly.
+     */
+    @Test
+    public void testDisableUsageFlow() throws Exception {
+        final int clientId = 12341;
+        final int uid = 1000;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        InOrder inOrder = inOrder(mMockContext, mMockNative, mockCallback);
+
+        // (1) check initial state
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        validateCorrectNanStatusChangeBroadcast(inOrder, true);
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
+
+        // (2) connect (successfully)
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (3) disable usage & verify callbacks
+        mDut.disableUsage();
+        mMockLooper.dispatchAll();
+        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
+        inOrder.verify(mMockNative).disable((short) 0);
+        inOrder.verify(mMockNative).deInitNan();
+        validateCorrectNanStatusChangeBroadcast(inOrder, false);
+        validateInternalClientInfoCleanedUp(clientId);
+
+        // (4) try connecting again and validate that just get an onNanDown
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+
+        // (5) disable usage again and validate that not much happens
+        mDut.disableUsage();
+        mMockLooper.dispatchAll();
+        collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
+
+        // (6) enable usage
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        collector.checkThat("usage enabled", mDut.isUsageEnabled(), equalTo(true));
+        validateCorrectNanStatusChangeBroadcast(inOrder, true);
+
+        // (7) connect (should be successful)
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        verifyNoMoreInteractions(mMockNative, mockCallback);
+    }
+
+    /**
+     * Validates that all events are delivered with correct arguments. Validates
+     * that IdentityChanged not delivered if configuration disables delivery.
+     */
+    @Test
+    public void testNanEventsDelivery() throws Exception {
+        final int clientId1 = 1005;
+        final int clientId2 = 1007;
+        final int clusterLow = 5;
+        final int clusterHigh = 100;
+        final int masterPref = 111;
+        final int uid = 1000;
+        final int reason = WifiNanEventCallback.REASON_OTHER;
         final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
 
-        ConfigRequest configRequest1 = new ConfigRequest.Builder().setClusterLow(clusterLow1)
-                .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1).build();
+        ConfigRequest configRequest1 = new ConfigRequest.Builder().setClusterLow(clusterLow)
+                .setClusterHigh(clusterHigh).setMasterPreference(masterPref)
+                .setEnableIdentityChangeCallback(false).build();
 
-        ConfigRequest configRequest2 = new ConfigRequest.Builder().setClusterLow(clusterLow2)
-                .setClusterHigh(clusterHigh2).setMasterPreference(masterPref2).build();
+        ConfigRequest configRequest2 = new ConfigRequest.Builder().setClusterLow(clusterLow)
+                .setClusterHigh(clusterHigh).setMasterPreference(masterPref)
+                .setEnableIdentityChangeCallback(true).build();
 
-        IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class);
-        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        InOrder inOrder = inOrder(mockListener, mMockNative);
+        IWifiNanEventCallback mockCallback1 = mock(IWifiNanEventCallback.class);
+        IWifiNanEventCallback mockCallback2 = mock(IWifiNanEventCallback.class);
+        ArgumentCaptor<Short> transactionIdCapture = ArgumentCaptor.forClass(Short.class);
+        InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative);
 
-        mDut.connect(uid, mockListener,
-                WifiNanEventListener.LISTEN_CONFIG_COMPLETED
-                        | WifiNanEventListener.LISTEN_CONFIG_FAILED
-                        | WifiNanEventListener.LISTEN_IDENTITY_CHANGED
-                        | WifiNanEventListener.LISTEN_NAN_DOWN);
-        mDut.requestConfig(uid, configRequest1);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionIdCapture.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionIdCapture.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest1));
-        short transactionId1 = transactionId.getValue();
+        // (1) connect 1st and 2nd clients
+        mDut.connect(clientId1, uid, mockCallback1, configRequest1);
+        mDut.connect(clientId2, uid, mockCallback2, configRequest2);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
+                eq(configRequest1), eq(true));
+        short transactionId = transactionIdCapture.getValue();
+        mDut.onConfigSuccessResponse(transactionId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback1).onConnectSuccess();
 
-        mDut.requestConfig(uid, configRequest2);
+        // (2) finish connection of 2nd client
+        inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
+                eq(configRequest2), eq(false));
+        transactionId = transactionIdCapture.getValue();
+        mDut.onConfigSuccessResponse(transactionId);
+
+        // (3) deliver NAN events
+        mDut.onClusterChangeNotification(WifiNanClientState.CLUSTER_CHANGE_EVENT_STARTED, someMac);
+        mDut.onInterfaceAddressChangeNotification(someMac);
+        mDut.onNanDownNotification(reason);
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest2));
-        short transactionId2 = transactionId.getValue();
+        inOrder.verify(mockCallback2).onConnectSuccess();
+        inOrder.verify(mockCallback2).onIdentityChanged(someMac);
 
-        mDut.onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_STARTED, someMac);
-        mDut.onConfigCompleted(transactionId1);
-        mDut.onConfigFailed(transactionId2, reason);
-        mDut.onInterfaceAddressChange(someMac);
-        mDut.onNanDown(reason);
-        mMockLooper.dispatchAll();
+        validateInternalClientInfoCleanedUp(clientId1);
+        validateInternalClientInfoCleanedUp(clientId2);
 
-        inOrder.verify(mockListener).onIdentityChanged();
-        inOrder.verify(mockListener).onConfigCompleted(configRequest1);
-        inOrder.verify(mockListener).onConfigFailed(configRequest2, reason);
-        inOrder.verify(mockListener).onIdentityChanged();
-        inOrder.verify(mockListener).onNanDown(reason);
-        verifyNoMoreInteractions(mockListener);
-
-        validateInternalTransactionInfoCleanedUp(transactionId1);
-        validateInternalTransactionInfoCleanedUp(transactionId2);
+        verifyNoMoreInteractions(mockCallback1, mockCallback2, mMockNative);
     }
 
+    /**
+     * Validate that when the HAL doesn't respond we get a TIMEOUT (which
+     * results in a failure response) at which point we can process additional
+     * commands. Steps: (1) connect, (2) publish - timeout, (3) publish +
+     * success.
+     */
     @Test
-    public void testNanEventsNotDelivered() throws Exception {
-        final int uid = 1005;
-        final int clusterLow1 = 5;
-        final int clusterHigh1 = 100;
-        final int masterPref1 = 111;
-        final int clusterLow2 = 7;
-        final int clusterHigh2 = 155;
-        final int masterPref2 = 0;
-        final int reason = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES;
-        final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
+    public void testHalNoResponseTimeout() throws Exception {
+        final int clientId = 12341;
+        final int uid = 1000;
+        final ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        final PublishConfig publishConfig = new PublishConfig.Builder().build();
 
-        ConfigRequest configRequest1 = new ConfigRequest.Builder().setClusterLow(clusterLow1)
-                .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1).build();
-
-        ConfigRequest configRequest2 = new ConfigRequest.Builder().setClusterLow(clusterLow2)
-                .setClusterHigh(clusterHigh2).setMasterPreference(masterPref2).build();
-
-        IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        InOrder inOrder = inOrder(mockListener, mMockNative);
+        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
 
-        mDut.connect(uid, mockListener, 0);
-        mDut.requestConfig(uid, configRequest1);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest1));
-        short transactionId1 = transactionId.getValue();
-
-        mDut.requestConfig(uid, configRequest2);
+        // (1) connect (successfully)
+        mDut.connect(clientId, uid, mockCallback, configRequest);
         mMockLooper.dispatchAll();
-
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest2));
-        short transactionId2 = transactionId.getValue();
-
-        mDut.onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_JOINED, someMac);
-        mDut.onConfigCompleted(transactionId1);
-        mDut.onConfigFailed(transactionId2, reason);
-        mDut.onInterfaceAddressChange(someMac);
-        mDut.onNanDown(reason);
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
         mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        verifyZeroInteractions(mockListener);
+        // (2) publish + timeout
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(anyShort(), eq(0), eq(publishConfig));
+        assertTrue(mAlarmManager.dispatch(WifiNanStateManager.HAL_COMMAND_TIMEOUT_TAG));
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback)
+                .onSessionConfigFail(WifiNanSessionCallback.REASON_OTHER);
+        validateInternalNoSessions(clientId);
 
-        validateInternalTransactionInfoCleanedUp(transactionId1);
-        validateInternalTransactionInfoCleanedUp(transactionId2);
+        // (3) publish + success
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, 9999);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
+
+        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
     }
 
+    /**
+     * Validates publish flow: (1) initial publish (2) fail. Expected: get a
+     * failure callback.
+     */
     @Test
-    public void testPublish() throws Exception {
-        final int uid = 1005;
-        final int sessionId = 20;
-        final String serviceName = "some-service-name";
-        final String ssi = "some much longer and more arbitrary data";
-        final int publishCount = 7;
-        final int reasonFail = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES;
-        final int reasonTerminate = WifiNanSessionListener.TERMINATE_REASON_DONE;
-        final int publishId1 = 15;
-        final int publishId2 = 22;
+    public void testPublishFail() throws Exception {
+        final int clientId = 1005;
+        final int uid = 1000;
+        final int reasonFail = WifiNanSessionCallback.REASON_NO_RESOURCES;
 
-        PublishData publishData = new PublishData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(ssi).build();
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        PublishConfig publishConfig = new PublishConfig.Builder().build();
 
-        PublishSettings publishSettings = new PublishSettings.Builder()
-                .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED)
-                .setPublishCount(publishCount).build();
-
-        IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        InOrder inOrder = inOrder(mockListener, mMockNative);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
 
-        int allEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED
-                | WifiNanSessionListener.LISTEN_MATCH
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL
-                | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED;
-
-        mDut.connect(uid, null, 0);
-        mDut.createSession(uid, sessionId, mockListener, allEvents);
-
-        // publish - fail
-        mDut.publish(uid, sessionId, publishData, publishSettings);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData),
-                eq(publishSettings));
-
-        mDut.onPublishFail(transactionId.getValue(), reasonFail);
+        // (0) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
         mMockLooper.dispatchAll();
-
-        inOrder.verify(mockListener).onPublishFail(reasonFail);
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-
-        // publish - success/terminate
-        mDut.publish(uid, sessionId, publishData, publishSettings);
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+                eq(configRequest), eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
         mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData),
-                eq(publishSettings));
-
-        mDut.onPublishSuccess(transactionId.getValue(), publishId1);
+        // (1) initial publish
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
         mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
 
-        mDut.onPublishTerminated(publishId1, reasonTerminate);
+        // (2) publish failure
+        mDut.onSessionConfigFailResponse(transactionId.getValue(), true, reasonFail);
         mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
+        validateInternalNoSessions(clientId);
 
-        inOrder.verify(mockListener).onPublishTerminated(reasonTerminate);
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-
-        // re-publish
-        mDut.publish(uid, sessionId, publishData, publishSettings);
-        mMockLooper.dispatchAll();
-
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData),
-                eq(publishSettings));
-
-        mDut.onPublishSuccess(transactionId.getValue(), publishId2);
-        mDut.publish(uid, sessionId, publishData, publishSettings);
-        mMockLooper.dispatchAll();
-
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId2),
-                eq(publishData), eq(publishSettings));
-        verifyNoMoreInteractions(mockListener, mMockNative);
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
     }
 
+    /**
+     * Validates the publish flow: (1) initial publish (2) success (3)
+     * termination (e.g. DONE) (4) update session attempt (5) terminateSession
+     * (6) update session attempt. Expected: session ID callback + session
+     * cleaned-up.
+     */
     @Test
-    public void testPublishNoCallbacks() throws Exception {
-        final int uid = 1005;
-        final int sessionId = 20;
-        final String serviceName = "some-service-name";
-        final String ssi = "some much longer and more arbitrary data";
-        final int publishCount = 7;
-        final int reasonFail = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES;
-        final int reasonTerminate = WifiNanSessionListener.TERMINATE_REASON_DONE;
+    public void testPublishSuccessTerminated() throws Exception {
+        final int clientId = 2005;
+        final int uid = 1000;
+        final int reasonTerminate = WifiNanSessionCallback.TERMINATE_REASON_DONE;
         final int publishId = 15;
 
-        PublishData publishData = new PublishData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(ssi).build();
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        PublishConfig publishConfig = new PublishConfig.Builder().build();
 
-        PublishSettings publishSettings = new PublishSettings.Builder()
-                .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED)
-                .setPublishCount(publishCount).build();
-
-        IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        InOrder inOrder = inOrder(mockListener, mMockNative);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
 
-        int allEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED
-                | WifiNanSessionListener.LISTEN_MATCH
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL
-                | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED;
-
-        mDut.connect(uid, null, 0);
-        mDut.createSession(uid, sessionId, mockListener,
-                allEvents & ~WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                        & ~WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED);
-
-        // publish - fail
-        mDut.publish(uid, sessionId, publishData, publishSettings);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData),
-                eq(publishSettings));
+        // (0) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+                eq(configRequest), eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        mDut.onPublishFail(transactionId.getValue(), reasonFail);
+        // (1) initial publish
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
+
+        // (2) publish success
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+
+        // (3) publish termination (from firmware - not app!)
+        mDut.onSessionTerminatedNotification(publishId, reasonTerminate, true);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionTerminated(reasonTerminate);
+
+        // (4) app update session (race condition: app didn't get termination
+        // yet)
+        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
         mMockLooper.dispatchAll();
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-
-        // publish - success/terminate
-        mDut.publish(uid, sessionId, publishData, publishSettings);
+        // (5) app terminates session
+        mDut.terminateSession(clientId, sessionId.getValue());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData),
-                eq(publishSettings));
-
-        mDut.onPublishSuccess(transactionId.getValue(), publishId);
+        // (6) app updates session (app already knows that terminated - will get
+        // a local FAIL).
+        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
         mMockLooper.dispatchAll();
 
-        mDut.onPublishTerminated(publishId, reasonTerminate);
-        mMockLooper.dispatchAll();
+        validateInternalSessionInfoCleanedUp(clientId, sessionId.getValue());
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        verifyNoMoreInteractions(mockListener, mMockNative);
+        verifyNoMoreInteractions(mockSessionCallback, mMockNative);
     }
 
+    /**
+     * Validate the publish flow: (1) initial publish + (2) success + (3) update
+     * + (4) update fails + (5) update + (6). Expected: session is still alive
+     * after update failure so second update succeeds (no callbacks).
+     */
     @Test
-    public void testSubscribe() throws Exception {
-        final int uid = 1005;
-        final int sessionId = 20;
-        final String serviceName = "some-service-name";
-        final String ssi = "some much longer and more arbitrary data";
-        final int subscribeCount = 7;
-        final int reasonFail = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES;
-        final int reasonTerminate = WifiNanSessionListener.TERMINATE_REASON_DONE;
-        final int subscribeId1 = 15;
-        final int subscribeId2 = 10;
+    public void testPublishUpdateFail() throws Exception {
+        final int clientId = 2005;
+        final int uid = 1000;
+        final int publishId = 15;
+        final int reasonFail = WifiNanSessionCallback.REASON_INVALID_ARGS;
 
-        SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(ssi).build();
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        PublishConfig publishConfig = new PublishConfig.Builder().build();
 
-        SubscribeSettings subscribeSettings = new SubscribeSettings.Builder()
-                .setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE)
-                .setSubscribeCount(subscribeCount).build();
-
-        IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        InOrder inOrder = inOrder(mockListener, mMockNative);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
 
-        int allEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED
-                | WifiNanSessionListener.LISTEN_MATCH
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL
-                | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED;
-
-        mDut.connect(uid, null, 0);
-        mDut.createSession(uid, sessionId, mockListener, allEvents);
-
-        // subscribe - fail
-        mDut.subscribe(uid, sessionId, subscribeData, subscribeSettings);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData),
-                eq(subscribeSettings));
-
-        mDut.onSubscribeFail(transactionId.getValue(), reasonFail);
+        // (0) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
         mMockLooper.dispatchAll();
-
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener).onSubscribeFail(reasonFail);
-
-        // subscribe - success/terminate
-        mDut.subscribe(uid, sessionId, subscribeData, subscribeSettings);
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
         mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData),
-                eq(subscribeSettings));
-
-        mDut.onSubscribeSuccess(transactionId.getValue(), subscribeId1);
+        // (1) initial publish
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
         mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
 
-        mDut.onSubscribeTerminated(subscribeId1, reasonTerminate);
+        // (2) publish success
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
         mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener).onSubscribeTerminated(reasonTerminate);
-
-        // re-subscribe
-        mDut.subscribe(uid, sessionId, subscribeData, subscribeSettings);
+        // (3) update publish
+        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
         mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId),
+                eq(publishConfig));
 
-        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData),
-                eq(subscribeSettings));
-
-        mDut.onSubscribeSuccess(transactionId.getValue(), subscribeId2);
-        mDut.subscribe(uid, sessionId, subscribeData, subscribeSettings);
+        // (4) update fails
+        mDut.onSessionConfigFailResponse(transactionId.getValue(), true, reasonFail);
         mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId2),
-                eq(subscribeData), eq(subscribeSettings));
-        verifyNoMoreInteractions(mockListener, mMockNative);
+        // (5) another update publish
+        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId),
+                eq(publishConfig));
+
+        // (6) update succeeds
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionConfigSuccess();
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
     }
 
+    /**
+     * Validate race condition: publish pending but session terminated (due to
+     * disconnect - can't terminate such a session directly from app). Need to
+     * make sure that once publish succeeds (failure isn't a problem) the
+     * session is immediately terminated since no-one is listening for it.
+     */
     @Test
-    public void testSubscribeNoCallbacks() throws Exception {
-        final int uid = 1005;
-        final int sessionId = 20;
-        final String serviceName = "some-service-name";
-        final String ssi = "some much longer and more arbitrary data";
-        final int subscribeCount = 7;
-        final int reasonFail = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES;
-        final int reasonTerminate = WifiNanSessionListener.TERMINATE_REASON_DONE;
+    public void testDisconnectWhilePublishPending() throws Exception {
+        final int clientId = 2005;
+        final int uid = 1000;
+        final int publishId = 15;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        PublishConfig publishConfig = new PublishConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (0) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (1) initial publish
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
+
+        // (2) disconnect (but doesn't get executed until get response for
+        // publish command)
+        mDut.disconnect(clientId);
+        mMockLooper.dispatchAll();
+
+        // (3) publish success
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
+        inOrder.verify(mMockNative).stopPublish(transactionId.capture(), eq(publishId));
+        inOrder.verify(mMockNative).disable((short) 0);
+
+        validateInternalClientInfoCleanedUp(clientId);
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
+    }
+
+    /**
+     * Validates subscribe flow: (1) initial subscribe (2) fail. Expected: get a
+     * failure callback.
+     */
+    @Test
+    public void testSubscribeFail() throws Exception {
+        final int clientId = 1005;
+        final int uid = 1000;
+        final int reasonFail = WifiNanSessionCallback.REASON_NO_RESOURCES;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (0) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (1) initial subscribe
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+
+        // (2) subscribe failure
+        mDut.onSessionConfigFailResponse(transactionId.getValue(), false, reasonFail);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
+        validateInternalNoSessions(clientId);
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
+    }
+
+    /**
+     * Validates the subscribe flow: (1) initial subscribe (2) success (3)
+     * termination (e.g. DONE) (4) update session attempt (5) terminateSession
+     * (6) update session attempt. Expected: session ID callback + session
+     * cleaned-up
+     */
+    @Test
+    public void testSubscribeSuccessTerminated() throws Exception {
+        final int clientId = 2005;
+        final int uid = 1000;
+        final int reasonTerminate = WifiNanSessionCallback.TERMINATE_REASON_DONE;
         final int subscribeId = 15;
 
-        SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(ssi).build();
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
 
-        SubscribeSettings subscribeSettings = new SubscribeSettings.Builder()
-                .setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE)
-                .setSubscribeCount(subscribeCount).build();
-
-        IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        InOrder inOrder = inOrder(mockListener, mMockNative);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
 
-        int allEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED
-                | WifiNanSessionListener.LISTEN_MATCH
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL
-                | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED;
-
-        mDut.connect(uid, null, 0);
-        mDut.createSession(uid, sessionId, mockListener,
-                allEvents & ~WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                        & ~WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED);
-
-        // subscribe - fail
-        mDut.subscribe(uid, sessionId, subscribeData, subscribeSettings);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData),
-                eq(subscribeSettings));
+        // (0) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        mDut.onSubscribeFail(transactionId.getValue(), reasonFail);
+        // (1) initial subscribe
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+
+        // (2) subscribe success
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+
+        // (3) subscribe termination (from firmware - not app!)
+        mDut.onSessionTerminatedNotification(subscribeId, reasonTerminate, false);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionTerminated(reasonTerminate);
+
+        // (4) app update session (race condition: app didn't get termination
+        // yet)
+        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
         mMockLooper.dispatchAll();
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-
-        // subscribe - success/terminate
-        mDut.subscribe(uid, sessionId, subscribeData, subscribeSettings);
+        // (5) app terminates session
+        mDut.terminateSession(clientId, sessionId.getValue());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData),
-                eq(subscribeSettings));
-
-        mDut.onSubscribeSuccess(transactionId.getValue(), subscribeId);
+        // (6) app updates session
+        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
         mMockLooper.dispatchAll();
 
-        mDut.onSubscribeTerminated(subscribeId, reasonTerminate);
-        mMockLooper.dispatchAll();
+        validateInternalSessionInfoCleanedUp(clientId, sessionId.getValue());
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        verifyNoMoreInteractions(mockListener, mMockNative);
+        verifyNoMoreInteractions(mockSessionCallback, mMockNative);
     }
 
+    /**
+     * Validate the subscribe flow: (1) initial subscribe + (2) success + (3)
+     * update + (4) update fails + (5) update + (6). Expected: session is still
+     * alive after update failure so second update succeeds (no callbacks).
+     */
+    @Test
+    public void testSubscribeUpdateFail() throws Exception {
+        final int clientId = 2005;
+        final int uid = 1000;
+        final int subscribeId = 15;
+        final int reasonFail = WifiNanSessionCallback.REASON_INVALID_ARGS;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (0) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (1) initial subscribe
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+
+        // (2) subscribe success
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+
+        // (3) update subscribe
+        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId),
+                eq(subscribeConfig));
+
+        // (4) update fails
+        mDut.onSessionConfigFailResponse(transactionId.getValue(), false, reasonFail);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionConfigFail(reasonFail);
+
+        // (5) another update subscribe
+        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId),
+                eq(subscribeConfig));
+
+        // (6) update succeeds
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionConfigSuccess();
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
+    }
+
+    /**
+     * Validate race condition: subscribe pending but session terminated (due to
+     * disconnect - can't terminate such a session directly from app). Need to
+     * make sure that once subscribe succeeds (failure isn't a problem) the
+     * session is immediately terminated since no-one is listening for it.
+     */
+    @Test
+    public void testDisconnectWhileSubscribePending() throws Exception {
+        final int clientId = 2005;
+        final int uid = 1000;
+        final int subscribeId = 15;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (0) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (1) initial subscribe
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+
+        // (2) disconnect (but doesn't get executed until get response for
+        // subscribe command)
+        mDut.disconnect(clientId);
+        mMockLooper.dispatchAll();
+
+        // (3) subscribe success
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
+        inOrder.verify(mMockNative).stopSubscribe((short) 0, subscribeId);
+        inOrder.verify(mMockNative).disable((short) 0);
+
+        validateInternalClientInfoCleanedUp(clientId);
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
+    }
+
+    /**
+     * Validate (1) subscribe (success), (2) match (i.e. discovery), (3) message reception,
+     * (4) message transmission failed (after ok queuing), (5) message transmission success.
+     */
     @Test
     public void testMatchAndMessages() throws Exception {
-        final int uid = 1005;
-        final int sessionId = 20;
+        final int clientId = 1005;
+        final int uid = 1000;
         final String serviceName = "some-service-name";
         final String ssi = "some much longer and more arbitrary data";
         final int subscribeCount = 7;
-        final int reasonFail = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES;
+        final int reasonFail = WifiNanSessionCallback.REASON_TX_FAIL;
         final int subscribeId = 15;
         final int requestorId = 22;
         final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
@@ -490,73 +893,87 @@
         final String peerMatchFilter = "filter binary array represented as string";
         final String peerMsg = "some message from peer";
         final int messageId = 6948;
+        final int messageId2 = 6949;
 
-        SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(ssi).build();
-
-        SubscribeSettings subscribeSettings = new SubscribeSettings.Builder()
-                .setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE)
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
+                .setServiceSpecificInfo(ssi)
+                .setSubscribeType(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE)
                 .setSubscribeCount(subscribeCount).build();
 
-        IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        InOrder inOrder = inOrder(mockListener, mMockNative);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
 
-        int allEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED
-                | WifiNanSessionListener.LISTEN_MATCH
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL
-                | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED;
-
-        mDut.connect(uid, null, 0);
-        mDut.createSession(uid, sessionId, mockListener, allEvents);
-        mDut.subscribe(uid, sessionId, subscribeData, subscribeSettings);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData),
-                eq(subscribeSettings));
+        // (0) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+                eq(configRequest), eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        mDut.onSubscribeSuccess(transactionId.getValue(), subscribeId);
-        mDut.onMatch(subscribeId, requestorId, peerMac, peerSsi.getBytes(), peerSsi.length(),
-                peerMatchFilter.getBytes(), peerMatchFilter.length());
-        mDut.onMessageReceived(subscribeId, requestorId, peerMac, peerMsg.getBytes(),
+        // (1) subscribe
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+
+        // (2) match
+        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+
+        // (3) message Rx
+        mDut.onMessageReceivedNotification(subscribeId, requestorId, peerMac, peerMsg.getBytes(),
                 peerMsg.length());
         mMockLooper.dispatchAll();
-
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener).onMatch(requestorId, peerSsi.getBytes(), peerSsi.length(),
-                peerMatchFilter.getBytes(), peerMatchFilter.length());
-        inOrder.verify(mockListener).onMessageReceived(requestorId, peerMsg.getBytes(),
+        inOrder.verify(mockSessionCallback).onMessageReceived(requestorId, peerMsg.getBytes(),
                 peerMsg.length());
 
-        mDut.sendMessage(uid, sessionId, requestorId, ssi.getBytes(), ssi.length(), messageId);
+        // (4) message Tx successful queuing
+        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), ssi.length(),
+                messageId, 0);
         mMockLooper.dispatchAll();
-
         inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
-                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
-
-        mDut.onMessageSendFail(transactionId.getValue(), reasonFail);
+                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()), eq(messageId));
+        short tid1 = transactionId.getValue();
+        mDut.onMessageSendQueuedSuccessResponse(tid1);
         mMockLooper.dispatchAll();
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener).onMessageSendFail(messageId, reasonFail);
-
-        mDut.sendMessage(uid, sessionId, requestorId, ssi.getBytes(), ssi.length(), messageId);
+        // (5) message Tx successful queuing
+        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(), ssi.length(),
+                messageId2, 0);
         mMockLooper.dispatchAll();
-
         inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
-                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()));
-
-        mDut.onMessageSendSuccess(transactionId.getValue());
+                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()), eq(messageId2));
+        short tid2 = transactionId.getValue();
+        mDut.onMessageSendQueuedSuccessResponse(tid2);
         mMockLooper.dispatchAll();
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener).onMessageSendSuccess(messageId);
+        // (4) and (5) final Tx results (on-air results)
+        mDut.onMessageSendFailNotification(tid1, reasonFail);
+        mDut.onMessageSendSuccessNotification(tid2);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId, reasonFail);
+        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId2);
+        validateInternalSendMessageQueuesCleanedUp(messageId);
+        validateInternalSendMessageQueuesCleanedUp(messageId2);
 
-        verifyNoMoreInteractions(mockListener, mMockNative);
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
     }
 
     /**
@@ -565,11 +982,11 @@
      */
     @Test
     public void testMultipleMessageSources() throws Exception {
-        final int uid = 300;
+        final int clientId = 300;
+        final int uid = 1000;
         final int clusterLow = 7;
         final int clusterHigh = 7;
         final int masterPref = 0;
-        final int sessionId = 26;
         final String serviceName = "some-service-name";
         final int publishId = 88;
         final int peerId1 = 568;
@@ -582,83 +999,79 @@
         final String msgToPeer2 = "hey there 0506...";
         final int msgToPeerId1 = 546;
         final int msgToPeerId2 = 9654;
-        final int reason = WifiNanSessionListener.FAIL_REASON_OTHER;
+        final int reason = WifiNanSessionCallback.REASON_OTHER;
 
         ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
                 .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
 
-        PublishData publishData = new PublishData.Builder().setServiceName(serviceName).build();
-
-        PublishSettings publishSettings = new PublishSettings.Builder()
-                .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED).build();
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
+                .setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED).build();
 
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class);
-        IWifiNanSessionListener mockSessionListener = mock(IWifiNanSessionListener.class);
-        InOrder inOrder = inOrder(mMockNative, mockListener, mockSessionListener);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
 
-        int allEvents = WifiNanEventListener.LISTEN_CONFIG_COMPLETED
-                | WifiNanEventListener.LISTEN_CONFIG_FAILED
-                | WifiNanEventListener.LISTEN_IDENTITY_CHANGED
-                | WifiNanEventListener.LISTEN_NAN_DOWN;
-
-        int allSessionEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED
-                | WifiNanSessionListener.LISTEN_MATCH
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL
-                | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED;
-
-        mDut.connect(uid, mockListener, allEvents);
-        mDut.requestConfig(uid, configRequest);
-        mDut.createSession(uid, sessionId, mockSessionListener, allSessionEvents);
-        mDut.publish(uid, sessionId, publishData, publishSettings);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest));
-        short transactionIdConfig = transactionId.getValue();
-
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData),
-                eq(publishSettings));
-        short transactionIdPublish = transactionId.getValue();
-
-        mDut.onConfigCompleted(transactionIdConfig);
-        mDut.onPublishSuccess(transactionIdPublish, publishId);
-        mDut.onMessageReceived(publishId, peerId1, peerMac1, msgFromPeer1.getBytes(),
-                msgFromPeer1.length());
-        mDut.onMessageReceived(publishId, peerId2, peerMac2, msgFromPeer2.getBytes(),
-                msgFromPeer2.length());
-        mDut.sendMessage(uid, sessionId, peerId2, msgToPeer2.getBytes(), msgToPeer2.length(),
-                msgToPeerId2);
-        mDut.sendMessage(uid, sessionId, peerId1, msgToPeer1.getBytes(), msgToPeer1.length(),
-                msgToPeerId1);
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
         mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        validateInternalTransactionInfoCleanedUp(transactionIdConfig);
-        validateInternalTransactionInfoCleanedUp(transactionIdPublish);
-        inOrder.verify(mockListener).onConfigCompleted(configRequest);
-        inOrder.verify(mockSessionListener).onMessageReceived(peerId1, msgFromPeer1.getBytes(),
+        // (2) publish
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+
+        // (3) message received from peers 1 & 2
+        mDut.onMessageReceivedNotification(publishId, peerId1, peerMac1, msgFromPeer1.getBytes(),
                 msgFromPeer1.length());
-        inOrder.verify(mockSessionListener).onMessageReceived(peerId2, msgFromPeer2.getBytes(),
+        mDut.onMessageReceivedNotification(publishId, peerId2, peerMac2, msgFromPeer2.getBytes(),
                 msgFromPeer2.length());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageReceived(peerId1, msgFromPeer1.getBytes(),
+                msgFromPeer1.length());
+        inOrder.verify(mockSessionCallback).onMessageReceived(peerId2, msgFromPeer2.getBytes(),
+                msgFromPeer2.length());
+
+        // (4) sending messages back to same peers: one Tx fails, other succeeds
+        mDut.sendMessage(clientId, sessionId.getValue(), peerId2, msgToPeer2.getBytes(),
+                msgToPeer2.length(), msgToPeerId2, 0);
+        mMockLooper.dispatchAll();
         inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId2),
-                eq(peerMac2), eq(msgToPeer2.getBytes()), eq(msgToPeer2.length()));
-        short transactionIdMsg2 = transactionId.getValue();
-        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId1),
-                eq(peerMac1), eq(msgToPeer1.getBytes()), eq(msgToPeer1.length()));
-        short transactionIdMsg1 = transactionId.getValue();
+                eq(peerMac2), eq(msgToPeer2.getBytes()), eq(msgToPeer2.length()), eq(msgToPeerId2));
+        short transactionIdVal = transactionId.getValue();
+        mDut.onMessageSendQueuedSuccessResponse(transactionIdVal);
+        mDut.onMessageSendSuccessNotification(transactionIdVal);
 
-        mDut.onMessageSendFail(transactionIdMsg1, reason);
-        mDut.onMessageSendSuccess(transactionIdMsg2);
+        mDut.sendMessage(clientId, sessionId.getValue(), peerId1, msgToPeer1.getBytes(),
+                msgToPeer1.length(), msgToPeerId1, 0);
         mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId2);
+        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId1),
+                eq(peerMac1), eq(msgToPeer1.getBytes()), eq(msgToPeer1.length()), eq(msgToPeerId1));
+        transactionIdVal = transactionId.getValue();
+        mDut.onMessageSendQueuedSuccessResponse(transactionIdVal);
+        mDut.onMessageSendFailNotification(transactionIdVal, reason);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageSendFail(msgToPeerId1, reason);
+        validateInternalSendMessageQueuesCleanedUp(msgToPeerId1);
+        validateInternalSendMessageQueuesCleanedUp(msgToPeerId2);
 
-        validateInternalTransactionInfoCleanedUp(transactionIdMsg1);
-        validateInternalTransactionInfoCleanedUp(transactionIdMsg2);
-        inOrder.verify(mockSessionListener).onMessageSendFail(msgToPeerId1, reason);
-        inOrder.verify(mockSessionListener).onMessageSendSuccess(msgToPeerId2);
-        verifyNoMoreInteractions(mMockNative, mockListener, mockSessionListener);
+        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
     }
 
     /**
@@ -667,11 +1080,11 @@
      */
     @Test
     public void testMessageWhilePeerChangesIdentity() throws Exception {
-        final int uid = 300;
+        final int clientId = 300;
+        final int uid = 1000;
         final int clusterLow = 7;
         final int clusterHigh = 7;
         final int masterPref = 0;
-        final int sessionId = 26;
         final String serviceName = "some-service-name";
         final int publishId = 88;
         final int peerId = 568;
@@ -686,387 +1099,1125 @@
         ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
                 .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
 
-        PublishData publishData = new PublishData.Builder().setServiceName(serviceName).build();
-
-        PublishSettings publishSettings = new PublishSettings.Builder()
-                .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED).build();
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
+                .setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED).build();
 
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class);
-        IWifiNanSessionListener mockSessionListener = mock(IWifiNanSessionListener.class);
-        InOrder inOrder = inOrder(mMockNative, mockListener, mockSessionListener);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
 
-        int allEvents = WifiNanEventListener.LISTEN_CONFIG_COMPLETED
-                | WifiNanEventListener.LISTEN_CONFIG_FAILED
-                | WifiNanEventListener.LISTEN_IDENTITY_CHANGED
-                | WifiNanEventListener.LISTEN_NAN_DOWN;
-
-        int allSessionEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED
-                | WifiNanSessionListener.LISTEN_MATCH
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL
-                | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED;
-
-        mDut.connect(uid, mockListener, allEvents);
-        mDut.requestConfig(uid, configRequest);
-        mDut.createSession(uid, sessionId, mockSessionListener, allSessionEvents);
-        mDut.publish(uid, sessionId, publishData, publishSettings);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest));
-        short transactionIdConfig = transactionId.getValue();
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData),
-                eq(publishSettings));
-        short transactionIdPublish = transactionId.getValue();
+        // (2) publish
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
 
-        mDut.onConfigCompleted(transactionIdConfig);
-        mDut.onPublishSuccess(transactionIdPublish, publishId);
-        mDut.onMessageReceived(publishId, peerId, peerMacOrig, msgFromPeer1.getBytes(),
+        // (3) message received & responded to
+        mDut.onMessageReceivedNotification(publishId, peerId, peerMacOrig, msgFromPeer1.getBytes(),
                 msgFromPeer1.length());
-        mDut.sendMessage(uid, sessionId, peerId, msgToPeer1.getBytes(), msgToPeer1.length(),
-                msgToPeerId1);
+        mDut.sendMessage(clientId, sessionId.getValue(), peerId, msgToPeer1.getBytes(),
+                msgToPeer1.length(), msgToPeerId1, 0);
         mMockLooper.dispatchAll();
-
-        validateInternalTransactionInfoCleanedUp(transactionIdConfig);
-        validateInternalTransactionInfoCleanedUp(transactionIdPublish);
-        inOrder.verify(mockListener).onConfigCompleted(configRequest);
-        inOrder.verify(mockSessionListener).onMessageReceived(peerId, msgFromPeer1.getBytes(),
+        inOrder.verify(mockSessionCallback).onMessageReceived(peerId, msgFromPeer1.getBytes(),
                 msgFromPeer1.length());
         inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId),
-                eq(peerMacOrig), eq(msgToPeer1.getBytes()), eq(msgToPeer1.length()));
-        short transactionIdMsg = transactionId.getValue();
-
-        mDut.onMessageSendSuccess(transactionIdMsg);
-        mDut.onMessageReceived(publishId, peerId, peerMacLater, msgFromPeer2.getBytes(),
-                msgFromPeer2.length());
-        mDut.sendMessage(uid, sessionId, peerId, msgToPeer2.getBytes(), msgToPeer2.length(),
-                msgToPeerId2);
+                eq(peerMacOrig), eq(msgToPeer1.getBytes()), eq(msgToPeer1.length()),
+                eq(msgToPeerId1));
+        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
+        mDut.onMessageSendSuccessNotification(transactionId.getValue());
         mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId1);
+        validateInternalSendMessageQueuesCleanedUp(msgToPeerId1);
 
-        validateInternalTransactionInfoCleanedUp(transactionIdMsg);
-        inOrder.verify(mockSessionListener).onMessageSendSuccess(msgToPeerId1);
-        inOrder.verify(mockSessionListener).onMessageReceived(peerId, msgFromPeer2.getBytes(),
+        // (4) message received with same peer ID but different MAC
+        mDut.onMessageReceivedNotification(publishId, peerId, peerMacLater, msgFromPeer2.getBytes(),
+                msgFromPeer2.length());
+        mDut.sendMessage(clientId, sessionId.getValue(), peerId, msgToPeer2.getBytes(),
+                msgToPeer2.length(), msgToPeerId2, 0);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageReceived(peerId, msgFromPeer2.getBytes(),
                 msgFromPeer2.length());
         inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId),
-                eq(peerMacLater), eq(msgToPeer2.getBytes()), eq(msgToPeer2.length()));
-        transactionIdMsg = transactionId.getValue();
+                eq(peerMacLater), eq(msgToPeer2.getBytes()), eq(msgToPeer2.length()),
+                eq(msgToPeerId2));
+        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
+        mDut.onMessageSendSuccessNotification(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageSendSuccess(msgToPeerId2);
+        validateInternalSendMessageQueuesCleanedUp(msgToPeerId2);
 
-        mDut.onMessageSendSuccess(transactionIdMsg);
+        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
+    }
+
+    /**
+     * Validate that get failure (with correct code) when trying to send a
+     * message to an invalid peer ID.
+     */
+    @Test
+    public void testSendMessageToInvalidPeerId() throws Exception {
+        final int clientId = 1005;
+        final int uid = 1000;
+        final String ssi = "some much longer and more arbitrary data";
+        final int subscribeId = 15;
+        final int requestorId = 22;
+        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
+        final String peerSsi = "some peer ssi data";
+        final String peerMatchFilter = "filter binary array represented as string";
+        final int messageId = 6948;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        validateInternalTransactionInfoCleanedUp(transactionIdMsg);
-        inOrder.verify(mockSessionListener).onMessageSendSuccess(msgToPeerId2);
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        verifyNoMoreInteractions(mMockNative, mockListener, mockSessionListener);
+        // (2) subscribe & match
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+
+        // (3) send message to invalid peer ID
+        mDut.sendMessage(clientId, sessionId.getValue(), requestorId + 5, ssi.getBytes(),
+                ssi.length(), messageId, 0);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
+                WifiNanSessionCallback.REASON_NO_MATCH_SESSION);
+        validateInternalSendMessageQueuesCleanedUp(messageId);
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
+    }
+
+    /**
+     * Validate that on send message timeout correct callback is dispatched and that a later
+     * firmware notification is ignored.
+     */
+    @Test
+    public void testSendMessageTimeout() throws Exception {
+        final int clientId = 1005;
+        final int uid = 1000;
+        final String ssi = "some much longer and more arbitrary data";
+        final int subscribeId = 15;
+        final int requestorId = 22;
+        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
+        final String peerSsi = "some peer ssi data";
+        final String peerMatchFilter = "filter binary array represented as string";
+        final int messageId = 6948;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) subscribe & match
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+
+        // (3) send 2 messages and enqueue successfully
+        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
+                ssi.length(), messageId, 0);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
+                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()), eq(messageId));
+        short transactionId1 = transactionId.getValue();
+        mDut.onMessageSendQueuedSuccessResponse(transactionId1);
+        mMockLooper.dispatchAll();
+
+        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
+                ssi.length(), messageId + 1, 0);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
+                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()),
+                eq(messageId + 1));
+        short transactionId2 = transactionId.getValue();
+        mDut.onMessageSendQueuedSuccessResponse(transactionId2);
+        mMockLooper.dispatchAll();
+
+        // (4) message send timeout
+        assertTrue(mAlarmManager.dispatch(WifiNanStateManager.HAL_SEND_MESSAGE_TIMEOUT_TAG));
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
+                WifiNanSessionCallback.REASON_TX_FAIL);
+        validateInternalSendMessageQueuesCleanedUp(messageId);
+
+        // (5) firmware response (unlikely - but good to check)
+        mDut.onMessageSendSuccessNotification(transactionId1);
+        mDut.onMessageSendSuccessNotification(transactionId2);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId + 1);
+
+        validateInternalSendMessageQueuesCleanedUp(messageId + 1);
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
+    }
+
+    /**
+     * Validate that when sending a message with a retry count the message is retried the specified
+     * number of times. Scenario ending with success.
+     */
+    @Test
+    public void testSendMessageRetransmitSuccess() throws Exception {
+        final int clientId = 1005;
+        final int uid = 1000;
+        final String ssi = "some much longer and more arbitrary data";
+        final int subscribeId = 15;
+        final int requestorId = 22;
+        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
+        final String peerSsi = "some peer ssi data";
+        final String peerMatchFilter = "filter binary array represented as string";
+        final int messageId = 6948;
+        final int retryCount = 3;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) subscribe & match
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+
+        // (3) send message and enqueue successfully
+        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
+                ssi.length(), messageId, retryCount);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
+                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()), eq(messageId));
+        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+
+        // (4) loop and fail until reach retryCount
+        for (int i = 0; i < retryCount; ++i) {
+            mDut.onMessageSendFailNotification(transactionId.getValue(),
+                    WifiNanSessionCallback.REASON_TX_FAIL);
+            mMockLooper.dispatchAll();
+            inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
+                    eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()),
+                    eq(messageId));
+            mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
+            mMockLooper.dispatchAll();
+        }
+
+        // (5) succeed on last retry
+        mDut.onMessageSendSuccessNotification(transactionId.getValue());
+        mMockLooper.dispatchAll();
+
+        inOrder.verify(mockSessionCallback).onMessageSendSuccess(messageId);
+        validateInternalSendMessageQueuesCleanedUp(messageId);
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
+    }
+
+    /**
+     * Validate that when sending a message with a retry count the message is retried the specified
+     * number of times. Scenario ending with failure.
+     */
+    @Test
+    public void testSendMessageRetransmitFail() throws Exception {
+        final int clientId = 1005;
+        final int uid = 1000;
+        final String ssi = "some much longer and more arbitrary data";
+        final int subscribeId = 15;
+        final int requestorId = 22;
+        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
+        final String peerSsi = "some peer ssi data";
+        final String peerMatchFilter = "filter binary array represented as string";
+        final int messageId = 6948;
+        final int retryCount = 3;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) subscribe & match
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+
+        // (3) send message and enqueue successfully
+        mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
+                ssi.length(), messageId, retryCount);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
+                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()), eq(messageId));
+        mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+
+        // (4) loop and fail until reach retryCount+1
+        for (int i = 0; i < retryCount + 1; ++i) {
+            mDut.onMessageSendFailNotification(transactionId.getValue(),
+                    WifiNanSessionCallback.REASON_TX_FAIL);
+            mMockLooper.dispatchAll();
+
+            if (i != retryCount) {
+                inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
+                        eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()),
+                        eq(messageId));
+                mDut.onMessageSendQueuedSuccessResponse(transactionId.getValue());
+                mMockLooper.dispatchAll();
+            }
+        }
+
+        inOrder.verify(mockSessionCallback).onMessageSendFail(messageId,
+                WifiNanSessionCallback.REASON_TX_FAIL);
+        validateInternalSendMessageQueuesCleanedUp(messageId);
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
     }
 
     @Test
+    public void testSendMessageQueueAllQueueFail() throws Exception {
+        WifiNanNative.Capabilities cap = getCapabilities();
+        testSendMessageQueue(SendMessageAnswer.OP_QUEUE_FAIL, cap,
+                cap.maxQueuedTransmitMessages + 5);
+    }
+
+    @Test
+    public void testSendMessageQueueAllTxSuccess() throws Exception {
+        WifiNanNative.Capabilities cap = getCapabilities();
+        testSendMessageQueue(SendMessageAnswer.OP_QUEUE_OK_SEND_OK, cap,
+                cap.maxQueuedTransmitMessages + 5);
+    }
+
+    @Test
+    public void testSendMessageQueueAllTxFailRetxOk() throws Exception {
+        WifiNanNative.Capabilities cap = getCapabilities();
+        testSendMessageQueue(SendMessageAnswer.OP_QUEUE_OK_SEND_RETX_OK, cap,
+                cap.maxQueuedTransmitMessages + 5);
+    }
+
+    @Test
+    public void testSendMessageQueueAllTxFail() throws Exception {
+        WifiNanNative.Capabilities cap = getCapabilities();
+        testSendMessageQueue(SendMessageAnswer.OP_QUEUE_OK_SEND_RETX_FAIL, cap,
+                cap.maxQueuedTransmitMessages + 5);
+    }
+
+    @Test
+    public void testSendMessageQueueRandomize() throws Exception {
+        WifiNanNative.Capabilities cap = getCapabilities();
+        testSendMessageQueue(SendMessageAnswer.OP_QUEUE_RANDOMIZE, cap,
+                cap.maxQueuedTransmitMessages * 10);
+    }
+
+    /**
+     * Validate that when sending more messages than can be queued by the firmware (based on
+     * capability information) they are queued. Support all possible test success/failure codes.
+     * @param behavior: SendMessageAnswer.OP_*.
+     */
+    private void testSendMessageQueue(int behavior, WifiNanNative.Capabilities cap, int numMessages)
+            throws Exception {
+        final int clientId = 1005;
+        final int uid = 1000;
+        final String ssi = "some much longer and more arbitrary data";
+        final int subscribeId = 15;
+        final int requestorId = 22;
+        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
+        final String peerSsi = "some peer ssi data";
+        final String peerMatchFilter = "filter binary array represented as string";
+        final int messageId = 6948;
+        final int retryCount = 3;
+        final int reason = WifiNanSessionCallback.REASON_OTHER;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> msgId = ArgumentCaptor.forClass(Integer.class);
+
+        // (0) initial conditions
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), cap);
+        mMockLooper.dispatchAll();
+
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        verify(mockCallback).onConnectSuccess();
+
+        // (2) subscribe & match
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+        mMockLooper.dispatchAll();
+        verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+        verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(), peerSsi.length(),
+                peerMatchFilter.getBytes(), peerMatchFilter.length());
+
+        // (3) send large number of messages
+        SendMessageAnswer answerObj = new SendMessageAnswer(behavior);
+        when(mMockNative.sendMessage(anyShort(), anyInt(), anyInt(), any(byte[].class),
+                any(byte[].class), anyInt(), anyInt())).thenAnswer(answerObj);
+        for (int i = 0; i < numMessages; ++i) {
+            mDut.sendMessage(clientId, sessionId.getValue(), requestorId, ssi.getBytes(),
+                    ssi.length(), messageId + i, retryCount);
+        }
+        mMockLooper.dispatchAll();
+
+        int numSends = answerObj.ops[SendMessageAnswer.OP_QUEUE_FAIL]
+                + answerObj.ops[SendMessageAnswer.OP_QUEUE_OK_SEND_OK]
+                + answerObj.ops[SendMessageAnswer.OP_QUEUE_OK_SEND_RETX_OK] * 2
+                + answerObj.ops[SendMessageAnswer.OP_QUEUE_OK_SEND_RETX_FAIL] * (retryCount + 1);
+        int numOnSendSuccess = answerObj.ops[SendMessageAnswer.OP_QUEUE_OK_SEND_OK]
+                + answerObj.ops[SendMessageAnswer.OP_QUEUE_OK_SEND_RETX_OK];
+        int numOnSendFail = answerObj.ops[SendMessageAnswer.OP_QUEUE_OK_SEND_RETX_FAIL];
+
+        Log.v("WifiNanStateManagerTest",
+                "testSendMessageQueue: ops=" + Arrays.toString(answerObj.ops) + ", numSends="
+                        + numSends + ", numOnSendSuccess=" + numOnSendSuccess + ", numOnSendFail="
+                        + numOnSendFail);
+
+        verify(mMockNative, times(numSends)).sendMessage(anyShort(), eq(subscribeId),
+                eq(requestorId), eq(peerMac), eq(ssi.getBytes()), eq(ssi.length()), anyInt());
+        verify(mockSessionCallback, times(numOnSendSuccess)).onMessageSendSuccess(anyInt());
+        verify(mockSessionCallback, times(numOnSendFail)).onMessageSendFail(anyInt(), anyInt());
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative);
+    }
+
+    private class SendMessageAnswer extends MockAnswerUtil.AnswerWithArguments {
+        public static final int OP_QUEUE_FAIL = 0;
+        public static final int OP_QUEUE_OK_SEND_OK = 1;
+        public static final int OP_QUEUE_OK_SEND_RETX_OK = 2;
+        public static final int OP_QUEUE_OK_SEND_RETX_FAIL = 3;
+
+        /* psuedo operation: randomly pick from the above 4 operations */
+        public static final int OP_QUEUE_RANDOMIZE = -1;
+
+        /* the number of operations which can be executed. Doesn't cound RANDOMIZE since it is
+         * resolved to one of the 4 types */
+        private static final int NUM_OPS = 4;
+
+        public int[] ops = new int[NUM_OPS];
+
+        private int mBehavior = 0;
+        private SparseIntArray mPacketBehavior = new SparseIntArray();
+
+        SendMessageAnswer(int behavior) {
+            mBehavior = behavior;
+        }
+
+        public boolean answer(short transactionId, int pubSubId, int requestorInstanceId,
+                byte[] dest, byte[] message, int messageLength, int messageId) throws Exception {
+            Log.v("WifiNanStateManagerTest",
+                    "SendMessageAnswer.answer: mBehavior=" + mBehavior + ", transactionId="
+                            + transactionId + ", messageId=" + messageId
+                            + ", mPacketBehavior[messageId]" + mPacketBehavior.get(messageId, -1));
+
+            int behavior = mBehavior;
+            if (behavior == OP_QUEUE_RANDOMIZE) {
+                behavior = mRandomNg.nextInt(NUM_OPS);
+            }
+
+            boolean packetRetx = mPacketBehavior.get(messageId, -1) != -1;
+            if (packetRetx) {
+                behavior = mPacketBehavior.get(messageId);
+            } else {
+                mPacketBehavior.put(messageId, behavior);
+            }
+
+            if (behavior == OP_QUEUE_FAIL) {
+                ops[OP_QUEUE_FAIL]++;
+                mDut.onMessageSendQueuedFailResponse(transactionId,
+                        WifiNanSessionCallback.REASON_OTHER);
+            } else if (behavior == OP_QUEUE_OK_SEND_OK) {
+                ops[OP_QUEUE_OK_SEND_OK]++;
+                mDut.onMessageSendQueuedSuccessResponse(transactionId);
+                mDut.onMessageSendSuccessNotification(transactionId);
+            } else if (behavior == OP_QUEUE_OK_SEND_RETX_OK) {
+                mDut.onMessageSendQueuedSuccessResponse(transactionId);
+                if (!packetRetx) {
+                    mDut.onMessageSendFailNotification(transactionId,
+                            WifiNanSessionCallback.REASON_TX_FAIL);
+                } else {
+                    ops[OP_QUEUE_OK_SEND_RETX_OK]++;
+                    mDut.onMessageSendSuccessNotification(transactionId);
+                }
+            } else if (behavior == OP_QUEUE_OK_SEND_RETX_FAIL) {
+                mDut.onMessageSendQueuedSuccessResponse(transactionId);
+                if (!packetRetx) {
+                    ops[OP_QUEUE_OK_SEND_RETX_FAIL]++;
+                }
+                mDut.onMessageSendFailNotification(transactionId,
+                        WifiNanSessionCallback.REASON_TX_FAIL);
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Validate that start ranging function fills-in correct MAC addresses for peer IDs and
+     * passed along to RTT module.
+     */
+    @Test
+    public void testStartRanging() throws Exception {
+        final int clientId = 1005;
+        final int uid = 1000;
+        final int subscribeId = 15;
+        final int requestorId = 22;
+        final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false);
+        final String peerSsi = "some peer ssi data";
+        final String peerMatchFilter = "filter binary array represented as string";
+        final int rangingId = 18423;
+        final RttManager.RttParams[] params = new RttManager.RttParams[2];
+        params[0] = new RttManager.RttParams();
+        params[0].bssid = Integer.toString(requestorId);
+        params[1] = new RttManager.RttParams();
+        params[1].bssid = Integer.toString(requestorId + 5);
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<WifiNanClientState> clientCaptor =
+                ArgumentCaptor.forClass(WifiNanClientState.class);
+        ArgumentCaptor<RttManager.RttParams[]> rttParamsCaptor =
+                ArgumentCaptor.forClass(RttManager.RttParams[].class);
+
+        InOrder inOrder = inOrder(mockCallback, mockSessionCallback, mMockNative,
+                mMockNanRttStateManager);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) subscribe & match
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mDut.onMatchNotification(subscribeId, requestorId, peerMac, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+        inOrder.verify(mockSessionCallback).onMatch(requestorId, peerSsi.getBytes(),
+                peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length());
+
+        // (3) start ranging: pass along a valid peer ID and an invalid one
+        mDut.startRanging(clientId, sessionId.getValue(), params, rangingId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNanRttStateManager).startRanging(eq(rangingId), clientCaptor.capture(),
+                rttParamsCaptor.capture());
+        collector.checkThat("RttParams[0].bssid", "06:07:08:09:0A:0B",
+                equalTo(rttParamsCaptor.getValue()[0].bssid));
+        collector.checkThat("RttParams[1].bssid", "", equalTo(rttParamsCaptor.getValue()[1].bssid));
+
+        verifyNoMoreInteractions(mockCallback, mockSessionCallback, mMockNative,
+                mMockNanRttStateManager);
+    }
+
+    /**
+     * Test sequence of configuration: (1) config1, (2) config2 - incompatible,
+     * (3) config3 - compatible with config1 (requiring upgrade), (4) disconnect
+     * config3 (should get a downgrade), (5) disconnect config1 (should get a
+     * disable).
+     */
+    @Test
     public void testConfigs() throws Exception {
-        final int uid1 = 9999;
+        final int clientId1 = 9999;
+        final int uid = 1000;
         final int clusterLow1 = 5;
         final int clusterHigh1 = 100;
         final int masterPref1 = 111;
-        final int uid2 = 1001;
+        final int clientId2 = 1001;
         final boolean support5g2 = true;
         final int clusterLow2 = 7;
         final int clusterHigh2 = 155;
         final int masterPref2 = 0;
-        final int uid3 = 55;
+        final int clientId3 = 55;
 
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
         ArgumentCaptor<ConfigRequest> crCapture = ArgumentCaptor.forClass(ConfigRequest.class);
 
         ConfigRequest configRequest1 = new ConfigRequest.Builder().setClusterLow(clusterLow1)
-                .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1).build();
+                .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1)
+                .setEnableIdentityChangeCallback(false).build();
 
         ConfigRequest configRequest2 = new ConfigRequest.Builder().setSupport5gBand(support5g2)
                 .setClusterLow(clusterLow2).setClusterHigh(clusterHigh2)
                 .setMasterPreference(masterPref2).build();
 
-        ConfigRequest configRequest3 = new ConfigRequest.Builder().build();
+        ConfigRequest configRequest3 = new ConfigRequest.Builder().setClusterLow(clusterLow1)
+                .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1)
+                .setEnableIdentityChangeCallback(true).build();
 
-        IWifiNanEventListener mockListener1 = mock(IWifiNanEventListener.class);
-        IWifiNanEventListener mockListener2 = mock(IWifiNanEventListener.class);
-        IWifiNanEventListener mockListener3 = mock(IWifiNanEventListener.class);
+        IWifiNanEventCallback mockCallback1 = mock(IWifiNanEventCallback.class);
+        IWifiNanEventCallback mockCallback2 = mock(IWifiNanEventCallback.class);
+        IWifiNanEventCallback mockCallback3 = mock(IWifiNanEventCallback.class);
 
-        InOrder inOrder = inOrder(mMockNative, mockListener1, mockListener2, mockListener3);
+        InOrder inOrder = inOrder(mMockNative, mockCallback1, mockCallback2, mockCallback3);
 
-        mDut.connect(uid1, mockListener1, WifiNanEventListener.LISTEN_CONFIG_COMPLETED);
-        mDut.requestConfig(uid1, configRequest1);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
+        // (1) config1 (valid)
+        mDut.connect(clientId1, uid, mockCallback1, configRequest1);
+        mMockLooper.dispatchAll();
         inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
-                crCapture.capture());
-        collector.checkThat("merge: stage 0", configRequest1, equalTo(crCapture.getValue()));
-
-        mDut.onConfigCompleted(transactionId.getValue());
+                crCapture.capture(), eq(true));
+        collector.checkThat("merge: stage 1", crCapture.getValue(), equalTo(configRequest1));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
         mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback1).onConnectSuccess();
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener1).onConfigCompleted(configRequest1);
-
-        mDut.connect(uid2, mockListener2, WifiNanEventListener.LISTEN_CONFIG_COMPLETED);
-        mDut.requestConfig(uid2, configRequest2);
+        // (2) config2 (incompatible with config1)
+        mDut.connect(clientId2, uid, mockCallback2, configRequest2);
         mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback2)
+                .onConnectFail(WifiNanEventCallback.REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG);
+        validateInternalClientInfoCleanedUp(clientId2);
 
+        // (3) config3 (compatible with config1 but requires upgrade - i.e. no
+        // OTA changes)
+        mDut.connect(clientId3, uid, mockCallback3, configRequest3);
+        mMockLooper.dispatchAll();
         inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
-                crCapture.capture());
-        collector.checkThat("merge: stage 1: support 5g", crCapture.getValue().mSupport5gBand,
-                equalTo(true));
-        collector.checkThat("merge: stage 1: master pref", crCapture.getValue().mMasterPreference,
-                equalTo(Math.max(masterPref1, masterPref2)));
-        collector.checkThat("merge: stage 1: cluster low", crCapture.getValue().mClusterLow,
-                equalTo(Math.min(clusterLow1, clusterLow2)));
-        collector.checkThat("merge: stage 1: cluster high", crCapture.getValue().mClusterHigh,
-                equalTo(Math.max(clusterHigh1, clusterHigh2)));
-
-        mDut.onConfigCompleted(transactionId.getValue());
+                crCapture.capture(), eq(false));
+        collector.checkThat("merge: stage 3: support 5g", crCapture.getValue().mSupport5gBand,
+                equalTo(false));
+        collector.checkThat("merge: stage 3: master pref", crCapture.getValue().mMasterPreference,
+                equalTo(masterPref1));
+        collector.checkThat("merge: stage 3: cluster low", crCapture.getValue().mClusterLow,
+                equalTo(clusterLow1));
+        collector.checkThat("merge: stage 3: cluster high", crCapture.getValue().mClusterHigh,
+                equalTo(clusterHigh1));
+        collector.checkThat("merge: stage 3: enable identity change callback",
+                crCapture.getValue().mEnableIdentityChangeCallback, equalTo(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
         mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback3).onConnectSuccess();
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener1).onConfigCompleted(crCapture.getValue());
-
-        mDut.connect(uid3, mockListener3, WifiNanEventListener.LISTEN_CONFIG_COMPLETED);
-        mDut.requestConfig(uid3, configRequest3);
+        // (4) disconnect config3: want a downgrade
+        mDut.disconnect(clientId3);
         mMockLooper.dispatchAll();
-
+        validateInternalClientInfoCleanedUp(clientId3);
         inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
-                crCapture.capture());
-        collector.checkThat("merge: stage 2: support 5g", crCapture.getValue().mSupport5gBand,
-                equalTo(true));
-        collector.checkThat("merge: stage 2: master pref", crCapture.getValue().mMasterPreference,
-                equalTo(Math.max(masterPref1, masterPref2)));
-        collector.checkThat("merge: stage 2: cluster low", crCapture.getValue().mClusterLow,
-                equalTo(Math.min(clusterLow1, clusterLow2)));
-        collector.checkThat("merge: stage 2: cluster high", crCapture.getValue().mClusterHigh,
-                equalTo(Math.max(clusterHigh1, clusterHigh2)));
-
-        mDut.onConfigCompleted(transactionId.getValue());
+                crCapture.capture(), eq(false));
+        collector.checkThat("merge: stage 4", crCapture.getValue(), equalTo(configRequest1));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
         mMockLooper.dispatchAll();
 
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener1).onConfigCompleted(crCapture.getValue());
-
-        mDut.disconnect(uid2);
+        // (5) disconnect config1: disable
+        mDut.disconnect(clientId1);
         mMockLooper.dispatchAll();
+        validateInternalClientInfoCleanedUp(clientId1);
+        inOrder.verify(mMockNative).disable((short) 0);
 
-        validateInternalClientInfoCleanedUp(uid2);
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
-                crCapture.capture());
-        collector.checkThat("merge: stage 3", configRequest1, equalTo(crCapture.getValue()));
-
-        mDut.onConfigCompleted(transactionId.getValue());
-        mMockLooper.dispatchAll();
-
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener1).onConfigCompleted(crCapture.getValue());
-
-        mDut.disconnect(uid1);
-        mMockLooper.dispatchAll();
-
-        validateInternalClientInfoCleanedUp(uid2);
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
-                crCapture.capture());
-        collector.checkThat("merge: stage 4", configRequest3, equalTo(crCapture.getValue()));
-
-        mDut.onConfigCompleted(transactionId.getValue());
-        mMockLooper.dispatchAll();
-
-        validateInternalTransactionInfoCleanedUp(transactionId.getValue());
-        inOrder.verify(mockListener3).onConfigCompleted(crCapture.getValue());
-
-        mDut.disconnect(uid3);
-        mMockLooper.dispatchAll();
-
-        validateInternalClientInfoCleanedUp(uid2);
-        inOrder.verify(mMockNative).disable(anyShort());
-
-        verifyNoMoreInteractions(mMockNative);
+        verifyNoMoreInteractions(mMockNative, mockCallback1, mockCallback2, mockCallback3);
     }
 
     /**
      * Summary: disconnect a client while there are pending transactions.
-     * Validate that no callbacks are called and that internal state is
-     * cleaned-up.
      */
     @Test
     public void testDisconnectWithPendingTransactions() throws Exception {
-        final int uid = 125;
+        final int clientId = 125;
+        final int uid = 1000;
         final int clusterLow = 5;
         final int clusterHigh = 100;
         final int masterPref = 111;
-        final int sessionId = 20;
         final String serviceName = "some-service-name";
         final String ssi = "some much longer and more arbitrary data";
         final int publishCount = 7;
-        final int reason = WifiNanSessionListener.TERMINATE_REASON_DONE;
+        final int reason = WifiNanSessionCallback.TERMINATE_REASON_DONE;
         final int publishId = 22;
 
         ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
                 .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
 
-        PublishData publishData = new PublishData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(ssi).build();
-
-        PublishSettings publishSettings = new PublishSettings.Builder()
-                .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED)
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
+                .setServiceSpecificInfo(ssi).setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED)
                 .setPublishCount(publishCount).build();
 
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class);
-        IWifiNanSessionListener mockSessionListener = mock(IWifiNanSessionListener.class);
-        InOrder inOrder = inOrder(mMockNative, mockListener, mockSessionListener);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
 
-        int allEvents = WifiNanEventListener.LISTEN_CONFIG_COMPLETED
-                | WifiNanEventListener.LISTEN_CONFIG_FAILED
-                | WifiNanEventListener.LISTEN_IDENTITY_CHANGED
-                | WifiNanEventListener.LISTEN_NAN_DOWN;
-
-        int allSessionEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED
-                | WifiNanSessionListener.LISTEN_MATCH
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL
-                | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED;
-
-        mDut.connect(uid, mockListener, allEvents);
-        mDut.createSession(uid, sessionId, mockSessionListener, allSessionEvents);
-        mDut.requestConfig(uid, configRequest);
-        mDut.publish(uid, sessionId, publishData, publishSettings);
-        mDut.disconnect(uid);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest));
-        short transactionIdConfig = transactionId.getValue();
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData),
-                eq(publishSettings));
-        short transactionIdPublish = transactionId.getValue();
+        // (2) publish (no response yet)
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
 
-        validateInternalClientInfoCleanedUp(uid);
-        validateInternalTransactionInfoCleanedUp(transactionIdPublish);
-
-        mDut.onConfigCompleted(transactionIdConfig);
-        mDut.onPublishSuccess(transactionIdPublish, publishId);
+        // (3) disconnect (but doesn't get executed until get a RESPONSE to the
+        // previous publish)
+        mDut.disconnect(clientId);
         mMockLooper.dispatchAll();
 
-        mDut.onPublishTerminated(publishId, reason);
+        // (4) get successful response to the publish
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(anyInt());
+        inOrder.verify(mMockNative).stopPublish((short) 0, publishId);
+        inOrder.verify(mMockNative).disable((short) 0);
+
+        validateInternalClientInfoCleanedUp(clientId);
+
+        // (5) trying to publish on the same client: NOP
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
         mMockLooper.dispatchAll();
 
-        verifyZeroInteractions(mockListener, mockSessionListener);
+        // (6) got some callback on original publishId - should be ignored
+        mDut.onSessionTerminatedNotification(publishId, reason, true);
+        mMockLooper.dispatchAll();
+
+        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
     }
 
     /**
-     * Summary: destroy a session while there are pending transactions. Validate
-     * that no callbacks are called and that internal state is cleaned-up.
+     * Validate that an unknown transaction (i.e. a callback from HAL with an
+     * unknown type) is simply ignored - but also cleans up its state.
      */
     @Test
-    public void testDestroySessionWithPendingTransactions() throws Exception {
-        final int uid = 128;
+    public void testUnknownTransactionType() throws Exception {
+        final int clientId = 129;
+        final int uid = 1000;
         final int clusterLow = 15;
         final int clusterHigh = 192;
         final int masterPref = 234;
-        final int publishSessionId = 19;
-        final int subscribeSessionId = 24;
         final String serviceName = "some-service-name";
         final String ssi = "some much longer and more arbitrary data";
         final int publishCount = 15;
-        final int subscribeCount = 22;
-        final int reason = WifiNanSessionListener.TERMINATE_REASON_DONE;
-        final int publishId = 23;
-        final int subscribeId = 55;
 
         ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
                 .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build();
 
-        PublishData publishData = new PublishData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(ssi).build();
-
-        PublishSettings publishSettings = new PublishSettings.Builder()
-                .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED)
+        PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
+                .setServiceSpecificInfo(ssi).setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED)
                 .setPublishCount(publishCount).build();
 
-        SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName)
-                .setServiceSpecificInfo(ssi).build();
-
-        SubscribeSettings subscribeSettings = new SubscribeSettings.Builder()
-                .setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE)
-                .setSubscribeCount(subscribeCount).build();
-
         ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
-        IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class);
-        IWifiNanSessionListener mockPublishSessionListener = mock(IWifiNanSessionListener.class);
-        IWifiNanSessionListener mockSubscribeSessionListener = mock(IWifiNanSessionListener.class);
-        InOrder inOrder = inOrder(mMockNative, mockListener, mockPublishSessionListener,
-                mockSubscribeSessionListener);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockPublishSessionCallback = mock(IWifiNanSessionCallback.class);
+        InOrder inOrder = inOrder(mMockNative, mockCallback, mockPublishSessionCallback);
 
-        int allEvents = WifiNanEventListener.LISTEN_CONFIG_COMPLETED
-                | WifiNanEventListener.LISTEN_CONFIG_FAILED
-                | WifiNanEventListener.LISTEN_IDENTITY_CHANGED
-                | WifiNanEventListener.LISTEN_NAN_DOWN;
-
-        int allSessionEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL
-                | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL
-                | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED
-                | WifiNanSessionListener.LISTEN_MATCH
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS
-                | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL
-                | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED;
-
-        mDut.connect(uid, mockListener, allEvents);
-        mDut.requestConfig(uid, configRequest);
-        mDut.createSession(uid, publishSessionId, mockPublishSessionListener, allSessionEvents);
-        mDut.publish(uid, publishSessionId, publishData, publishSettings);
-        mDut.createSession(uid, subscribeSessionId, mockSubscribeSessionListener, allSessionEvents);
-        mDut.subscribe(uid, subscribeSessionId, subscribeData, subscribeSettings);
-        mDut.destroySession(uid, publishSessionId);
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
         mMockLooper.dispatchAll();
 
-        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest));
-        short transactionIdConfig = transactionId.getValue();
-
-        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData),
-                eq(publishSettings));
-        short transactionIdPublish = transactionId.getValue();
-
-        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData),
-                eq(subscribeSettings));
-        short transactionIdSubscribe = transactionId.getValue();
-
-        validateInternalTransactionInfoCleanedUp(transactionIdPublish);
-
-        mDut.onConfigCompleted(transactionIdConfig);
-        mDut.onPublishSuccess(transactionIdPublish, publishId);
-        mDut.onSubscribeSuccess(transactionIdSubscribe, subscribeId);
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
         mMockLooper.dispatchAll();
-
-        mDut.onPublishTerminated(publishId, reason);
-        mDut.destroySession(uid, subscribeSessionId);
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
         mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
 
-        inOrder.verify(mockListener).onConfigCompleted(configRequest);
-        verifyZeroInteractions(mockPublishSessionListener);
-        verifyNoMoreInteractions(mockSubscribeSessionListener);
+        // (2) publish - no response
+        mDut.publish(clientId, publishConfig, mockPublishSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
+
+        verifyNoMoreInteractions(mMockNative, mockCallback, mockPublishSessionCallback);
     }
 
+    /**
+     * Validate that a NoOp transaction (i.e. a callback from HAL which doesn't
+     * require any action except clearing up state) actually cleans up its state
+     * (and does nothing else).
+     */
     @Test
-    public void testTransactionIdIncrement() {
+    public void testNoOpTransaction() throws Exception {
+        final int clientId = 1294;
+        final int uid = 1000;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (1) connect (no response)
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+
+        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
+    }
+
+    /**
+     * Validate that getting callbacks from HAL with unknown (expired)
+     * transaction ID or invalid publish/subscribe ID session doesn't have any
+     * impact.
+     */
+    @Test
+    public void testInvalidCallbackIdParameters() throws Exception {
+        final int pubSubId = 1235;
+        final int clientId = 132;
+        final int uid = 1000;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        InOrder inOrder = inOrder(mMockNative, mockCallback);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (1) connect and succeed
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        short transactionIdConfig = transactionId.getValue();
+        mDut.onConfigSuccessResponse(transactionIdConfig);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) use the same transaction ID to send a bunch of other responses
+        mDut.onConfigSuccessResponse(transactionIdConfig);
+        mDut.onConfigFailedResponse(transactionIdConfig, -1);
+        mDut.onSessionConfigFailResponse(transactionIdConfig, true, -1);
+        mDut.onMessageSendQueuedSuccessResponse(transactionIdConfig);
+        mDut.onMessageSendQueuedFailResponse(transactionIdConfig, -1);
+        mDut.onSessionConfigFailResponse(transactionIdConfig, false, -1);
+        mDut.onMatchNotification(-1, -1, new byte[0], new byte[0], 0, new byte[0], 0);
+        mDut.onSessionTerminatedNotification(-1, -1, true);
+        mDut.onSessionTerminatedNotification(-1, -1, false);
+        mDut.onMessageReceivedNotification(-1, -1, new byte[0], new byte[0], 0);
+        mDut.onSessionConfigSuccessResponse(transactionIdConfig, true, pubSubId);
+        mDut.onSessionConfigSuccessResponse(transactionIdConfig, false, pubSubId);
+        mMockLooper.dispatchAll();
+
+        verifyNoMoreInteractions(mMockNative, mockCallback);
+    }
+
+    /**
+     * Validate that trying to update-subscribe on a publish session fails.
+     */
+    @Test
+    public void testSubscribeOnPublishSessionType() throws Exception {
+        final int clientId = 188;
+        final int uid = 1000;
+        final int publishId = 25;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        PublishConfig publishConfig = new PublishConfig.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest),
+                eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) publish
+        mDut.publish(clientId, publishConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, publishId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+
+        // (3) update-subscribe -> failure
+        mDut.updateSubscribe(clientId, sessionId.getValue(), subscribeConfig);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback)
+                .onSessionConfigFail(WifiNanSessionCallback.REASON_OTHER);
+
+        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
+    }
+
+    /**
+     * Validate that trying to (re)subscribe on a publish session or (re)publish
+     * on a subscribe session fails.
+     */
+    @Test
+    public void testPublishOnSubscribeSessionType() throws Exception {
+        final int clientId = 188;
+        final int uid = 1000;
+        final int subscribeId = 25;
+
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        PublishConfig publishConfig = new PublishConfig.Builder().build();
+        SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
+
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+                eq(configRequest), eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        // (2) subscribe
+        mDut.subscribe(clientId, subscribeConfig, mockSessionCallback);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeConfig));
+        mDut.onSessionConfigSuccessResponse(transactionId.getValue(), false, subscribeId);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+
+        // (3) update-publish -> error
+        mDut.updatePublish(clientId, sessionId.getValue(), publishConfig);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockSessionCallback)
+                .onSessionConfigFail(WifiNanSessionCallback.REASON_OTHER);
+
+        verifyNoMoreInteractions(mMockNative, mockCallback, mockSessionCallback);
+    }
+
+    /**
+     * Validate that the session ID increments monotonically
+     */
+    @Test
+    public void testSessionIdIncrement() throws Exception {
+        final int clientId = 188;
+        final int uid = 1000;
         int loopCount = 100;
 
-        short prevId = 0;
+        ConfigRequest configRequest = new ConfigRequest.Builder().build();
+        PublishConfig publishConfig = new PublishConfig.Builder().build();
+
+        ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class);
+        ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class);
+        IWifiNanEventCallback mockCallback = mock(IWifiNanEventCallback.class);
+        IWifiNanSessionCallback mockSessionCallback = mock(IWifiNanSessionCallback.class);
+        InOrder inOrder = inOrder(mMockNative, mockCallback, mockSessionCallback);
+
+        mDut.enableUsage();
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).getCapabilities(transactionId.capture());
+        mDut.onCapabilitiesUpdateResponse(transactionId.getValue(), getCapabilities());
+        mMockLooper.dispatchAll();
+
+        // (1) connect
+        mDut.connect(clientId, uid, mockCallback, configRequest);
+        mMockLooper.dispatchAll();
+        inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(),
+                eq(configRequest), eq(true));
+        mDut.onConfigSuccessResponse(transactionId.getValue());
+        mMockLooper.dispatchAll();
+        inOrder.verify(mockCallback).onConnectSuccess();
+
+        int prevId = 0;
         for (int i = 0; i < loopCount; ++i) {
-            short id = mDut.createNextTransactionId();
+            // (2) publish
+            mDut.publish(clientId, publishConfig, mockSessionCallback);
+            mMockLooper.dispatchAll();
+            inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishConfig));
+
+            // (3) publish-success
+            mDut.onSessionConfigSuccessResponse(transactionId.getValue(), true, i + 1);
+            mMockLooper.dispatchAll();
+            inOrder.verify(mockSessionCallback).onSessionStarted(sessionId.capture());
+
             if (i != 0) {
-                assertTrue("Transaction ID incrementing", id > prevId);
+                assertTrue("Session ID incrementing", sessionId.getValue() > prevId);
             }
-            prevId = id;
+            prevId = sessionId.getValue();
         }
     }
 
@@ -1079,34 +2230,83 @@
 
     /**
      * Utility routine used to validate that the internal state is cleaned-up
-     * after the specific transaction ID. To be used in every test which
-     * involves a transaction.
+     * after a client is disconnected. To be used in every test which terminates
+     * a client.
      *
-     * @param transactionId The transaction ID whose state should be erased.
+     * @param clientId The ID of the client which should be deleted.
      */
-    public void validateInternalTransactionInfoCleanedUp(short transactionId) throws Exception {
-        Object info = getInternalPendingTransactionInfo(mDut, transactionId);
-        collector.checkThat("Transaction record not cleared up for transactionId=" + transactionId,
-                info, nullValue());
+    private void validateInternalClientInfoCleanedUp(int clientId) throws Exception {
+        WifiNanClientState client = getInternalClientState(mDut, clientId);
+        collector.checkThat("Client record not cleared up for clientId=" + clientId, client,
+                nullValue());
     }
 
     /**
      * Utility routine used to validate that the internal state is cleaned-up
-     * after a client is disconnected. To be used in every test which terminates
-     * a client.
+     * (deleted) after a session is terminated through API (not callback!). To
+     * be used in every test which terminates a session.
      *
-     * @param uid The ID of the client which should be deleted.
+     * @param clientId The ID of the client containing the session.
+     * @param sessionId The ID of the terminated session.
      */
-    public void validateInternalClientInfoCleanedUp(int uid) throws Exception {
-        WifiNanClientState client = getInternalClientState(mDut, uid);
-        collector.checkThat("Client record not cleared up for uid=" + uid, client, nullValue());
+    private void validateInternalSessionInfoCleanedUp(int clientId, int sessionId)
+            throws Exception {
+        WifiNanClientState client = getInternalClientState(mDut, clientId);
+        collector.checkThat("Client record exists clientId=" + clientId, client, notNullValue());
+        WifiNanSessionState session = getInternalSessionState(client, sessionId);
+        collector.checkThat("Client record not cleaned-up for sessionId=" + sessionId, session,
+                nullValue());
+    }
+
+    /**
+     * Utility routine used to validate that the internal state is cleaned-up
+     * (deleted) correctly. Checks that a specific client has no sessions
+     * attached to it.
+     *
+     * @param clientId The ID of the client which we want to check.
+     */
+    private void validateInternalNoSessions(int clientId) throws Exception {
+        WifiNanClientState client = getInternalClientState(mDut, clientId);
+        collector.checkThat("Client record exists clientId=" + clientId, client, notNullValue());
+
+        Field field = WifiNanClientState.class.getDeclaredField("mSessions");
+        field.setAccessible(true);
+        @SuppressWarnings("unchecked")
+        SparseArray<WifiNanSessionState> sessions = (SparseArray<WifiNanSessionState>) field
+                .get(client);
+
+        collector.checkThat("No sessions exist for clientId=" + clientId, sessions.size(),
+                equalTo(0));
+    }
+
+    /**
+     * Validates that the broadcast sent on NAN status change is correct.
+     *
+     * @param expectedEnabled The expected change status - i.e. are we expected
+     *            to announce that NAN is enabled (true) or disabled (false).
+     */
+    private void validateCorrectNanStatusChangeBroadcast(InOrder inOrder, boolean expectedEnabled) {
+        ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
+
+        inOrder.verify(mMockContext).sendBroadcastAsUser(intent.capture(), eq(UserHandle.ALL));
+
+        collector.checkThat("intent action", intent.getValue().getAction(),
+                equalTo(WifiNanManager.WIFI_NAN_STATE_CHANGED_ACTION));
+        collector.checkThat("intent contains wifi status key",
+                intent.getValue().getExtras().containsKey(WifiNanManager.EXTRA_WIFI_STATE),
+                equalTo(true));
+        collector.checkThat("intnent wifi status key value",
+                intent.getValue().getExtras().getInt(WifiNanManager.EXTRA_WIFI_STATE),
+                equalTo(expectedEnabled ? WifiNanManager.WIFI_NAN_STATE_ENABLED
+                        : WifiNanManager.WIFI_NAN_STATE_DISABLED));
     }
 
     /*
      * Utilities
      */
 
-    private static WifiNanStateManager installNewNanStateManagerAndResetState() throws Exception {
+    private static WifiNanStateManager installNewNanStateManager()
+            throws Exception {
         Constructor<WifiNanStateManager> ctr = WifiNanStateManager.class.getDeclaredConstructor();
         ctr.setAccessible(true);
         WifiNanStateManager nanStateManager = ctr.newInstance();
@@ -1118,30 +2318,95 @@
         return WifiNanStateManager.getInstance();
     }
 
+    private static void installMocksInStateManager(WifiNanStateManager nanStateManager,
+            WifiNanRttStateManager mockRtt, WifiNanDataPathStateManager mockDpMgr)
+            throws Exception {
+        Field field = WifiNanStateManager.class.getDeclaredField("mRtt");
+        field.setAccessible(true);
+        field.set(nanStateManager, mockRtt);
+
+        field = WifiNanStateManager.class.getDeclaredField("mDataPathMgr");
+        field.setAccessible(true);
+        field.set(nanStateManager, mockDpMgr);
+    }
+
     private static void installMockWifiNanNative(WifiNanNative obj) throws Exception {
         Field field = WifiNanNative.class.getDeclaredField("sWifiNanNativeSingleton");
         field.setAccessible(true);
         field.set(null, obj);
     }
 
-    private static Object getInternalPendingTransactionInfo(WifiNanStateManager dut,
-            short transactionId) throws Exception {
-        Field field = WifiNanStateManager.class.getDeclaredField("mPendingResponses");
-        field.setAccessible(true);
-        @SuppressWarnings("unchecked")
-        SparseArray<Object> pendingResponses = (SparseArray<Object>) field.get(dut);
-
-        return pendingResponses.get(transactionId);
-    }
-
-    private static WifiNanClientState getInternalClientState(WifiNanStateManager dut,
-            int uid) throws Exception {
+    private static WifiNanClientState getInternalClientState(WifiNanStateManager dut, int clientId)
+            throws Exception {
         Field field = WifiNanStateManager.class.getDeclaredField("mClients");
         field.setAccessible(true);
         @SuppressWarnings("unchecked")
         SparseArray<WifiNanClientState> clients = (SparseArray<WifiNanClientState>) field.get(dut);
 
-        return clients.get(uid);
+        return clients.get(clientId);
+    }
+
+    private static WifiNanSessionState getInternalSessionState(WifiNanClientState client,
+            int sessionId) throws Exception {
+        Field field = WifiNanClientState.class.getDeclaredField("mSessions");
+        field.setAccessible(true);
+        @SuppressWarnings("unchecked")
+        SparseArray<WifiNanSessionState> sessions = (SparseArray<WifiNanSessionState>) field
+                .get(client);
+
+        return sessions.get(sessionId);
+    }
+
+    private void validateInternalSendMessageQueuesCleanedUp(int messageId) throws Exception {
+        Field field = WifiNanStateManager.class.getDeclaredField("mSm");
+        field.setAccessible(true);
+        WifiNanStateManager.WifiNanStateMachine sm =
+                (WifiNanStateManager.WifiNanStateMachine) field.get(mDut);
+
+        field = WifiNanStateManager.WifiNanStateMachine.class.getDeclaredField(
+                "mHostQueuedSendMessages");
+        field.setAccessible(true);
+        SparseArray<Message> hostQueuedSendMessages = (SparseArray<Message>) field.get(sm);
+
+        field = WifiNanStateManager.WifiNanStateMachine.class.getDeclaredField(
+                "mFwQueuedSendMessages");
+        field.setAccessible(true);
+        Map<Short, Message> fwQueuedSendMessages = (Map<Short, Message>) field.get(sm);
+
+        for (int i = 0; i < hostQueuedSendMessages.size(); ++i) {
+            Message msg = hostQueuedSendMessages.valueAt(i);
+            if (msg.getData().getInt("message_id") == messageId) {
+                collector.checkThat(
+                        "Message not cleared-up from host queue. Message ID=" + messageId, msg,
+                        nullValue());
+            }
+        }
+
+        for (Message msg: fwQueuedSendMessages.values()) {
+            if (msg.getData().getInt("message_id") == messageId) {
+                collector.checkThat(
+                        "Message not cleared-up from firmware queue. Message ID=" + messageId, msg,
+                        nullValue());
+            }
+        }
+    }
+
+    private static WifiNanNative.Capabilities getCapabilities() {
+        WifiNanNative.Capabilities cap = new WifiNanNative.Capabilities();
+        cap.maxConcurrentNanClusters = 1;
+        cap.maxPublishes = 2;
+        cap.maxSubscribes = 2;
+        cap.maxServiceNameLen = 255;
+        cap.maxMatchFilterLen = 255;
+        cap.maxTotalMatchFilterLen = 255;
+        cap.maxServiceSpecificInfoLen = 255;
+        cap.maxVsaDataLen = 255;
+        cap.maxMeshDataLen = 255;
+        cap.maxNdiInterfaces = 1;
+        cap.maxNdpSessions = 1;
+        cap.maxAppInfoLen = 255;
+        cap.maxQueuedTransmitMessages = 6;
+        return cap;
     }
 }
 
diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
index 1355961..cd3909e 100644
--- a/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/scanner/BaseWifiScannerImplTest.java
@@ -23,16 +23,16 @@
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
+import android.app.test.TestAlarmManager;
 import android.content.Context;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiScanner;
 import android.net.wifi.WifiScanner.ScanData;
 import android.net.wifi.WifiSsid;
 import android.os.SystemClock;
+import android.os.test.TestLooper;
 
 import com.android.server.wifi.Clock;
-import com.android.server.wifi.MockAlarmManager;
-import com.android.server.wifi.MockLooper;
 import com.android.server.wifi.MockResources;
 import com.android.server.wifi.MockWifiMonitor;
 import com.android.server.wifi.ScanDetail;
@@ -59,9 +59,9 @@
  */
 public abstract class BaseWifiScannerImplTest {
     @Mock Context mContext;
-    MockAlarmManager mAlarmManager;
+    TestAlarmManager mAlarmManager;
     MockWifiMonitor mWifiMonitor;
-    MockLooper mLooper;
+    TestLooper mLooper;
     @Mock WifiNative mWifiNative;
     MockResources mResources;
     @Mock Clock mClock;
@@ -75,8 +75,8 @@
     public void setUpBase() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        mLooper = new MockLooper();
-        mAlarmManager = new MockAlarmManager();
+        mLooper = new TestLooper();
+        mAlarmManager = new TestAlarmManager();
         mWifiMonitor = new MockWifiMonitor();
         mResources = new MockResources();
 
@@ -86,7 +86,7 @@
                 .thenReturn(mAlarmManager.getAlarmManager());
 
         when(mContext.getResources()).thenReturn(mResources);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime());
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
     }
 
     protected Set<Integer> expectedBandScanFreqs(int band) {
@@ -389,7 +389,7 @@
                         WifiScanner.WIFI_BAND_24_GHZ)
                 .build();
 
-        long approxScanStartUs = mClock.elapsedRealtime() * 1000;
+        long approxScanStartUs = mClock.getElapsedSinceBootMillis() * 1000;
         ArrayList<ScanDetail> rawResults = new ArrayList<>(Arrays.asList(
                         new ScanDetail(WifiSsid.createFromAsciiEncoded("TEST AP 1"),
                                 "00:00:00:00:00:00", "", -70, 2450,
diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/SupplicantPnoScannerTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/SupplicantPnoScannerTest.java
index 39709f8..35e7ce3 100644
--- a/tests/wifitests/src/com/android/server/wifi/scanner/SupplicantPnoScannerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/scanner/SupplicantPnoScannerTest.java
@@ -22,16 +22,17 @@
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
+import android.app.test.TestAlarmManager;
 import android.content.Context;
+import android.os.test.TestLooper;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiScanner;
 import android.os.SystemClock;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.R;
+
 import com.android.server.wifi.Clock;
-import com.android.server.wifi.MockAlarmManager;
-import com.android.server.wifi.MockLooper;
 import com.android.server.wifi.MockResources;
 import com.android.server.wifi.MockWifiMonitor;
 import com.android.server.wifi.ScanResults;
@@ -56,9 +57,9 @@
 public class SupplicantPnoScannerTest {
 
     @Mock Context mContext;
-    MockAlarmManager mAlarmManager;
+    TestAlarmManager mAlarmManager;
     MockWifiMonitor mWifiMonitor;
-    MockLooper mLooper;
+    TestLooper mLooper;
     @Mock WifiNative mWifiNative;
     MockResources mResources;
     @Mock Clock mClock;
@@ -68,8 +69,8 @@
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        mLooper = new MockLooper();
-        mAlarmManager = new MockAlarmManager();
+        mLooper = new TestLooper();
+        mAlarmManager = new TestAlarmManager();
         mWifiMonitor = new MockWifiMonitor();
         mResources = new MockResources();
 
@@ -77,7 +78,7 @@
         when(mContext.getSystemService(Context.ALARM_SERVICE))
                 .thenReturn(mAlarmManager.getAlarmManager());
         when(mContext.getResources()).thenReturn(mResources);
-        when(mClock.elapsedRealtime()).thenReturn(SystemClock.elapsedRealtime());
+        when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime());
     }
 
     /**
diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
index 03a11dc..82d9e8d 100644
--- a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
@@ -22,6 +22,8 @@
 import static org.mockito.Matchers.*;
 import static org.mockito.Mockito.*;
 
+import android.app.test.MockAnswerUtil.AnswerWithArguments;
+import android.app.test.TestAlarmManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.IntentFilter;
@@ -35,17 +37,15 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.WorkSource;
+import android.os.test.TestLooper;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Pair;
 
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
-import com.android.server.wifi.BidirectionalAsyncChannel;
+import com.android.internal.util.test.BidirectionalAsyncChannel;
 import com.android.server.wifi.Clock;
-import com.android.server.wifi.MockAlarmManager;
-import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
-import com.android.server.wifi.MockLooper;
 import com.android.server.wifi.ScanResults;
 import com.android.server.wifi.TestUtil;
 import com.android.server.wifi.WifiInjector;
@@ -78,14 +78,14 @@
     public static final String TAG = "WifiScanningServiceTest";
 
     @Mock Context mContext;
-    MockAlarmManager mAlarmManager;
+    TestAlarmManager mAlarmManager;
     @Mock WifiScannerImpl mWifiScannerImpl;
     @Mock WifiScannerImpl.WifiScannerImplFactory mWifiScannerImplFactory;
     @Mock IBatteryStats mBatteryStats;
     @Mock WifiInjector mWifiInjector;
     @Mock Clock mClock;
     WifiMetrics mWifiMetrics;
-    MockLooper mLooper;
+    TestLooper mLooper;
     WifiScanningServiceImpl mWifiScanningServiceImpl;
 
 
@@ -93,7 +93,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        mAlarmManager = new MockAlarmManager();
+        mAlarmManager = new TestAlarmManager();
         when(mContext.getSystemService(Context.ALARM_SERVICE))
                 .thenReturn(mAlarmManager.getAlarmManager());
         mWifiMetrics = new WifiMetrics(mClock);
@@ -103,7 +103,7 @@
                 new int[]{5150, 5175},
                 new int[]{5600, 5650, 5660});
 
-        mLooper = new MockLooper();
+        mLooper = new TestLooper();
         when(mWifiScannerImplFactory
                 .create(any(Context.class), any(Looper.class), any(Clock.class)))
                 .thenReturn(mWifiScannerImpl);
diff --git a/tests/wifitests/src/com/android/server/wifi/ByteArrayRingBufferTest.java b/tests/wifitests/src/com/android/server/wifi/util/ByteArrayRingBufferTest.java
similarity index 100%
rename from tests/wifitests/src/com/android/server/wifi/ByteArrayRingBufferTest.java
rename to tests/wifitests/src/com/android/server/wifi/util/ByteArrayRingBufferTest.java
diff --git a/tests/wifitests/src/com/android/server/wifi/util/ScanDetailUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
similarity index 93%
rename from tests/wifitests/src/com/android/server/wifi/util/ScanDetailUtilTest.java
rename to tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
index 07d2521..275a40b 100644
--- a/tests/wifitests/src/com/android/server/wifi/util/ScanDetailUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
@@ -33,10 +33,10 @@
 import java.util.Arrays;
 
 /**
- * Unit tests for {@link com.android.server.wifi.util.ScanDetailUtil}.
+ * Unit tests for {@link com.android.server.wifi.util.ScanResultUtil}.
  */
 @SmallTest
-public class ScanDetailUtilTest {
+public class ScanResultUtilTest {
 
     @Test
     public void convertScanResult() {
@@ -49,7 +49,7 @@
             createIE(InformationElement.EID_SSID, ssid.getBytes(StandardCharsets.UTF_8))
         };
 
-        ScanDetail output = ScanDetailUtil.toScanDetail(input);
+        ScanDetail output = ScanResultUtil.toScanDetail(input);
 
         validateScanDetail(input, output);
     }
@@ -66,7 +66,7 @@
         };
         input.anqpLines = Arrays.asList("LINE 1", "line 2", "Line 3");
 
-        ScanDetail output = ScanDetailUtil.toScanDetail(input);
+        ScanDetail output = ScanResultUtil.toScanDetail(input);
 
         validateScanDetail(input, output);
     }
@@ -80,7 +80,7 @@
             createIE(InformationElement.EID_SSID, ssid.getBytes(StandardCharsets.UTF_8))
         };
 
-        ScanDetail output = ScanDetailUtil.toScanDetail(input);
+        ScanDetail output = ScanResultUtil.toScanDetail(input);
 
         validateScanDetail(input, output);
     }
diff --git a/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
new file mode 100644
index 0000000..7b06164
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
@@ -0,0 +1,402 @@
+/*
+ * 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 com.android.server.wifi.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.*;
+
+import android.net.IpConfiguration;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
+import android.net.wifi.WifiEnterpriseConfig;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Pair;
+import android.util.Xml;
+
+import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.WifiConfigurationTestUtil;
+import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
+import com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil;
+import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
+import com.android.server.wifi.util.XmlUtil.WifiEnterpriseConfigXmlUtil;
+
+import org.junit.Test;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.util.XmlUtil}.
+ */
+@SmallTest
+public class XmlUtilTest {
+
+    private static final String TEST_PACKAGE_NAME = "XmlUtilPackage";
+    private static final String TEST_STATIC_IP_GATEWAY_ADDRESS = "192.168.48.1";
+    private static final String TEST_DUMMY_CONFIG_KEY = "XmlUtilDummyConfigKey";
+    private static final String TEST_IDENTITY = "XmlUtilTestIdentity";
+    private static final String TEST_ANON_IDENTITY = "XmlUtilTestAnonIdentity";
+    private static final String TEST_PASSWORD = "XmlUtilTestPassword";
+    private static final String TEST_CLIENT_CERT = "XmlUtilTestClientCert";
+    private static final String TEST_CA_CERT = "XmlUtilTestCaCert";
+    private static final String TEST_SUBJECT_MATCH = "XmlUtilTestSubjectMatch";
+    private static final String TEST_ENGINE = "XmlUtilTestEngine";
+    private static final String TEST_ENGINE_ID = "XmlUtilTestEngineId";
+    private static final String TEST_PRIVATE_KEY_ID = "XmlUtilTestPrivateKeyId";
+    private static final String TEST_ALTSUBJECT_MATCH = "XmlUtilTestAltSubjectMatch";
+    private static final String TEST_DOM_SUFFIX_MATCH = "XmlUtilTestDomSuffixMatch";
+    private static final String TEST_CA_PATH = "XmlUtilTestCaPath";
+    private static final int TEST_EAP_METHOD = WifiEnterpriseConfig.Eap.PEAP;
+    private static final int TEST_PHASE2_METHOD = WifiEnterpriseConfig.Phase2.MSCHAPV2;
+    private final String mXmlDocHeader = "XmlUtilTest";
+
+    /**
+     * Verify that a open WifiConfiguration is serialized & deserialized correctly.
+     */
+    @Test
+    public void testOpenWifiConfigurationSerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createOpenNetwork());
+    }
+
+    /**
+     * Verify that a open hidden WifiConfiguration is serialized & deserialized correctly.
+     */
+    @Test
+    public void testOpenHiddenWifiConfigurationSerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createOpenHiddenNetwork());
+    }
+
+    /**
+     * Verify that a psk WifiConfiguration is serialized & deserialized correctly.
+     */
+    @Test
+    public void testPskWifiConfigurationSerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createPskNetwork());
+    }
+
+    /**
+     * Verify that a psk hidden WifiConfiguration is serialized & deserialized correctly.
+     */
+    @Test
+    public void testPskHiddenWifiConfigurationSerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createPskHiddenNetwork());
+    }
+
+    /**
+     * Verify that a WEP WifiConfiguration is serialized & deserialized correctly.
+     */
+    @Test
+    public void testWepWifiConfigurationSerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeWifiConfiguration(WifiConfigurationTestUtil.createWepNetwork());
+    }
+
+    /**
+     * Verify that a EAP WifiConfiguration is serialized & deserialized correctly only for
+     * ConfigStore.
+     */
+    @Test
+    public void testEapWifiConfigurationSerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeWifiConfigurationForConfigStore(
+                WifiConfigurationTestUtil.createEapNetwork());
+    }
+
+    /**
+     * Verify that a static IpConfiguration with PAC proxy is serialized & deserialized correctly.
+     */
+    @Test
+    public void testStaticIpConfigurationWithPacProxySerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeIpConfiguration(
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
+    }
+
+    /**
+     * Verify that a static IpConfiguration with static proxy is serialized & deserialized correctly.
+     */
+    @Test
+    public void testStaticIpConfigurationWithStaticProxySerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeIpConfiguration(
+                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
+    }
+
+    /**
+     * Verify that a partial static IpConfiguration with PAC proxy is serialized & deserialized
+     * correctly.
+     */
+    @Test
+    public void testPartialStaticIpConfigurationWithPacProxySerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeIpConfiguration(
+                WifiConfigurationTestUtil.createPartialStaticIpConfigurationWithPacProxy());
+    }
+
+    /**
+     * Verify that a DHCP IpConfiguration with PAC proxy is serialized & deserialized
+     * correctly.
+     */
+    @Test
+    public void testDHCPIpConfigurationWithPacProxySerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeIpConfiguration(
+                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy());
+    }
+
+    /**
+     * Verify that a DHCP IpConfiguration with Static proxy is serialized & deserialized
+     * correctly.
+     */
+    @Test
+    public void testDHCPIpConfigurationWithStaticProxySerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        serializeDeserializeIpConfiguration(
+                WifiConfigurationTestUtil.createDHCPIpConfigurationWithStaticProxy());
+    }
+
+    /**
+     * Verify that a EAP WifiConfiguration is serialized & deserialized correctly for config store.
+     * This basically exercises all the elements being serialized in config store.
+     */
+    @Test
+    public void testEapWifiConfigurationSerializeDeserializeForConfigStore()
+            throws IOException, XmlPullParserException {
+        WifiConfiguration configuration = WifiConfigurationTestUtil.createEapNetwork();
+        configuration.linkedConfigurations = new HashMap<>();
+        configuration.linkedConfigurations.put(TEST_DUMMY_CONFIG_KEY, Integer.valueOf(1));
+        configuration.defaultGwMacAddress = TEST_STATIC_IP_GATEWAY_ADDRESS;
+        configuration.validatedInternetAccess = true;
+        configuration.noInternetAccessExpected = true;
+        configuration.userApproved = WifiConfiguration.USER_UNSPECIFIED;
+        configuration.meteredHint = true;
+        configuration.useExternalScores = true;
+        configuration.numAssociation = 5;
+        configuration.lastUpdateUid = configuration.lastConnectUid = configuration.creatorUid;
+        configuration.creatorName = configuration.lastUpdateName = TEST_PACKAGE_NAME;
+        configuration.creationTime = "04-04-2016";
+
+        serializeDeserializeWifiConfigurationForConfigStore(configuration);
+    }
+
+    /**
+     * Verify that an enabled network selection status object is serialized & deserialized
+     * correctly.
+     */
+    @Test
+    public void testEnabledNetworkSelectionStatusSerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        NetworkSelectionStatus status = new NetworkSelectionStatus();
+        status.setNetworkSelectionStatus(NetworkSelectionStatus.NETWORK_SELECTION_ENABLED);
+        status.setNetworkSelectionDisableReason(NetworkSelectionStatus.NETWORK_SELECTION_ENABLE);
+        status.setConnectChoice(TEST_DUMMY_CONFIG_KEY);
+        status.setConnectChoiceTimestamp(867889);
+        status.setHasEverConnected(true);
+        serializeDeserializeNetworkSelectionStatus(status);
+    }
+
+    /**
+     * Verify that a temporarily disabled network selection status object is serialized &
+     * deserialized correctly.
+     */
+    @Test
+    public void testTemporarilyDisabledNetworkSelectionStatusSerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        NetworkSelectionStatus status = new NetworkSelectionStatus();
+        status.setNetworkSelectionStatus(
+                NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED);
+        status.setNetworkSelectionDisableReason(
+                NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION);
+        serializeDeserializeNetworkSelectionStatus(status);
+    }
+
+    /**
+     * Verify that a WifiEnterpriseConfig object is serialized & deserialized correctly.
+     */
+    @Test
+    public void testWifiEnterpriseConfigSerializeDeserialize()
+            throws IOException, XmlPullParserException {
+        WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+        config.setFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, TEST_IDENTITY);
+        config.setFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY, TEST_ANON_IDENTITY);
+        config.setFieldValue(WifiEnterpriseConfig.PASSWORD_KEY, TEST_PASSWORD);
+        config.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, TEST_CLIENT_CERT);
+        config.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, TEST_CA_CERT);
+        config.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, TEST_SUBJECT_MATCH);
+        config.setFieldValue(WifiEnterpriseConfig.ENGINE_KEY, TEST_ENGINE);
+        config.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, TEST_ENGINE_ID);
+        config.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, TEST_PRIVATE_KEY_ID);
+        config.setFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, TEST_ALTSUBJECT_MATCH);
+        config.setFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, TEST_DOM_SUFFIX_MATCH);
+        config.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, TEST_CA_PATH);
+        config.setEapMethod(TEST_EAP_METHOD);
+        config.setPhase2Method(TEST_PHASE2_METHOD);
+        serializeDeserializeWifiEnterpriseConfig(config);
+    }
+
+    private byte[] serializeWifiConfigurationForBackup(WifiConfiguration configuration)
+            throws IOException, XmlPullParserException {
+        final XmlSerializer out = new FastXmlSerializer();
+        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
+        WifiConfigurationXmlUtil.writeToXmlForBackup(out, configuration);
+        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
+        return outputStream.toByteArray();
+    }
+
+    private byte[] serializeWifiConfigurationForConfigStore(
+            WifiConfiguration configuration)
+            throws IOException, XmlPullParserException {
+        final XmlSerializer out = new FastXmlSerializer();
+        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
+        WifiConfigurationXmlUtil.writeToXmlForConfigStore(out, configuration);
+        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
+        return outputStream.toByteArray();
+    }
+
+    private Pair<String, WifiConfiguration> deserializeWifiConfiguration(byte[] data)
+            throws IOException, XmlPullParserException {
+        // Deserialize the configuration object.
+        final XmlPullParser in = Xml.newPullParser();
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
+        in.setInput(inputStream, StandardCharsets.UTF_8.name());
+        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
+        return WifiConfigurationXmlUtil.parseFromXml(in, in.getDepth());
+    }
+
+    /**
+     * This helper method tests the serialization for backup/restore.
+     */
+    private void serializeDeserializeWifiConfigurationForBackupRestore(
+            WifiConfiguration configuration)
+            throws IOException, XmlPullParserException {
+        Pair<String, WifiConfiguration> retrieved;
+        // Test serialization/deserialization for config store.
+        retrieved =
+                deserializeWifiConfiguration(
+                        serializeWifiConfigurationForBackup(configuration));
+        assertEquals(retrieved.first, retrieved.second.configKey());
+        WifiConfigurationTestUtil.assertConfigurationEqualForBackup(
+                configuration, retrieved.second);
+    }
+
+    /**
+     * This helper method tests the serialization for config store.
+     */
+    private void serializeDeserializeWifiConfigurationForConfigStore(
+            WifiConfiguration configuration)
+            throws IOException, XmlPullParserException {
+        // Reset enterprise config because this needs to be serialized/deserialized separately.
+        configuration.enterpriseConfig = new WifiEnterpriseConfig();
+        Pair<String, WifiConfiguration> retrieved;
+        // Test serialization/deserialization for config store.
+        retrieved =
+                deserializeWifiConfiguration(
+                        serializeWifiConfigurationForConfigStore(configuration));
+        assertEquals(retrieved.first, retrieved.second.configKey());
+        WifiConfigurationTestUtil.assertConfigurationEqualForConfigStore(
+                configuration, retrieved.second);
+    }
+
+    /**
+     * This helper method tests both the serialization for backup/restore and config store.
+     */
+    private void serializeDeserializeWifiConfiguration(WifiConfiguration configuration)
+            throws IOException, XmlPullParserException {
+        Pair<String, WifiConfiguration> retrieved;
+        // Test serialization/deserialization for backup first.
+        serializeDeserializeWifiConfigurationForBackupRestore(configuration);
+
+        // Test serialization/deserialization for config store.
+        serializeDeserializeWifiConfigurationForConfigStore(configuration);
+    }
+
+    private void serializeDeserializeIpConfiguration(IpConfiguration configuration)
+            throws IOException, XmlPullParserException {
+        // Serialize the configuration object.
+        final XmlSerializer out = new FastXmlSerializer();
+        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
+        IpConfigurationXmlUtil.writeToXml(out, configuration);
+        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
+
+        // Deserialize the configuration object.
+        final XmlPullParser in = Xml.newPullParser();
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+        in.setInput(inputStream, StandardCharsets.UTF_8.name());
+        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
+        IpConfiguration retrievedConfiguration =
+                IpConfigurationXmlUtil.parseFromXml(in, in.getDepth());
+        assertEquals(configuration, retrievedConfiguration);
+    }
+
+    private void serializeDeserializeNetworkSelectionStatus(NetworkSelectionStatus status)
+            throws IOException, XmlPullParserException {
+        // Serialize the configuration object.
+        final XmlSerializer out = new FastXmlSerializer();
+        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
+        NetworkSelectionStatusXmlUtil.writeToXml(out, status);
+        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
+
+        // Deserialize the configuration object.
+        final XmlPullParser in = Xml.newPullParser();
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+        in.setInput(inputStream, StandardCharsets.UTF_8.name());
+        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
+        NetworkSelectionStatus retrievedStatus =
+                NetworkSelectionStatusXmlUtil.parseFromXml(in, in.getDepth());
+        WifiConfigurationTestUtil.assertNetworkSelectionStatusEqualForConfigStore(
+                status, retrievedStatus);
+    }
+
+    private void serializeDeserializeWifiEnterpriseConfig(WifiEnterpriseConfig config)
+            throws IOException, XmlPullParserException {
+        // Serialize the configuration object.
+        final XmlSerializer out = new FastXmlSerializer();
+        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        out.setOutput(outputStream, StandardCharsets.UTF_8.name());
+        XmlUtil.writeDocumentStart(out, mXmlDocHeader);
+        WifiEnterpriseConfigXmlUtil.writeToXml(out, config);
+        XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
+
+        // Deserialize the configuration object.
+        final XmlPullParser in = Xml.newPullParser();
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+        in.setInput(inputStream, StandardCharsets.UTF_8.name());
+        XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
+        WifiEnterpriseConfig retrievedConfig =
+                WifiEnterpriseConfigXmlUtil.parseFromXml(in, in.getDepth());
+        WifiConfigurationTestUtil.assertWifiEnterpriseConfigEqualForConfigStore(
+                config, retrievedConfig);
+    }
+}
