Improve Tuner VTS: Generate LnbLive Combos

This CL allows the VTS to read a vendor's configuration file, determine
if the given devices could support the Lnb Live dataflow, and generate
all combinations of units to run them on corresponding integration tests.

Bug: b/182519645

Test: vts-tradefed run vts --module VtsHalTvTunerTargetTest. Manual
tests with different input configuration files.

Change-Id: Iba5262375b3053e0093f91fd3b05a9ebd42ca7d0
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index f8e4d0b..0285e04 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -494,23 +494,32 @@
     if (!lnbLive.support) {
         return;
     }
-    if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) {
-        vector<int32_t> ids;
-        ASSERT_TRUE(mLnbTests.getLnbIds(ids));
-        ASSERT_TRUE(ids.size() > 0);
-        ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
-    } else {
-        int32_t id;
-        ASSERT_TRUE(mLnbTests.openLnbByName(lnbMap[lnbLive.lnbId].name, id));
+    vector<LnbLiveHardwareConnections> lnbLive_configs = generateLnbLiveConfigurations();
+    if (lnbLive_configs.empty()) {
+        ALOGD("No frontends that support satellites.");
+        return;
     }
-    ASSERT_TRUE(mLnbTests.setLnbCallback());
-    ASSERT_TRUE(mLnbTests.setVoltage(lnbMap[lnbLive.lnbId].voltage));
-    ASSERT_TRUE(mLnbTests.setTone(lnbMap[lnbLive.lnbId].tone));
-    ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbMap[lnbLive.lnbId].position));
-    for (auto msgName : lnbLive.diseqcMsgs) {
-        ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
+    for (auto& combination : lnbLive_configs) {
+        lnbLive = combination;
+
+        if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) {
+            vector<int32_t> ids;
+            ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+            ASSERT_TRUE(ids.size() > 0);
+            ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+        } else {
+            int32_t id;
+            ASSERT_TRUE(mLnbTests.openLnbByName(lnbMap[lnbLive.lnbId].name, id));
+        }
+        ASSERT_TRUE(mLnbTests.setLnbCallback());
+        ASSERT_TRUE(mLnbTests.setVoltage(lnbMap[lnbLive.lnbId].voltage));
+        ASSERT_TRUE(mLnbTests.setTone(lnbMap[lnbLive.lnbId].tone));
+        ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbMap[lnbLive.lnbId].position));
+        for (auto msgName : lnbLive.diseqcMsgs) {
+            ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
+        }
+        ASSERT_TRUE(mLnbTests.closeLnb());
     }
-    ASSERT_TRUE(mLnbTests.closeLnb());
 }
 
 TEST_P(TunerDemuxAidlTest, openDemux) {
@@ -1019,8 +1028,16 @@
     if (!lnbLive.support) {
         return;
     }
-    broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId],
-                                     frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]);
+    vector<LnbLiveHardwareConnections> lnbLive_configs = generateLnbLiveConfigurations();
+    if (lnbLive_configs.empty()) {
+        ALOGD("No frontends that support satellites.");
+        return;
+    }
+    for (auto& combination : lnbLive_configs) {
+        lnbLive = combination;
+        broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId],
+                                         frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, MediaFilterWithSharedMemoryHandle) {
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
index d4536aa..d6b852f 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -65,6 +65,9 @@
 }
 
 void clearIds() {
+    lnbIds.clear();
+    diseqcMsgs.clear();
+    frontendIds.clear();
     recordDvrIds.clear();
     audioFilterIds.clear();
     videoFilterIds.clear();
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index f3928a3..2ff19cd 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -173,6 +173,55 @@
     return playback_configs;
 }
 
+/*
+ * index 0 - frontends
+ * index 1 - audio filters
+ * index 2 - video filters
+ * index 3 - lnbs
+ */
+static inline vector<LnbLiveHardwareConnections> generateLnbLiveCombinations() {
+    vector<LnbLiveHardwareConnections> combinations;
+    vector<vector<string>> deviceIds{frontendIds, audioFilterIds, videoFilterIds, lnbIds};
+
+    const int frontendIndex = 0;
+    const int audioFilterIndex = 1;
+    const int videoFilterIndex = 2;
+    const int lnbIndex = 3;
+
+    // TODO: Find a better way to vary diseqcMsgs, if at all
+    auto idCombinations = generateIdCombinations(deviceIds);
+    for (auto& combo : idCombinations) {
+        const string feId = combo[frontendIndex];
+        auto type = frontendMap[feId].type;
+        if (type == FrontendType::DVBS || type == FrontendType::ISDBS ||
+            type == FrontendType::ISDBS3) {
+            LnbLiveHardwareConnections mLnbLive;
+            mLnbLive.frontendId = feId;
+            mLnbLive.audioFilterId = combo[audioFilterIndex];
+            mLnbLive.videoFilterId = combo[videoFilterIndex];
+            mLnbLive.lnbId = combo[lnbIndex];
+            mLnbLive.diseqcMsgs = diseqcMsgs;
+            combinations.push_back(mLnbLive);
+        }
+    }
+
+    return combinations;
+}
+
+static inline vector<LnbLiveHardwareConnections> generateLnbLiveConfigurations() {
+    vector<LnbLiveHardwareConnections> lnbLive_configs;
+    if (configuredLnbLive) {
+        ALOGD("Using LnbLive configuration provided.");
+        lnbLive_configs = {lnbLive};
+    } else {
+        ALOGD("LnbLive not provided. Generating possible combinations. Consider adding it to the "
+              "configuration file.");
+        lnbLive_configs = generateLnbLiveCombinations();
+    }
+
+    return lnbLive_configs;
+}
+
 /** Config all the frontends that would be used in the tests */
 inline void initFrontendConfig() {
     // The test will use the internal default fe when default fe is connected to any data flow
@@ -368,8 +417,8 @@
     TunerTestingConfigAidlReader1_0::connectDvrRecord(record);
     TunerTestingConfigAidlReader1_0::connectTimeFilter(timeFilter);
     TunerTestingConfigAidlReader1_0::connectDescrambling(descrambling);
-    TunerTestingConfigAidlReader1_0::connectLnbLive(lnbLive);
     TunerTestingConfigAidlReader1_0::connectLnbRecord(lnbRecord);
+    TunerTestingConfigAidlReader1_0::connectLnbLive(lnbLive);
     TunerTestingConfigAidlReader1_0::connectDvrPlayback(playback);
 };