wifi(implementation): Add unit test framework

We're going to add some non-trivial logic in wifi chip to handle
multiple chip configurations (to support devices with different
capabilities). So, adding a unit test framework in preparation
for testing those changes.

The mocks only mock legacy HAL methods which are in use during chip
configuration & interface creation/deletion.

Bug: 68775880
Test: Compiles
Change-Id: I8575df02f54656f77077d14ac9535ccc974bdff3
diff --git a/wifi/1.2/default/Android.mk b/wifi/1.2/default/Android.mk
index b242cfc..2205e4e 100644
--- a/wifi/1.2/default/Android.mk
+++ b/wifi/1.2/default/Android.mk
@@ -13,8 +13,11 @@
 # limitations under the License.
 LOCAL_PATH := $(call my-dir)
 
+###
+### android.hardware.wifi static library
+###
 include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.wifi@1.0-service
+LOCAL_MODULE := android.hardware.wifi@1.0-service-lib
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_PROPRIETARY_MODULE := true
 LOCAL_CPPFLAGS := -Wall -Werror -Wextra
@@ -24,10 +27,10 @@
 LOCAL_SRC_FILES := \
     hidl_struct_util.cpp \
     hidl_sync_util.cpp \
-    service.cpp \
     wifi.cpp \
     wifi_ap_iface.cpp \
     wifi_chip.cpp \
+    wifi_feature_flags.cpp \
     wifi_legacy_hal.cpp \
     wifi_legacy_hal_stubs.cpp \
     wifi_mode_controller.cpp \
@@ -49,5 +52,63 @@
     android.hardware.wifi@1.0 \
     android.hardware.wifi@1.1 \
     android.hardware.wifi@1.2
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+include $(BUILD_STATIC_LIBRARY)
+
+###
+### android.hardware.wifi daemon
+###
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.wifi@1.0-service
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_CPPFLAGS := -Wall -Werror -Wextra
+LOCAL_SRC_FILES := \
+    service.cpp
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    libcutils \
+    libhidlbase \
+    libhidltransport \
+    liblog \
+    libnl \
+    libutils \
+    libwifi-hal \
+    libwifi-system-iface \
+    android.hardware.wifi@1.0 \
+    android.hardware.wifi@1.1 \
+    android.hardware.wifi@1.2
+LOCAL_STATIC_LIBRARIES := \
+    android.hardware.wifi@1.0-service-lib
 LOCAL_INIT_RC := android.hardware.wifi@1.0-service.rc
 include $(BUILD_EXECUTABLE)
+
+###
+### android.hardware.wifi unit tests.
+###
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.wifi@1.0-service-tests
+LOCAL_SRC_FILES := \
+    tests/main.cpp \
+    tests/mock_wifi_feature_flags.cpp \
+    tests/mock_wifi_legacy_hal.cpp \
+    tests/mock_wifi_mode_controller.cpp \
+    tests/wifi_chip_unit_tests.cpp
+LOCAL_STATIC_LIBRARIES := \
+    libgmock \
+    libgtest \
+    android.hardware.wifi@1.0-service-lib
+LOCAL_SHARED_LIBRARIES := \
+    libbase \
+    libcutils \
+    libhidlbase \
+    libhidltransport \
+    liblog \
+    libnl \
+    libutils \
+    libwifi-hal \
+    libwifi-system-iface \
+    android.hardware.wifi@1.0 \
+    android.hardware.wifi@1.1 \
+    android.hardware.wifi@1.2
+include $(BUILD_NATIVE_TEST)
diff --git a/wifi/1.2/default/service.cpp b/wifi/1.2/default/service.cpp
index 6297cf2..01d22bd 100644
--- a/wifi/1.2/default/service.cpp
+++ b/wifi/1.2/default/service.cpp
@@ -20,9 +20,17 @@
 #include <utils/StrongPointer.h>
 
 #include "wifi.h"
+#include "wifi_feature_flags.h"
+#include "wifi_legacy_hal.h"
+#include "wifi_mode_controller.h"
 
 using android::hardware::configureRpcThreadpool;
 using android::hardware::joinRpcThreadpool;
+using android::hardware::wifi::V1_2::implementation::feature_flags::
+    WifiFeatureFlags;
+using android::hardware::wifi::V1_2::implementation::legacy_hal::WifiLegacyHal;
+using android::hardware::wifi::V1_2::implementation::mode_controller::
+    WifiModeController;
 
 int main(int /*argc*/, char** argv) {
     android::base::InitLogging(
@@ -33,7 +41,10 @@
 
     // Setup hwbinder service
     android::sp<android::hardware::wifi::V1_2::IWifi> service =
-        new android::hardware::wifi::V1_2::implementation::Wifi();
+        new android::hardware::wifi::V1_2::implementation::Wifi(
+            std::make_shared<WifiLegacyHal>(),
+            std::make_shared<WifiModeController>(),
+            std::make_shared<WifiFeatureFlags>());
     CHECK_EQ(service->registerAsService(), android::NO_ERROR)
         << "Failed to register wifi HAL";
 
diff --git a/wifi/1.2/default/tests/main.cpp b/wifi/1.2/default/tests/main.cpp
new file mode 100644
index 0000000..9aac837
--- /dev/null
+++ b/wifi/1.2/default/tests/main.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ::testing::InitGoogleMock(&argc, argv);
+    // Force ourselves to always log to stderr
+    android::base::InitLogging(argv, android::base::StderrLogger);
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/1.2/default/tests/mock_wifi_feature_flags.cpp b/wifi/1.2/default/tests/mock_wifi_feature_flags.cpp
new file mode 100644
index 0000000..8d0b192
--- /dev/null
+++ b/wifi/1.2/default/tests/mock_wifi_feature_flags.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+
+#include "mock_wifi_feature_flags.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+namespace feature_flags {
+
+MockWifiFeatureFlags::MockWifiFeatureFlags() {}
+
+}  // namespace feature_flags
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.2/default/tests/mock_wifi_feature_flags.h b/wifi/1.2/default/tests/mock_wifi_feature_flags.h
new file mode 100644
index 0000000..85927f9
--- /dev/null
+++ b/wifi/1.2/default/tests/mock_wifi_feature_flags.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_WIFI_FEATURE_FLAGS_H_
+#define MOCK_WIFI_FEATURE_FLAGS_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_feature_flags.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+namespace feature_flags {
+
+class MockWifiFeatureFlags : public WifiFeatureFlags {
+   public:
+    MockWifiFeatureFlags();
+
+    MOCK_METHOD0(isAwareSupported, bool());
+};
+
+}  // namespace feature_flags
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // MOCK_WIFI_FEATURE_FLAGS_H_
diff --git a/wifi/1.2/default/tests/mock_wifi_legacy_hal.cpp b/wifi/1.2/default/tests/mock_wifi_legacy_hal.cpp
new file mode 100644
index 0000000..8381dde
--- /dev/null
+++ b/wifi/1.2/default/tests/mock_wifi_legacy_hal.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "mock_wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+namespace legacy_hal {
+
+MockWifiLegacyHal::MockWifiLegacyHal() : WifiLegacyHal() {}
+}  // namespace legacy_hal
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.2/default/tests/mock_wifi_legacy_hal.h b/wifi/1.2/default/tests/mock_wifi_legacy_hal.h
new file mode 100644
index 0000000..8e1696e
--- /dev/null
+++ b/wifi/1.2/default/tests/mock_wifi_legacy_hal.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_WIFI_LEGACY_HAL_H_
+#define MOCK_WIFI_LEGACY_HAL_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_legacy_hal.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+namespace legacy_hal {
+
+class MockWifiLegacyHal : public WifiLegacyHal {
+   public:
+    MockWifiLegacyHal();
+    MOCK_METHOD0(initialize, wifi_error());
+    MOCK_METHOD0(start, wifi_error());
+    MOCK_METHOD2(stop, wifi_error(std::unique_lock<std::recursive_mutex>*,
+                                  const std::function<void()>&));
+    MOCK_METHOD2(setDfsFlag, wifi_error(const std::string&, bool));
+    MOCK_METHOD2(nanRegisterCallbackHandlers,
+                 wifi_error(const std::string&, const NanCallbackHandlers&));
+    MOCK_METHOD2(nanDisableRequest,
+                 wifi_error(const std::string&, transaction_id));
+    MOCK_METHOD3(nanDataInterfaceDelete,
+                 wifi_error(const std::string&, transaction_id,
+                            const std::string&));
+};
+}  // namespace legacy_hal
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // MOCK_WIFI_LEGACY_HAL_H_
diff --git a/wifi/1.2/default/tests/mock_wifi_mode_controller.cpp b/wifi/1.2/default/tests/mock_wifi_mode_controller.cpp
new file mode 100644
index 0000000..461a581
--- /dev/null
+++ b/wifi/1.2/default/tests/mock_wifi_mode_controller.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "mock_wifi_mode_controller.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+namespace mode_controller {
+
+MockWifiModeController::MockWifiModeController() : WifiModeController() {}
+}  // namespace mode_controller
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.2/default/tests/mock_wifi_mode_controller.h b/wifi/1.2/default/tests/mock_wifi_mode_controller.h
new file mode 100644
index 0000000..73ff5f0
--- /dev/null
+++ b/wifi/1.2/default/tests/mock_wifi_mode_controller.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_WIFI_MODE_CONTROLLER_H_
+#define MOCK_WIFI_MODE_CONTROLLER_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_mode_controller.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+namespace mode_controller {
+
+class MockWifiModeController : public WifiModeController {
+   public:
+    MockWifiModeController();
+    MOCK_METHOD1(changeFirmwareMode, bool(IfaceType));
+    MOCK_METHOD1(isFirmwareModeChangeNeeded, bool(IfaceType));
+    MOCK_METHOD0(deinitialize, bool());
+};
+}  // namespace mode_controller
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // MOCK_WIFI_MODE_CONTROLLER_H_
diff --git a/wifi/1.2/default/tests/runtests.sh b/wifi/1.2/default/tests/runtests.sh
new file mode 100755
index 0000000..a1bbc93
--- /dev/null
+++ b/wifi/1.2/default/tests/runtests.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+
+# Copyright(C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0(the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http:// www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+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
+
+#NOTE We can't actually run these commands, since they rely on functions added by
+#build / envsetup.sh to the bash shell environment.
+echo "+ mmma -j32 $ANDROID_BUILD_TOP/"
+make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk \
+    MODULES-IN-hardware-interfaces-wifi-1.2-default
+
+set -x # print commands
+
+adb wait-for-device
+adb root
+adb wait-for-device
+
+#'disable-verity' will appear in 'adb remount' output if
+#dm - verity is enabled and needs to be disabled.
+if adb remount | grep 'disable-verity'; then
+  adb disable-verity
+  adb reboot
+  adb wait-for-device
+  adb root
+  adb wait-for-device
+  adb remount
+fi
+
+adb sync
+
+adb shell /data/nativetest64/android.hardware.wifi@1.0-service-tests/android.hardware.wifi@1.0-service-tests
diff --git a/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
new file mode 100644
index 0000000..5d217d6
--- /dev/null
+++ b/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <gmock/gmock.h>
+
+#undef NAN  // This is weird, NAN is defined in bionic/libc/include/math.h:38
+#include "wifi_chip.h"
+
+#include "mock_wifi_feature_flags.h"
+#include "mock_wifi_legacy_hal.h"
+#include "mock_wifi_mode_controller.h"
+
+using testing::NiceMock;
+using testing::Return;
+using testing::Test;
+
+namespace {}  // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+
+class WifiChipTest : public Test {
+   protected:
+    void setupV1IfaceCombination() {
+        EXPECT_CALL(*feature_flags_, isAwareSupported())
+            .WillRepeatedly(testing::Return(false));
+    }
+
+    void setupV2IfaceCombination() {
+        EXPECT_CALL(*feature_flags_, isAwareSupported())
+            .WillRepeatedly(testing::Return(true));
+    }
+
+    sp<WifiChip> chip_;
+
+    ChipId chip_id_ = 5;
+    std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+        new NiceMock<legacy_hal::MockWifiLegacyHal>};
+    std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>>
+        mode_controller_{new NiceMock<mode_controller::MockWifiModeController>};
+    std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
+        feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
+
+   public:
+    void SetUp() override {
+        chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_,
+                             feature_flags_);
+    }
+};
+
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.2/default/wifi.cpp b/wifi/1.2/default/wifi.cpp
index a2d8f9f..5a8b66e 100644
--- a/wifi/1.2/default/wifi.cpp
+++ b/wifi/1.2/default/wifi.cpp
@@ -33,9 +33,13 @@
 using hidl_return_util::validateAndCall;
 using hidl_return_util::validateAndCallWithLock;
 
-Wifi::Wifi()
-    : legacy_hal_(new legacy_hal::WifiLegacyHal()),
-      mode_controller_(new mode_controller::WifiModeController()),
+Wifi::Wifi(
+    const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+    const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
+    const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
+    : legacy_hal_(legacy_hal),
+      mode_controller_(mode_controller),
+      feature_flags_(feature_flags),
       run_state_(RunState::STOPPED) {}
 
 bool Wifi::isValid() {
@@ -91,7 +95,8 @@
     WifiStatus wifi_status = initializeLegacyHal();
     if (wifi_status.code == WifiStatusCode::SUCCESS) {
         // Create the chip instance once the HAL is started.
-        chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_);
+        chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,
+                             feature_flags_);
         run_state_ = RunState::STARTED;
         for (const auto& callback : event_cb_handler_.getCallbacks()) {
             if (!callback->onStart().isOk()) {
diff --git a/wifi/1.2/default/wifi.h b/wifi/1.2/default/wifi.h
index 114d774..d76e9c9 100644
--- a/wifi/1.2/default/wifi.h
+++ b/wifi/1.2/default/wifi.h
@@ -25,6 +25,7 @@
 
 #include "hidl_callback_util.h"
 #include "wifi_chip.h"
+#include "wifi_feature_flags.h"
 #include "wifi_legacy_hal.h"
 #include "wifi_mode_controller.h"
 
@@ -39,7 +40,10 @@
  */
 class Wifi : public V1_2::IWifi {
    public:
-    Wifi();
+    Wifi(const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+         const std::shared_ptr<mode_controller::WifiModeController>
+             mode_controller,
+         const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
 
     bool isValid();
 
@@ -72,6 +76,7 @@
     // and shared with all the child HIDL interface objects.
     std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
+    std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
     RunState run_state_;
     sp<WifiChip> chip_;
     hidl_callback_util::HidlCallbackHandler<IWifiEventCallback>
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index 49cf888..c4956e0 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -20,7 +20,6 @@
 #include "hidl_return_util.h"
 #include "hidl_struct_util.h"
 #include "wifi_chip.h"
-#include "wifi_feature_flags.h"
 #include "wifi_status_util.h"
 
 namespace {
@@ -103,10 +102,12 @@
 
 WifiChip::WifiChip(
     ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-    const std::weak_ptr<mode_controller::WifiModeController> mode_controller)
+    const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
+    const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags)
     : chip_id_(chip_id),
       legacy_hal_(legacy_hal),
       mode_controller_(mode_controller),
+      feature_flags_(feature_flags),
       is_valid_(true),
       current_mode_id_(kInvalidModeId),
       debug_ring_buffer_cb_registered_(false) {}
@@ -404,7 +405,7 @@
     const IWifiChip::ChipIfaceCombinationLimit
         sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
     IWifiChip::ChipIfaceCombinationLimit sta_chip_iface_combination_limit_2;
-    if (WifiFeatureFlags::wifiHidlFeatureAware) {
+    if (feature_flags_.lock()->isAwareSupported()) {
         sta_chip_iface_combination_limit_2 = {{IfaceType::P2P, IfaceType::NAN},
                                               1};
     } else {
@@ -572,7 +573,7 @@
 
 std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
     // Only 1 of NAN or P2P iface can be active at a time.
-    if (WifiFeatureFlags::wifiHidlFeatureAware) {
+    if (feature_flags_.lock()->isAwareSupported()) {
         if (current_mode_id_ != kStaChipModeId || !nan_ifaces_.empty() ||
             !p2p_ifaces_.empty()) {
             return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
diff --git a/wifi/1.2/default/wifi_chip.h b/wifi/1.2/default/wifi_chip.h
index 4830af9..b843cf3 100644
--- a/wifi/1.2/default/wifi_chip.h
+++ b/wifi/1.2/default/wifi_chip.h
@@ -24,6 +24,7 @@
 
 #include "hidl_callback_util.h"
 #include "wifi_ap_iface.h"
+#include "wifi_feature_flags.h"
 #include "wifi_legacy_hal.h"
 #include "wifi_mode_controller.h"
 #include "wifi_nan_iface.h"
@@ -45,10 +46,12 @@
  */
 class WifiChip : public V1_1::IWifiChip {
    public:
-    WifiChip(ChipId chip_id,
-             const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
-             const std::weak_ptr<mode_controller::WifiModeController>
-                 mode_controller);
+    WifiChip(
+        ChipId chip_id,
+        const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+        const std::weak_ptr<mode_controller::WifiModeController>
+            mode_controller,
+        const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags);
     // HIDL does not provide a built-in mechanism to let the server invalidate
     // a HIDL interface object after creation. If any client process holds onto
     // a reference to the object in their context, any method calls on that
@@ -193,6 +196,7 @@
     ChipId chip_id_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
+    std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
     std::vector<sp<WifiApIface>> ap_ifaces_;
     std::vector<sp<WifiNanIface>> nan_ifaces_;
     std::vector<sp<WifiP2pIface>> p2p_ifaces_;
diff --git a/wifi/1.2/default/wifi_feature_flags.cpp b/wifi/1.2/default/wifi_feature_flags.cpp
new file mode 100644
index 0000000..aba31fb
--- /dev/null
+++ b/wifi/1.2/default/wifi_feature_flags.cpp
@@ -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.
+ */
+
+#include "wifi_feature_flags.h"
+
+namespace {
+#ifdef WIFI_HIDL_FEATURE_AWARE
+static const bool wifiHidlFeatureAware = true;
+#else
+static const bool wifiHidlFeatureAware = false;
+#endif  // WIFI_HIDL_FEATURE_AWARE
+}  // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+namespace feature_flags {
+
+WifiFeatureFlags::WifiFeatureFlags() {}
+bool WifiFeatureFlags::isAwareSupported() { return wifiHidlFeatureAware; }
+
+}  // namespace feature_flags
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.2/default/wifi_feature_flags.h b/wifi/1.2/default/wifi_feature_flags.h
index da4ca37..a31ac0f 100644
--- a/wifi/1.2/default/wifi_feature_flags.h
+++ b/wifi/1.2/default/wifi_feature_flags.h
@@ -22,16 +22,17 @@
 namespace wifi {
 namespace V1_2 {
 namespace implementation {
+namespace feature_flags {
 
 class WifiFeatureFlags {
    public:
-#ifdef WIFI_HIDL_FEATURE_AWARE
-    static const bool wifiHidlFeatureAware = true;
-#else
-    static const bool wifiHidlFeatureAware = false;
-#endif  // WIFI_HIDL_FEATURE_AWARE
+    WifiFeatureFlags();
+    virtual ~WifiFeatureFlags() = default;
+
+    virtual bool isAwareSupported();
 };
 
+}  // namespace feature_flags
 }  // namespace implementation
 }  // namespace V1_2
 }  // namespace wifi
diff --git a/wifi/1.2/default/wifi_legacy_hal.cpp b/wifi/1.2/default/wifi_legacy_hal.cpp
index 8289c67..3b056b0 100644
--- a/wifi/1.2/default/wifi_legacy_hal.cpp
+++ b/wifi/1.2/default/wifi_legacy_hal.cpp
@@ -446,7 +446,7 @@
     const std::string& iface_name) {
     feature_set set;
     static_assert(sizeof(set) == sizeof(uint32_t),
-                  "Some features can not be represented in output");
+                  "Some feature_flags can not be represented in output");
     wifi_error status = global_func_table_.wifi_get_supported_feature_set(
         getIfaceHandle(iface_name), &set);
     return {status, static_cast<uint32_t>(set)};
@@ -750,11 +750,11 @@
 
 std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet(
     const std::string& iface_name) {
-    uint32_t supported_features;
+    uint32_t supported_feature_flags;
     wifi_error status =
         global_func_table_.wifi_get_logger_supported_feature_set(
-            getIfaceHandle(iface_name), &supported_features);
-    return {status, supported_features};
+            getIfaceHandle(iface_name), &supported_feature_flags);
+    return {status, supported_feature_flags};
 }
 
 wifi_error WifiLegacyHal::startPktFateMonitoring(
diff --git a/wifi/1.2/default/wifi_legacy_hal.h b/wifi/1.2/default/wifi_legacy_hal.h
index 193928b..64a3f0a 100644
--- a/wifi/1.2/default/wifi_legacy_hal.h
+++ b/wifi/1.2/default/wifi_legacy_hal.h
@@ -141,15 +141,16 @@
 class WifiLegacyHal {
    public:
     WifiLegacyHal();
+    virtual ~WifiLegacyHal() = default;
 
     // Initialize the legacy HAL function table.
-    wifi_error initialize();
+    virtual wifi_error initialize();
     // Start the legacy HAL and the event looper thread.
-    wifi_error start();
+    virtual wifi_error start();
     // Deinitialize the legacy HAL and wait for the event loop thread to exit
     // using a predefined timeout.
-    wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
-                    const std::function<void()>& on_complete_callback);
+    virtual wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
+                            const std::function<void()>& on_complete_callback);
     // Wrappers for all the functions in the legacy HAL function table.
     std::pair<wifi_error, std::string> getDriverVersion(
         const std::string& iface_name);
@@ -189,7 +190,7 @@
     wifi_error stopGscan(const std::string& iface_name, wifi_request_id id);
     std::pair<wifi_error, std::vector<uint32_t>> getValidFrequenciesForBand(
         const std::string& iface_name, wifi_band band);
-    wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on);
+    virtual wifi_error setDfsFlag(const std::string& iface_name, bool dfs_on);
     // Link layer stats functions.
     wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug);
     wifi_error disableLinkLayerStats(const std::string& iface_name);
@@ -275,12 +276,12 @@
     wifi_error setRttLcr(const std::string& iface_name, wifi_request_id id,
                          const wifi_lcr_information& info);
     // NAN functions.
-    wifi_error nanRegisterCallbackHandlers(
+    virtual wifi_error nanRegisterCallbackHandlers(
         const std::string& iface_name, const NanCallbackHandlers& callbacks);
     wifi_error nanEnableRequest(const std::string& iface_name,
                                 transaction_id id, const NanEnableRequest& msg);
-    wifi_error nanDisableRequest(const std::string& iface_name,
-                                 transaction_id id);
+    virtual wifi_error nanDisableRequest(const std::string& iface_name,
+                                         transaction_id id);
     wifi_error nanPublishRequest(const std::string& iface_name,
                                  transaction_id id,
                                  const NanPublishRequest& msg);
@@ -311,9 +312,9 @@
     wifi_error nanDataInterfaceCreate(const std::string& iface_name,
                                       transaction_id id,
                                       const std::string& data_iface_name);
-    wifi_error nanDataInterfaceDelete(const std::string& iface_name,
-                                      transaction_id id,
-                                      const std::string& data_iface_name);
+    virtual wifi_error nanDataInterfaceDelete(
+        const std::string& iface_name, transaction_id id,
+        const std::string& data_iface_name);
     wifi_error nanDataRequestInitiator(const std::string& iface_name,
                                        transaction_id id,
                                        const NanDataPathInitiatorRequest& msg);
diff --git a/wifi/1.2/default/wifi_mode_controller.h b/wifi/1.2/default/wifi_mode_controller.h
index 839bf9e..e54fa6e 100644
--- a/wifi/1.2/default/wifi_mode_controller.h
+++ b/wifi/1.2/default/wifi_mode_controller.h
@@ -37,15 +37,16 @@
 class WifiModeController {
    public:
     WifiModeController();
+    virtual ~WifiModeController() = default;
 
     // Checks if a firmware mode change is necessary to support the specified
     // iface type operations.
-    bool isFirmwareModeChangeNeeded(IfaceType type);
+    virtual bool isFirmwareModeChangeNeeded(IfaceType type);
     // Change the firmware mode to support the specified iface type operations.
-    bool changeFirmwareMode(IfaceType type);
+    virtual bool changeFirmwareMode(IfaceType type);
     // Unload the driver. This should be invoked whenever |IWifi.stop()| is
     // invoked.
-    bool deinitialize();
+    virtual bool deinitialize();
 
    private:
     std::unique_ptr<wifi_hal::DriverTool> driver_tool_;