wifi(implementation): Move set/getMacaddress to a util class

This is just a refactor to move the setMacAddress & getFactoryMacAddress
methods to a util class within the HAL. This can be then reused in AP
iface for mac randomization of SoftAp.

This also fixes a bug in the existing setMacAddress() method, the
current method always sets wlan0 up/down. STA interface could be wlan1
on some devices.

Bug: 78353419
Test: ./hardware/interfaces/wifi/1.3/default/tests/runtests.sh
Test: Manually verified STA MAC randomization still works.
Change-Id: I0bb8154f7e6dcae37c977454423c8c299762260e
diff --git a/wifi/1.3/default/Android.mk b/wifi/1.3/default/Android.mk
index 01fa934..eb07a9a 100644
--- a/wifi/1.3/default/Android.mk
+++ b/wifi/1.3/default/Android.mk
@@ -43,6 +43,7 @@
     wifi_ap_iface.cpp \
     wifi_chip.cpp \
     wifi_feature_flags.cpp \
+    wifi_iface_util.cpp \
     wifi_legacy_hal.cpp \
     wifi_legacy_hal_stubs.cpp \
     wifi_mode_controller.cpp \
@@ -139,6 +140,7 @@
     tests/hidl_struct_util_unit_tests.cpp \
     tests/main.cpp \
     tests/mock_wifi_feature_flags.cpp \
+    tests/mock_wifi_iface_util.cpp \
     tests/mock_wifi_legacy_hal.cpp \
     tests/mock_wifi_mode_controller.cpp \
     tests/ringbuffer_unit_tests.cpp \
diff --git a/wifi/1.3/default/service.cpp b/wifi/1.3/default/service.cpp
index 5daf659..73015cf 100644
--- a/wifi/1.3/default/service.cpp
+++ b/wifi/1.3/default/service.cpp
@@ -30,6 +30,7 @@
 using android::hardware::LazyServiceRegistrar;
 using android::hardware::wifi::V1_3::implementation::feature_flags::
     WifiFeatureFlags;
+using android::hardware::wifi::V1_3::implementation::iface_util::WifiIfaceUtil;
 using android::hardware::wifi::V1_3::implementation::legacy_hal::WifiLegacyHal;
 using android::hardware::wifi::V1_3::implementation::mode_controller::
     WifiModeController;
@@ -52,6 +53,7 @@
         new android::hardware::wifi::V1_3::implementation::Wifi(
             std::make_shared<WifiLegacyHal>(),
             std::make_shared<WifiModeController>(),
+            std::make_shared<WifiIfaceUtil>(),
             std::make_shared<WifiFeatureFlags>());
     if (kLazyService) {
         LazyServiceRegistrar registrar;
diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.cpp b/wifi/1.3/default/tests/mock_wifi_iface_util.cpp
new file mode 100644
index 0000000..706cb6a
--- /dev/null
+++ b/wifi/1.3/default/tests/mock_wifi_iface_util.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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_iface_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_3 {
+namespace implementation {
+namespace iface_util {
+
+MockWifiIfaceUtil::MockWifiIfaceUtil() : WifiIfaceUtil() {}
+}  // namespace iface_util
+}  // namespace implementation
+}  // namespace V1_3
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.3/default/tests/mock_wifi_iface_util.h b/wifi/1.3/default/tests/mock_wifi_iface_util.h
new file mode 100644
index 0000000..6fb8f71
--- /dev/null
+++ b/wifi/1.3/default/tests/mock_wifi_iface_util.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_WIFI_IFACE_UTIL_H_
+#define MOCK_WIFI_IFACE_UTIL_H_
+
+#include <gmock/gmock.h>
+
+#include "wifi_iface_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_3 {
+namespace implementation {
+namespace iface_util {
+
+class MockWifiIfaceUtil : public WifiIfaceUtil {
+   public:
+    MockWifiIfaceUtil();
+    MOCK_METHOD1(getFactoryMacAddress,
+                 std::array<uint8_t, 6>(const std::string&));
+    MOCK_METHOD2(setMacAddress,
+                 bool(const std::string&, const std::array<uint8_t, 6>&));
+};
+}  // namespace iface_util
+}  // namespace implementation
+}  // namespace V1_3
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // MOCK_WIFI_IFACE_UTIL_H_
diff --git a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
index 3fcc39e..134563c 100644
--- a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
@@ -23,6 +23,7 @@
 #include "wifi_chip.h"
 
 #include "mock_wifi_feature_flags.h"
