wifi(hal): Use debug property to select one of  preset HAL iface combination

This will be useful for testing/debugging STA + STA & AP + AP feature.

Note: I originally planned to read the entire iface combination from the
property (i.e would be much more flexible), but that is way too complex
and error prone. So, instead pre-define some combinations that we would
want to switch between and use the property as an index.

Bug: 173044646
Test: Manual:
i) adb shell "/vendor/bin/sh -c '/vendor/bin/setprop
persist.vendor.debug.wifi.hal.preset_interface_combination_idx 0'"
ii) adb reboot
iii) Ensure that AP + AP was enabled.

Change-Id: Iea63835c39fce78307a056a5ed94efcbd35cdfb6
diff --git a/wifi/1.5/default/wifi_feature_flags.cpp b/wifi/1.5/default/wifi_feature_flags.cpp
index 9f91bd7..124ba32 100644
--- a/wifi/1.5/default/wifi_feature_flags.cpp
+++ b/wifi/1.5/default/wifi_feature_flags.cpp
@@ -14,6 +14,11 @@
  * limitations under the License.
  */
 
+#include <string>
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+
 #include "wifi_feature_flags.h"
 
 namespace android {
@@ -131,7 +136,7 @@
 #define AP IfaceType::AP
 #define P2P IfaceType::P2P
 #define NAN IfaceType::NAN
-static const std::vector<IWifiChip::ChipMode> kChipModes{
+static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
     {kMainModeId,
      ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})},
 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
@@ -146,6 +151,50 @@
                              {WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
 #endif
 };
+
+constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
+    "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
+// List of pre-defined interface combinations that can be enabled at runtime via
+// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
+// corresponding index value.
+static const std::vector<
+    std::pair<std::string, std::vector<IWifiChip::ChipMode>>>
+    kDebugChipModes{
+        // Legacy combination - No STA/AP concurrencies.
+        // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
+        {"No STA/AP Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + AP concurrency
+        // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
+        {"STA + AP Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + STA concurrency
+        // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
+        {"Dual STA Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+        // AP + AP + STA concurrency
+        // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
+        {"Dual AP Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + STA concurrency and AP + AP + STA concurrency
+        // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
+        {"Dual STA & Dual AP Concurrency",
+         {{kMainModeId,
+           ChipIfaceCombination::make_vec(
+               {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}};
+
 #undef STA
 #undef AP
 #undef P2P
@@ -161,9 +210,31 @@
 
 WifiFeatureFlags::WifiFeatureFlags() {}
 
+std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty,
+                            buffer.data(), nullptr);
+    // Debug propety not set, use the device preset interface combination.
+    if (res <= 0) return kChipModesPrimary;
+
+    // Debug propety set, use one of the debug preset interface combination.
+    unsigned long idx = std::stoul(buffer.data());
+    if (idx >= kDebugChipModes.size()) {
+        LOG(ERROR) << "Invalid index set in property: "
+                   << kDebugPresetInterfaceCombinationIdxProperty;
+        return kChipModesPrimary;
+    }
+    std::string name;
+    std::vector<IWifiChip::ChipMode> chip_modes;
+    std::tie(name, chip_modes) = kDebugChipModes[idx];
+    LOG(INFO) << "Using debug chip mode: <" << name << "> set via property: "
+              << kDebugPresetInterfaceCombinationIdxProperty;
+    return chip_modes;
+}
+
 std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(
     bool is_primary) {
-    return (is_primary) ? kChipModes : kChipModesSecondary;
+    return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
 }
 
 }  // namespace feature_flags