Improve Tuner VTS Configuration: Dynamically determine possible
dataflows

This CL allows the VTS to read the contents of vendors'
configuration files and determine which dataflows can be tested
depending on the devices provided. This only implements the logic of
determining which data flows are possible. Currently, the data flow
section of the configuration file is still being read, and
configurations are not being cycled yet. Additionally, TearDown() was
overidden for each testing class.

Bug: b/182519645

Test: vts-tradefed run vts --module VtsHalTvTunerTargetTest
Change-Id: Ib3b3c4de62e6556ef44b42e855a369a5015d66ff
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
index e8a7a79..57c7592 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -45,6 +45,8 @@
         ALOGW("[vts] failed to validate connections.");
         return false;
     }
+    determineDataFlows();
+
     return true;
 }
 
@@ -62,6 +64,14 @@
     return success();
 }
 
+void clearIds() {
+    recordDvrIds.clear();
+    audioFilterIds.clear();
+    videoFilterIds.clear();
+    playbackDvrIds.clear();
+    recordFilterIds.clear();
+}
+
 class TunerLnbAidlTest : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
@@ -77,6 +87,11 @@
         mLnbTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -105,6 +120,11 @@
         mFilterTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -135,6 +155,11 @@
         mFilterTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -201,6 +226,11 @@
         mDvrTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -238,6 +268,12 @@
         mLnbTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+        mLnbId = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -278,6 +314,11 @@
         mFrontendTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -308,6 +349,12 @@
         mDvrTests.setService(mService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+        mLnbId = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
@@ -354,6 +401,11 @@
         mDescramblerTests.setCasService(mCasService);
     }
 
+    virtual void TearDown() override {
+        clearIds();
+        mService = nullptr;
+    }
+
   protected:
     static void description(const std::string& description) {
         RecordProperty("description", description);
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index f093b8e..c4b0962 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -182,6 +182,87 @@
     TunerTestingConfigAidlReader1_0::readDiseqcMessages(diseqcMsgMap);
 };
 
+inline void determineScan() {
+    if (!frontendMap.empty()) {
+        scan.hasFrontendConnection = true;
+        ALOGD("Can support scan");
+    }
+}
+
+inline void determineTimeFilter() {
+    if (!timeFilterMap.empty()) {
+        timeFilter.support = true;
+        ALOGD("Can support time filter");
+    }
+}
+
+inline void determineDvrPlayback() {
+    if (!playbackDvrIds.empty() && !audioFilterIds.empty() && !videoFilterIds.empty()) {
+        playback.support = true;
+        ALOGD("Can support dvr playback");
+    }
+}
+
+inline void determineLnbLive() {
+    if (!audioFilterIds.empty() && !videoFilterIds.empty() && !frontendMap.empty() &&
+        !lnbMap.empty()) {
+        lnbLive.support = true;
+        ALOGD("Can support lnb live");
+    }
+}
+
+inline void determineLnbRecord() {
+    if (!frontendMap.empty() && !recordFilterIds.empty() && !recordDvrIds.empty() &&
+        !lnbMap.empty()) {
+        lnbRecord.support = true;
+        ALOGD("Can support lnb record");
+    }
+}
+
+inline void determineLive() {
+    if (videoFilterIds.empty() || audioFilterIds.empty() || frontendMap.empty()) {
+        return;
+    }
+    if (hasSwFe && !hasHwFe && dvrMap.empty()) {
+        ALOGD("Cannot configure Live. Only software frontends and no dvr connections");
+        return;
+    }
+    ALOGD("Can support live");
+    live.hasFrontendConnection = true;
+}
+
+inline void determineDescrambling() {
+    if (descramblerMap.empty() || audioFilterIds.empty() || videoFilterIds.empty()) {
+        return;
+    }
+    if (frontendMap.empty() && playbackDvrIds.empty()) {
+        ALOGD("Cannot configure descrambling. No frontends or playback dvr's");
+        return;
+    }
+    if (hasSwFe && !hasHwFe && playbackDvrIds.empty()) {
+        ALOGD("cannot configure descrambling. Only SW frontends and no playback dvr's");
+        return;
+    }
+    ALOGD("Can support descrambling");
+    descrambling.support = true;
+}
+
+inline void determineDvrRecord() {
+    if (recordDvrIds.empty() || recordFilterIds.empty()) {
+        return;
+    }
+    if (frontendMap.empty() && playbackDvrIds.empty()) {
+        ALOGD("Cannot support dvr record. No frontends and  no playback dvr's");
+        return;
+    }
+    if (hasSwFe && !hasHwFe && playbackDvrIds.empty()) {
+        ALOGD("Cannot support dvr record. Only SW frontends and no playback dvr's");
+        return;
+    }
+    ALOGD("Can support dvr record.");
+    record.support = true;
+}
+
 /** Read the vendor configurations of which hardware to use for each test cases/data flows */
 inline void connectHardwaresToTestCases() {
     TunerTestingConfigAidlReader1_0::connectLiveBroadcast(live);
@@ -194,6 +275,17 @@
     TunerTestingConfigAidlReader1_0::connectDvrPlayback(playback);
 };
 
