wifi(implementation): Support multiple ifaces of same type

Making all of the iface object fields in WifiChip to vectors to support
multiple ifaces of the same type.

Bug: 65671875
Test: Device boots up and connects to wifi networks.
Change-Id: I4c0c927c0269e54210cc1f81203c1797d72e969c
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index 4e2191d..49cf888 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -27,8 +27,8 @@
 using android::hardware::hidl_string;
 using android::hardware::hidl_vec;
 using android::hardware::wifi::V1_0::ChipModeId;
-using android::hardware::wifi::V1_0::IWifiChip;
 using android::hardware::wifi::V1_0::IfaceType;
+using android::hardware::wifi::V1_0::IWifiChip;
 using android::sp;
 
 constexpr ChipModeId kStaChipModeId = 0;
@@ -36,11 +36,39 @@
 constexpr ChipModeId kInvalidModeId = UINT32_MAX;
 
 template <typename Iface>
-void invalidateAndClear(sp<Iface>& iface) {
-    if (iface.get()) {
+void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
+    iface->invalidate();
+    ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface),
+                 ifaces.end());
+}
+
+template <typename Iface>
+void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
+    for (const auto& iface : ifaces) {
         iface->invalidate();
-        iface.clear();
     }
+    ifaces.clear();
+}
+
+template <typename Iface>
+std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
+    std::vector<hidl_string> names;
+    for (const auto& iface : ifaces) {
+        names.emplace_back(iface->getName());
+    }
+    return names;
+}
+
+template <typename Iface>
+sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces,
+                        const std::string& name) {
+    std::vector<hidl_string> names;
+    for (const auto& iface : ifaces) {
+        if (name == iface->getName()) {
+            return iface;
+        }
+    }
+    return nullptr;
 }
 
 std::string getWlan0IfaceName() {
@@ -317,10 +345,10 @@
 }
 
 void WifiChip::invalidateAndRemoveAllIfaces() {
-    invalidateAndClear(ap_iface_);
-    invalidateAndClear(nan_iface_);
-    invalidateAndClear(p2p_iface_);
-    invalidateAndClear(sta_iface_);
+    invalidateAndClearAll(ap_ifaces_);
+    invalidateAndClearAll(nan_ifaces_);
+    invalidateAndClearAll(p2p_ifaces_);
+    invalidateAndClearAll(sta_ifaces_);
     // Since all the ifaces are invalid now, all RTT controller objects
     // using those ifaces also need to be invalidated.
     for (const auto& rtt : rtt_controllers_) {
@@ -497,40 +525,43 @@
 }
 
 std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
-    if (current_mode_id_ != kApChipModeId || ap_iface_.get()) {
+    if (current_mode_id_ != kApChipModeId || !ap_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::string ifname = getWlan0IfaceName();
-    ap_iface_ = new WifiApIface(ifname, legacy_hal_);
+    sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_);
+    ap_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
         }
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
 std::pair<WifiStatus, std::vector<hidl_string>>
 WifiChip::getApIfaceNamesInternal() {
-    if (!ap_iface_.get()) {
+    if (ap_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), {getWlan0IfaceName()}};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
 }
 
 std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
     const std::string& ifname) {
-    if (!ap_iface_.get() || (ifname != getWlan0IfaceName())) {
+    const auto iface = findUsingName(ap_ifaces_, ifname);
+    if (!iface.get()) {
         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
 WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
-    if (!ap_iface_.get() || (ifname != getWlan0IfaceName())) {
+    const auto iface = findUsingName(ap_ifaces_, ifname);
+    if (!iface.get()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
-    invalidateAndClear(ap_iface_);
+    invalidateAndClear(ap_ifaces_, iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
             LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
@@ -542,18 +573,19 @@
 std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
     // Only 1 of NAN or P2P iface can be active at a time.
     if (WifiFeatureFlags::wifiHidlFeatureAware) {
-        if (current_mode_id_ != kStaChipModeId || nan_iface_.get() ||
-            p2p_iface_.get()) {
+        if (current_mode_id_ != kStaChipModeId || !nan_ifaces_.empty() ||
+            !p2p_ifaces_.empty()) {
             return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
         }
         std::string ifname = getWlan0IfaceName();
-        nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
+        sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
+        nan_ifaces_.push_back(iface);
         for (const auto& callback : event_cb_handler_.getCallbacks()) {
             if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
                 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
             }
         }
-        return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
+        return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
     } else {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
@@ -561,25 +593,27 @@
 
 std::pair<WifiStatus, std::vector<hidl_string>>
 WifiChip::getNanIfaceNamesInternal() {
-    if (!nan_iface_.get()) {
+    if (nan_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), {getWlan0IfaceName()}};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
 }
 
 std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
     const std::string& ifname) {
-    if (!nan_iface_.get() || (ifname != getWlan0IfaceName())) {
+    const auto iface = findUsingName(nan_ifaces_, ifname);
+    if (!iface.get()) {
         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
 WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
-    if (!nan_iface_.get() || (ifname != getWlan0IfaceName())) {
+    const auto iface = findUsingName(nan_ifaces_, ifname);
+    if (!iface.get()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
-    invalidateAndClear(nan_iface_);
+    invalidateAndClear(nan_ifaces_, iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
@@ -590,41 +624,44 @@
 
 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
     // Only 1 of NAN or P2P iface can be active at a time.
-    if (current_mode_id_ != kStaChipModeId || p2p_iface_.get() ||
-        nan_iface_.get()) {
+    if (current_mode_id_ != kStaChipModeId || !p2p_ifaces_.empty() ||
+        !nan_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::string ifname = getP2pIfaceName();
-    p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
+    sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
+    p2p_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
         }
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
 std::pair<WifiStatus, std::vector<hidl_string>>
 WifiChip::getP2pIfaceNamesInternal() {
-    if (!p2p_iface_.get()) {
+    if (p2p_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), {getP2pIfaceName()}};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
 }
 
 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
     const std::string& ifname) {
-    if (!p2p_iface_.get() || (ifname != getP2pIfaceName())) {
+    const auto iface = findUsingName(p2p_ifaces_, ifname);
+    if (!iface.get()) {
         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
 WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
-    if (!p2p_iface_.get() || (ifname != getP2pIfaceName())) {
+    const auto iface = findUsingName(p2p_ifaces_, ifname);
+    if (!iface.get()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
-    invalidateAndClear(p2p_iface_);
+    invalidateAndClear(p2p_ifaces_, iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
             LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
@@ -634,40 +671,43 @@
 }
 
 std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
-    if (current_mode_id_ != kStaChipModeId || sta_iface_.get()) {
+    if (current_mode_id_ != kStaChipModeId || !sta_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::string ifname = getWlan0IfaceName();
-    sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
+    sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_);
+    sta_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
         }
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
 std::pair<WifiStatus, std::vector<hidl_string>>
 WifiChip::getStaIfaceNamesInternal() {
-    if (!sta_iface_.get()) {
+    if (sta_ifaces_.empty()) {
         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), {getWlan0IfaceName()}};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
 }
 
 std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal(
     const std::string& ifname) {
-    if (!sta_iface_.get() || (ifname != getWlan0IfaceName())) {
+    const auto iface = findUsingName(sta_ifaces_, ifname);
+    if (!iface.get()) {
         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
     }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
+    return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
 }
 
 WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
-    if (!sta_iface_.get() || (ifname != getWlan0IfaceName())) {
+    const auto iface = findUsingName(sta_ifaces_, ifname);
+    if (!iface.get()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
-    invalidateAndClear(sta_iface_);
+    invalidateAndClear(sta_ifaces_, iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
             LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";