Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c22ce3b authored by Amy Zhang's avatar Amy Zhang
Browse files

Enhance Tuner 1.0 VTS testing and configurations

Broadcom shared a valuable patch to enhance Tuner 1.0 VTS per their
testing experience on the real devices.

We evaluated the suggestions and fix the following issues:
1. Allow testers to set a default frontend
2. Allow testers to enable/disable frontend
3. Skip FMQ creation on filters that do not need FMQ
4. Don't fail if the vendor impl rejects a foreign keytoken
5. Better logs
6. Clean up filter and its callback on close regardless of the closing
result
7. More filter size constants options

Suggestions from: Gareth Fenn <gfenn@broadcom.com>
Test: atest VtsHalTvTunerV1_0TargetTest
Bug: 177960135

Change-Id: Ie4dcc6cb284b2b57879f286c436f5bd9adf43201
Merged-In: Ie4dcc6cb284b2b57879f286c436f5bd9adf43201
parent 5e3c4580
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ void DvrCallback::playbackThreadLoop() {
    uint8_t* buffer;
    ALOGW("[vts] playback thread loop start %s", mInputDataFile.c_str());
    if (fd < 0) {
        EXPECT_TRUE(fd >= 0) << "Failed to open: " + mInputDataFile;
        mPlaybackThreadRunning = false;
        ALOGW("[vts] Error %s", strerror(errno));
    }
@@ -178,7 +179,7 @@ void DvrCallback::recordThreadLoop(RecordSettings* /*recordSettings*/, bool* kee
            // Our current implementation filter the data and write it into the filter FMQ
            // immediately after the DATA_READY from the VTS/framework
            if (!readRecordFMQ()) {
                ALOGD("[vts] record data failed to be filtered. Ending thread");
                ALOGW("[vts] record data failed to be filtered. Ending thread");
                mRecordThreadRunning = false;
                break;
            }
+15 −9
Original line number Diff line number Diff line
@@ -70,6 +70,10 @@ void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) {
}

bool FilterCallback::readFilterEventData() {
    if (mFilterMQ == NULL) {
        ALOGW("[vts] FMQ is not configured and does not need to be tested.");
        return true;
    }
    bool result = false;
    DemuxFilterEvent filterEvent = mFilterEvent;
    ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId);
@@ -218,7 +222,11 @@ AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint32_t
    return AssertionResult(status == Result::SUCCESS);
}

