Add IfaceConcurrencyType and related methods for AP_BRIDGED concurrency

Add IfaceConcurrencyType to represent Iface implementations that
have different concurrency implications for the same IfaceType, such as
Bridged AP and Single AP for IWifiApIface. Add a new IWifiChip HAL API,
getAvailableModes_1_6 to return the new concurrency type combos.

Bug: 207055799
Test: 1.6/default/tests/runtests.sh
Change-Id: Iad20a3d95d54dd8b624db912fd3153c2a3372f45
diff --git a/wifi/1.6/default/wifi_chip.cpp b/wifi/1.6/default/wifi_chip.cpp
index 4fff770..0e2accf 100644
--- a/wifi/1.6/default/wifi_chip.cpp
+++ b/wifi/1.6/default/wifi_chip.cpp
@@ -728,6 +728,11 @@
                            &WifiChip::getSupportedRadioCombinationsMatrixInternal, hidl_status_cb);
 }
 
+Return<void> WifiChip::getAvailableModes_1_6(getAvailableModes_1_6_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getAvailableModesInternal_1_6, hidl_status_cb);
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
     invalidateAndClearBridgedApAll();
     invalidateAndClearAll(ap_ifaces_);
@@ -784,9 +789,10 @@
     return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
 }
 
-std::pair<WifiStatus, std::vector<V1_4::IWifiChip::ChipMode>>
+std::pair<WifiStatus, std::vector<V1_0::IWifiChip::ChipMode>>
 WifiChip::getAvailableModesInternal() {
-    return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
+    // Deprecated support -- use getAvailableModes_1_6.
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
 }
 
 WifiStatus WifiChip::configureChipInternal(
@@ -910,7 +916,7 @@
 }
 
 std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createApIfaceInternal() {
-    if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::string ifname = allocateApIfaceName();
@@ -923,7 +929,7 @@
 }
 
 std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createBridgedApIfaceInternal() {
-    if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
@@ -1040,7 +1046,7 @@
 }
 
 std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::createNanIfaceInternal() {
-    if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::NAN)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     bool is_dedicated_iface = true;
@@ -1092,7 +1098,7 @@
 }
 
 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
