wifi(implementation): Send NAN disabled on wlan0 down & up

When the iface state is toggled for MAC address change on the underlying
interface for NAN operations, send NAN disabled event up to the
framework. The iface down/up toggle resets all NAN operations in the
firmware. So, this callback should trigger a cleanup of any
operations initiated by the framework.

Bug: 132943959
Test: Unit tests in the follow-up CL.
Test: Will send for regression tests.
Change-Id: I760dc5ca3b9276956f5edd40a97c3c13811f442c
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index 27320c4..6c2fd67 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -861,7 +861,7 @@
     }
     // These are still assumed to be based on wlan0.
     std::string ifname = getFirstActiveWlanIfaceName();
-    sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
+    sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_, iface_util_);
     nan_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
diff --git a/wifi/1.3/default/wifi_iface_util.cpp b/wifi/1.3/default/wifi_iface_util.cpp
index 5d61271..7042af0 100644
--- a/wifi/1.3/default/wifi_iface_util.cpp
+++ b/wifi/1.3/default/wifi_iface_util.cpp
@@ -39,7 +39,8 @@
 namespace implementation {
 namespace iface_util {
 
-WifiIfaceUtil::WifiIfaceUtil() : random_mac_address_(nullptr) {}
+WifiIfaceUtil::WifiIfaceUtil()
+    : random_mac_address_(nullptr), event_handlers_map_() {}
 
 std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(
     const std::string& iface_name) {
@@ -60,6 +61,14 @@
         LOG(ERROR) << "SetUpState(true) failed.";
         return false;
     }
+    IfaceEventHandlers event_handlers = {};
+    const auto it = event_handlers_map_.find(iface_name);
+    if (it != event_handlers_map_.end()) {
+        event_handlers = it->second;
+    }
+    if (event_handlers.on_state_toggle_off_on != nullptr) {
+        event_handlers.on_state_toggle_off_on(iface_name);
+    }
     LOG(DEBUG) << "Successfully SetMacAddress.";
     return true;
 }
@@ -73,6 +82,16 @@
     return *random_mac_address_.get();
 }
 
+void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
+                                               IfaceEventHandlers handlers) {
+    event_handlers_map_[iface_name] = handlers;
+}
+
+void WifiIfaceUtil::unregisterIfaceEventHandlers(
+    const std::string& iface_name) {
+    event_handlers_map_.erase(iface_name);
+}
+
 std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
     std::array<uint8_t, 6> address = {};
     std::random_device rd;
diff --git a/wifi/1.3/default/wifi_iface_util.h b/wifi/1.3/default/wifi_iface_util.h
index b238234..325fbe8 100644
--- a/wifi/1.3/default/wifi_iface_util.h
+++ b/wifi/1.3/default/wifi_iface_util.h
@@ -28,6 +28,13 @@
 namespace implementation {
 namespace iface_util {
 
+// Iface event handlers.
+struct IfaceEventHandlers {
+    // Callback to be invoked when the iface is set down & up for MAC address
+    // change.
+    std::function<void(const std::string& iface_name)> on_state_toggle_off_on;
+};
+
 /**
  * Util class for common iface operations.
  */
@@ -45,11 +52,17 @@
     // daemon. (So, changes on every reboot)
     virtual std::array<uint8_t, 6> getOrCreateRandomMacAddress();
 
+    // Register for any iface event callbacks for the provided interface.
+    virtual void registerIfaceEventHandlers(const std::string& iface_name,
+                                            IfaceEventHandlers handlers);
+    virtual void unregisterIfaceEventHandlers(const std::string& iface_name);
+
    private:
     std::array<uint8_t, 6> createRandomMacAddress();
 
     wifi_system::InterfaceTool iface_tool_;
     std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
+    std::map<std::string, IfaceEventHandlers> event_handlers_map_;
 };
 
 }  // namespace iface_util
diff --git a/wifi/1.3/default/wifi_nan_iface.cpp b/wifi/1.3/default/wifi_nan_iface.cpp
index 4325f44..ff9f422 100644
--- a/wifi/1.3/default/wifi_nan_iface.cpp
+++ b/wifi/1.3/default/wifi_nan_iface.cpp
@@ -30,8 +30,12 @@
 
 WifiNanIface::WifiNanIface(
     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) {
     // Register all the callbacks here. these should be valid for the lifetime
     // of the object. Whenever the mode changes legacy HAL will remove
     // all of these callbacks.
@@ -498,6 +502,26 @@
         LOG(ERROR) << "Failed to register nan callbacks. Invalidating object";
         invalidate();
     }
+
+    // Register for iface state toggle events.
+    iface_util::IfaceEventHandlers event_handlers = {};
+    event_handlers.on_state_toggle_off_on =
+        [weak_ptr_this](const std::string& /* iface_name */) {
+            const auto shared_ptr_this = weak_ptr_this.promote();
+            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                LOG(ERROR) << "Callback invoked on an invalid object";
+                return;
+            }
+            // Tell framework that NAN has been disabled.
+            WifiNanStatus status = {
+                NanStatusType::UNSUPPORTED_CONCURRENCY_NAN_DISABLED, ""};
+            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                if (!callback->eventDisabled(status).isOk()) {
+                    LOG(ERROR) << "Failed to invoke the callback";
+                }
+            }
+        };
+    iface_util_.lock()->registerIfaceEventHandlers(ifname_, event_handlers);
 }
 
 void WifiNanIface::invalidate() {
@@ -505,7 +529,7 @@
     legacy_hal_.lock()->nanDisableRequest(ifname_, 0xFFFF);
     legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFE, "aware_data0");
     legacy_hal_.lock()->nanDataInterfaceDelete(ifname_, 0xFFFD, "aware_data1");
-
+    iface_util_.lock()->unregisterIfaceEventHandlers(ifname_);
     legacy_hal_.reset();
     event_cb_handler_.invalidate();
     event_cb_handler_1_2_.invalidate();
diff --git a/wifi/1.3/default/wifi_nan_iface.h b/wifi/1.3/default/wifi_nan_iface.h
index f735d61..737be93 100644
--- a/wifi/1.3/default/wifi_nan_iface.h
+++ b/wifi/1.3/default/wifi_nan_iface.h
@@ -22,6 +22,7 @@
 #include <android/hardware/wifi/1.2/IWifiNanIface.h>
 
 #include "hidl_callback_util.h"
+#include "wifi_iface_util.h"
 #include "wifi_legacy_hal.h"
 
 namespace android {
@@ -37,7 +38,8 @@
 class WifiNanIface : public V1_2::IWifiNanIface {
    public:
     WifiNanIface(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();
@@ -147,6 +149,7 @@
 
     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<V1_0::IWifiNanIfaceEventCallback>
         event_cb_handler_;