AssertionResult FilterTests::getFilterMQDescriptor(uint32_t filterId) {
AssertionResult FilterTests::getFilterMQDescriptor(uint32_t filterId, bool getMqDesc) {
    if (!getMqDesc) {
        ALOGE("[vts] Filter does not need FMQ.");
        return success();
    }
    Result status;
    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
    EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
@@ -279,7 +287,6 @@ AssertionResult FilterTests::clearTimeStamp() {
AssertionResult FilterTests::closeFilter(uint32_t filterId) {
    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
    Result status = mFilters[filterId]->close();
    if (status == Result::SUCCESS) {
    for (int i = 0; i < mUsedFilterIds.size(); i++) {
        if (mUsedFilterIds[i] == filterId) {
            mUsedFilterIds.erase(mUsedFilterIds.begin() + i);
@@ -288,7 +295,6 @@ AssertionResult FilterTests::closeFilter(uint32_t filterId) {
    }
    mFilterCallbacks.erase(filterId);
    mFilters.erase(filterId);
    }
    return AssertionResult(status == Result::SUCCESS);
}

+1 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ class FilterTests {
    AssertionResult getTimeStamp();
    AssertionResult getNewlyOpenedFilterId(uint32_t& filterId);
    AssertionResult configFilter(DemuxFilterSettings setting, uint32_t filterId);
    AssertionResult getFilterMQDescriptor(uint32_t filterId);
    AssertionResult getFilterMQDescriptor(uint32_t filterId, bool getMqDesc);
    AssertionResult setFilterDataSource(uint32_t sourceFilterId, uint32_t sinkFilterId);
    AssertionResult setFilterDataSourceToDemux(uint32_t filterId);
    AssertionResult startFilter(uint32_t filterId);
+29 −19
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf,
    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
    ASSERT_TRUE(mFilterTests.startFilter(filterId));
    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
@@ -75,6 +75,9 @@ void TunerFilterHidlTest::testTimeFilter(TimeFilterConfig filterConf) {

void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
                                                       FrontendConfig frontendConf) {
    if (!frontendConf.enable) {
        return;
    }
    uint32_t feId;
    uint32_t demuxId;
    sp<IDemux> demux;
@@ -99,7 +102,7 @@ void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
    ASSERT_TRUE(mFilterTests.startFilter(filterId));
    // tune test
    ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
@@ -145,7 +148,7 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv
    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
    mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback());
    ASSERT_TRUE(mDvrTests.startDvrPlayback());
    ASSERT_TRUE(mFilterTests.startFilter(filterId));
@@ -160,6 +163,9 @@ void TunerPlaybackHidlTest::playbackSingleFilterTest(FilterConfig filterConf, Dv

void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
                                                 FrontendConfig frontendConf, DvrConfig dvrConf) {
    if (!frontendConf.enable) {
        return;
    }
    uint32_t feId;
    uint32_t demuxId;
    sp<IDemux> demux;
@@ -184,7 +190,7 @@ void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
    filter = mFilterTests.getFilterById(filterId);
    ASSERT_TRUE(filter != nullptr);
    mDvrTests.startRecordOutputThread(dvrConf.settings.record());
@@ -247,7 +253,7 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC
    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
    filter = mFilterTests.getFilterById(filterId);
    ASSERT_TRUE(filter != nullptr);
    ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter));
@@ -265,6 +271,9 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC
void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
                                                      FrontendConfig frontendConf,
                                                      DescramblerConfig descConfig) {
    if (!frontendConf.enable) {
        return;
    }
    uint32_t feId;
    uint32_t demuxId;
    sp<IDemux> demux;
@@ -328,17 +337,17 @@ void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> m

TEST_P(TunerFrontendHidlTest, TuneFrontend) {
    description("Tune one Frontend with specific setting and check Lock event");
    mFrontendTests.tuneTest(frontendArray[DVBT]);
    mFrontendTests.tuneTest(frontendArray[defaultFrontend]);
}

TEST_P(TunerFrontendHidlTest, AutoScanFrontend) {
    description("Run an auto frontend scan with specific setting and check lock scanMessage");
    mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_AUTO);
    mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_AUTO);
}

TEST_P(TunerFrontendHidlTest, BlindScanFrontend) {
    description("Run an blind frontend scan with specific setting and check lock scanMessage");
    mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND);
    mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_BLIND);
}

TEST_P(TunerLnbHidlTest, OpenLnbByName) {
@@ -374,7 +383,7 @@ TEST_P(TunerDemuxHidlTest, openDemux) {
    uint32_t feId;
    uint32_t demuxId;
    sp<IDemux> demux;
    mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
    mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
    ASSERT_TRUE(feId != INVALID_ID);
    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -394,7 +403,7 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) {
    uint32_t avSyncHwId;
    sp<IFilter> mediaFilter;

    mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
    mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
    ASSERT_TRUE(feId != INVALID_ID);
    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -422,7 +431,7 @@ TEST_P(TunerDemuxHidlTest, getAvSyncTime) {
TEST_P(TunerFilterHidlTest, StartFilterInDemux) {
    description("Open and start a filter in Demux.");
    // TODO use paramterized tests
    configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[DVBT]);
    configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]);
}

TEST_P(TunerFilterHidlTest, SetFilterLinkage) {
@@ -463,22 +472,22 @@ TEST_P(TunerFilterHidlTest, testTimeFilter) {

TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowVideoFilterTest) {
    description("Test Video Filter functionality in Broadcast use case.");
    broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendArray[DVBT]);
    broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendArray[defaultFrontend]);
}

TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowAudioFilterTest) {
    description("Test Audio Filter functionality in Broadcast use case.");
    broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendArray[DVBT]);
    broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendArray[defaultFrontend]);
}

TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowSectionFilterTest) {
    description("Test Section Filter functionality in Broadcast use case.");
    broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendArray[DVBT]);
    broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendArray[defaultFrontend]);
}

TEST_P(TunerBroadcastHidlTest, IonBufferTest) {
    description("Test the av filter data bufferring.");
    broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[DVBT]);
    broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]);
}

TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) {
@@ -494,13 +503,14 @@ TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) {
TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) {
    description("Attach a single filter to the record dvr test.");
    // TODO use paramterized tests
    attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendArray[DVBT],
    attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend],
                                      dvrArray[DVR_RECORD0]);
}

TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) {
    description("Feed ts data from frontend to recording and test with ts record filter");
    recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]);
    recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend],
                           dvrArray[DVR_RECORD0]);
}

TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) {
@@ -513,7 +523,7 @@ TEST_P(TunerDescramblerHidlTest, CreateDescrambler) {
    uint32_t feId;
    uint32_t demuxId;
    sp<IDemux> demux;
    mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
    mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
    ASSERT_TRUE(feId != INVALID_ID);
    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -530,7 +540,7 @@ TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) {
    set<FilterConfig> filterConfs;
    filterConfs.insert(filterArray[TS_AUDIO0]);
    filterConfs.insert(filterArray[TS_VIDEO1]);
    scrambledBroadcastTest(filterConfs, frontendArray[DVBT], descramblerArray[DESC_0]);
    scrambledBroadcastTest(filterConfs, frontendArray[defaultFrontend], descramblerArray[DESC_0]);
}

INSTANTIATE_TEST_SUITE_P(
+9 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ using android::hardware::tv::tuner::V1_0::RecordSettings;

using namespace std;

const uint32_t FMQ_SIZE_512K = 0x80000;
const uint32_t FMQ_SIZE_1M = 0x100000;
const uint32_t FMQ_SIZE_4M = 0x400000;
const uint32_t FMQ_SIZE_16M = 0x1000000;
@@ -134,6 +135,7 @@ struct FilterConfig {
    uint32_t bufferSize;
    DemuxFilterType type;
    DemuxFilterSettings settings;
    bool getMqDesc;

    bool operator<(const FilterConfig& /*c*/) const { return false; }
};
@@ -144,6 +146,7 @@ struct TimeFilterConfig {
};

struct FrontendConfig {
    bool enable;
    bool isSoftwareFe;
    FrontendType type;
    FrontendSettings settings;
@@ -191,6 +194,8 @@ static DemuxFilterType filterLinkageTypes[LINKAGE_DIR][FILTER_MAIN_TYPE_BIT_COUN
static DvrConfig dvrArray[DVR_MAX];
static DescramblerConfig descramblerArray[DESC_MAX];
static vector<string> goldenOutputFiles;
static int defaultFrontend = DVBT;
static int defaultScanFrontend = SCAN_DVBT;

/** Configuration array for the frontend tune test */
inline void initFrontendConfig() {
@@ -216,7 +221,9 @@ inline void initFrontendConfig() {
    frontendArray[DVBT].tuneStatusTypes = types;
    frontendArray[DVBT].expectTuneStatuses = statuses;
    frontendArray[DVBT].isSoftwareFe = true;
    frontendArray[DVBS].enable = true;
    frontendArray[DVBS].type = FrontendType::DVBS;
    frontendArray[DVBS].enable = true;
    frontendArray[DVBS].isSoftwareFe = true;
};

@@ -283,6 +290,7 @@ inline void initFilterConfig() {
            .isRaw = false,
            .streamId = 0xbd,
    });
    filterArray[TS_PES0].getMqDesc = true;
    // TS PCR filter setting
    filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS;
    filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR);
@@ -303,6 +311,7 @@ inline void initFilterConfig() {
    filterArray[TS_SECTION0].settings.ts().filterSettings.section({
            .isRaw = false,
    });
    filterArray[TS_SECTION0].getMqDesc = true;
    // TS RECORD filter setting
    filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS;
    filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD);