From a53f554ca881333b3f4119a5cd0036f0ef9c4783 Mon Sep 17 00:00:00 2001 From: Frankie Lizcano Date: Thu, 7 Jul 2022 17:32:06 +0000 Subject: [PATCH 1/5] Improve Tuner VTS: Generate DVR Playback Combos This CL allows the VTS to read a vendor's configuration file, determine if the given devices could support the playback dataflow, and generate all combinations of units (dvr, audio filter, video filter, section filters) to run them on corresponding integration tests. Additionally, began storing section filter id's and eliminated the check to see if they were stored already by utilizing the TearDown() function between integration tests. Bug: b/182519645 Test: vts-tradefed run vts --module VtsHalTvTunerTargetTest. Manual tests with different input configuration files. Change-Id: I8e8be258dce9927e755f9c8bdb41441f367a196b --- .../functional/VtsHalTvTunerTargetTest.cpp | 22 ++++- .../vts/functional/VtsHalTvTunerTargetTest.h | 1 + .../VtsHalTvTunerTestConfigurations.h | 98 +++++++++++++++++++ .../config/TunerTestingConfigAidlReaderV1_0.h | 3 + 4 files changed, 120 insertions(+), 4 deletions(-) diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp index 07e3e3cbe2..f8e4d0b521 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp @@ -839,10 +839,16 @@ TEST_P(TunerFilterAidlTest, FilterDelayHintTest) { TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) { description("Feed ts data from playback and configure Ts section filter to get output"); - if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) { + if (!playback.support) { return; } - playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]); + vector playback_configs = generatePlaybackConfigs(); + for (auto& configuration : playback_configs) { + if (configuration.sectionFilterId.compare(emptyHardwareId) != 0) { + playback = configuration; + playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]); + } + } } TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsAudioFilterTest) { @@ -850,7 +856,11 @@ TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsAudioFilterTest) { if (!playback.support) { return; } - playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]); + vector playback_configs = generatePlaybackConfigs(); + for (auto& configuration : playback_configs) { + playback = configuration; + playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]); + } } TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsVideoFilterTest) { @@ -858,7 +868,11 @@ TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsVideoFilterTest) { if (!playback.support) { return; } - playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]); + vector playback_configs = generatePlaybackConfigs(); + for (auto& configuration : playback_configs) { + playback = configuration; + playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]); + } } TEST_P(TunerRecordAidlTest, RecordDataFlowWithTsRecordFilterTest) { diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h index 57c7592a8b..d4536aad1e 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h @@ -70,6 +70,7 @@ void clearIds() { videoFilterIds.clear(); playbackDvrIds.clear(); recordFilterIds.clear(); + sectionFilterIds.clear(); } class TunerLnbAidlTest : public testing::TestWithParam { diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h index c4b09629bf..f3928a35ae 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h @@ -75,6 +75,104 @@ static LnbLiveHardwareConnections lnbLive; static LnbRecordHardwareConnections lnbRecord; static TimeFilterHardwareConnections timeFilter; +/* + * This function takes in a 2d vector of device Id's + * The n vectors correlate to the ids for n different devices (eg frontends, filters) + * The resultant 2d vector is every combination of id's with 1 id from each vector + */ +inline vector> generateIdCombinations(vector>& ids) { + vector> combinations; + + // The index of each vector in ids that will be used in the next combination + // EG {0, 2} means combo {ids[0][0] ids[1][2]} will be next + const int size = static_cast(ids.size()); + vector indexes_used_in_combination(size, 0); + + // The vector number from ids whose elements we will cycle through to make combinations. + // First, start at the right most vector + int cycled_vector = size - 1; + + while (cycled_vector >= 0) { + // Make a combination (one at a time) + vector combo; + for (size_t i = 0; i < indexes_used_in_combination.size(); ++i) { + const int combo_index = indexes_used_in_combination[i]; + combo.push_back(ids[i][combo_index]); + } + combinations.push_back(combo); + + // Find the right most vector that still has space [elements left] to cycle through and + // create a combination + while (cycled_vector >= 0 && + indexes_used_in_combination[cycled_vector] == ids[cycled_vector].size() - 1) { + cycled_vector--; + } + + // Use this check to avoid segmentation faults + if (cycled_vector >= 0) { + // Once found, we have a vector we can cycle through, so increase to its next element + indexes_used_in_combination[cycled_vector]++; + + // Reset the other vectors to the right to their first element so we can cycle through + // them again with the new element from cycled vector + for (size_t i = cycled_vector + 1; i < indexes_used_in_combination.size(); ++i) { + indexes_used_in_combination[i] = 0; + } + + // all the vectors to the right were reset, so we can cycle through them again + // Start at the furthest right vector + cycled_vector = size - 1; + } + } + + return combinations; +} + +/* + * index 0 - playback dvr + * index 1 - audio filters + * index 2 - video filters + * index 3 - optional section filters + */ +static inline vector generatePlaybackCombinations() { + vector combinations; + vector sectionFilterIds_optional = sectionFilterIds; + sectionFilterIds_optional.push_back(emptyHardwareId); + vector> deviceIds{playbackDvrIds, audioFilterIds, videoFilterIds, + sectionFilterIds_optional}; + + const int dvrIndex = 0; + const int audioFilterIndex = 1; + const int videoFilterIndex = 2; + const int sectionFilterIndex = 3; + + auto idCombinations = generateIdCombinations(deviceIds); + for (auto& combo : idCombinations) { + DvrPlaybackHardwareConnections mPlayback; + mPlayback.dvrId = combo[dvrIndex]; + mPlayback.audioFilterId = combo[audioFilterIndex]; + mPlayback.videoFilterId = combo[videoFilterIndex]; + mPlayback.sectionFilterId = combo[sectionFilterIndex]; + combinations.push_back(mPlayback); + } + + return combinations; +} + +static inline vector generatePlaybackConfigs() { + vector playback_configs; + if (configuredPlayback) { + ALOGD("Using DVR playback configuration provided."); + playback_configs = {playback}; + } else { + ALOGD("Dvr playback not provided. Generating possible combinations. Consider adding it to " + "the configuration file."); + playback_configs = generatePlaybackCombinations(); + } + + return playback_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 diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h index 7c757b4ebb..27b458fcb7 100644 --- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h +++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h @@ -83,6 +83,7 @@ static vector recordDvrIds; static vector audioFilterIds; static vector videoFilterIds; static vector recordFilterIds; +static vector sectionFilterIds; #define PROVISION_STR \ "{ " \ @@ -838,6 +839,8 @@ struct TunerTestingConfigAidlReader1_0 { videoFilterIds.push_back(filterConfig.getId()); } else if (subType == FilterSubTypeEnum::RECORD) { recordFilterIds.push_back(filterConfig.getId()); + } else if (subType == FilterSubTypeEnum::SECTION) { + sectionFilterIds.push_back(filterConfig.getId()); } switch (mainType) { From 1e283b38646543b72853d1b39eabaa0d9a3ff5ea Mon Sep 17 00:00:00 2001 From: Frankie Lizcano Date: Fri, 8 Jul 2022 21:07:42 +0000 Subject: [PATCH 2/5] 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 --- .../functional/VtsHalTvTunerTargetTest.cpp | 51 ++++++++++++------- .../vts/functional/VtsHalTvTunerTargetTest.h | 3 ++ .../VtsHalTvTunerTestConfigurations.h | 51 ++++++++++++++++++- .../config/TunerTestingConfigAidlReaderV1_0.h | 6 +++ 4 files changed, 93 insertions(+), 18 deletions(-) diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp index f8e4d0b521..0285e0405e 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp @@ -494,23 +494,32 @@ TEST_P(TunerLnbAidlTest, SendDiseqcMessageToLnb) { if (!lnbLive.support) { return; } - if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) { - vector 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 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 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 @@ TEST_P(TunerBroadcastAidlTest, LnbBroadcastDataFlowVideoFilterTest) { if (!lnbLive.support) { return; } - broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId], - frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]); + vector 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 d4536aad1e..d6b852f62a 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h @@ -65,6 +65,9 @@ AssertionResult filterDataOutputTestBase(FilterTests& tests) { } 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 f3928a35ae..2ff19cd207 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h @@ -173,6 +173,55 @@ static inline vector generatePlaybackConfigs() { return playback_configs; } +/* + * index 0 - frontends + * index 1 - audio filters + * index 2 - video filters + * index 3 - lnbs + */ +static inline vector generateLnbLiveCombinations() { + vector combinations; + vector> 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 generateLnbLiveConfigurations() { + vector 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 @@ inline void connectHardwaresToTestCases() { 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); }; diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h index 27b458fcb7..31f07553d1 100644 --- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h +++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h @@ -84,6 +84,9 @@ static vector audioFilterIds; static vector videoFilterIds; static vector recordFilterIds; static vector sectionFilterIds; +static vector frontendIds; +static vector lnbIds; +static vector diseqcMsgs; #define PROVISION_STR \ "{ " \ @@ -268,6 +271,7 @@ struct TunerTestingConfigAidlReader1_0 { auto frontends = *hardwareConfig.getFirstFrontends(); for (auto feConfig : frontends.getFrontend()) { string id = feConfig.getId(); + frontendIds.push_back(id); if (id.compare(string("FE_DEFAULT")) == 0) { // overrid default frontendMap.erase(string("FE_DEFAULT")); @@ -438,6 +442,7 @@ struct TunerTestingConfigAidlReader1_0 { auto lnbs = *hardwareConfig.getFirstLnbs(); for (auto lnbConfig : lnbs.getLnb()) { string id = lnbConfig.getId(); + lnbIds.push_back(id); if (lnbConfig.hasName()) { lnbMap[id].name = lnbConfig.getName(); } else { @@ -481,6 +486,7 @@ struct TunerTestingConfigAidlReader1_0 { auto msgs = *hardwareConfig.getFirstDiseqcMessages(); for (auto msgConfig : msgs.getDiseqcMessage()) { string name = msgConfig.getMsgName(); + diseqcMsgs.push_back(name); for (uint8_t atom : msgConfig.getMsgBody()) { diseqcMsgMap[name].push_back(atom); } From 3138d6b7eafcec65473c13e9fde5c3b2d590b32c Mon Sep 17 00:00:00 2001 From: Frankie Lizcano Date: Mon, 11 Jul 2022 22:06:45 +0000 Subject: [PATCH 3/5] Improve Tuner VTS: Generate Scan Combos This CL allows the VTS to read a vendor's configuration file, determine if the given devices could support the Scan dataflow, and runs the integration tests with all valid frontends. Bug: b/182519645 Test: vts-tradefed run vts --module VtsHalTvTunerTargetTest. Manual tests with different input configuration files. Change-Id: Ic6756e284090fbd1961a9ed12c1a4b541fb834b8 --- .../functional/VtsHalTvTunerTargetTest.cpp | 18 ++++++++++-- .../VtsHalTvTunerTestConfigurations.h | 28 ++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp index 0285e0405e..95061b583c 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp @@ -926,7 +926,11 @@ TEST_P(TunerFrontendAidlTest, AutoScanFrontend) { if (!scan.hasFrontendConnection) { return; } - mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO); + vector scan_configs = generateScanConfigurations(); + for (auto& configuration : scan_configs) { + scan = configuration; + mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO); + } } TEST_P(TunerFrontendAidlTest, BlindScanFrontend) { @@ -934,7 +938,11 @@ TEST_P(TunerFrontendAidlTest, BlindScanFrontend) { if (!scan.hasFrontendConnection) { return; } - mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); + vector scan_configs = generateScanConfigurations(); + for (auto& configuration : scan_configs) { + scan = configuration; + mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); + } } TEST_P(TunerFrontendAidlTest, TuneFrontendWithFrontendSettings) { @@ -950,7 +958,11 @@ TEST_P(TunerFrontendAidlTest, BlindScanFrontendWithEndFrequency) { if (!scan.hasFrontendConnection) { return; } - mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); + vector scan_configs = generateScanConfigurations(); + for (auto& configuration : scan_configs) { + scan = configuration; + mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); + } } TEST_P(TunerFrontendAidlTest, LinkToCiCam) { diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h index 2ff19cd207..aa38e4879b 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h @@ -222,6 +222,32 @@ static inline vector generateLnbLiveConfigurations() return lnbLive_configs; } +static inline vector generateScanCombinations() { + vector combinations; + + for (auto& id : frontendIds) { + ScanHardwareConnections mScan; + mScan.frontendId = id; + combinations.push_back(mScan); + } + + return combinations; +} + +static inline vector generateScanConfigurations() { + vector scan_configs; + if (configuredScan) { + ALOGD("Using scan configuration provided."); + scan_configs = {scan}; + } else { + ALOGD("Scan not provided. Generating possible combinations. Consider adding it to " + "the configuration file."); + scan_configs = generateScanCombinations(); + } + + return scan_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 @@ -417,8 +443,8 @@ inline void connectHardwaresToTestCases() { TunerTestingConfigAidlReader1_0::connectDvrRecord(record); TunerTestingConfigAidlReader1_0::connectTimeFilter(timeFilter); TunerTestingConfigAidlReader1_0::connectDescrambling(descrambling); - TunerTestingConfigAidlReader1_0::connectLnbRecord(lnbRecord); TunerTestingConfigAidlReader1_0::connectLnbLive(lnbLive); + TunerTestingConfigAidlReader1_0::connectLnbRecord(lnbRecord); TunerTestingConfigAidlReader1_0::connectDvrPlayback(playback); }; From ecba02ae0e501d5ff98dff319cf704e1ce0d3124 Mon Sep 17 00:00:00 2001 From: Frankie Lizcano Date: Tue, 12 Jul 2022 17:56:54 +0000 Subject: [PATCH 4/5] Improve Tuner VTS: Generate LnbRecord Combos This CL allows the VTS to read a vendor's configuration file, determine if the given devices could support the LnbRecord dataflow, and generate all combinations of units (frontend, record filter, dvr, lnb) 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: I470d593195d3f6e81cea9758b5758ec47ad3d21c --- .../functional/VtsHalTvTunerTargetTest.cpp | 14 +++-- .../VtsHalTvTunerTestConfigurations.h | 51 ++++++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp index 95061b583c..a6c523f3de 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp @@ -908,9 +908,17 @@ TEST_P(TunerRecordAidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { if (!lnbRecord.support) { return; } - recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId], - frontendMap[lnbRecord.frontendId], dvrMap[lnbRecord.dvrRecordId], - lnbMap[lnbRecord.lnbId]); + vector lnbRecord_configs = generateLnbRecordConfigurations(); + if (lnbRecord_configs.empty()) { + ALOGD("No frontends that support satellites."); + return; + } + for (auto& configuration : lnbRecord_configs) { + lnbRecord = configuration; + recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId], + frontendMap[lnbRecord.frontendId], + dvrMap[lnbRecord.dvrRecordId], lnbMap[lnbRecord.lnbId]); + } } TEST_P(TunerFrontendAidlTest, TuneFrontend) { diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h index aa38e4879b..bcc8c61e0d 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h @@ -248,6 +248,55 @@ static inline vector generateScanConfigurations() { return scan_configs; } +/* + * index 0 - frontends + * index 1 - record filter + * index 2 - Record Dvr + * index 3 - Lnb + */ +static inline vector generateLnbRecordCombinations() { + vector combinations; + vector> deviceIds{frontendIds, recordFilterIds, recordDvrIds, lnbIds}; + + const int frontendIndex = 0; + const int recordFilterIndex = 1; + const int dvrIndex = 2; + const int lnbIndex = 3; + + auto idCombinations = generateIdCombinations(deviceIds); + // TODO : Find a better way to vary diseqcMsgs, if at all + for (auto& combo : idCombinations) { + const string feId = combo[frontendIndex]; + auto type = frontendMap[feId].type; + if (type == FrontendType::DVBS || type == FrontendType::ISDBS || + type == FrontendType::ISDBS3) { + LnbRecordHardwareConnections mLnbRecord; + mLnbRecord.frontendId = feId; + mLnbRecord.recordFilterId = combo[recordFilterIndex]; + mLnbRecord.dvrRecordId = combo[dvrIndex]; + mLnbRecord.lnbId = combo[lnbIndex]; + mLnbRecord.diseqcMsgs = diseqcMsgs; + combinations.push_back(mLnbRecord); + } + } + + return combinations; +} + +static inline vector generateLnbRecordConfigurations() { + vector lnbRecord_configs; + if (configuredLnbRecord) { + ALOGD("Using LnbRecord configuration provided."); + lnbRecord_configs = {lnbRecord}; + } else { + ALOGD("LnbRecord not provided. Generating possible combinations. Consider adding it to " + "the configuration file."); + lnbRecord_configs = generateLnbRecordCombinations(); + } + + return lnbRecord_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 @@ -425,7 +474,7 @@ inline void determineDvrRecord() { return; } if (frontendMap.empty() && playbackDvrIds.empty()) { - ALOGD("Cannot support dvr record. No frontends and no playback dvr's"); + ALOGD("Cannot support dvr record. No frontends and no playback dvr's"); return; } if (hasSwFe && !hasHwFe && playbackDvrIds.empty()) { From f4e0796ef34e596d527239ce94274b61187a9cc9 Mon Sep 17 00:00:00 2001 From: Frankie Lizcano Date: Wed, 13 Jul 2022 20:54:34 +0000 Subject: [PATCH 5/5] Improve Tuner VTS: Generate Descrambling Combos This CL allows the VTS to read a vendor's configuration file, determine if the given devices could support the Descrambling dataflow, and generate all combinations of units to run them on corresponding integration tests. Each combination is error checked to ensure they meet the minumum requirements, and any invalid ones are discared, which may narrow the combination space immensely. Bug: b/182519645 Test: vts-tradefed run vts --module VtsHalTvTunerTargetTest. Manual tests with different input configuration files. Change-Id: Ic1b9dae6b43f8f01bc4e490ef9e910a933562bd2 --- .../functional/VtsHalTvTunerTargetTest.cpp | 60 +++++++++----- .../vts/functional/VtsHalTvTunerTargetTest.h | 1 + .../VtsHalTvTunerTestConfigurations.h | 81 +++++++++++++++++++ .../config/TunerTestingConfigAidlReaderV1_0.h | 2 + 4 files changed, 123 insertions(+), 21 deletions(-) diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp index a6c523f3de..e6c66911d8 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp @@ -1073,25 +1073,34 @@ TEST_P(TunerDescramblerAidlTest, CreateDescrambler) { if (!descrambling.support) { return; } - int32_t demuxId; - std::shared_ptr demux; - ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - - if (descrambling.hasFrontendConnection) { - int32_t feId; - mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId); - ASSERT_TRUE(feId != INVALID_ID); - ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); - ASSERT_TRUE(mFrontendTests.setFrontendCallback()); - ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + vector descrambling_configs = + generateDescramblingConfigurations(); + if (descrambling_configs.empty()) { + ALOGD("No valid descrambling combinations in the configuration file."); + return; } + for (auto& combination : descrambling_configs) { + descrambling = combination; + int32_t demuxId; + std::shared_ptr demux; + ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); - ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId)); - ASSERT_TRUE(mDescramblerTests.closeDescrambler()); - ASSERT_TRUE(mDemuxTests.closeDemux()); + if (descrambling.hasFrontendConnection) { + int32_t feId; + mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId); + ASSERT_TRUE(feId != INVALID_ID); + ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); + ASSERT_TRUE(mFrontendTests.setFrontendCallback()); + ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); + } - if (descrambling.hasFrontendConnection) { - ASSERT_TRUE(mFrontendTests.closeFrontend()); + ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId)); + ASSERT_TRUE(mDescramblerTests.closeDescrambler()); + ASSERT_TRUE(mDemuxTests.closeDemux()); + + if (descrambling.hasFrontendConnection) { + ASSERT_TRUE(mFrontendTests.closeFrontend()); + } } } @@ -1100,11 +1109,20 @@ TEST_P(TunerDescramblerAidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { if (!descrambling.support) { return; } - set filterConfs; - filterConfs.insert(static_cast(filterMap[descrambling.audioFilterId])); - filterConfs.insert(static_cast(filterMap[descrambling.videoFilterId])); - scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId], - descramblerMap[descrambling.descramblerId]); + vector descrambling_configs = + generateDescramblingConfigurations(); + if (descrambling_configs.empty()) { + ALOGD("No valid descrambling combinations in the configuration file."); + return; + } + for (auto& combination : descrambling_configs) { + descrambling = combination; + set filterConfs; + filterConfs.insert(static_cast(filterMap[descrambling.audioFilterId])); + filterConfs.insert(static_cast(filterMap[descrambling.videoFilterId])); + scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId], + descramblerMap[descrambling.descramblerId]); + } } INSTANTIATE_TEST_SUITE_P(PerInstance, TunerBroadcastAidlTest, diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h index d6b852f62a..6ffa18f5bd 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h @@ -69,6 +69,7 @@ void clearIds() { diseqcMsgs.clear(); frontendIds.clear(); recordDvrIds.clear(); + descramblerIds.clear(); audioFilterIds.clear(); videoFilterIds.clear(); playbackDvrIds.clear(); diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h index bcc8c61e0d..de12dc0efa 100644 --- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h +++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h @@ -297,6 +297,87 @@ static inline vector generateLnbRecordConfiguratio return lnbRecord_configs; } +/* + * index 0 - decramblers + * index 1 - frontends + * index 2 - audio filters + * index 3 - video filters + * index 4 - Dvr SW Fe Connections + * index 5 - DVR Source Connections + */ +static inline vector generateDescramblingCombinations() { + vector combinations; + vector mfrontendIds = frontendIds; + vector mDvrFeConnectionIds = playbackDvrIds; + vector mDvrSourceConnectionIds = playbackDvrIds; + + // Add the empty hardware id to each vector to include combinations where these 3 fields might + // be optional + mfrontendIds.push_back(emptyHardwareId); + mDvrFeConnectionIds.push_back(emptyHardwareId); + mDvrSourceConnectionIds.push_back(emptyHardwareId); + + const int descramblerIndex = 0; + const int frontendIndex = 1; + const int audioFilterIndex = 2; + const int videoFilterIndex = 3; + const int dvrFeIdIndex = 4; + const int dvrSourceIdIndex = 5; + + vector> deviceIds{descramblerIds, mfrontendIds, audioFilterIds, + videoFilterIds, mDvrFeConnectionIds, mDvrSourceConnectionIds}; + auto idCombinations = generateIdCombinations(deviceIds); + for (auto& combo : idCombinations) { + DescramblingHardwareConnections mDescrambling; + const string feId = combo[frontendIndex]; + const string dvrSwFeId = combo[dvrFeIdIndex]; + const string dvrSourceId = combo[dvrSourceIdIndex]; + mDescrambling.hasFrontendConnection = feId.compare(emptyHardwareId) == 0 ? false : true; + if (!mDescrambling.hasFrontendConnection) { + if (dvrSourceId.compare(emptyHardwareId) == 0) { + // If combination does not have a frontend or dvr source connection, do not include + // it + continue; + } + } else { + if (frontendMap[feId].isSoftwareFe && dvrSwFeId.compare(emptyHardwareId) == 0) { + // If combination has a software frontend and no dvr->software frontend connection, + // do not include it + continue; + } + } + if (dvrSwFeId.compare(dvrSourceId) == 0) { + // If dvr->software frontend connection is the same as dvr source input to tuner, do not + // include it. + continue; + } + mDescrambling.frontendId = feId; + mDescrambling.audioFilterId = combo[audioFilterIndex]; + mDescrambling.videoFilterId = combo[videoFilterIndex]; + mDescrambling.dvrSoftwareFeId = dvrSwFeId; + mDescrambling.dvrSourceId = dvrSourceId; + mDescrambling.descramblerId = combo[descramblerIndex]; + combinations.push_back(mDescrambling); + } + + return combinations; +} + +static inline vector generateDescramblingConfigurations() { + vector descrambling_configs; + if (configuredDescrambling) { + ALOGD("Using Descrambling configuration provided."); + descrambling_configs = {descrambling}; + } else { + ALOGD("Descrambling not provided. Generating possible combinations. Consider adding it to " + "the " + "configuration file."); + descrambling_configs = generateDescramblingCombinations(); + } + + return descrambling_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 diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h index 31f07553d1..53246d38d8 100644 --- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h +++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h @@ -87,6 +87,7 @@ static vector sectionFilterIds; static vector frontendIds; static vector lnbIds; static vector diseqcMsgs; +static vector descramblerIds; #define PROVISION_STR \ "{ " \ @@ -461,6 +462,7 @@ struct TunerTestingConfigAidlReader1_0 { auto descramblers = *hardwareConfig.getFirstDescramblers(); for (auto descramblerConfig : descramblers.getDescrambler()) { string id = descramblerConfig.getId(); + descramblerIds.push_back(id); descramblerMap[id].casSystemId = static_cast(descramblerConfig.getCasSystemId()); if (descramblerConfig.hasProvisionStr()) {