+#include "mock_wifi_iface_util.h"
 #include "mock_wifi_legacy_hal.h"
 #include "mock_wifi_mode_controller.h"
 
@@ -263,7 +264,7 @@
    public:
     void SetUp() override {
         chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_,
-                             feature_flags_);
+                             iface_util_, feature_flags_);
 
         EXPECT_CALL(*mode_controller_, changeFirmwareMode(testing::_))
             .WillRepeatedly(testing::Return(true));
@@ -278,6 +279,8 @@
         new NiceMock<legacy_hal::MockWifiLegacyHal>};
     std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>>
         mode_controller_{new NiceMock<mode_controller::MockWifiModeController>};
+    std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
+        new NiceMock<iface_util::MockWifiIfaceUtil>};
     std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
         feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
 };
diff --git a/wifi/1.3/default/wifi.cpp b/wifi/1.3/default/wifi.cpp
index e3af1ea..1f64085 100644
--- a/wifi/1.3/default/wifi.cpp
+++ b/wifi/1.3/default/wifi.cpp
@@ -36,9 +36,11 @@
 Wifi::Wifi(
     const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
     const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
+    const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
     const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
     : legacy_hal_(legacy_hal),
       mode_controller_(mode_controller),
+      iface_util_(iface_util),
       feature_flags_(feature_flags),
       run_state_(RunState::STOPPED) {}
 
@@ -105,7 +107,7 @@
     if (wifi_status.code == WifiStatusCode::SUCCESS) {
         // Create the chip instance once the HAL is started.
         chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,
-                             feature_flags_);
+                             iface_util_, feature_flags_);
         run_state_ = RunState::STARTED;
         for (const auto& callback : event_cb_handler_.getCallbacks()) {
             if (!callback->onStart().isOk()) {
diff --git a/wifi/1.3/default/wifi.h b/wifi/1.3/default/wifi.h
index e921424..c4ab773 100644
--- a/wifi/1.3/default/wifi.h
+++ b/wifi/1.3/default/wifi.h
@@ -43,6 +43,7 @@
     Wifi(const std::shared_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
          const std::shared_ptr<mode_controller::WifiModeController>
              mode_controller,
+         const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
          const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
 
     bool isValid();
@@ -78,6 +79,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<iface_util::WifiIfaceUtil> iface_util_;
     std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
     RunState run_state_;
     sp<WifiChip> chip_;
diff --git a/wifi/1.3/default/wifi_ap_iface.cpp b/wifi/1.3/default/wifi_ap_iface.cpp
index c203e47..025ece3 100644
--- a/wifi/1.3/default/wifi_ap_iface.cpp
+++ b/wifi/1.3/default/wifi_ap_iface.cpp
@@ -30,8 +30,12 @@
 
 WifiApIface::WifiApIface(
     const std::string& ifname,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
-    : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}
+    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+    const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+    : ifname_(ifname),
+      legacy_hal_(legacy_hal),
+      iface_util_(iface_util),
+      is_valid_(true) {}
 
 void WifiApIface::invalidate() {
     legacy_hal_.reset();
diff --git a/wifi/1.3/default/wifi_ap_iface.h b/wifi/1.3/default/wifi_ap_iface.h
index 9f3d870..6dbfc18 100644
--- a/wifi/1.3/default/wifi_ap_iface.h
+++ b/wifi/1.3/default/wifi_ap_iface.h
@@ -20,6 +20,8 @@
 #include <android-base/macros.h>
 #include <android/hardware/wifi/1.0/IWifiApIface.h>
 
+#include "wifi_iface_util.h"
+
 #include "wifi_legacy_hal.h"
 
 namespace android {
@@ -35,7 +37,8 @@
 class WifiApIface : public V1_0::IWifiApIface {
    public:
     WifiApIface(const std::string& ifname,
-                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+                const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
     // Refer to |WifiChip::invalidate()|.
     void invalidate();
     bool isValid();
@@ -59,6 +62,7 @@
 
     std::string ifname_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
     bool is_valid_;
 
     DISALLOW_COPY_AND_ASSIGN(WifiApIface);
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index e7ebc3b..9640a61 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -313,10 +313,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<iface_util::WifiIfaceUtil> iface_util,
     const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags)
     : chip_id_(chip_id),
       legacy_hal_(legacy_hal),
       mode_controller_(mode_controller),
+      iface_util_(iface_util),
       feature_flags_(feature_flags),
       is_valid_(true),
       current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
@@ -775,7 +777,7 @@
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::string ifname = allocateApOrStaIfaceName();
-    sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_);
+    sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_, iface_util_);
     ap_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
@@ -914,7 +916,7 @@
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::string ifname = allocateApOrStaIfaceName();
-    sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_);
+    sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
     sta_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
diff --git a/wifi/1.3/default/wifi_chip.h b/wifi/1.3/default/wifi_chip.h
index d14ced6..3eb0aee 100644
--- a/wifi/1.3/default/wifi_chip.h
+++ b/wifi/1.3/default/wifi_chip.h
@@ -53,6 +53,7 @@
         const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
         const std::weak_ptr<mode_controller::WifiModeController>
             mode_controller,
+        const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util,
         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
@@ -233,6 +234,7 @@
     ChipId chip_id_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
+    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
     std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
     std::vector<sp<WifiApIface>> ap_ifaces_;
     std::vector<sp<WifiNanIface>> nan_ifaces_;
diff --git a/wifi/1.3/default/wifi_iface_util.cpp b/wifi/1.3/default/wifi_iface_util.cpp
new file mode 100644
index 0000000..39fa1e8
--- /dev/null
+++ b/wifi/1.3/default/wifi_iface_util.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <private/android_filesystem_config.h>
+
+#include "wifi_iface_util.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_3 {
+namespace implementation {
+namespace iface_util {
+
+WifiIfaceUtil::WifiIfaceUtil() {}
+
+std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(
+    const std::string& iface_name) {
+    return iface_tool_.GetFactoryMacAddress(iface_name.c_str());
+}
+
+bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
+                                  const std::array<uint8_t, 6>& mac) {
+    if (!iface_tool_.SetUpState(iface_name.c_str(), false)) {
+        LOG(ERROR) << "SetUpState(false) failed.";
+        return false;
+    }
+    if (!iface_tool_.SetMacAddress(iface_name.c_str(), mac)) {
+        LOG(ERROR) << "SetMacAddress failed.";
+        return false;
+    }
+    if (!iface_tool_.SetUpState(iface_name.c_str(), true)) {
+        LOG(ERROR) << "SetUpState(true) failed.";
+        return false;
+    }
+    LOG(DEBUG) << "Successfully SetMacAddress.";
+    return true;
+}
+
+}  // namespace iface_util
+}  // namespace implementation
+}  // namespace V1_3
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.3/default/wifi_iface_util.h b/wifi/1.3/default/wifi_iface_util.h
new file mode 100644
index 0000000..9495322
--- /dev/null
+++ b/wifi/1.3/default/wifi_iface_util.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WIFI_IFACE_UTIL_H_
+#define WIFI_IFACE_UTIL_H_
+
+#include <wifi_system/interface_tool.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_3 {
+namespace implementation {
+namespace iface_util {
+
+/**
+ * Util class for common iface operations.
+ */
+class WifiIfaceUtil {
+   public:
+    WifiIfaceUtil();
+    virtual ~WifiIfaceUtil() = default;
+
+    virtual std::array<uint8_t, 6> getFactoryMacAddress(
+        const std::string& iface_name);
+    virtual bool setMacAddress(const std::string& iface_name,
+                               const std::array<uint8_t, 6>& mac);
+
+   private:
+    wifi_system::InterfaceTool iface_tool_;
+};
+
+}  // namespace iface_util
+}  // namespace implementation
+}  // namespace V1_3
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // WIFI_IFACE_UTIL_H_
diff --git a/wifi/1.3/default/wifi_sta_iface.cpp b/wifi/1.3/default/wifi_sta_iface.cpp
index f7157a3..17f3e3d 100644
--- a/wifi/1.3/default/wifi_sta_iface.cpp
+++ b/wifi/1.3/default/wifi_sta_iface.cpp
@@ -30,8 +30,12 @@
 
 WifiStaIface::WifiStaIface(
     const std::string& ifname,
-    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
-    : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {
+    const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+    const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
+    : ifname_(ifname),
+      legacy_hal_(legacy_hal),
+      iface_util_(iface_util),
+      is_valid_(true) {
     // Turn on DFS channel usage for STA iface.
     legacy_hal::wifi_error legacy_status =
         legacy_hal_.lock()->setDfsFlag(ifname_, true);
@@ -622,28 +626,17 @@
 
 WifiStatus WifiStaIface::setMacAddressInternal(
     const std::array<uint8_t, 6>& mac) {
-    if (!iface_tool_.SetWifiUpState(false)) {
-        LOG(ERROR) << "SetWifiUpState(false) failed.";
+    bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
+    if (!status) {
         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
     }
-
-    if (!iface_tool_.SetMacAddress(ifname_.c_str(), mac)) {
-        LOG(ERROR) << "SetMacAddress failed.";
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-
-    if (!iface_tool_.SetWifiUpState(true)) {
-        LOG(ERROR) << "SetWifiUpState(true) failed.";
-        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
-    }
-    LOG(DEBUG) << "Successfully SetMacAddress.";
     return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
 std::pair<WifiStatus, std::array<uint8_t, 6>>
 WifiStaIface::getFactoryMacAddressInternal() {
     std::array<uint8_t, 6> mac =
-        iface_tool_.GetFactoryMacAddress(ifname_.c_str());
+        iface_util_.lock()->getFactoryMacAddress(ifname_);
     return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
 }
 
diff --git a/wifi/1.3/default/wifi_sta_iface.h b/wifi/1.3/default/wifi_sta_iface.h
index 69cb82a..9224939 100644
--- a/wifi/1.3/default/wifi_sta_iface.h
+++ b/wifi/1.3/default/wifi_sta_iface.h
@@ -21,9 +21,8 @@
 #include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
 #include <android/hardware/wifi/1.3/IWifiStaIface.h>
 
-#include <wifi_system/interface_tool.h>
-
 #include "hidl_callback_util.h"
+#include "wifi_iface_util.h"
 #include "wifi_legacy_hal.h"
 
 namespace android {
@@ -39,7 +38,8 @@
 class WifiStaIface : public V1_3::IWifiStaIface {
    public:
     WifiStaIface(const std::string& ifname,
-                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
+                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
+                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
     // Refer to |WifiChip::invalidate()|.
     void invalidate();
     bool isValid();
@@ -162,10 +162,10 @@
 
     std::string ifname_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
+    std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
     bool is_valid_;
     hidl_callback_util::HidlCallbackHandler<IWifiStaIfaceEventCallback>
         event_cb_handler_;
-    wifi_system::InterfaceTool iface_tool_;
 
     DISALLOW_COPY_AND_ASSIGN(WifiStaIface);
 };