+inline void determineDataFlows() {
+    determineScan();
+    determineTimeFilter();
+    determineDvrPlayback();
+    determineLnbLive();
+    determineLnbRecord();
+    determineLive();
+    determineDescrambling();
+    determineDvrRecord();
+}
+
 inline bool validateConnections() {
     if (record.support && !record.hasFrontendConnection &&
         record.dvrSourceId.compare(emptyHardwareId) == 0) {
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index b6e1020..7c757b4 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -62,10 +62,28 @@
 using namespace aidl::android::hardware::tv::tuner;
 using namespace android::media::tuner::testing::configuration::V1_0;
 
+static bool hasHwFe = false;
+static bool hasSwFe = false;
+static bool configFileRead = false;
+static bool configuredLive = false;
+static bool configuredScan = false;
+static bool configuredRecord = false;
+static bool configuredLnbLive = false;
+static bool configuredPlayback = false;
+static bool configuredLnbRecord = false;
+static bool configuredTimeFilter = false;
+static bool configuredDescrambling = false;
+
 const string emptyHardwareId = "";
 
 static string mConfigFilePath;
 
+static vector<string> playbackDvrIds;
+static vector<string> recordDvrIds;
+static vector<string> audioFilterIds;
+static vector<string> videoFilterIds;
+static vector<string> recordFilterIds;
+
 #define PROVISION_STR                                      \
     "{                                                   " \
     "  \"id\": 21140844,                                 " \
@@ -310,6 +328,11 @@
                 }
                 frontendMap[id].type = type;
                 frontendMap[id].isSoftwareFe = feConfig.getIsSoftwareFrontend();
+                if (frontendMap[id].isSoftwareFe) {
+                    hasSwFe = true;
+                } else {
+                    hasHwFe = true;
+                }
                 // TODO: b/182519645 complete the tune status config
                 frontendMap[id].tuneStatusTypes = types;
                 frontendMap[id].expectTuneStatuses = statuses;
@@ -384,11 +407,13 @@
                 DvrType type;
                 switch (dvrConfig.getType()) {
                     case DvrTypeEnum::PLAYBACK:
+                        playbackDvrIds.push_back(id);
                         type = DvrType::PLAYBACK;
                         dvrMap[id].settings.set<DvrSettings::Tag::playback>(
                                 readPlaybackSettings(dvrConfig));
                         break;
                     case DvrTypeEnum::RECORD:
+                        recordDvrIds.push_back(id);
                         type = DvrType::RECORD;
                         dvrMap[id].settings.set<DvrSettings::Tag::record>(
                                 readRecordSettings(dvrConfig));
@@ -477,6 +502,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasClearLiveBroadcast()) {
             live.hasFrontendConnection = true;
+            configuredLive = true;
         } else {
             live.hasFrontendConnection = false;
             return;
@@ -510,6 +536,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasScan()) {
             scan.hasFrontendConnection = true;
+            configuredScan = true;
         } else {
             scan.hasFrontendConnection = false;
             return;
@@ -522,6 +549,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasDvrPlayback()) {
             playback.support = true;
+            configuredPlayback = true;
         } else {
             playback.support = false;
             return;
@@ -548,6 +576,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasDvrRecord()) {
             record.support = true;
+            configuredRecord = true;
         } else {
             record.support = false;
             return;
@@ -572,6 +601,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasDescrambling()) {
             descrambling.support = true;
+            configuredDescrambling = true;
         } else {
             descrambling.support = false;
             return;
@@ -601,6 +631,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasLnbLive()) {
             lnbLive.support = true;
+            configuredLnbLive = true;
         } else {
             lnbLive.support = false;
             return;
@@ -625,6 +656,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasLnbRecord()) {
             lnbRecord.support = true;
+            configuredLnbRecord = true;
         } else {
             lnbRecord.support = false;
             return;
@@ -649,6 +681,7 @@
         auto dataFlow = getDataFlowConfiguration();
         if (dataFlow.hasTimeFilter()) {
             timeFilter.support = true;
+            configuredTimeFilter = true;
         } else {
             timeFilter.support = false;
             return;
@@ -799,6 +832,14 @@
         auto mainType = filterConfig.getMainType();
         auto subType = filterConfig.getSubType();
 
+        if (subType == FilterSubTypeEnum::AUDIO) {
+            audioFilterIds.push_back(filterConfig.getId());
+        } else if (subType == FilterSubTypeEnum::VIDEO) {
+            videoFilterIds.push_back(filterConfig.getId());
+        } else if (subType == FilterSubTypeEnum::RECORD) {
+            recordFilterIds.push_back(filterConfig.getId());
+        }
+
         switch (mainType) {
             case FilterMainTypeEnum::TS: {
                 ALOGW("[ConfigReader] filter main type is ts");