-    if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::P2P)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::string ifname = getPredefinedP2pIfaceName();
@@ -1136,7 +1142,7 @@
 }
 
 std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> WifiChip::createStaIfaceInternal() {
-    if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
+    if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
     std::string ifname = allocateStaIfaceName();
@@ -1436,7 +1442,8 @@
 
 std::pair<WifiStatus, sp<V1_6::IWifiRttController>> WifiChip::createRttControllerInternal_1_6(
         const sp<IWifiIface>& bound_iface) {
-    if (sta_ifaces_.size() == 0 && !canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
+    if (sta_ifaces_.size() == 0 &&
+        !canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
         LOG(ERROR) << "createRttControllerInternal_1_6: Chip cannot support STAs "
                       "(and RTT by extension)";
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
@@ -1489,6 +1496,11 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_matrix};
 }
 
+std::pair<WifiStatus, std::vector<V1_6::IWifiChip::ChipMode>>
+WifiChip::getAvailableModesInternal_1_6() {
+    return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
+}
+
 WifiStatus WifiChip::handleChipConfiguration(
         /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
     // If the chip is already configured in a different mode, stop
@@ -1606,7 +1618,8 @@
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
-std::vector<V1_4::IWifiChip::ChipIfaceCombination> WifiChip::getCurrentModeIfaceCombinations() {
+std::vector<V1_6::IWifiChip::ChipConcurrencyCombination>
+WifiChip::getCurrentModeConcurrencyCombinations() {
     if (!isValidModeId(current_mode_id_)) {
         LOG(ERROR) << "Chip not configured in a mode yet";
         return {};
@@ -1616,27 +1629,39 @@
             return mode.availableCombinations;
         }
     }
-    CHECK(0) << "Expected to find iface combinations for current mode!";
+    CHECK(0) << "Expected to find concurrency combinations for current mode!";
     return {};
 }
 
-// Returns a map indexed by IfaceType with the number of ifaces currently
-// created of the corresponding type.
-std::map<IfaceType, size_t> WifiChip::getCurrentIfaceCombination() {
-    std::map<IfaceType, size_t> iface_counts;
-    iface_counts[IfaceType::AP] = ap_ifaces_.size();
-    iface_counts[IfaceType::NAN] = nan_ifaces_.size();
-    iface_counts[IfaceType::P2P] = p2p_ifaces_.size();
-    iface_counts[IfaceType::STA] = sta_ifaces_.size();
+// Returns a map indexed by IfaceConcurrencyType with the number of ifaces currently
+// created of the corresponding concurrency type.
+std::map<IfaceConcurrencyType, size_t> WifiChip::getCurrentConcurrencyCombination() {
+    std::map<IfaceConcurrencyType, size_t> iface_counts;
+    uint32_t num_ap = 0;
+    uint32_t num_ap_bridged = 0;
+    for (const auto& ap_iface : ap_ifaces_) {
+        std::string ap_iface_name = ap_iface->getName();
+        if (br_ifaces_ap_instances_.count(ap_iface_name) > 0 &&
+            br_ifaces_ap_instances_[ap_iface_name].size() > 1) {
+            num_ap_bridged++;
+        } else {
+            num_ap++;
+        }
+    }
+    iface_counts[IfaceConcurrencyType::AP] = num_ap;
+    iface_counts[IfaceConcurrencyType::AP_BRIDGED] = num_ap_bridged;
+    iface_counts[IfaceConcurrencyType::NAN] = nan_ifaces_.size();
+    iface_counts[IfaceConcurrencyType::P2P] = p2p_ifaces_.size();
+    iface_counts[IfaceConcurrencyType::STA] = sta_ifaces_.size();
     return iface_counts;
 }
 
-// This expands the provided iface combinations to a more parseable
+// This expands the provided concurrency combinations to a more parseable
 // form. Returns a vector of available combinations possible with the number
-// of ifaces of each type in the combination.
-// This method is a port of HalDeviceManager.expandIfaceCombos() from framework.
-std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations(
-        const V1_4::IWifiChip::ChipIfaceCombination& combination) {
+// of each concurrency type in the combination.
+// This method is a port of HalDeviceManager.expandConcurrencyCombos() from framework.
+std::vector<std::map<IfaceConcurrencyType, size_t>> WifiChip::expandConcurrencyCombinations(
+        const V1_6::IWifiChip::ChipConcurrencyCombination& combination) {
     uint32_t num_expanded_combos = 1;
     for (const auto& limit : combination.limits) {
         for (uint32_t i = 0; i < limit.maxIfaces; i++) {
@@ -1644,12 +1669,14 @@
         }
     }
 
-    // Allocate the vector of expanded combos and reset all iface counts to 0
+    // Allocate the vector of expanded combos and reset all concurrency type counts to 0
     // in each combo.
-    std::vector<std::map<IfaceType, size_t>> expanded_combos;
+    std::vector<std::map<IfaceConcurrencyType, size_t>> expanded_combos;
     expanded_combos.resize(num_expanded_combos);
     for (auto& expanded_combo : expanded_combos) {
-        for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
+        for (const auto type :
+             {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
+              IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
             expanded_combo[type] = 0;
         }
     }
@@ -1666,12 +1693,15 @@
     return expanded_combos;
 }
 
-bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
-        const std::map<IfaceType, size_t>& expanded_combo, IfaceType requested_type) {
-    const auto current_combo = getCurrentIfaceCombination();
+bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
+        const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+        IfaceConcurrencyType requested_type) {
+    const auto current_combo = getCurrentConcurrencyCombination();
 
     // Check if we have space for 1 more iface of |type| in this combo
-    for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
+    for (const auto type :
+         {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
+          IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
         size_t num_ifaces_needed = current_combo.at(type);
         if (type == requested_type) {
             num_ifaces_needed++;
@@ -1685,21 +1715,22 @@
 }
 
 // This method does the following:
-// a) Enumerate all possible iface combos by expanding the current
-//    ChipIfaceCombination.
-// b) Check if the requested iface type can be added to the current mode
-//    with the iface combination that is already active.
-bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType requested_type) {
+// a) Enumerate all possible concurrency combos by expanding the current
+//    ChipConcurrencyCombination.
+// b) Check if the requested concurrency type can be added to the current mode
+//    with the concurrency combination that is already active.
+bool WifiChip::canCurrentModeSupportConcurrencyTypeWithCurrentTypes(
+        IfaceConcurrencyType requested_type) {
     if (!isValidModeId(current_mode_id_)) {
         LOG(ERROR) << "Chip not configured in a mode yet";
         return false;
     }
-    const auto combinations = getCurrentModeIfaceCombinations();
+    const auto combinations = getCurrentModeConcurrencyCombinations();
     for (const auto& combination : combinations) {
-        const auto expanded_combos = expandIfaceCombinations(combination);
+        const auto expanded_combos = expandConcurrencyCombinations(combination);
         for (const auto& expanded_combo : expanded_combos) {
-            if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(expanded_combo,
-                                                                         requested_type)) {
+            if (canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(expanded_combo,
+                                                                                  requested_type)) {
                 return true;
             }
         }
@@ -1707,15 +1738,17 @@
     return false;
 }
 
-// Note: This does not consider ifaces already active. It only checks if the
-// provided expanded iface combination can support the requested combo.
-bool WifiChip::canExpandedIfaceComboSupportIfaceCombo(
-        const std::map<IfaceType, size_t>& expanded_combo,
-        const std::map<IfaceType, size_t>& req_combo) {
-    // Check if we have space for 1 more iface of |type| in this combo
-    for (const auto type : {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
+// Note: This does not consider concurrency types already active. It only checks if the
+// provided expanded concurrency combination can support the requested combo.
+bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyCombo(
+        const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
+        const std::map<IfaceConcurrencyType, size_t>& req_combo) {
+    // Check if we have space for 1 more |type| in this combo
+    for (const auto type :
+         {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
+          IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
         if (req_combo.count(type) == 0) {
-            // Iface of "type" not in the req_combo.
+            // Concurrency type not in the req_combo.
             continue;
         }
         size_t num_ifaces_needed = req_combo.at(type);
@@ -1727,21 +1760,22 @@
     return true;
 }
 // This method does the following:
-// a) Enumerate all possible iface combos by expanding the current
-//    ChipIfaceCombination.
-// b) Check if the requested iface combo can be added to the current mode.
-// Note: This does not consider ifaces already active. It only checks if the
+// a) Enumerate all possible concurrency combos by expanding the current
+//    ChipConcurrencyCombination.
+// b) Check if the requested concurrency combo can be added to the current mode.
+// Note: This does not consider concurrency types already active. It only checks if the
 // current mode can support the requested combo.
-bool WifiChip::canCurrentModeSupportIfaceCombo(const std::map<IfaceType, size_t>& req_combo) {
+bool WifiChip::canCurrentModeSupportConcurrencyCombo(
+        const std::map<IfaceConcurrencyType, size_t>& req_combo) {
     if (!isValidModeId(current_mode_id_)) {
         LOG(ERROR) << "Chip not configured in a mode yet";
         return false;
     }
-    const auto combinations = getCurrentModeIfaceCombinations();
+    const auto combinations = getCurrentModeConcurrencyCombinations();
     for (const auto& combination : combinations) {
-        const auto expanded_combos = expandIfaceCombinations(combination);
+        const auto expanded_combos = expandConcurrencyCombinations(combination);
         for (const auto& expanded_combo : expanded_combos) {
-            if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo, req_combo)) {
+            if (canExpandedConcurrencyComboSupportConcurrencyCombo(expanded_combo, req_combo)) {
                 return true;
             }
         }
@@ -1750,14 +1784,14 @@
 }
 
 // This method does the following:
-// a) Enumerate all possible iface combos by expanding the current
-//    ChipIfaceCombination.
-// b) Check if the requested iface type can be added to the current mode.
-bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) {
-    // Check if we can support at least 1 iface of type.
-    std::map<IfaceType, size_t> req_iface_combo;
+// a) Enumerate all possible concurrency combos by expanding the current
+//    ChipConcurrencyCombination.
+// b) Check if the requested concurrency type can be added to the current mode.
+bool WifiChip::canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type) {
+    // Check if we can support at least 1 of the requested concurrency type.
+    std::map<IfaceConcurrencyType, size_t> req_iface_combo;
     req_iface_combo[requested_type] = 1;
-    return canCurrentModeSupportIfaceCombo(req_iface_combo);
+    return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
 }
 
 bool WifiChip::isValidModeId(ChipModeId mode_id) {
@@ -1771,17 +1805,17 @@
 
 bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
     // Check if we can support at least 1 STA & 1 AP concurrently.
-    std::map<IfaceType, size_t> req_iface_combo;
-    req_iface_combo[IfaceType::AP] = 1;
-    req_iface_combo[IfaceType::STA] = 1;
-    return canCurrentModeSupportIfaceCombo(req_iface_combo);
+    std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+    req_iface_combo[IfaceConcurrencyType::STA] = 1;
+    req_iface_combo[IfaceConcurrencyType::AP] = 1;
+    return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
 }
 
 bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
     // Check if we can support at least 2 STA concurrently.
-    std::map<IfaceType, size_t> req_iface_combo;
-    req_iface_combo[IfaceType::STA] = 2;
-    return canCurrentModeSupportIfaceCombo(req_iface_combo);
+    std::map<IfaceConcurrencyType, size_t> req_iface_combo;
+    req_iface_combo[IfaceConcurrencyType::STA] = 2;
+    return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
 }
 
 std::string WifiChip::getFirstActiveWlanIfaceName() {