/* * Copyright 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "VtsHalTvTunerTargetTest.h" #include #include #include #include namespace { AssertionResult TunerBroadcastAidlTest::filterDataOutputTest() { return filterDataOutputTestBase(mFilterTests); } AssertionResult TunerPlaybackAidlTest::filterDataOutputTest() { return filterDataOutputTestBase(mFilterTests); } AssertionResult TunerDescramblerAidlTest::filterDataOutputTest() { return filterDataOutputTestBase(mFilterTests); } void TunerFilterAidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf) { int32_t feId; int32_t demuxId; std::shared_ptr demux; int64_t filterId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); if (filterConf.type.mainType == DemuxFilterMainType::IP) { ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); } if (filterConf.monitorEventTypes > 0) { ASSERT_TRUE(mFilterTests.configureMonitorEvent(filterId, filterConf.monitorEventTypes)); } ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); if (filterConf.monitorEventTypes > 0) { ASSERT_TRUE(mFilterTests.testMonitorEvent(filterId, filterConf.monitorEventTypes)); } ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } void TunerFilterAidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterConf, FilterConfig filterReconf, FrontendConfig frontendConf) { int32_t feId; int32_t demuxId; std::shared_ptr demux; int64_t filterId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); if (frontendConf.isSoftwareFe) { mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]); } ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterReconf.settings, filterId)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.startIdTest(filterId)); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } void TunerFilterAidlTest::testTimeFilter(TimeFilterConfig filterConf) { int32_t demuxId; std::shared_ptr demux; DemuxCapabilities caps; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.getDemuxCaps(caps)); ASSERT_TRUE(caps.bTimeFilter); mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openTimeFilterInDemux()); ASSERT_TRUE(mFilterTests.setTimeStamp(filterConf.timeStamp)); ASSERT_TRUE(mFilterTests.getTimeStamp()); ASSERT_TRUE(mFilterTests.clearTimeStamp()); ASSERT_TRUE(mFilterTests.closeTimeFilter()); ASSERT_TRUE(mDemuxTests.closeDemux()); } void TunerBroadcastAidlTest::broadcastSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf) { int32_t feId; int32_t demuxId; std::shared_ptr demux; int64_t filterId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); if (mLnbId != INVALID_LNB_ID) { ASSERT_TRUE(mFrontendTests.setLnb(mLnbId)); } if (frontendConf.isSoftwareFe) { mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]); } ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); ASSERT_TRUE(filterDataOutputTest()); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } void TunerBroadcastAidlTest::broadcastSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf, LnbConfig lnbConf) { if (lnbConf.name.compare(emptyHardwareId) == 0) { vector ids; ASSERT_TRUE(mLnbTests.getLnbIds(ids)); ASSERT_TRUE(ids.size() > 0); ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); mLnbId = ids[0]; } else { ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, mLnbId)); } ASSERT_TRUE(mLnbTests.setLnbCallback()); ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage)); ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone)); ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConf.position)); if (!frontendConf.isSoftwareFe) { broadcastSingleFilterTest(filterConf, frontendConf); } ASSERT_TRUE(mLnbTests.closeLnb()); mLnbId = INVALID_LNB_ID; } void TunerBroadcastAidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf) { int32_t feId; int32_t demuxId; std::shared_ptr demux; int64_t filterId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); if (frontendConf.isSoftwareFe) { mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]); } ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId)); ASSERT_TRUE(mFilterTests.configAvFilterStreamType(filterConf.streamType, filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); ASSERT_TRUE(filterDataOutputTest()); ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.releaseShareAvHandle(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } void TunerPlaybackAidlTest::playbackSingleFilterTest(FilterConfig filterConf, DvrConfig dvrConf) { int32_t demuxId; std::shared_ptr demux; int64_t filterId; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); mFilterTests.setDemux(demux); mDvrTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.get()); ASSERT_TRUE(mDvrTests.startDvrPlayback()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(filterDataOutputTest()); mDvrTests.stopPlaybackThread(); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mDvrTests.stopDvrPlayback()); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); mDvrTests.closeDvrPlayback(); ASSERT_TRUE(mDemuxTests.closeDemux()); } void TunerPlaybackAidlTest::setStatusCheckIntervalHintTest(int64_t statusCheckIntervalHint, DvrConfig dvrConf) { int32_t demuxId; std::shared_ptr demux; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); mDvrTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); ASSERT_TRUE(mDvrTests.setPlaybackStatusCheckIntervalHint(statusCheckIntervalHint)); mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.get()); ASSERT_TRUE(mDvrTests.startDvrPlayback()); mDvrTests.stopPlaybackThread(); ASSERT_TRUE(mDvrTests.stopDvrPlayback()); mDvrTests.closeDvrPlayback(); ASSERT_TRUE(mDemuxTests.closeDemux()); } void TunerRecordAidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf, LnbConfig lnbConf) { if (lnbConf.name.compare(emptyHardwareId) == 0) { vector ids; ASSERT_TRUE(mLnbTests.getLnbIds(ids)); ASSERT_TRUE(ids.size() > 0); ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); mLnbId = ids[0]; } else { ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, mLnbId)); } ASSERT_TRUE(mLnbTests.setLnbCallback()); ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage)); ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone)); ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConf.position)); for (auto msgName : lnbRecord.diseqcMsgs) { ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName])); } if (!frontendConf.isSoftwareFe) { recordSingleFilterTest(filterConf, frontendConf, dvrConf, Dataflow_Context::LNBRECORD); } ASSERT_TRUE(mLnbTests.closeLnb()); mLnbId = INVALID_LNB_ID; } void TunerRecordAidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf) { int32_t demuxId; std::shared_ptr demux; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); mDvrTests.setDemux(demux); DvrConfig dvrSourceConfig; if (record.hasFrontendConnection) { int32_t feId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); } else { dvrSourceConfig = dvrMap[record.dvrSourceId]; ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings)); ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); } int64_t filterId; std::shared_ptr filter; mFilterTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); filter = mFilterTests.getFilterById(filterId); ASSERT_TRUE(filter != nullptr); ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); ASSERT_TRUE(mDvrTests.startDvrRecord()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mDvrTests.stopDvrRecord()); ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); mDvrTests.closeDvrRecord(); ASSERT_TRUE(mDemuxTests.closeDemux()); if (record.hasFrontendConnection) { ASSERT_TRUE(mFrontendTests.closeFrontend()); } } void TunerRecordAidlTest::recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf, DvrConfig dvrConf, Dataflow_Context context) { int32_t demuxId; std::shared_ptr demux; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); mDvrTests.setDemux(demux); DvrConfig dvrSourceConfig; if (context == Dataflow_Context::RECORD) { if (record.hasFrontendConnection) { int32_t feId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); if (frontendConf.isSoftwareFe) { mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]); } ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDvrTests(&mDvrTests); } else { dvrSourceConfig = dvrMap[record.dvrSourceId]; ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings)); ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); } } else if (context == Dataflow_Context::LNBRECORD) { // If function arrives here, frontend should not be software, so no need to configure a dvr // source or dvr fe connection that might be used for recording without an Lnb int32_t feId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); if (mLnbId != INVALID_LNB_ID) { ASSERT_TRUE(mFrontendTests.setLnb(mLnbId)); } else { FAIL(); } ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDvrTests(&mDvrTests); } int64_t filterId; std::shared_ptr filter; mFilterTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc)); filter = mFilterTests.getFilterById(filterId); ASSERT_TRUE(filter != nullptr); mDvrTests.startRecordOutputThread(dvrConf.settings.get()); ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter)); ASSERT_TRUE(mDvrTests.startDvrRecord()); ASSERT_TRUE(mFilterTests.startFilter(filterId)); if (context == Dataflow_Context::RECORD) { if (record.hasFrontendConnection) { ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); } else { // Start DVR Source mDvrTests.startPlaybackInputThread( dvrSourceConfig.playbackInputFile, dvrSourceConfig.settings.get()); ASSERT_TRUE(mDvrTests.startDvrPlayback()); } } else if (context == Dataflow_Context::LNBRECORD) { ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); } mDvrTests.testRecordOutput(); mDvrTests.stopRecordThread(); if (context == Dataflow_Context::RECORD) { if (record.hasFrontendConnection) { ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); } else { mDvrTests.stopPlaybackThread(); ASSERT_TRUE(mDvrTests.stopDvrPlayback()); } } else if (context == Dataflow_Context::LNBRECORD) { ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); } ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mDvrTests.stopDvrRecord()); ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); mDvrTests.closeDvrRecord(); if (context == Dataflow_Context::RECORD) { if (record.hasFrontendConnection) { ASSERT_TRUE(mFrontendTests.closeFrontend()); } else { mDvrTests.closeDvrPlayback(); } } else if (context == Dataflow_Context::LNBRECORD) { ASSERT_TRUE(mFrontendTests.closeFrontend()); } ASSERT_TRUE(mDemuxTests.closeDemux()); } void TunerRecordAidlTest::setStatusCheckIntervalHintTest(int64_t statusCheckIntervalHint, FrontendConfig frontendConf, DvrConfig dvrConf) { int32_t demuxId; std::shared_ptr demux; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); mDvrTests.setDemux(demux); DvrConfig dvrSourceConfig; if (record.hasFrontendConnection) { int32_t feId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); } else { dvrSourceConfig = dvrMap[record.dvrSourceId]; ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings)); ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); } ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings)); ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor()); ASSERT_TRUE(mDvrTests.setRecordStatusCheckIntervalHint(statusCheckIntervalHint)); ASSERT_TRUE(mDvrTests.startDvrRecord()); ASSERT_TRUE(mDvrTests.stopDvrRecord()); mDvrTests.closeDvrRecord(); ASSERT_TRUE(mDemuxTests.closeDemux()); if (record.hasFrontendConnection) { ASSERT_TRUE(mFrontendTests.closeFrontend()); } } void TunerDescramblerAidlTest::scrambledBroadcastTest(set mediaFilterConfs, FrontendConfig frontendConf, DescramblerConfig descConfig, Dataflow_Context context) { int32_t demuxId; std::shared_ptr demux; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); DvrConfig dvrSourceConfig; if (context == Dataflow_Context::DESCRAMBLING) { if (descrambling.hasFrontendConnection) { int32_t feId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); if (frontendConf.isSoftwareFe) { mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]); } ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); } else { dvrSourceConfig = dvrMap[descrambling.dvrSourceId]; mDvrTests.setDemux(demux); ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize)); ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings)); ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor()); } } else if (context == Dataflow_Context::LNBDESCRAMBLING) { int32_t feId; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); if (mLnbId != INVALID_LNB_ID) { ASSERT_TRUE(mFrontendTests.setLnb(mLnbId)); } else { // If, for some reason, the test got here without failing. We fail it here. ALOGD("mLnbId is null. Something went wrong. Exiting ScrambledBroadcastWithLnbId."); FAIL(); } ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFrontendTests.setDemux(demux); } set filterIds; int64_t filterId; set::iterator config; set::iterator id; mFilterTests.setDemux(demux); for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter((*config).settings, filterId)); filterIds.insert(filterId); } ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId)); vector token; ASSERT_TRUE(mDescramblerTests.getKeyToken(descConfig.casSystemId, descConfig.provisionStr, descConfig.hidlPvtData, token)); mDescramblerTests.setKeyToken(token); vector pids; DemuxPid pid; for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { ASSERT_TRUE(mDescramblerTests.getDemuxPidFromFilterSettings((*config).type, (*config).settings, pid)); pids.push_back(pid); ASSERT_TRUE(mDescramblerTests.addPid(pid, nullptr)); } for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.startFilter(*id)); } if (context == Dataflow_Context::DESCRAMBLING) { if (descrambling.hasFrontendConnection) { // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); } else { // Start DVR Source mDvrTests.startPlaybackInputThread( dvrSourceConfig.playbackInputFile, dvrSourceConfig.settings.get()); ASSERT_TRUE(mDvrTests.startDvrPlayback()); } } else if (context == Dataflow_Context::LNBDESCRAMBLING) { ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/)); } ASSERT_TRUE(filterDataOutputTest()); if (context == Dataflow_Context::DESCRAMBLING) { if (descrambling.hasFrontendConnection) { ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); } else { mDvrTests.stopPlaybackThread(); ASSERT_TRUE(mDvrTests.stopDvrPlayback()); } } else if (context == Dataflow_Context::LNBDESCRAMBLING) { ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/)); } for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.stopFilter(*id)); } for (auto pid : pids) { ASSERT_TRUE(mDescramblerTests.removePid(pid, nullptr)); } ASSERT_TRUE(mDescramblerTests.closeDescrambler()); for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.closeFilter(*id)); } if (context == Dataflow_Context::DESCRAMBLING) { if (descrambling.hasFrontendConnection) { ASSERT_TRUE(mFrontendTests.closeFrontend()); } else { mDvrTests.closeDvrPlayback(); } } else if (context == Dataflow_Context::LNBDESCRAMBLING) { ASSERT_TRUE(mFrontendTests.closeFrontend()); } ASSERT_TRUE(mDemuxTests.closeDemux()); } void TunerDescramblerAidlTest::scrambledBroadcastTestWithLnb( set& mediaFilterConfs, FrontendConfig& frontendConf, DescramblerConfig& descConfig, LnbConfig& lnbConfig) { // We can test the Lnb individually and make sure it functions properly. If the frontend is // software, we cannot test the whole dataflow. If the frontend is hardware, we can if (lnbConfig.name.compare(emptyHardwareId) == 0) { vector ids; ASSERT_TRUE(mLnbTests.getLnbIds(ids)); ASSERT_TRUE(ids.size() > 0); ASSERT_TRUE(mLnbTests.openLnbById(ids[0])); mLnbId = ids[0]; } else { ASSERT_TRUE(mLnbTests.openLnbByName(lnbConfig.name, mLnbId)); } // Once Lnb is opened, test some of its basic functionality ASSERT_TRUE(mLnbTests.setLnbCallback()); ASSERT_TRUE(mLnbTests.setVoltage(lnbConfig.voltage)); ASSERT_TRUE(mLnbTests.setTone(lnbConfig.tone)); ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConfig.position)); if (!frontendConf.isSoftwareFe) { ALOGD("Frontend is not software, testing entire dataflow."); scrambledBroadcastTest(mediaFilterConfs, frontendConf, descConfig, Dataflow_Context::LNBDESCRAMBLING); } else { ALOGD("Frontend is software, did not test the entire dataflow, but tested the Lnb " "individually."); } ASSERT_TRUE(mLnbTests.closeLnb()); mLnbId = INVALID_LNB_ID; } TEST_P(TunerLnbAidlTest, SendDiseqcMessageToLnb) { description("Open and configure an Lnb with specific settings then send a diseqc msg to it."); if (!lnbLive.support) { return; } vector lnbLive_configs = generateLnbLiveConfigurations(); if (lnbLive_configs.empty()) { ALOGD("No frontends that support satellites."); return; } 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()); } } TEST_P(TunerDemuxAidlTest, openDemux) { description("Open and close a Demux."); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; int32_t feId; int32_t demuxId; std::shared_ptr demux; mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } } TEST_P(TunerDemuxAidlTest, openDemuxById) { description("Open (with id) and close a Demux."); std::vector demuxIds; ASSERT_TRUE(mDemuxTests.getDemuxIds(demuxIds)); for (int i = 0; i < demuxIds.size(); i++) { std::shared_ptr demux; ASSERT_TRUE(mDemuxTests.openDemuxById(demuxIds[i], demux)); ASSERT_TRUE(mDemuxTests.closeDemux()); } } TEST_P(TunerDemuxAidlTest, getDemuxInfo) { description("Check getDemuxInfo against demux caps"); std::vector demuxIds; ASSERT_TRUE(mDemuxTests.getDemuxIds(demuxIds)); int32_t combinedFilterTypes = 0; for (int i = 0; i < demuxIds.size(); i++) { DemuxInfo demuxInfo; ASSERT_TRUE(mDemuxTests.getDemuxInfo(demuxIds[i], demuxInfo)); combinedFilterTypes |= demuxInfo.filterTypes; } if (demuxIds.size() > 0) { DemuxCapabilities demuxCaps; ASSERT_TRUE(mDemuxTests.getDemuxCaps(demuxCaps)); ASSERT_TRUE(demuxCaps.filterCaps == combinedFilterTypes); } } TEST_P(TunerDemuxAidlTest, getAvSyncTime) { description("Get the A/V sync time from a PCR filter."); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; if (live.pcrFilterId.compare(emptyHardwareId) == 0) { continue; } int32_t feId; int32_t demuxId; std::shared_ptr demux; int64_t mediaFilterId; int64_t pcrFilterId; int32_t avSyncHwId; std::shared_ptr mediaFilter; mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.videoFilterId].type, filterMap[live.videoFilterId].bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId)); ASSERT_TRUE( mFilterTests.configFilter(filterMap[live.videoFilterId].settings, mediaFilterId)); mediaFilter = mFilterTests.getFilterById(mediaFilterId); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.pcrFilterId].type, filterMap[live.pcrFilterId].bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId)); ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.pcrFilterId].settings, pcrFilterId)); ASSERT_TRUE(mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId)); ASSERT_TRUE(pcrFilterId == avSyncHwId); ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId)); ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId)); ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } } TEST_P(TunerFilterAidlTest, StartFilterInDemux) { description("Open and start a filter in Demux."); if (!live.hasFrontendConnection) { return; } // TODO use parameterized tests auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } } TEST_P(TunerFilterAidlTest, ConfigIpFilterInDemuxWithCid) { description("Open and configure an ip filter in Demux."); // TODO use parameterized tests if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; if (live.ipFilterId.compare(emptyHardwareId) == 0) { continue; } configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]); } } TEST_P(TunerFilterAidlTest, ReconfigFilterToReceiveStartId) { description("Recofigure and restart a filter to test start id."); if (!live.hasFrontendConnection) { return; } // TODO use parameterized tests auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId], filterMap[live.videoFilterId], frontendMap[live.frontendId]); } } TEST_P(TunerFilterAidlTest, SetFilterLinkage) { description("Pick up all the possible linkages from the demux caps and set them up."); DemuxCapabilities caps; int32_t demuxId; std::shared_ptr demux; ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.getDemuxCaps(caps)); mFilterTests.setDemux(demux); for (int i = 0; i < caps.linkCaps.size(); i++) { uint32_t bitMask = 1; for (int j = 0; j < FILTER_MAIN_TYPE_BIT_COUNT; j++) { if (caps.linkCaps[i] & (bitMask << j)) { int64_t sourceFilterId; int64_t sinkFilterId; ASSERT_TRUE(mFilterTests.openFilterInDemux(getLinkageFilterType(i), FMQ_SIZE_16M)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(sourceFilterId)); ASSERT_TRUE(mFilterTests.openFilterInDemux(getLinkageFilterType(j), FMQ_SIZE_16M)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(sinkFilterId)); ASSERT_TRUE(mFilterTests.setFilterDataSource(sourceFilterId, sinkFilterId)); ASSERT_TRUE(mFilterTests.setFilterDataSourceToDemux(sinkFilterId)); ASSERT_TRUE(mFilterTests.closeFilter(sinkFilterId)); ASSERT_TRUE(mFilterTests.closeFilter(sourceFilterId)); } } } ASSERT_TRUE(mDemuxTests.closeDemux()); } TEST_P(TunerFilterAidlTest, testTimeFilter) { description("Open a timer filter in Demux and set time stamp."); if (!timeFilter.support) { return; } // TODO use parameterized tests auto timeFilter_configs = generateTimeFilterConfigurations(); for (auto& configuration : timeFilter_configs) { timeFilter = configuration; testTimeFilter(timeFilterMap[timeFilter.timeFilterId]); } } static bool isEventProducingFilter(const FilterConfig& filterConfig) { switch (filterConfig.type.mainType) { case DemuxFilterMainType::TS: { auto tsFilterType = filterConfig.type.subType.get(); return (tsFilterType == DemuxTsFilterType::SECTION || tsFilterType == DemuxTsFilterType::PES || tsFilterType == DemuxTsFilterType::AUDIO || tsFilterType == DemuxTsFilterType::VIDEO || tsFilterType == DemuxTsFilterType::RECORD || tsFilterType == DemuxTsFilterType::TEMI); } case DemuxFilterMainType::MMTP: { auto mmtpFilterType = filterConfig.type.subType.get(); return (mmtpFilterType == DemuxMmtpFilterType::SECTION || mmtpFilterType == DemuxMmtpFilterType::PES || mmtpFilterType == DemuxMmtpFilterType::AUDIO || mmtpFilterType == DemuxMmtpFilterType::VIDEO || mmtpFilterType == DemuxMmtpFilterType::RECORD || mmtpFilterType == DemuxMmtpFilterType::DOWNLOAD); } case DemuxFilterMainType::IP: { auto ipFilterType = filterConfig.type.subType.get(); return (ipFilterType == DemuxIpFilterType::SECTION); } case DemuxFilterMainType::TLV: { auto tlvFilterType = filterConfig.type.subType.get(); return (tlvFilterType == DemuxTlvFilterType::SECTION); } case DemuxFilterMainType::ALP: { auto alpFilterType = filterConfig.type.subType.get(); return (alpFilterType == DemuxAlpFilterType::SECTION); } default: return false; } } static bool isMediaFilter(const FilterConfig& filterConfig) { switch (filterConfig.type.mainType) { case DemuxFilterMainType::TS: { // TS Audio and Video filters are media filters auto tsFilterType = filterConfig.type.subType.get(); return (tsFilterType == DemuxTsFilterType::AUDIO || tsFilterType == DemuxTsFilterType::VIDEO); } case DemuxFilterMainType::MMTP: { // MMTP Audio and Video filters are media filters auto mmtpFilterType = filterConfig.type.subType.get(); return (mmtpFilterType == DemuxMmtpFilterType::AUDIO || mmtpFilterType == DemuxMmtpFilterType::VIDEO); } default: return false; } } static int getDemuxFilterEventDataLength(const DemuxFilterEvent& event) { switch (event.getTag()) { case DemuxFilterEvent::Tag::section: return event.get().dataLength; case DemuxFilterEvent::Tag::media: return event.get().dataLength; case DemuxFilterEvent::Tag::pes: return event.get().dataLength; case DemuxFilterEvent::Tag::download: return event.get().dataLength; case DemuxFilterEvent::Tag::ipPayload: return event.get().dataLength; case DemuxFilterEvent::Tag::tsRecord: case DemuxFilterEvent::Tag::mmtpRecord: case DemuxFilterEvent::Tag::temi: case DemuxFilterEvent::Tag::monitorEvent: case DemuxFilterEvent::Tag::startId: return 0; } } // TODO: move boilerplate into text fixture void TunerFilterAidlTest::testDelayHint(const FilterConfig& filterConf) { if (!filterConf.timeDelayInMs && !filterConf.dataDelayInBytes) { return; } if (!isEventProducingFilter(filterConf)) { return; } int32_t feId; int32_t demuxId; std::shared_ptr demux; int64_t filterId; mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); bool mediaFilter = isMediaFilter(filterConf); auto filter = mFilterTests.getFilterById(filterId); // startTime needs to be set before calling setDelayHint. auto startTime = std::chrono::steady_clock::now(); int timeDelayInMs = filterConf.timeDelayInMs; if (timeDelayInMs > 0) { FilterDelayHint delayHint; delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS; delayHint.hintValue = timeDelayInMs; // setDelayHint should fail for media filters. ASSERT_EQ(filter->setDelayHint(delayHint).isOk(), !mediaFilter); } int dataDelayInBytes = filterConf.dataDelayInBytes; if (dataDelayInBytes > 0) { FilterDelayHint delayHint; delayHint.hintType = FilterDelayHintType::DATA_SIZE_DELAY_IN_BYTES; delayHint.hintValue = dataDelayInBytes; // setDelayHint should fail for media filters. ASSERT_EQ(filter->setDelayHint(delayHint).isOk(), !mediaFilter); } // start and stop filter (and wait for first callback) in order to // circumvent callback scheduler race conditions after adjusting filter // delays. auto cb = mFilterTests.getFilterCallbacks().at(filterId); auto future = cb->verifyFilterCallback([](const std::vector&) { return true; }); // The configure stage can also produce events, so we should set the delay // hint beforehand. ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); mFilterTests.startFilter(filterId); auto timeout = std::chrono::seconds(30); ASSERT_EQ(future.wait_for(timeout), std::future_status::ready); mFilterTests.stopFilter(filterId); if (!mediaFilter) { int callbackSize = 0; future = cb->verifyFilterCallback( [&callbackSize](const std::vector& events) { for (const auto& event : events) { callbackSize += getDemuxFilterEventDataLength(event); } return true; }); ASSERT_TRUE(mFilterTests.startFilter(filterId)); // block and wait for callback to be received. ASSERT_EQ(future.wait_for(timeout), std::future_status::ready); auto duration = std::chrono::steady_clock::now() - startTime; bool delayHintTest = duration >= std::chrono::milliseconds(timeDelayInMs); bool dataSizeTest = callbackSize >= dataDelayInBytes; if (timeDelayInMs > 0 && dataDelayInBytes > 0) { ASSERT_TRUE(delayHintTest || dataSizeTest); } else { // if only one of time delay / data delay is configured, one of them // holds true by default, so we want both assertions to be true. ASSERT_TRUE(delayHintTest && dataSizeTest); } ASSERT_TRUE(mFilterTests.stopFilter(filterId)); } ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } TEST_P(TunerFilterAidlTest, FilterDelayHintTest) { description("Test filter time delay hint."); if (!live.hasFrontendConnection) { return; } for (const auto& obj : filterMap) { testDelayHint(obj.second); } } TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) { description("Feed ts data from playback and configure Ts section filter to get output"); if (!playback.support) { return; } 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) { description("Feed ts data from playback and configure Ts audio filter to get output"); if (!playback.support) { return; } vector playback_configs = generatePlaybackConfigs(); for (auto& configuration : playback_configs) { playback = configuration; playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]); } } TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsVideoFilterTest) { description("Feed ts data from playback and configure Ts video filter to get output"); if (!playback.support) { return; } vector playback_configs = generatePlaybackConfigs(); for (auto& configuration : playback_configs) { playback = configuration; playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]); } } TEST_P(TunerPlaybackAidlTest, SetStatusCheckIntervalHintToPlaybackTest) { description("Set status check interval hint to playback test."); if (!playback.support) { return; } vector playback_configs = generatePlaybackConfigs(); for (auto& configuration : playback_configs) { playback = configuration; setStatusCheckIntervalHintTest(STATUS_CHECK_INTERVAL_MS, dvrMap[playback.dvrId]); } } TEST_P(TunerRecordAidlTest, RecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from frontend to recording and test with ts record filter"); if (!record.support) { return; } // Recording is not currently supported for IPTV frontend if (frontendMap[live.frontendId].type == FrontendType::IPTV) { return; } auto record_configs = generateRecordConfigurations(); for (auto& configuration : record_configs) { record = configuration; recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId], dvrMap[record.dvrRecordId], Dataflow_Context::RECORD); } } TEST_P(TunerRecordAidlTest, AttachFiltersToRecordTest) { description("Attach a single filter to the record dvr test."); // TODO use parameterized tests if (!record.support) { return; } // Recording is not currently supported for IPTV frontend if (frontendMap[live.frontendId].type == FrontendType::IPTV) { return; } auto record_configs = generateRecordConfigurations(); for (auto& configuration : record_configs) { record = configuration; attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId], frontendMap[record.frontendId], dvrMap[record.dvrRecordId]); } } TEST_P(TunerRecordAidlTest, LnbRecordDataFlowWithTsRecordFilterTest) { description("Feed ts data from Fe with Lnb to recording and test with ts record filter"); if (!lnbRecord.support) { return; } 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(TunerRecordAidlTest, SetStatusCheckIntervalHintToRecordTest) { description("Set status check interval hint to record test."); if (!record.support) { return; } // Recording is not currently supported for IPTV frontend if (frontendMap[live.frontendId].type == FrontendType::IPTV) { return; } auto record_configs = generateRecordConfigurations(); for (auto& configuration : record_configs) { record = configuration; setStatusCheckIntervalHintTest(STATUS_CHECK_INTERVAL_MS, frontendMap[record.frontendId], dvrMap[record.dvrRecordId]); } } TEST_P(TunerFrontendAidlTest, TuneFrontend) { description("Tune one Frontend with specific setting and check Lock event"); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; mFrontendTests.tuneTest(frontendMap[live.frontendId]); } } TEST_P(TunerFrontendAidlTest, AutoScanFrontend) { description("Run an auto frontend scan with specific setting and check lock scanMessage"); if (!scan.hasFrontendConnection) { return; } vector scan_configs = generateScanConfigurations(); for (auto& configuration : scan_configs) { scan = configuration; mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO); } } TEST_P(TunerFrontendAidlTest, BlindScanFrontend) { description("Run an blind frontend scan with specific setting and check lock scanMessage"); if (!scan.hasFrontendConnection) { return; } // Blind scan is not applicable for IPTV frontend if (frontendMap[live.frontendId].type == FrontendType::IPTV) { return; } vector scan_configs = generateScanConfigurations(); for (auto& configuration : scan_configs) { scan = configuration; // Skip test if the frontend implementation doesn't support blind scan if (!frontendMap[scan.frontendId].supportBlindScan) { continue; } mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); } } TEST_P(TunerFrontendAidlTest, TuneFrontendWithFrontendSettings) { description("Tune one Frontend with setting and check Lock event"); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; mFrontendTests.tuneTest(frontendMap[live.frontendId]); } } TEST_P(TunerFrontendAidlTest, BlindScanFrontendWithEndFrequency) { description("Run an blind frontend scan with setting and check lock scanMessage"); if (!scan.hasFrontendConnection) { return; } // Blind scan is not application for IPTV frontend if (frontendMap[live.frontendId].type == FrontendType::IPTV) { return; } vector scan_configs = generateScanConfigurations(); for (auto& configuration : scan_configs) { scan = configuration; // Skip test if the frontend implementation doesn't support blind scan if (!frontendMap[scan.frontendId].supportBlindScan) { continue; } mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND); } } TEST_P(TunerFrontendAidlTest, LinkToCiCam) { description("Test Frontend link to CiCam"); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; if (!frontendMap[live.frontendId].canConnectToCiCam) { continue; } mFrontendTests.tuneTest(frontendMap[live.frontendId]); } } TEST_P(TunerFrontendAidlTest, getHardwareInfo) { description("Test Frontend get hardware info"); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; mFrontendTests.debugInfoTest(frontendMap[live.frontendId]); } } TEST_P(TunerFrontendAidlTest, maxNumberOfFrontends) { description("Test Max Frontend number"); if (!live.hasFrontendConnection) { return; } mFrontendTests.maxNumberOfFrontendsTest(); } TEST_P(TunerFrontendAidlTest, statusReadinessTest) { description("Test Max Frontend status readiness"); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; mFrontendTests.statusReadinessTest(frontendMap[live.frontendId]); } } TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowVideoFilterTest) { description("Test Video Filter functionality in Broadcast use case."); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } } TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowAudioFilterTest) { description("Test Audio Filter functionality in Broadcast use case."); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]); } } TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowSectionFilterTest) { description("Test Section Filter functionality in Broadcast use case."); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; if (live.sectionFilterId.compare(emptyHardwareId) == 0) { continue; } broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]); } } TEST_P(TunerBroadcastAidlTest, IonBufferTest) { description("Test the av filter data bufferring."); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } } TEST_P(TunerBroadcastAidlTest, LnbBroadcastDataFlowVideoFilterTest) { description("Test Video Filter functionality in Broadcast with Lnb use case."); if (!lnbLive.support) { return; } 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) { description("Test the Media Filter with shared memory handle"); if (!live.hasFrontendConnection) { return; } auto live_configs = generateLiveConfigurations(); for (auto& configuration : live_configs) { live = configuration; mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]); } } TEST_P(TunerDescramblerAidlTest, CreateDescrambler) { description("Create Descrambler"); if (!descrambling.support) { return; } 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)); 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)); } ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId)); ASSERT_TRUE(mDescramblerTests.closeDescrambler()); ASSERT_TRUE(mDemuxTests.closeDemux()); if (descrambling.hasFrontendConnection) { ASSERT_TRUE(mFrontendTests.closeFrontend()); } } } TEST_P(TunerDescramblerAidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { description("Test ts audio filter in scrambled broadcast use case"); if (!descrambling.support) { return; } 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], Dataflow_Context::DESCRAMBLING); } } TEST_P(TunerDescramblerAidlTest, ScrambledBroadcastDataFlowMediaFiltersTestWithLnb) { description("Test media filters in scrambled broadcast use case with Lnb"); if (!lnbDescrambling.support) { return; } auto lnbDescrambling_configs = generateLnbDescramblingConfigurations(); if (lnbDescrambling_configs.empty()) { ALOGD("No frontends that support satellites."); return; } for (auto& configuration : lnbDescrambling_configs) { lnbDescrambling = configuration; set filterConfs; filterConfs.insert(static_cast(filterMap[lnbDescrambling.audioFilterId])); filterConfs.insert(static_cast(filterMap[lnbDescrambling.videoFilterId])); scrambledBroadcastTestWithLnb(filterConfs, frontendMap[lnbDescrambling.frontendId], descramblerMap[lnbDescrambling.descramblerId], lnbMap[lnbDescrambling.lnbId]); } } INSTANTIATE_TEST_SUITE_P(PerInstance, TunerBroadcastAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)), android::PrintInstanceNameToString); INSTANTIATE_TEST_SUITE_P(PerInstance, TunerFrontendAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)), android::PrintInstanceNameToString); INSTANTIATE_TEST_SUITE_P(PerInstance, TunerFilterAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)), android::PrintInstanceNameToString); INSTANTIATE_TEST_SUITE_P(PerInstance, TunerRecordAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)), android::PrintInstanceNameToString); INSTANTIATE_TEST_SUITE_P(PerInstance, TunerLnbAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)), android::PrintInstanceNameToString); INSTANTIATE_TEST_SUITE_P(PerInstance, TunerDemuxAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)), android::PrintInstanceNameToString); INSTANTIATE_TEST_SUITE_P(PerInstance, TunerPlaybackAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)), android::PrintInstanceNameToString); INSTANTIATE_TEST_SUITE_P(PerInstance, TunerDescramblerAidlTest, testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)), android::PrintInstanceNameToString); } // namespace // Start thread pool to receive callbacks from AIDL service. int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); ABinderProcess_setThreadPoolMaxThreadCount(1); ABinderProcess_startThreadPool(); return RUN_ALL_TESTS(); }