Add dvr dynamic configuration into Tuner 1.0 VTS
Test: atest VtsHalTvTunerV1_0TargetTest
Bug: 182519645
CTS-Coverage-Bug: 184077478
Change-Id: I04ef708064179e62c0c7b8c790fe844543b3eac8
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 92996f9..5fbdd2d 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -86,17 +86,14 @@
uint32_t filterId;
mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
- if (feId == INVALID_ID) {
- // TODO broadcast test on Cuttlefish needs licensed ts input,
- // these tests are runnable on vendor device with real frontend module
- // or with manual ts installing and use DVBT frontend.
- return;
- }
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
if (mLnbId) {
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);
@@ -178,6 +175,9 @@
if (mLnbId) {
ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId));
}
+ if (frontendConf.isSoftwareFe) {
+ mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
+ }
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
mFilterTests.setDemux(demux);
@@ -279,14 +279,11 @@
set<uint32_t>::iterator id;
mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
- if (feId == INVALID_ID) {
- // TODO broadcast test on Cuttlefish needs licensed ts input,
- // these tests are runnable on vendor device with real frontend module
- // or with manual ts installing and use DVBT frontend.
- return;
- }
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+ if (frontendConf.isSoftwareFe) {
+ mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]);
+ }
ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
mFilterTests.setDemux(demux);
@@ -301,7 +298,7 @@
TunerKeyToken token;
ASSERT_TRUE(mDescramblerTests.getKeyToken(descConfig.casSystemId, descConfig.provisionStr,
descConfig.hidlPvtData, token));
- ASSERT_TRUE(mDescramblerTests.setKeyToken(token));
+ mDescramblerTests.setKeyToken(token);
vector<DemuxPid> pids;
DemuxPid pid;
for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) {
@@ -497,66 +494,12 @@
broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendMap[live.frontendId]);
}
-TEST_P(TunerBroadcastHidlTest, BroadcastEsDataFlowMediaFiltersTest) {
- description("Test Meida Filters functionality in Broadcast use case with ES input.");
- uint32_t feId;
- uint32_t demuxId;
- sp<IDemux> demux;
- uint32_t filterId;
-
- mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
- if (feId == INVALID_ID) {
- // TODO broadcast test on Cuttlefish needs licensed ts input,
- // these tests are runnable on vendor device with real frontend module
- // or with manual ts installing and use defaultFrontend frontend.
- return;
- }
- 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(filterArray[TS_AUDIO1].type,
- filterArray[TS_AUDIO1].bufferSize));
- ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
- ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_AUDIO1].settings, filterId));
- ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterArray[TS_AUDIO1].getMqDesc));
- ASSERT_TRUE(mFilterTests.startFilter(filterId));
- ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type,
- filterArray[TS_VIDEO1].bufferSize));
- ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
- ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, filterId));
- ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterArray[TS_VIDEO1].getMqDesc));
- ASSERT_TRUE(mFilterTests.startFilter(filterId));
- // tune test
- // TODO: replace with customized dvr input
- PlaybackSettings playbackSettings{
- .statusMask = 0xf,
- .lowThreshold = 0x1000,
- .highThreshold = 0x07fff,
- .dataFormat = DataFormat::ES,
- .packetSize = 188,
- };
- DvrConfig dvrConfig{
- .type = DvrType::PLAYBACK,
- .playbackInputFile = "/data/local/tmp/test.es",
- .bufferSize = FMQ_SIZE_4M,
- };
- dvrConfig.settings.playback(playbackSettings);
- mFrontendTests.setSoftwareFrontendDvrConfig(dvrConfig);
- ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendMap[live.frontendId], 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());
-}
-
TEST_P(TunerPlaybackHidlTest, PlaybackDataFlowWithTsSectionFilterTest) {
description("Feed ts data from playback and configure Ts section filter to get output");
- playbackSingleFilterTest(filterArray[TS_SECTION0], dvrArray[DVR_PLAYBACK0]);
+ if (!playback.support) {
+ return;
+ }
+ playbackSingleFilterTest(filterArray[TS_SECTION0], dvrMap[playback.dvrId]);
}
TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) {
@@ -566,7 +509,7 @@
return;
}
attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendMap[record.frontendId],
- dvrArray[DVR_RECORD0]);
+ dvrMap[record.dvrRecordId]);
}
TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) {
@@ -575,7 +518,7 @@
return;
}
recordSingleFilterTest(filterArray[TS_RECORD0], frontendMap[record.frontendId],
- dvrArray[DVR_RECORD0]);
+ dvrMap[record.dvrRecordId]);
}
TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) {
@@ -584,7 +527,7 @@
return;
}
recordSingleFilterTestWithLnb(filterArray[TS_RECORD0], frontendMap[lnbRecord.frontendId],
- dvrArray[DVR_RECORD0], lnbArray[LNB0]);
+ dvrMap[record.dvrRecordId], lnbArray[LNB0]);
}
TEST_P(TunerDescramblerHidlTest, CreateDescrambler) {
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
index d1f6a45..9723c2d 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
@@ -33,6 +33,7 @@
return false;
}
initFrontendConfig();
+ initDvrConfig();
connectHardwaresToTestCases();
if (!validateConnections()) {
ALOGW("[vts] failed to validate connections.");
@@ -42,7 +43,6 @@
initLnbConfig();
initFilterConfig();
initTimeFilterConfig();
- initDvrConfig();
initDescramblerConfig();
return true;
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
index 384455b..a1c5cd9 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
@@ -115,12 +115,6 @@
} Diseqc;
typedef enum {
- DVR_RECORD0,
- DVR_PLAYBACK0,
- DVR_MAX,
-} Dvr;
-
-typedef enum {
DESC_0,
DESC_MAX,
} Descrambler;
@@ -147,13 +141,6 @@
LnbPosition position;
};
-struct DvrConfig {
- DvrType type;
- uint32_t bufferSize;
- DvrSettings settings;
- string playbackInputFile;
-};
-
struct DescramblerConfig {
uint32_t casSystemId;
string provisionStr;
@@ -166,24 +153,25 @@
static FilterConfig filterArray[FILTER_MAX];
static TimeFilterConfig timeFilterArray[TIMER_MAX];
static DemuxFilterType filterLinkageTypes[LINKAGE_DIR][FILTER_MAIN_TYPE_BIT_COUNT];
-static DvrConfig dvrArray[DVR_MAX];
static DescramblerConfig descramblerArray[DESC_MAX];
// Hardware configs
static map<string, FrontendConfig> frontendMap;
+static map<string, DvrConfig> dvrMap;
// Hardware and test cases connections
static LiveBroadcastHardwareConnections live;
static ScanHardwareConnections scan;
+static DvrPlaybackHardwareConnections playback;
static DvrRecordHardwareConnections record;
static DescramblingHardwareConnections descrambling;
static LnbLiveHardwareConnections lnbLive;
static LnbRecordHardwareConnections lnbRecord;
-/** Configuration array for the frontend tune test */
+/** Config all the frontends that would be used in the tests */
inline void initFrontendConfig() {
- // The test will use the internal default fe is default fe is connected to any data flow without
- // overriding in the xml config.
+ // The test will use the internal default fe when default fe is connected to any data flow
+ // without overriding in the xml config.
string defaultFeId = "FE_DEFAULT";
FrontendDvbtSettings dvbtSettings{
.frequency = 578000,
@@ -208,10 +196,17 @@
TunerTestingConfigReader::readFrontendConfig1_0(frontendMap);
};
+/** Config all the dvrs that would be used in the tests */
+inline void initDvrConfig() {
+ // Read customized config
+ TunerTestingConfigReader::readDvrConfig1_0(dvrMap);
+};
+
/** Read the vendor configurations of which hardware to use for each test cases/data flows */
inline void connectHardwaresToTestCases() {
TunerTestingConfigReader::connectLiveBroadcast(live);
TunerTestingConfigReader::connectScan(scan);
+ TunerTestingConfigReader::connectDvrPlayback(playback);
TunerTestingConfigReader::connectDvrRecord(record);
TunerTestingConfigReader::connectDescrambling(descrambling);
TunerTestingConfigReader::connectLnbLive(lnbLive);
@@ -228,7 +223,34 @@
feIsValid &= lnbLive.support ? frontendMap.find(lnbLive.frontendId) != frontendMap.end() : true;
feIsValid &=
lnbRecord.support ? frontendMap.find(lnbRecord.frontendId) != frontendMap.end() : true;
- return feIsValid;
+
+ if (!feIsValid) {
+ ALOGW("[vts config] dynamic config fe connection is invalid.");
+ return false;
+ }
+
+ bool dvrIsValid = frontendMap[live.frontendId].isSoftwareFe
+ ? dvrMap.find(live.dvrSoftwareFeId) != dvrMap.end()
+ : true;
+ dvrIsValid &= playback.support ? dvrMap.find(playback.dvrId) != dvrMap.end() : true;
+
+ if (record.support) {
+ if (frontendMap[record.frontendId].isSoftwareFe) {
+ dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end();
+ }
+ dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end();
+ }
+
+ if (descrambling.support && frontendMap[descrambling.frontendId].isSoftwareFe) {
+ dvrIsValid &= dvrMap.find(descrambling.dvrSoftwareFeId) != dvrMap.end();
+ }
+
+ if (!dvrIsValid) {
+ ALOGW("[vts config] dynamic config dvr connection is invalid.");
+ return false;
+ }
+
+ return true;
}
// TODO: remove all the manual configs after the dynamic config refactoring is done.
@@ -341,31 +363,6 @@
timeFilterArray[TIMER0].timeStamp = 1;
}
-/** Configuration array for the dvr test */
-inline void initDvrConfig() {
- RecordSettings recordSettings{
- .statusMask = 0xf,
- .lowThreshold = 0x1000,
- .highThreshold = 0x07fff,
- .dataFormat = DataFormat::TS,
- .packetSize = 188,
- };
- dvrArray[DVR_RECORD0].type = DvrType::RECORD;
- dvrArray[DVR_RECORD0].bufferSize = FMQ_SIZE_4M;
- dvrArray[DVR_RECORD0].settings.record(recordSettings);
- PlaybackSettings playbackSettings{
- .statusMask = 0xf,
- .lowThreshold = 0x1000,
- .highThreshold = 0x07fff,
- .dataFormat = DataFormat::TS,
- .packetSize = 188,
- };
- dvrArray[DVR_PLAYBACK0].type = DvrType::PLAYBACK;
- dvrArray[DVR_PLAYBACK0].playbackInputFile = "/data/local/tmp/segment000000.ts";
- dvrArray[DVR_PLAYBACK0].bufferSize = FMQ_SIZE_4M;
- dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings);
-};
-
/** Configuration array for the descrambler test */
inline void initDescramblerConfig() {
descramblerArray[DESC_0].casSystemId = CLEAR_KEY_SYSTEM_ID;
diff --git a/tv/tuner/config/OWNERS b/tv/tuner/config/OWNERS
new file mode 100644
index 0000000..1b3d095
--- /dev/null
+++ b/tv/tuner/config/OWNERS
@@ -0,0 +1,4 @@
+nchalko@google.com
+amyjojo@google.com
+shubang@google.com
+quxiangfang@google.com
diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReader.h
index 5c7f564..aa2b75c 100644
--- a/tv/tuner/config/TunerTestingConfigReader.h
+++ b/tv/tuner/config/TunerTestingConfigReader.h
@@ -70,8 +70,16 @@
vector<FrontendStatus> expectTuneStatuses;
};
+struct DvrConfig {
+ DvrType type;
+ uint32_t bufferSize;
+ DvrSettings settings;
+ string playbackInputFile;
+};
+
struct LiveBroadcastHardwareConnections {
string frontendId;
+ string dvrSoftwareFeId;
/* string audioFilterId;
string videoFilterId;
list string of extra filters; */
@@ -81,9 +89,20 @@
string frontendId;
};
+struct DvrPlaybackHardwareConnections {
+ bool support;
+ string frontendId;
+ string dvrId;
+ /* string audioFilterId;
+ string videoFilterId;
+ list string of extra filters; */
+};
+
struct DvrRecordHardwareConnections {
bool support;
string frontendId;
+ string dvrRecordId;
+ string dvrSoftwareFeId;
/* string recordFilterId;
string dvrId; */
};
@@ -91,6 +110,7 @@
struct DescramblingHardwareConnections {
bool support;
string frontendId;
+ string dvrSoftwareFeId;
/* string descramblerId;
string audioFilterId;
string videoFilterId;
@@ -196,9 +216,41 @@
}
}
+ static void readDvrConfig1_0(map<string, DvrConfig>& dvrMap) {
+ auto hardwareConfig = getHardwareConfig();
+ if (hardwareConfig.hasDvrs()) {
+ auto dvrs = *hardwareConfig.getFirstDvrs();
+ for (auto dvrConfig : dvrs.getDvr()) {
+ string id = dvrConfig.getId();
+ DvrType type;
+ switch (dvrConfig.getType()) {
+ case DvrTypeEnum::PLAYBACK:
+ type = DvrType::PLAYBACK;
+ dvrMap[id].settings.playback(readPlaybackSettings(dvrConfig));
+ break;
+ case DvrTypeEnum::RECORD:
+ type = DvrType::RECORD;
+ dvrMap[id].settings.record(readRecordSettings(dvrConfig));
+ break;
+ case DvrTypeEnum::UNKNOWN:
+ ALOGW("[ConfigReader] invalid DVR type");
+ return;
+ }
+ dvrMap[id].type = type;
+ dvrMap[id].bufferSize = static_cast<uint32_t>(dvrConfig.getBufferSize());
+ if (dvrConfig.hasInputFilePath()) {
+ dvrMap[id].playbackInputFile = dvrConfig.getInputFilePath();
+ }
+ }
+ }
+ }
+
static void connectLiveBroadcast(LiveBroadcastHardwareConnections& live) {
auto liveConfig = getDataFlowConfiguration().getFirstClearLiveBroadcast();
live.frontendId = liveConfig->getFrontendConnection();
+ if (liveConfig->hasDvrSoftwareFeConnection()) {
+ live.dvrSoftwareFeId = liveConfig->getDvrSoftwareFeConnection();
+ }
}
static void connectScan(ScanHardwareConnections& scan) {
@@ -206,6 +258,16 @@
scan.frontendId = scanConfig->getFrontendConnection();
}
+ static void connectDvrPlayback(DvrPlaybackHardwareConnections& playback) {
+ auto dataFlow = getDataFlowConfiguration();
+ if (!dataFlow.hasDvrPlayback()) {
+ playback.support = false;
+ return;
+ }
+ auto playbackConfig = dataFlow.getFirstDvrPlayback();
+ playback.dvrId = playbackConfig->getDvrConnection();
+ }
+
static void connectDvrRecord(DvrRecordHardwareConnections& record) {
auto dataFlow = getDataFlowConfiguration();
if (!dataFlow.hasDvrRecord()) {
@@ -214,6 +276,10 @@
}
auto recordConfig = dataFlow.getFirstDvrRecord();
record.frontendId = recordConfig->getFrontendConnection();
+ record.dvrRecordId = recordConfig->getDvrRecordConnection();
+ if (recordConfig->hasDvrSoftwareFeConnection()) {
+ record.dvrSoftwareFeId = recordConfig->getDvrSoftwareFeConnection();
+ }
}
static void connectDescrambling(DescramblingHardwareConnections& descrambling) {
@@ -224,6 +290,9 @@
}
auto descConfig = dataFlow.getFirstDescrambling();
descrambling.frontendId = descConfig->getFrontendConnection();
+ if (descConfig->hasDvrSoftwareFeConnection()) {
+ descrambling.dvrSoftwareFeId = descConfig->getDvrSoftwareFeConnection();
+ }
}
static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) {
@@ -248,7 +317,7 @@
private:
static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) {
- ALOGW("[ConfigReader] type is dvbt");
+ ALOGW("[ConfigReader] fe type is dvbt");
FrontendDvbtSettings dvbtSettings{
.frequency = (uint32_t)feConfig.getFrequency(),
};
@@ -266,7 +335,7 @@
}
static FrontendDvbsSettings readDvbsFrontendSettings(Frontend feConfig) {
- ALOGW("[ConfigReader] type is dvbs");
+ ALOGW("[ConfigReader] fe type is dvbs");
FrontendDvbsSettings dvbsSettings{
.frequency = (uint32_t)feConfig.getFrequency(),
};
@@ -281,6 +350,30 @@
return dvbsSettings;
}
+ static PlaybackSettings readPlaybackSettings(Dvr dvrConfig) {
+ ALOGW("[ConfigReader] dvr type is playback");
+ PlaybackSettings playbackSettings{
+ .statusMask = static_cast<uint8_t>(dvrConfig.getStatusMask()),
+ .lowThreshold = static_cast<uint32_t>(dvrConfig.getLowThreshold()),
+ .highThreshold = static_cast<uint32_t>(dvrConfig.getHighThreshold()),
+ .dataFormat = static_cast<DataFormat>(dvrConfig.getDataFormat()),
+ .packetSize = static_cast<uint8_t>(dvrConfig.getPacketSize()),
+ };
+ return playbackSettings;
+ }
+
+ static RecordSettings readRecordSettings(Dvr dvrConfig) {
+ ALOGW("[ConfigReader] dvr type is record");
+ RecordSettings recordSettings{
+ .statusMask = static_cast<uint8_t>(dvrConfig.getStatusMask()),
+ .lowThreshold = static_cast<uint32_t>(dvrConfig.getLowThreshold()),
+ .highThreshold = static_cast<uint32_t>(dvrConfig.getHighThreshold()),
+ .dataFormat = static_cast<DataFormat>(dvrConfig.getDataFormat()),
+ .packetSize = static_cast<uint8_t>(dvrConfig.getPacketSize()),
+ };
+ return recordSettings;
+ }
+
static TunerConfiguration getTunerConfig() { return *read(configFilePath.c_str()); }
static HardwareConfiguration getHardwareConfig() {
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index b0f410d..1ebd8e1 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -5,12 +5,14 @@
ctor public DataFlowConfiguration();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.ClearLiveBroadcast getClearLiveBroadcast();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling getDescrambling();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback getDvrPlayback();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord getDvrRecord();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive getLnbLive();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord getLnbRecord();
method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan getScan();
method public void setClearLiveBroadcast(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.ClearLiveBroadcast);
method public void setDescrambling(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Descrambling);
+ method public void setDvrPlayback(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrPlayback);
method public void setDvrRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.DvrRecord);
method public void setLnbLive(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbLive);
method public void setLnbRecord(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.LnbRecord);
@@ -19,19 +21,33 @@
public static class DataFlowConfiguration.ClearLiveBroadcast {
ctor public DataFlowConfiguration.ClearLiveBroadcast();
+ method @Nullable public String getDvrSoftwareFeConnection();
method @Nullable public String getFrontendConnection();
+ method public void setDvrSoftwareFeConnection(@Nullable String);
method public void setFrontendConnection(@Nullable String);
}
public static class DataFlowConfiguration.Descrambling {
ctor public DataFlowConfiguration.Descrambling();
+ method @Nullable public String getDvrSoftwareFeConnection();
method @Nullable public String getFrontendConnection();
+ method public void setDvrSoftwareFeConnection(@Nullable String);
method public void setFrontendConnection(@Nullable String);
}
+ public static class DataFlowConfiguration.DvrPlayback {
+ ctor public DataFlowConfiguration.DvrPlayback();
+ method @Nullable public String getDvrConnection();
+ method public void setDvrConnection(@Nullable String);
+ }
+
public static class DataFlowConfiguration.DvrRecord {
ctor public DataFlowConfiguration.DvrRecord();
+ method @Nullable public String getDvrRecordConnection();
+ method @Nullable public String getDvrSoftwareFeConnection();
method @Nullable public String getFrontendConnection();
+ method public void setDvrRecordConnection(@Nullable String);
+ method public void setDvrSoftwareFeConnection(@Nullable String);
method public void setFrontendConnection(@Nullable String);
}
@@ -43,7 +59,9 @@
public static class DataFlowConfiguration.LnbRecord {
ctor public DataFlowConfiguration.LnbRecord();
+ method @Nullable public String getDvrRecordConnection();
method @Nullable public String getFrontendConnection();
+ method public void setDvrRecordConnection(@Nullable String);
method public void setFrontendConnection(@Nullable String);
}
@@ -71,6 +89,50 @@
method public void setTransmissionMode(@Nullable java.math.BigInteger);
}
+ public class Dvr {
+ ctor public Dvr();
+ method @Nullable public java.math.BigInteger getBufferSize();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum getDataFormat();
+ method @Nullable public java.math.BigInteger getHighThreshold();
+ method @Nullable public String getId();
+ method @Nullable public String getInputFilePath();
+ method @Nullable public java.math.BigInteger getLowThreshold();
+ method @Nullable public java.math.BigInteger getPacketSize();
+ method @Nullable public java.math.BigInteger getStatusMask();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.DvrTypeEnum getType();
+ method public void setBufferSize(@Nullable java.math.BigInteger);
+ method public void setDataFormat(@Nullable android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum);
+ method public void setHighThreshold(@Nullable java.math.BigInteger);
+ method public void setId(@Nullable String);
+ method public void setInputFilePath(@Nullable String);
+ method public void setLowThreshold(@Nullable java.math.BigInteger);
+ method public void setPacketSize(@Nullable java.math.BigInteger);
+ method public void setStatusMask(@Nullable java.math.BigInteger);
+ method public void setType(@Nullable android.media.tuner.testing.configuration.V1_0.DvrTypeEnum);
+ }
+
+ public enum DvrDataFormatEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum ES;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum PES;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum SHV_TLV;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrDataFormatEnum TS;
+ }
+
+ public enum DvrStatusEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrStatusEnum DATA_READY;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrStatusEnum HIGH_WATER;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrStatusEnum LOW_WATER;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrStatusEnum OVERFLOW;
+ }
+
+ public enum DvrTypeEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrTypeEnum PLAYBACK;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvrTypeEnum RECORD;
+ }
+
public class Frontend {
ctor public Frontend();
method @Nullable public java.math.BigInteger getConnectToCicamId();
@@ -108,10 +170,17 @@
public class HardwareConfiguration {
ctor public HardwareConfiguration();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs getDvrs();
method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends getFrontends();
+ method public void setDvrs(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs);
method public void setFrontends(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends);
}
+ public static class HardwareConfiguration.Dvrs {
+ ctor public HardwareConfiguration.Dvrs();
+ method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.Dvr> getDvr();
+ }
+
public static class HardwareConfiguration.Frontends {
ctor public HardwareConfiguration.Frontends();
method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.Frontend> getFrontend();
diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config.xml
index c4080d9..001e045 100644
--- a/tv/tuner/config/sample_tuner_vts_config.xml
+++ b/tv/tuner/config/sample_tuner_vts_config.xml
@@ -60,16 +60,49 @@
connectToCicamId="0" frequency="578000" endFrequency="800000">
</frontend>
</frontends>
+ <!-- Dvr section:
+ This section contains configurations of all the dvrs that would be used in the tests.
+ - This section is optional and can be skipped if DVR is not supported.
+ - The users can configure 1 or more dvr elements in the dvrs sections.
+
+ Each dvr element contain the following attributes:
+ "id": unique id of the dvr that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "type": the dvr type.
+ "bufferSize": the dvr buffer size.
+ "statusMask": register callbacks of specific status.
+ "lowThreshold": the dvr status low threshold.
+ "highThreshold": the dvr status high threshold.
+ "dataFormat": the dvr data format.
+ "packetSize": the dvr packet size.
+ "inputFilePath": the dvr playback input file path. Only required in playback dvr.
+ -->
+ <dvrs>
+ <dvr id="DVR_PLAYBACK_0" type="PLAYBACK" bufferSize="4194304"
+ statusMask="15" lowThreshold="4096" highThreshold="32767"
+ dataFormat="TS" packetSize="188" inputFilePath="/data/local/tmp/segment000000.ts"/>
+ <dvr id="DVR_RECORD_0" type="RECORD" bufferSize="4194304"
+ statusMask="15" lowThreshold="4096" highThreshold="32767"
+ dataFormat="TS" packetSize="188"/>
+ <dvr id="DVR_PLAYBACK_1" type="PLAYBACK" bufferSize="4194304"
+ statusMask="15" lowThreshold="4096" highThreshold="32767"
+ dataFormat="ES" packetSize="188" inputFilePath="/data/local/tmp/test.es"/>
+ </dvrs>
</hardwareConfiguration>
<!-- Data flow configuration section connects each data flow under test to the ids of the
hardwares that would be used during the tests. -->
<dataFlowConfiguration>
- <clearLiveBroadcast frontendConnection="FE_DEFAULT"/>
+ <clearLiveBroadcast frontendConnection="FE_DEFAULT"
+ dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
<scan frontendConnection="FE_DEFAULT"/>
- <descrambling frontendConnection="FE_DEFAULT"/>
- <dvrRecord frontendConnection="FE_DEFAULT"/>
+ <descrambling frontendConnection="FE_DEFAULT"
+ dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
+ <dvrRecord frontendConnection="FE_DEFAULT"
+ dvrRecordConnection="DVR_RECORD_0"
+ dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
<lnbLive frontendConnection="FE_DVBS_0"/>
- <lnbRecord frontendConnection="FE_DVBS_0"/>
+ <lnbRecord frontendConnection="FE_DVBS_0"
+ dvrRecordConnection="DVR_RECORD_0"/>
</dataFlowConfiguration>
</TunerConfiguration>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index cd8b061..45d25e5 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -99,14 +99,80 @@
</xs:choice>
<xs:attribute name="id" type="frontendId" use="required"/>
<xs:attribute name="type" type="frontendTypeEnum" use="required"/>
- <xs:attribute name="isSoftwareFrontend" type="xs:boolean" use="required"/>
<!-- A dvr connection is required in the data flow config section when
"isSoftwareFrontend" is true. -->
+ <xs:attribute name="isSoftwareFrontend" type="xs:boolean" use="required"/>
<xs:attribute name="frequency" type="xs:nonNegativeInteger" use="required"/>
<xs:attribute name="connectToCicamId" type="xs:nonNegativeInteger" use="optional"/>
<xs:attribute name="endFrequency" type="xs:nonNegativeInteger" use="optional"/>
</xs:complexType>
+ <!-- DVR SESSION -->
+ <xs:simpleType name="dvrId">
+ <!-- Dvr id must be DVR_TYPE_NUM. <dvr id="DVR_PLAYBACK_0"/> -->
+ <xs:restriction base="xs:string">
+ <xs:pattern value="DVR_RECORD_[0-9]+|DVR_PLAYBACK_[0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="dvrStatusMask">
+ <!-- Dvr status mask must masking the <dvrStatusEnum> -->
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="0"/>
+ <xs:maxInclusive value="15"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="dvrStatusEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="DATA_READY" />
+ <xs:enumeration value="LOW_WATER" />
+ <xs:enumeration value="HIGH_WATER" />
+ <xs:enumeration value="OVERFLOW" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="dvrTypeEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="PLAYBACK" />
+ <xs:enumeration value="RECORD" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="dvrDataFormatEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="TS" />
+ <xs:enumeration value="PES" />
+ <xs:enumeration value="ES" />
+ <xs:enumeration value="SHV_TLV" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="dvr">
+ <xs:annotation>
+ <xs:documentation>
+ Each dvr element contain the following attributes:
+ "id": unique id of the dvr that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "type": the dvr type.
+ "bufferSize": the dvr buffer size.
+ "statusMask": register callbacks of specific status.
+ "lowThreshold": the dvr status low threshold.
+ "highThreshold": the dvr status high threshold.
+ "dataFormat": the dvr data format.
+ "packetSize": the dvr packet size.
+ "inputFilePath": the dvr playback input file path. Only required in playback
+ dvr.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="id" type="dvrId" use="required"/>
+ <xs:attribute name="type" type="dvrTypeEnum" use="required"/>
+ <xs:attribute name="bufferSize" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="statusMask" type="dvrStatusMask" use="required"/>
+ <xs:attribute name="lowThreshold" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="highThreshold" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="dataFormat" type="dvrDataFormatEnum" use="required"/>
+ <xs:attribute name="packetSize" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="inputFilePath" type="xs:anyURI" use="optional"/>
+ </xs:complexType>
+
<!-- HARDWARE CONFIGURATION SESSION -->
<xs:complexType name="hardwareConfiguration">
<xs:sequence>
@@ -131,6 +197,23 @@
</xs:sequence>
</xs:complexType>
</xs:element>
+ <xs:element name="dvrs" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ This section contains configurations of all the dvrs that would be used
+ in the tests.
+ - This section is optional and can be skipped if the device does
+ not support dvr.
+ - The users can configure 1 or more dvr elements in the dvrs
+ sections.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="dvr" type="dvr" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
</xs:sequence>
</xs:complexType>
@@ -139,8 +222,9 @@
<xs:sequence>
<xs:element name="clearLiveBroadcast" minOccurs="1" maxOccurs="1">
<xs:complexType>
- <!-- TODO: add optional dvr config for software input -->
<xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ <!-- DVR is only required when the frontend is using the software input -->
+ <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="scan" minOccurs="1" maxOccurs="1">
@@ -151,11 +235,21 @@
<xs:element name="descrambling" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ <!-- DVR is only required when the frontend is using the software input -->
+ <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="dvrPlayback" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:attribute name="dvrConnection" type="dvrId" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="dvrRecord" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ <xs:attribute name="dvrRecordConnection" type="dvrId" use="required"/>
+ <!-- DVR is only required when the frontend is using the software input -->
+ <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="lnbLive" minOccurs="0" maxOccurs="1">
@@ -166,6 +260,7 @@
<xs:element name="lnbRecord" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ <xs:attribute name="dvrRecordConnection" type="dvrId" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>