Merge changes from topics "24ch Audio HAL", "360RA HAL"
* changes:
audio: Add AUDIO_CHANNEL_OUT_22POINT2 constant
audio: Add AUDIO_CHANNEL_OUT_13POINT_360RA constant
diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal
index 9788345..05a7585 100644
--- a/radio/1.6/IRadioIndication.hal
+++ b/radio/1.6/IRadioIndication.hal
@@ -107,7 +107,7 @@
/**
* Indicates physical channel configurations.
*
- * An empty configs list indicates that the radio is in idle mode.
+ * An empty configs list shall be returned when the radio is in idle mode (i.e. RRC idle).
*
* @param type Type of radio indication
* @param configs Vector of PhysicalChannelConfigs
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index f2c06b7..60b0edc 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -232,6 +232,7 @@
* RadioError:RADIO_NOT_AVAILABLE
* RadioError:INTERNAL_ERR
* RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_STATE
*/
oneway setNrDualConnectivityStateResponse(RadioResponseInfo info);
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index a9c21ff..87320da 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -378,6 +378,7 @@
CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
{::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR,
+ ::android::hardware::radio::V1_6::RadioError::INVALID_STATE,
::android::hardware::radio::V1_6::RadioError::NONE}));
}
}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
index f3c5477..c2e21b6 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -60,29 +60,36 @@
* `attestationKey` parameter of `generateKey()`, `importKey()` or `importWrappedKey()`), and in
* the non-attestaion case, whether the key can self-sign.
*
- * 1. Attestation with factory key. If Tag::ATTESTATION_CHALLENGE is provided and the
- * `attestationKey` parameter on the generate/import call is null, the returned certificate
- * chain must contain an attestation certificate signed with a factory-provisioned
- * attestation key, and the full certificate chain for that factory-provisioned attestation
- * key.
+ * 1. Asymmetric key attestation with factory key. If Tag::ATTESTATION_CHALLENGE is provided
+ * and the `attestationKey` parameter on the generate/import call is null, the returned
+ * certificate chain must contain an attestation certificate signed with a factory-
+ * provisioned attestation key, and the full certificate chain for that factory-provisioned
+ * attestation key. Tag::ATTESTATION_APPLICATION_ID must also be provided when the
+ * ATTESTATION_CHALLENGE is provided, otherwise ATTESTATION_APPLICATION_ID_MISSING will be
+ * returned.
*
- * 2. Attestation with caller-provided key. If Tag::ATTESTATION_CHALLENGE is provided and the
- * `attestationKey` parameter on the generat/import call is non-null and contains the key
- * blob of a key with KeyPurpose::ATTEST_KEY, the returned certificate chain must contain
- * only an attestation certificate signed with the specified key. The caller must know the
- * certificate chain for the provided key.
+ * 2. Asymmetric key attestation with caller-provided key. If Tag::ATTESTATION_CHALLENGE is
+ * provided and the `attestationKey` parameter on the generat/import call is non-null and
+ * contains the key blob of a key with KeyPurpose::ATTEST_KEY, the returned certificate
+ * chain must contain only an attestation certificate signed with the specified key. The
+ * caller must know the certificate chain for the provided key. Tag::
+ * ATTESTATION_APPLICATION_ID must also be provided when the ATTESTATION_CHALLENGE is
+ * provided, otherwise ATTESTATION_APPLICATION_ID_MISSING will be returned.
*
- * 3. Non-attestation with signing key. If Tag::ATTESTATION_CHALLENGE is not provided and the
- * generated/imported key has KeyPurpose::SIGN, then the returned certificate chain must
- * contain only a single self-signed certificate with no attestation extension.
+ * 3. Asymmetric key non-attestation with signing key. If Tag::ATTESTATION_CHALLENGE is not
+ * provided and the generated/imported key has KeyPurpose::SIGN, then the returned
+ * certificate chain must contain only a single self-signed certificate with no attestation
+ * extension. Tag::ATTESTATION_APPLICATION_ID will be ignored if provided.
*
- * 4. Non-attestation with non-signing key. If TAG::ATTESTATION_CHALLENGE is not provided and
- * the generated/imported key does not have KeyPurpose::SIGN, then the returned certificate
- * chain must contain only a single certificate with an empty signature and no attestation
- * extension.
+ * 4. Asymmetric key non-attestation with non-signing key. If TAG::ATTESTATION_CHALLENGE is
+ * not provided and the generated/imported key does not have KeyPurpose::SIGN, then the
+ * returned certificate chain must contain only a single certificate with an empty signature
+ * and no attestation extension. Tag::ATTESTATION_APPLICATION_ID will be ignored if
+ * provided.
*
- * 5. Symmetric key. If the generated/imported key is symmetric, the certificate chain must be
- * empty.
+ * 5. Symmetric key. If the generated/imported key is symmetric, the certificate chain must
+ * return empty, any Tag::ATTESTATION_CHALLENGE or Tag::ATTESTATION_APPLICATION_ID inputs,
+ * if provided, are ignored.
*/
Certificate[] certificateChain;
}
diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp
index 48ce384..0430646 100644
--- a/tv/tuner/1.0/default/Tuner.cpp
+++ b/tv/tuner/1.0/default/Tuner.cpp
@@ -141,6 +141,8 @@
// IP filter can be an MMTP filter's data source.
caps.linkCaps = {0x00, 0x00, 0x02, 0x00, 0x00};
+ // Support time filter testing
+ caps.bTimeFilter = true;
_hidl_cb(Result::SUCCESS, caps);
return Void();
}
diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp
index 47d3b2f..6187c73 100644
--- a/tv/tuner/1.0/vts/functional/Android.bp
+++ b/tv/tuner/1.0/vts/functional/Android.bp
@@ -35,6 +35,15 @@
"DescramblerTests.cpp",
"LnbTests.cpp",
],
+ generated_headers: [
+ "tuner_testing_dynamic_configuration_V1_0_enums",
+ "tuner_testing_dynamic_configuration_V1_0_parser",
+ ],
+ generated_sources: [
+ "tuner_testing_dynamic_configuration_V1_0_enums",
+ "tuner_testing_dynamic_configuration_V1_0_parser",
+ ],
+ header_libs: ["libxsdc-utils"],
static_libs: [
"android.hardware.cas@1.0",
"android.hardware.cas@1.1",
@@ -49,6 +58,12 @@
],
shared_libs: [
"libbinder",
+ "libxml2",
+ ],
+ data: [
+ ":tuner_frontend_input_ts",
+ ":tuner_frontend_input_es",
+ ":tuner_testing_dynamic_configuration_V1_0",
],
test_suites: [
"general-tests",
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
index 45951d2..b35d112 100644
--- a/tv/tuner/1.0/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
@@ -370,13 +370,11 @@
mIsSoftwareFe = config.isSoftwareFe;
bool result = true;
if (mIsSoftwareFe && testWithDemux) {
- DvrConfig dvrConfig;
- getSoftwareFrontendPlaybackConfig(dvrConfig);
- result &= mDvrTests.openDvrInDemux(dvrConfig.type, dvrConfig.bufferSize) == success();
- result &= mDvrTests.configDvrPlayback(dvrConfig.settings) == success();
+ result &= mDvrTests.openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) == success();
+ result &= mDvrTests.configDvrPlayback(mDvrConfig.settings) == success();
result &= mDvrTests.getDvrPlaybackMQDescriptor() == success();
- mDvrTests.startPlaybackInputThread(dvrConfig.playbackInputFile,
- dvrConfig.settings.playback());
+ mDvrTests.startPlaybackInputThread(mDvrConfig.playbackInputFile,
+ mDvrConfig.settings.playback());
if (!result) {
ALOGW("[vts] Software frontend dvr configure failed.");
return failure();
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.h b/tv/tuner/1.0/vts/functional/FrontendTests.h
index c536325..33ff603 100644
--- a/tv/tuner/1.0/vts/functional/FrontendTests.h
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.h
@@ -104,6 +104,7 @@
void setService(sp<ITuner> tuner) {
mService = tuner;
mDvrTests.setService(tuner);
+ getDefaultSoftwareFrontendPlaybackConfig(mDvrConfig);
}
AssertionResult getFrontendIds();
@@ -125,12 +126,14 @@
void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; }
void setDemux(sp<IDemux> demux) { mDvrTests.setDemux(demux); }
+ void setSoftwareFrontendDvrConfig(DvrConfig conf) { mDvrConfig = conf; }
protected:
static AssertionResult failure() { return ::testing::AssertionFailure(); }
static AssertionResult success() { return ::testing::AssertionSuccess(); }
- void getSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) {
+ // TODO: replace with customized dvr input
+ void getDefaultSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) {
PlaybackSettings playbackSettings{
.statusMask = 0xf,
.lowThreshold = 0x1000,
@@ -151,4 +154,5 @@
DvrTests mDvrTests;
bool mIsSoftwareFe = false;
+ DvrConfig mDvrConfig;
};
diff --git a/tv/tuner/1.0/vts/functional/LnbTests.cpp b/tv/tuner/1.0/vts/functional/LnbTests.cpp
index 9080f59..9338c73 100644
--- a/tv/tuner/1.0/vts/functional/LnbTests.cpp
+++ b/tv/tuner/1.0/vts/functional/LnbTests.cpp
@@ -48,10 +48,11 @@
return AssertionResult(status == Result::SUCCESS);
}
-AssertionResult LnbTests::openLnbByName(string lnbName) {
+AssertionResult LnbTests::openLnbByName(string lnbName, uint32_t& id) {
Result status;
- mService->openLnbByName(lnbName, [&](Result result, uint32_t /*lnbId*/, const sp<ILnb>& lnb) {
+ mService->openLnbByName(lnbName, [&](Result result, uint32_t lnbId, const sp<ILnb>& lnb) {
mLnb = lnb;
+ id = lnbId;
status = result;
});
diff --git a/tv/tuner/1.0/vts/functional/LnbTests.h b/tv/tuner/1.0/vts/functional/LnbTests.h
index 2fdbe2c..62b42ff 100644
--- a/tv/tuner/1.0/vts/functional/LnbTests.h
+++ b/tv/tuner/1.0/vts/functional/LnbTests.h
@@ -64,7 +64,7 @@
AssertionResult getLnbIds(vector<uint32_t>& ids);
AssertionResult openLnbById(uint32_t lnbId);
- AssertionResult openLnbByName(string lnbName);
+ AssertionResult openLnbByName(string lnbName, uint32_t& lnbId);
AssertionResult setLnbCallback();
AssertionResult setVoltage(LnbVoltage voltage);
AssertionResult setTone(LnbTone tone);
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 22ba271..4c92665 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -18,16 +18,15 @@
namespace {
-AssertionResult TunerBroadcastHidlTest::filterDataOutputTest(vector<string> /*goldenOutputFiles*/) {
+AssertionResult TunerBroadcastHidlTest::filterDataOutputTest() {
return filterDataOutputTestBase(mFilterTests);
}
-AssertionResult TunerPlaybackHidlTest::filterDataOutputTest(vector<string> /*goldenOutputFiles*/) {
+AssertionResult TunerPlaybackHidlTest::filterDataOutputTest() {
return filterDataOutputTestBase(mFilterTests);
}
-AssertionResult TunerDescramblerHidlTest::filterDataOutputTest(
- vector<string> /*goldenOutputFiles*/) {
+AssertionResult TunerDescramblerHidlTest::filterDataOutputTest() {
return filterDataOutputTestBase(mFilterTests);
}
@@ -57,13 +56,16 @@
}
void TunerFilterHidlTest::testTimeFilter(TimeFilterConfig filterConf) {
- if (!filterConf.supportTimeFilter) {
+ if (!timeFilter.support) {
return;
}
uint32_t demuxId;
sp<IDemux> 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));
@@ -75,26 +77,20 @@
void TunerBroadcastHidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
FrontendConfig frontendConf) {
- if (!frontendConf.enable) {
- return;
- }
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
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);
@@ -106,7 +102,7 @@
ASSERT_TRUE(mFilterTests.startFilter(filterId));
// tune test
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
- ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
+ ASSERT_TRUE(filterDataOutputTest());
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
ASSERT_TRUE(mFilterTests.closeFilter(filterId));
@@ -117,14 +113,16 @@
void TunerBroadcastHidlTest::broadcastSingleFilterTestWithLnb(FilterConfig filterConf,
FrontendConfig frontendConf,
LnbConfig lnbConf) {
- vector<uint32_t> ids;
- ASSERT_TRUE(mLnbTests.getLnbIds(ids));
- if (!lnbConf.usingLnb) {
- return;
+ if (lnbConf.name.compare(emptyHardwareId) == 0) {
+ vector<uint32_t> ids;
+ ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+ ASSERT_TRUE(ids.size() > 0);
+ ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+ mLnbId = &ids[0];
+ } else {
+ mLnbId = (uint32_t*)malloc(sizeof(uint32_t));
+ ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId));
}
- ASSERT_TRUE(ids.size() > 0);
- ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
- *mLnbId = ids[0];
ASSERT_TRUE(mLnbTests.setLnbCallback());
ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage));
ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone));
@@ -152,7 +150,7 @@
mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback());
ASSERT_TRUE(mDvrTests.startDvrPlayback());
ASSERT_TRUE(mFilterTests.startFilter(filterId));
- ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
+ ASSERT_TRUE(filterDataOutputTest());
mDvrTests.stopPlaybackThread();
ASSERT_TRUE(mFilterTests.stopFilter(filterId));
ASSERT_TRUE(mDvrTests.stopDvrPlayback());
@@ -163,9 +161,6 @@
void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
FrontendConfig frontendConf, DvrConfig dvrConf) {
- if (!frontendConf.enable) {
- return;
- }
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
@@ -179,6 +174,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);
@@ -213,18 +211,23 @@
void TunerRecordHidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf,
FrontendConfig frontendConf,
DvrConfig dvrConf, LnbConfig lnbConf) {
- vector<uint32_t> ids;
- ASSERT_TRUE(mLnbTests.getLnbIds(ids));
- if (!lnbConf.usingLnb) {
- return;
+ if (lnbConf.name.compare(emptyHardwareId) == 0) {
+ vector<uint32_t> ids;
+ ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+ ASSERT_TRUE(ids.size() > 0);
+ ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+ mLnbId = &ids[0];
+ } else {
+ mLnbId = (uint32_t*)malloc(sizeof(uint32_t));
+ ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId));
}
- ASSERT_TRUE(ids.size() > 0);
- ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
- *mLnbId = ids[0];
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]));
+ }
recordSingleFilterTest(filterConf, frontendConf, dvrConf);
ASSERT_TRUE(mLnbTests.closeLnb());
mLnbId = nullptr;
@@ -271,9 +274,6 @@
void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
FrontendConfig frontendConf,
DescramblerConfig descConfig) {
- if (!frontendConf.enable) {
- return;
- }
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
@@ -283,14 +283,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);
@@ -305,7 +302,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++) {
@@ -319,7 +316,7 @@
}
// tune test
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
- ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles));
+ ASSERT_TRUE(filterDataOutputTest());
ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
for (id = filterIds.begin(); id != filterIds.end(); id++) {
ASSERT_TRUE(mFilterTests.stopFilter(*id));
@@ -337,44 +334,37 @@
TEST_P(TunerFrontendHidlTest, TuneFrontend) {
description("Tune one Frontend with specific setting and check Lock event");
- mFrontendTests.tuneTest(frontendArray[defaultFrontend]);
+ mFrontendTests.tuneTest(frontendMap[live.frontendId]);
}
TEST_P(TunerFrontendHidlTest, AutoScanFrontend) {
description("Run an auto frontend scan with specific setting and check lock scanMessage");
- mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_AUTO);
+ mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO);
}
TEST_P(TunerFrontendHidlTest, BlindScanFrontend) {
description("Run an blind frontend scan with specific setting and check lock scanMessage");
- mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_BLIND);
-}
-
-TEST_P(TunerLnbHidlTest, OpenLnbByName) {
- description("Open and configure an Lnb with name then send a diseqc msg to it.");
- ASSERT_TRUE(mLnbTests.openLnbByName(lnbArray[LNB_EXTERNAL].name));
- ASSERT_TRUE(mLnbTests.setLnbCallback());
- ASSERT_TRUE(mLnbTests.setVoltage(lnbArray[LNB_EXTERNAL].voltage));
- ASSERT_TRUE(mLnbTests.setTone(lnbArray[LNB_EXTERNAL].tone));
- ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbArray[LNB_EXTERNAL].position));
- ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgArray[DISEQC_POWER_ON]));
- ASSERT_TRUE(mLnbTests.closeLnb());
+ mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
}
TEST_P(TunerLnbHidlTest, SendDiseqcMessageToLnb) {
description("Open and configure an Lnb with specific settings then send a diseqc msg to it.");
- vector<uint32_t> ids;
- ASSERT_TRUE(mLnbTests.getLnbIds(ids));
- if (!lnbArray[LNB0].usingLnb) {
- return;
+ if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) {
+ vector<uint32_t> ids;
+ ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+ ASSERT_TRUE(ids.size() > 0);
+ ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+ } else {
+ uint32_t id;
+ ASSERT_TRUE(mLnbTests.openLnbByName(lnbMap[lnbLive.lnbId].name, id));
}
- ASSERT_TRUE(ids.size() > 0);
- ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
ASSERT_TRUE(mLnbTests.setLnbCallback());
- ASSERT_TRUE(mLnbTests.setVoltage(lnbArray[LNB0].voltage));
- ASSERT_TRUE(mLnbTests.setTone(lnbArray[LNB0].tone));
- ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbArray[LNB0].position));
- ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgArray[DISEQC_POWER_ON]));
+ 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());
}
@@ -383,7 +373,7 @@
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
- mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
+ mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -395,6 +385,9 @@
TEST_P(TunerDemuxHidlTest, getAvSyncTime) {
description("Get the A/V sync time from a PCR filter.");
+ if (live.pcrFilterId.compare(emptyHardwareId) == 0) {
+ return;
+ }
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
@@ -403,22 +396,22 @@
uint32_t avSyncHwId;
sp<IFilter> mediaFilter;
- mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
+ 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(filterArray[TS_VIDEO1].type,
- filterArray[TS_VIDEO1].bufferSize));
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.videoFilterId].type,
+ filterMap[live.videoFilterId].bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(mediaFilterId));
- ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, mediaFilterId));
+ ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.videoFilterId].settings, mediaFilterId));
mediaFilter = mFilterTests.getFilterById(mediaFilterId);
- ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_PCR0].type,
- filterArray[TS_PCR0].bufferSize));
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.pcrFilterId].type,
+ filterMap[live.pcrFilterId].bufferSize));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(pcrFilterId));
- ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_PCR0].settings, 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));
@@ -431,7 +424,7 @@
TEST_P(TunerFilterHidlTest, StartFilterInDemux) {
description("Open and start a filter in Demux.");
// TODO use paramterized tests
- configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]);
+ configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
}
TEST_P(TunerFilterHidlTest, SetFilterLinkage) {
@@ -448,11 +441,9 @@
if (caps.linkCaps[i] & (bitMask << j)) {
uint32_t sourceFilterId;
uint32_t sinkFilterId;
- ASSERT_TRUE(mFilterTests.openFilterInDemux(filterLinkageTypes[SOURCE][i],
- FMQ_SIZE_16M));
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(getLinkageFilterType(i), FMQ_SIZE_16M));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(sourceFilterId));
- ASSERT_TRUE(
- mFilterTests.openFilterInDemux(filterLinkageTypes[SINK][j], FMQ_SIZE_16M));
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(getLinkageFilterType(j), FMQ_SIZE_16M));
ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(sinkFilterId));
ASSERT_TRUE(mFilterTests.setFilterDataSource(sourceFilterId, sinkFilterId));
ASSERT_TRUE(mFilterTests.setFilterDataSourceToDemux(sinkFilterId));
@@ -467,63 +458,87 @@
TEST_P(TunerFilterHidlTest, testTimeFilter) {
description("Open a timer filter in Demux and set time stamp.");
// TODO use paramterized tests
- testTimeFilter(timeFilterArray[TIMER0]);
+ testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
}
TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowVideoFilterTest) {
description("Test Video Filter functionality in Broadcast use case.");
- broadcastSingleFilterTest(filterArray[TS_VIDEO1], frontendArray[defaultFrontend]);
+ broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
}
TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowAudioFilterTest) {
description("Test Audio Filter functionality in Broadcast use case.");
- broadcastSingleFilterTest(filterArray[TS_AUDIO0], frontendArray[defaultFrontend]);
+ broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]);
}
TEST_P(TunerBroadcastHidlTest, BroadcastDataFlowSectionFilterTest) {
description("Test Section Filter functionality in Broadcast use case.");
- broadcastSingleFilterTest(filterArray[TS_SECTION0], frontendArray[defaultFrontend]);
+ if (live.sectionFilterId.compare(emptyHardwareId) == 0) {
+ return;
+ }
+ broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]);
}
TEST_P(TunerBroadcastHidlTest, IonBufferTest) {
description("Test the av filter data bufferring.");
- broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]);
+ broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
}
TEST_P(TunerBroadcastHidlTest, LnbBroadcastDataFlowVideoFilterTest) {
description("Test Video Filter functionality in Broadcast with Lnb use case.");
- broadcastSingleFilterTest(filterArray[TS_VIDEO0], frontendArray[DVBS]);
+ if (!lnbLive.support) {
+ return;
+ }
+ broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId],
+ frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]);
}
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 || playback.sectionFilterId.compare(emptyHardwareId) == 0) {
+ return;
+ }
+ playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]);
}
TEST_P(TunerRecordHidlTest, AttachFiltersToRecordTest) {
description("Attach a single filter to the record dvr test.");
// TODO use paramterized tests
- attachSingleFilterToRecordDvrTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend],
- dvrArray[DVR_RECORD0]);
+ if (!record.support) {
+ return;
+ }
+ attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
+ frontendMap[record.frontendId], dvrMap[record.dvrRecordId]);
}
TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) {
description("Feed ts data from frontend to recording and test with ts record filter");
- recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend],
- dvrArray[DVR_RECORD0]);
+ if (!record.support) {
+ return;
+ }
+ recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
+ dvrMap[record.dvrRecordId]);
}
TEST_P(TunerRecordHidlTest, LnbRecordDataFlowWithTsRecordFilterTest) {
description("Feed ts data from Fe with Lnb to recording and test with ts record filter");
- recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBS], dvrArray[DVR_RECORD0]);
+ if (lnbRecord.support) {
+ return;
+ }
+ recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId],
+ frontendMap[lnbRecord.frontendId], dvrMap[lnbRecord.dvrRecordId],
+ lnbMap[lnbRecord.lnbId]);
}
TEST_P(TunerDescramblerHidlTest, CreateDescrambler) {
description("Create Descrambler");
+ if (descrambling.support) {
+ return;
+ }
uint32_t feId;
uint32_t demuxId;
sp<IDemux> demux;
- mFrontendTests.getFrontendIdByType(frontendArray[defaultFrontend].type, feId);
+ mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId);
ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -537,10 +552,14 @@
TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) {
description("Test ts audio filter in scrambled broadcast use case");
+ if (descrambling.support) {
+ return;
+ }
set<FilterConfig> filterConfs;
- filterConfs.insert(filterArray[TS_AUDIO0]);
- filterConfs.insert(filterArray[TS_VIDEO1]);
- scrambledBroadcastTest(filterConfs, frontendArray[defaultFrontend], descramblerArray[DESC_0]);
+ filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.audioFilterId]));
+ filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.videoFilterId]));
+ scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId],
+ descramblerMap[descrambling.descramblerId]);
}
INSTANTIATE_TEST_SUITE_P(
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
index 5a23ca5..e240604 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
@@ -20,6 +20,9 @@
#include "LnbTests.h"
using android::hardware::tv::tuner::V1_0::DataFormat;
+using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxTlvFilterType;
using android::hardware::tv::tuner::V1_0::IDescrambler;
static AssertionResult success() {
@@ -28,14 +31,22 @@
namespace {
-void initConfiguration() {
+bool initConfiguration() {
+ if (!TunerTestingConfigReader::checkConfigFileExists()) {
+ return false;
+ }
initFrontendConfig();
- initFrontendScanConfig();
- initLnbConfig();
initFilterConfig();
- initTimeFilterConfig();
initDvrConfig();
+ initLnbConfig();
+ initTimeFilterConfig();
initDescramblerConfig();
+ connectHardwaresToTestCases();
+ if (!validateConnections()) {
+ ALOGW("[vts] failed to validate connections.");
+ return false;
+ }
+ return true;
}
AssertionResult filterDataOutputTestBase(FilterTests tests) {
@@ -53,7 +64,7 @@
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
}
@@ -75,7 +86,7 @@
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mLnbTests.setService(mService);
}
@@ -97,7 +108,7 @@
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
@@ -123,7 +134,7 @@
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
@@ -138,6 +149,29 @@
void configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf);
void testTimeFilter(TimeFilterConfig filterConf);
+ DemuxFilterType getLinkageFilterType(int bit) {
+ DemuxFilterType type;
+ type.mainType = static_cast<DemuxFilterMainType>(1 << bit);
+ switch (type.mainType) {
+ case DemuxFilterMainType::TS:
+ type.subType.tsFilterType(DemuxTsFilterType::UNDEFINED);
+ break;
+ case DemuxFilterMainType::MMTP:
+ type.subType.mmtpFilterType(DemuxMmtpFilterType::UNDEFINED);
+ break;
+ case DemuxFilterMainType::IP:
+ type.subType.ipFilterType(DemuxIpFilterType::UNDEFINED);
+ break;
+ case DemuxFilterMainType::TLV:
+ type.subType.tlvFilterType(DemuxTlvFilterType::UNDEFINED);
+ break;
+ case DemuxFilterMainType::ALP:
+ type.subType.alpFilterType(DemuxAlpFilterType::UNDEFINED);
+ break;
+ }
+ return type;
+ }
+
sp<ITuner> mService;
FrontendTests mFrontendTests;
DemuxTests mDemuxTests;
@@ -152,7 +186,7 @@
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
@@ -173,7 +207,7 @@
LnbTests mLnbTests;
DvrTests mDvrTests;
- AssertionResult filterDataOutputTest(vector<string> goldenOutputFiles);
+ AssertionResult filterDataOutputTest();
void broadcastSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf);
void broadcastSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf,
@@ -191,7 +225,7 @@
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
@@ -210,7 +244,7 @@
FilterTests mFilterTests;
DvrTests mDvrTests;
- AssertionResult filterDataOutputTest(vector<string> goldenOutputFiles);
+ AssertionResult filterDataOutputTest();
void playbackSingleFilterTest(FilterConfig filterConf, DvrConfig dvrConf);
};
@@ -223,7 +257,7 @@
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
ASSERT_NE(mService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
@@ -265,7 +299,7 @@
mCasService = IMediaCasService::getService();
ASSERT_NE(mService, nullptr);
ASSERT_NE(mCasService, nullptr);
- initConfiguration();
+ ASSERT_TRUE(initConfiguration());
mFrontendTests.setService(mService);
mDemuxTests.setService(mService);
@@ -281,7 +315,7 @@
void scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
FrontendConfig frontendConf, DescramblerConfig descConfig);
- AssertionResult filterDataOutputTest(vector<string> /*goldenOutputFiles*/);
+ AssertionResult filterDataOutputTest();
sp<ITuner> mService;
sp<IMediaCasService> mCasService;
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
index 92a8130..65f8615 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
@@ -21,372 +21,224 @@
#include <hidl/Status.h>
#include <hidlmemory/FrameworkUtils.h>
-using android::hardware::tv::tuner::V1_0::DataFormat;
-using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
-using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
+#include "../../../config/TunerTestingConfigReader.h"
+
using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
-using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
-using android::hardware::tv::tuner::V1_0::DemuxFilterType;
-using android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
-using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
-using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType;
-using android::hardware::tv::tuner::V1_0::DemuxTlvFilterType;
-using android::hardware::tv::tuner::V1_0::DemuxTpid;
using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
-using android::hardware::tv::tuner::V1_0::DvrSettings;
-using android::hardware::tv::tuner::V1_0::DvrType;
using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
-using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
-using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
-using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
-using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
-using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
using android::hardware::tv::tuner::V1_0::FrontendSettings;
using android::hardware::tv::tuner::V1_0::FrontendStatus;
using android::hardware::tv::tuner::V1_0::FrontendStatusType;
using android::hardware::tv::tuner::V1_0::FrontendType;
-using android::hardware::tv::tuner::V1_0::LnbPosition;
-using android::hardware::tv::tuner::V1_0::LnbTone;
-using android::hardware::tv::tuner::V1_0::LnbVoltage;
-using android::hardware::tv::tuner::V1_0::PlaybackSettings;
-using android::hardware::tv::tuner::V1_0::RecordSettings;
using namespace std;
+using namespace android::media::tuner::testing::configuration::V1_0;
-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;
-#define CLEAR_KEY_SYSTEM_ID 0xF6D8
-#define FILTER_MAIN_TYPE_BIT_COUNT 32
-#define PROVISION_STR \
- "{ " \
- " \"id\": 21140844, " \
- " \"name\": \"Test Title\", " \
- " \"lowercase_organization_name\": \"Android\", " \
- " \"asset_key\": { " \
- " \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\" " \
- " }, " \
- " \"cas_type\": 1, " \
- " \"track_types\": [ ] " \
- "} "
+#define FILTER_MAIN_TYPE_BIT_COUNT 5
-typedef enum {
- TS_VIDEO0,
- TS_VIDEO1,
- TS_AUDIO0,
- TS_PES0,
- TS_PCR0,
- TS_SECTION0,
- TS_TS0,
- TS_RECORD0,
- FILTER_MAX,
-} Filter;
+// Hardware configs
+static map<string, FrontendConfig> frontendMap;
+static map<string, FilterConfig> filterMap;
+static map<string, DvrConfig> dvrMap;
+static map<string, LnbConfig> lnbMap;
+static map<string, TimeFilterConfig> timeFilterMap;
+static map<string, vector<uint8_t>> diseqcMsgMap;
+static map<string, DescramblerConfig> descramblerMap;
-typedef enum {
- TIMER0,
- TIMER_MAX,
-} TimeFilter;
+// 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;
+static TimeFilterHardwareConnections timeFilter;
-typedef enum {
- SOURCE,
- SINK,
- LINKAGE_DIR,
-} Linkage;
-
-typedef enum {
- DVBT,
- DVBS,
- FRONTEND_MAX,
-} Frontend;
-
-typedef enum {
- LNB0,
- LNB_EXTERNAL,
- LNB_MAX,
-} Lnb;
-
-typedef enum {
- DISEQC_POWER_ON,
- DISEQC_MAX,
-} Diseqc;
-
-typedef enum {
- SCAN_DVBT,
- SCAN_MAX,
-} FrontendScan;
-
-typedef enum {
- DVR_RECORD0,
- DVR_PLAYBACK0,
- DVR_SOFTWARE_FE,
- DVR_MAX,
-} Dvr;
-
-typedef enum {
- DESC_0,
- DESC_MAX,
-} Descrambler;
-
-struct FilterConfig {
- uint32_t bufferSize;
- DemuxFilterType type;
- DemuxFilterSettings settings;
- bool getMqDesc;
-
- bool operator<(const FilterConfig& /*c*/) const { return false; }
-};
-
-struct TimeFilterConfig {
- bool supportTimeFilter;
- uint64_t timeStamp;
-};
-
-struct FrontendConfig {
- bool enable;
- bool isSoftwareFe;
- FrontendType type;
- FrontendSettings settings;
- vector<FrontendStatusType> tuneStatusTypes;
- vector<FrontendStatus> expectTuneStatuses;
-};
-
-struct LnbConfig {
- bool usingLnb;
- string name;
- LnbVoltage voltage;
- LnbTone tone;
- LnbPosition position;
-};
-
-struct ChannelConfig {
- int32_t frontendId;
- int32_t channelId;
- std::string channelName;
- DemuxTpid videoPid;
- DemuxTpid audioPid;
-};
-
-struct DvrConfig {
- DvrType type;
- uint32_t bufferSize;
- DvrSettings settings;
- string playbackInputFile;
-};
-
-struct DescramblerConfig {
- uint32_t casSystemId;
- string provisionStr;
- vector<uint8_t> hidlPvtData;
-};
-
-static FrontendConfig frontendArray[FILTER_MAX];
-static FrontendConfig frontendScanArray[SCAN_MAX];
-static LnbConfig lnbArray[LNB_MAX];
-static vector<uint8_t> diseqcMsgArray[DISEQC_MAX];
-static ChannelConfig channelArray[FRONTEND_MAX];
-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];
-static vector<string> goldenOutputFiles;
-static int defaultFrontend = DVBT;
-static int defaultScanFrontend = SCAN_DVBT;
-
-/** 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 when default fe is connected to any data flow
+ // without overriding in the xml config.
+ string defaultFeId = "FE_DEFAULT";
FrontendDvbtSettings dvbtSettings{
.frequency = 578000,
.transmissionMode = FrontendDvbtTransmissionMode::AUTO,
.bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ,
- .constellation = FrontendDvbtConstellation::AUTO,
- .hierarchy = FrontendDvbtHierarchy::AUTO,
- .hpCoderate = FrontendDvbtCoderate::AUTO,
- .lpCoderate = FrontendDvbtCoderate::AUTO,
- .guardInterval = FrontendDvbtGuardInterval::AUTO,
.isHighPriority = true,
- .standard = FrontendDvbtStandard::T,
};
- frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings);
+ frontendMap[defaultFeId].type = FrontendType::DVBT;
+ frontendMap[defaultFeId].settings.dvbt(dvbtSettings);
+
vector<FrontendStatusType> types;
types.push_back(FrontendStatusType::DEMOD_LOCK);
FrontendStatus status;
status.isDemodLocked(true);
vector<FrontendStatus> statuses;
statuses.push_back(status);
- 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;
+ frontendMap[defaultFeId].tuneStatusTypes = types;
+ frontendMap[defaultFeId].expectTuneStatuses = statuses;
+ frontendMap[defaultFeId].isSoftwareFe = true;
+
+ // Read customized config
+ TunerTestingConfigReader::readFrontendConfig1_0(frontendMap);
};
-/** Configuration array for the frontend scan test */
-inline void initFrontendScanConfig() {
- frontendScanArray[SCAN_DVBT].type = FrontendType::DVBT;
- frontendScanArray[SCAN_DVBT].settings.dvbt({
- .frequency = 578000,
- .transmissionMode = FrontendDvbtTransmissionMode::MODE_8K,
- .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ,
- .constellation = FrontendDvbtConstellation::AUTO,
- .hierarchy = FrontendDvbtHierarchy::AUTO,
- .hpCoderate = FrontendDvbtCoderate::AUTO,
- .lpCoderate = FrontendDvbtCoderate::AUTO,
- .guardInterval = FrontendDvbtGuardInterval::AUTO,
- .isHighPriority = true,
- .standard = FrontendDvbtStandard::T,
- });
-};
-
-/** Configuration array for the Lnb test */
-inline void initLnbConfig() {
- lnbArray[LNB0].usingLnb = true;
- lnbArray[LNB0].voltage = LnbVoltage::VOLTAGE_12V;
- lnbArray[LNB0].tone = LnbTone::NONE;
- lnbArray[LNB0].position = LnbPosition::UNDEFINED;
- lnbArray[LNB_EXTERNAL].usingLnb = true;
- lnbArray[LNB_EXTERNAL].name = "default_lnb_external";
- lnbArray[LNB_EXTERNAL].voltage = LnbVoltage::VOLTAGE_5V;
- lnbArray[LNB_EXTERNAL].tone = LnbTone::NONE;
- lnbArray[LNB_EXTERNAL].position = LnbPosition::UNDEFINED;
-};
-
-/** Diseqc messages array for the Lnb test */
-inline void initDiseqcMsg() {
- diseqcMsgArray[DISEQC_POWER_ON] = {0xE, 0x0, 0x0, 0x0, 0x0, 0x3};
-};
-
-/** Configuration array for the filter test */
inline void initFilterConfig() {
- // TS VIDEO filter setting for default implementation testing
- filterArray[TS_VIDEO0].type.mainType = DemuxFilterMainType::TS;
- filterArray[TS_VIDEO0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
- filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M;
- filterArray[TS_VIDEO0].settings.ts().tpid = 256;
- filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false});
- filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS;
- filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
- filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M;
- filterArray[TS_VIDEO1].settings.ts().tpid = 256;
- filterArray[TS_VIDEO1].settings.ts().filterSettings.av({.isPassthrough = false});
- // TS AUDIO filter setting
- filterArray[TS_AUDIO0].type.mainType = DemuxFilterMainType::TS;
- filterArray[TS_AUDIO0].type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
- filterArray[TS_AUDIO0].bufferSize = FMQ_SIZE_16M;
- filterArray[TS_AUDIO0].settings.ts().tpid = 256;
- filterArray[TS_AUDIO0].settings.ts().filterSettings.av({.isPassthrough = false});
- // TS PES filter setting
- filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS;
- filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES);
- filterArray[TS_PES0].bufferSize = FMQ_SIZE_16M;
- filterArray[TS_PES0].settings.ts().tpid = 256;
- filterArray[TS_PES0].settings.ts().filterSettings.pesData({
- .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);
- filterArray[TS_PCR0].bufferSize = FMQ_SIZE_16M;
- filterArray[TS_PCR0].settings.ts().tpid = 256;
- filterArray[TS_PCR0].settings.ts().filterSettings.noinit();
- // TS filter setting
- filterArray[TS_TS0].type.mainType = DemuxFilterMainType::TS;
- filterArray[TS_TS0].type.subType.tsFilterType(DemuxTsFilterType::TS);
- filterArray[TS_TS0].bufferSize = FMQ_SIZE_16M;
- filterArray[TS_TS0].settings.ts().tpid = 256;
- filterArray[TS_TS0].settings.ts().filterSettings.noinit();
- // TS SECTION filter setting
- filterArray[TS_SECTION0].type.mainType = DemuxFilterMainType::TS;
- filterArray[TS_SECTION0].type.subType.tsFilterType(DemuxTsFilterType::SECTION);
- filterArray[TS_SECTION0].bufferSize = FMQ_SIZE_16M;
- filterArray[TS_SECTION0].settings.ts().tpid = 256;
- 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);
- filterArray[TS_RECORD0].settings.ts().tpid = 81;
- filterArray[TS_RECORD0].settings.ts().filterSettings.record({
- .scIndexType = DemuxRecordScIndexType::NONE,
- });
+ // The test will use the internal default filter when default filter is connected to any
+ // data flow without overriding in the xml config.
+ string defaultAudioFilterId = "FILTER_AUDIO_DEFAULT";
+ string defaultVideoFilterId = "FILTER_VIDEO_DEFAULT";
- // TS Linkage filter setting
- filterLinkageTypes[SOURCE][0].mainType = DemuxFilterMainType::TS;
- filterLinkageTypes[SOURCE][0].subType.tsFilterType(DemuxTsFilterType::TS);
- filterLinkageTypes[SINK][0] = filterLinkageTypes[SOURCE][0];
- // MMTP Linkage filter setting
- filterLinkageTypes[SOURCE][1].mainType = DemuxFilterMainType::MMTP;
- filterLinkageTypes[SOURCE][1].subType.mmtpFilterType(DemuxMmtpFilterType::AUDIO);
- filterLinkageTypes[SINK][1] = filterLinkageTypes[SOURCE][1];
- // IP Linkage filter setting
- filterLinkageTypes[SOURCE][2].mainType = DemuxFilterMainType::IP;
- filterLinkageTypes[SOURCE][2].subType.ipFilterType(DemuxIpFilterType::IP);
- filterLinkageTypes[SINK][2] = filterLinkageTypes[SOURCE][2];
- // TLV Linkage filter setting
- filterLinkageTypes[SOURCE][3].mainType = DemuxFilterMainType::TLV;
- filterLinkageTypes[SOURCE][3].subType.tlvFilterType(DemuxTlvFilterType::TLV);
- filterLinkageTypes[SINK][3] = filterLinkageTypes[SOURCE][3];
- // ALP Linkage PTP filter setting
- filterLinkageTypes[SOURCE][4].mainType = DemuxFilterMainType::ALP;
- filterLinkageTypes[SOURCE][4].subType.alpFilterType(DemuxAlpFilterType::PTP);
- filterLinkageTypes[SINK][4] = filterLinkageTypes[SOURCE][4];
+ filterMap[defaultVideoFilterId].type.mainType = DemuxFilterMainType::TS;
+ filterMap[defaultVideoFilterId].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
+ filterMap[defaultVideoFilterId].bufferSize = FMQ_SIZE_16M;
+ filterMap[defaultVideoFilterId].settings.ts().tpid = 256;
+ filterMap[defaultVideoFilterId].settings.ts().filterSettings.av({.isPassthrough = false});
+
+ filterMap[defaultAudioFilterId].type.mainType = DemuxFilterMainType::TS;
+ filterMap[defaultAudioFilterId].type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
+ filterMap[defaultAudioFilterId].bufferSize = FMQ_SIZE_16M;
+ filterMap[defaultAudioFilterId].settings.ts().tpid = 256;
+ filterMap[defaultAudioFilterId].settings.ts().filterSettings.av({.isPassthrough = false});
+
+ // Read customized config
+ TunerTestingConfigReader::readFilterConfig1_0(filterMap);
};
-/** Configuration array for the timer filter test */
-inline void initTimeFilterConfig() {
- timeFilterArray[TIMER0].supportTimeFilter = true;
- timeFilterArray[TIMER0].timeStamp = 1;
-}
-
-/** Configuration array for the dvr test */
+/** Config all the dvrs that would be used in the tests */
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);
- PlaybackSettings softwareFePlaybackSettings{
- .statusMask = 0xf,
- .lowThreshold = 0x1000,
- .highThreshold = 0x07fff,
- .dataFormat = DataFormat::TS,
- .packetSize = 188,
- };
- dvrArray[DVR_SOFTWARE_FE].type = DvrType::PLAYBACK;
- dvrArray[DVR_SOFTWARE_FE].playbackInputFile = "/data/local/tmp/segment000000.ts";
- dvrArray[DVR_SOFTWARE_FE].bufferSize = FMQ_SIZE_4M;
- dvrArray[DVR_SOFTWARE_FE].settings.playback(softwareFePlaybackSettings);
+ // Read customized config
+ TunerTestingConfigReader::readDvrConfig1_0(dvrMap);
};
-/** Configuration array for the descrambler test */
-inline void initDescramblerConfig() {
- descramblerArray[DESC_0].casSystemId = CLEAR_KEY_SYSTEM_ID;
- descramblerArray[DESC_0].provisionStr = PROVISION_STR;
- descramblerArray[DESC_0].hidlPvtData.resize(256);
+/** Config all the lnbs that would be used in the tests */
+inline void initLnbConfig() {
+ // Read customized config
+ TunerTestingConfigReader::readLnbConfig1_0(lnbMap);
+ TunerTestingConfigReader::readDiseqcMessages(diseqcMsgMap);
};
+
+/** Config all the time filters that would be used in the tests */
+inline void initTimeFilterConfig() {
+ // Read customized config
+ TunerTestingConfigReader::readTimeFilterConfig1_0(timeFilterMap);
+};
+
+/** Config all the descramblers that would be used in the tests */
+inline void initDescramblerConfig() {
+ // Read customized config
+ TunerTestingConfigReader::readDescramblerConfig1_0(descramblerMap);
+};
+
+/** 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);
+ TunerTestingConfigReader::connectLnbRecord(lnbRecord);
+ TunerTestingConfigReader::connectTimeFilter(timeFilter);
+};
+
+inline bool validateConnections() {
+ bool feIsValid = frontendMap.find(live.frontendId) != frontendMap.end() &&
+ frontendMap.find(scan.frontendId) != frontendMap.end();
+ feIsValid &= record.support ? frontendMap.find(record.frontendId) != frontendMap.end() : true;
+ feIsValid &= descrambling.support
+ ? frontendMap.find(descrambling.frontendId) != frontendMap.end()
+ : true;
+ feIsValid &= lnbLive.support ? frontendMap.find(lnbLive.frontendId) != frontendMap.end() : true;
+ feIsValid &=
+ lnbRecord.support ? frontendMap.find(lnbRecord.frontendId) != frontendMap.end() : true;
+
+ 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;
+ }
+
+ bool filterIsValid = filterMap.find(live.audioFilterId) != filterMap.end() &&
+ filterMap.find(live.videoFilterId) != filterMap.end();
+ filterIsValid &= playback.support
+ ? (filterMap.find(playback.audioFilterId) != filterMap.end() &&
+ filterMap.find(playback.videoFilterId) != filterMap.end())
+ : true;
+ filterIsValid &=
+ record.support ? filterMap.find(record.recordFilterId) != filterMap.end() : true;
+ filterIsValid &= descrambling.support
+ ? (filterMap.find(descrambling.audioFilterId) != filterMap.end() &&
+ filterMap.find(descrambling.videoFilterId) != filterMap.end())
+ : true;
+ filterIsValid &= lnbLive.support ? (filterMap.find(lnbLive.audioFilterId) != filterMap.end() &&
+ filterMap.find(lnbLive.videoFilterId) != filterMap.end())
+ : true;
+ filterIsValid &=
+ lnbRecord.support ? filterMap.find(lnbRecord.recordFilterId) != filterMap.end() : true;
+
+ if (!filterIsValid) {
+ ALOGW("[vts config] dynamic config filter connection is invalid.");
+ return false;
+ }
+
+ bool lnbIsValid = lnbLive.support ? lnbMap.find(lnbLive.lnbId) != lnbMap.end() : true;
+ lnbIsValid &= lnbRecord.support ? lnbMap.find(lnbRecord.lnbId) != lnbMap.end() : true;
+
+ if (!lnbIsValid) {
+ ALOGW("[vts config] dynamic config lnb connection is invalid.");
+ return false;
+ }
+
+ bool descramblerIsValid =
+ descrambling.support
+ ? descramblerMap.find(descrambling.descramblerId) != descramblerMap.end()
+ : true;
+
+ if (!descramblerIsValid) {
+ ALOGW("[vts config] dynamic config descrambler connection is invalid.");
+ return false;
+ }
+
+ bool diseqcMsgIsValid = true;
+ if (lnbLive.support) {
+ for (auto msgName : lnbLive.diseqcMsgs) {
+ diseqcMsgIsValid &= diseqcMsgMap.find(msgName) != diseqcMsgMap.end();
+ }
+ }
+ if (lnbRecord.support) {
+ for (auto msgName : lnbRecord.diseqcMsgs) {
+ diseqcMsgIsValid &= diseqcMsgMap.find(msgName) != diseqcMsgMap.end();
+ }
+ }
+
+ if (!diseqcMsgIsValid) {
+ ALOGW("[vts config] dynamic config diseqcMsg sender is invalid.");
+ return false;
+ }
+
+ return true;
+}
diff --git a/tv/tuner/assets/Android.bp b/tv/tuner/assets/Android.bp
new file mode 100644
index 0000000..79244ed
--- /dev/null
+++ b/tv/tuner/assets/Android.bp
@@ -0,0 +1,26 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+genrule {
+ name: "tuner_frontend_input_es",
+ srcs: ["tuner_frontend_input.es"],
+ out: [
+ "test.es",
+ ],
+ cmd: "cp -f $(in) $(genDir)/test.es",
+}
+
+genrule {
+ name: "tuner_frontend_input_ts",
+ srcs: ["tuner_frontend_input.ts"],
+ out: [
+ "segment000000.ts",
+ ],
+ cmd: "cp -f $(in) $(genDir)/segment000000.ts",
+}
diff --git a/tv/tuner/assets/tuner_frontend_input.es b/tv/tuner/assets/tuner_frontend_input.es
new file mode 100644
index 0000000..b53c957
--- /dev/null
+++ b/tv/tuner/assets/tuner_frontend_input.es
Binary files differ
diff --git a/tv/tuner/assets/tuner_frontend_input.ts b/tv/tuner/assets/tuner_frontend_input.ts
new file mode 100644
index 0000000..8992c7b
--- /dev/null
+++ b/tv/tuner/assets/tuner_frontend_input.ts
Binary files differ
diff --git a/tv/tuner/config/Android.bp b/tv/tuner/config/Android.bp
new file mode 100644
index 0000000..ddbf3a7
--- /dev/null
+++ b/tv/tuner/config/Android.bp
@@ -0,0 +1,31 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+ name: "tuner_testing_dynamic_configuration_V1_0",
+ srcs: ["tuner_testing_dynamic_configuration.xsd"],
+ package_name: "android.media.tuner.testing.configuration.V1_0",
+ nullability: true,
+}
+
+xsd_config {
+ name: "tuner_testing_dynamic_configuration_V1_0_enums",
+ srcs: ["tuner_testing_dynamic_configuration.xsd"],
+ package_name: "android.media.tuner.testing.configuration.V1_0",
+ nullability: true,
+ enums_only: true,
+}
+
+xsd_config {
+ name: "tuner_testing_dynamic_configuration_V1_0_parser",
+ srcs: ["tuner_testing_dynamic_configuration.xsd"],
+ package_name: "android.media.tuner.testing.configuration.V1_0",
+ nullability: true,
+ parser_only: true,
+}
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
new file mode 100644
index 0000000..90499c4
--- /dev/null
+++ b/tv/tuner/config/TunerTestingConfigReader.h
@@ -0,0 +1,732 @@
+/*
+ * 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 <android-base/logging.h>
+#include <android/hardware/tv/tuner/1.0/types.h>
+#include <android_media_tuner_testing_configuration_V1_0.h>
+#include <android_media_tuner_testing_configuration_V1_0_enums.h>
+#include <binder/MemoryDealer.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+
+using namespace std;
+using namespace android::media::tuner::testing::configuration::V1_0;
+
+using android::hardware::tv::tuner::V1_0::DataFormat;
+using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
+using android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType;
+using android::hardware::tv::tuner::V1_0::DemuxTlvFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxTpid;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
+using android::hardware::tv::tuner::V1_0::DvrSettings;
+using android::hardware::tv::tuner::V1_0::DvrType;
+using android::hardware::tv::tuner::V1_0::FrontendDvbsSettings;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
+using android::hardware::tv::tuner::V1_0::FrontendSettings;
+using android::hardware::tv::tuner::V1_0::FrontendStatus;
+using android::hardware::tv::tuner::V1_0::FrontendStatusType;
+using android::hardware::tv::tuner::V1_0::FrontendType;
+using android::hardware::tv::tuner::V1_0::LnbPosition;
+using android::hardware::tv::tuner::V1_0::LnbTone;
+using android::hardware::tv::tuner::V1_0::LnbVoltage;
+using android::hardware::tv::tuner::V1_0::PlaybackSettings;
+using android::hardware::tv::tuner::V1_0::RecordSettings;
+
+const string configFilePath = "/vendor/etc/tuner_vts_config.xml";
+const string emptyHardwareId = "";
+
+#define PROVISION_STR \
+ "{ " \
+ " \"id\": 21140844, " \
+ " \"name\": \"Test Title\", " \
+ " \"lowercase_organization_name\": \"Android\", " \
+ " \"asset_key\": { " \
+ " \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\" " \
+ " }, " \
+ " \"cas_type\": 1, " \
+ " \"track_types\": [ ] " \
+ "} "
+
+struct FrontendConfig {
+ bool isSoftwareFe;
+ FrontendType type;
+ FrontendSettings settings;
+ vector<FrontendStatusType> tuneStatusTypes;
+ vector<FrontendStatus> expectTuneStatuses;
+};
+
+struct FilterConfig {
+ uint32_t bufferSize;
+ DemuxFilterType type;
+ DemuxFilterSettings settings;
+ bool getMqDesc;
+
+ bool operator<(const FilterConfig& /*c*/) const { return false; }
+};
+
+struct DvrConfig {
+ DvrType type;
+ uint32_t bufferSize;
+ DvrSettings settings;
+ string playbackInputFile;
+};
+
+struct LnbConfig {
+ string name;
+ LnbVoltage voltage;
+ LnbTone tone;
+ LnbPosition position;
+};
+
+struct TimeFilterConfig {
+ uint64_t timeStamp;
+};
+
+struct DescramblerConfig {
+ uint32_t casSystemId;
+ string provisionStr;
+ vector<uint8_t> hidlPvtData;
+};
+
+struct LiveBroadcastHardwareConnections {
+ string frontendId;
+ string dvrSoftwareFeId;
+ string audioFilterId;
+ string videoFilterId;
+ string sectionFilterId;
+ string pcrFilterId;
+ /* list string of extra filters; */
+};
+
+struct ScanHardwareConnections {
+ string frontendId;
+};
+
+struct DvrPlaybackHardwareConnections {
+ bool support;
+ string frontendId;
+ string dvrId;
+ string audioFilterId;
+ string videoFilterId;
+ string sectionFilterId;
+ /* list string of extra filters; */
+};
+
+struct DvrRecordHardwareConnections {
+ bool support;
+ string frontendId;
+ string dvrRecordId;
+ string dvrSoftwareFeId;
+ string recordFilterId;
+};
+
+struct DescramblingHardwareConnections {
+ bool support;
+ string frontendId;
+ string dvrSoftwareFeId;
+ string audioFilterId;
+ string videoFilterId;
+ string descramblerId;
+ /* list string of extra filters; */
+};
+
+struct LnbLiveHardwareConnections {
+ bool support;
+ string frontendId;
+ string audioFilterId;
+ string videoFilterId;
+ string lnbId;
+ vector<string> diseqcMsgs;
+ /* list string of extra filters; */
+};
+
+struct LnbRecordHardwareConnections {
+ bool support;
+ string frontendId;
+ string dvrRecordId;
+ string recordFilterId;
+ string lnbId;
+ vector<string> diseqcMsgs;
+ /* list string of extra filters; */
+};
+
+struct TimeFilterHardwareConnections {
+ bool support;
+ string timeFilterId;
+};
+
+struct TunerTestingConfigReader {
+ public:
+ static bool checkConfigFileExists() {
+ auto res = read(configFilePath.c_str());
+ if (res == nullopt) {
+ ALOGW("[ConfigReader] Couldn't read /vendor/etc/tuner_vts_config.xml."
+ "Please check tuner_testing_dynamic_configuration.xsd"
+ "and sample_tuner_vts_config.xml for more details on how to config Tune VTS.");
+ }
+ return (res != nullopt);
+ }
+
+ static void readFrontendConfig1_0(map<string, FrontendConfig>& frontendMap) {
+ auto hardwareConfig = getHardwareConfig();
+ if (hardwareConfig.hasFrontends()) {
+ // TODO: b/182519645 complete the tune status config
+ vector<FrontendStatusType> types;
+ types.push_back(FrontendStatusType::DEMOD_LOCK);
+ FrontendStatus status;
+ status.isDemodLocked(true);
+ vector<FrontendStatus> statuses;
+ statuses.push_back(status);
+
+ auto frontends = *hardwareConfig.getFirstFrontends();
+ for (auto feConfig : frontends.getFrontend()) {
+ string id = feConfig.getId();
+ if (id.compare(string("FE_DEFAULT")) == 0) {
+ // overrid default
+ frontendMap.erase(string("FE_DEFAULT"));
+ }
+ FrontendType type;
+ switch (feConfig.getType()) {
+ case FrontendTypeEnum::UNDEFINED:
+ type = FrontendType::UNDEFINED;
+ break;
+ // TODO: b/182519645 finish all other frontend settings
+ case FrontendTypeEnum::ANALOG:
+ type = FrontendType::ANALOG;
+ break;
+ case FrontendTypeEnum::ATSC:
+ type = FrontendType::ATSC;
+ break;
+ case FrontendTypeEnum::ATSC3:
+ type = FrontendType::ATSC3;
+ break;
+ case FrontendTypeEnum::DVBC:
+ type = FrontendType::DVBC;
+ break;
+ case FrontendTypeEnum::DVBS:
+ type = FrontendType::DVBS;
+ frontendMap[id].settings.dvbs(readDvbsFrontendSettings(feConfig));
+ break;
+ case FrontendTypeEnum::DVBT: {
+ type = FrontendType::DVBT;
+ frontendMap[id].settings.dvbt(readDvbtFrontendSettings(feConfig));
+ break;
+ }
+ case FrontendTypeEnum::ISDBS:
+ type = FrontendType::ISDBS;
+ break;
+ case FrontendTypeEnum::ISDBS3:
+ type = FrontendType::ISDBS3;
+ break;
+ case FrontendTypeEnum::ISDBT:
+ type = FrontendType::ISDBT;
+ break;
+ case FrontendTypeEnum::DTMB:
+ // dtmb will be handled in readFrontendConfig1_1;
+ continue;
+ case FrontendTypeEnum::UNKNOWN:
+ ALOGW("[ConfigReader] invalid frontend type");
+ return;
+ }
+ frontendMap[id].type = type;
+ frontendMap[id].isSoftwareFe = feConfig.getIsSoftwareFrontend();
+ // TODO: b/182519645 complete the tune status config
+ frontendMap[id].tuneStatusTypes = types;
+ frontendMap[id].expectTuneStatuses = statuses;
+ }
+ }
+ }
+
+ static void readFilterConfig1_0(map<string, FilterConfig>& filterMap) {
+ auto hardwareConfig = getHardwareConfig();
+ if (hardwareConfig.hasFilters()) {
+ auto filters = *hardwareConfig.getFirstFilters();
+ for (auto filterConfig : filters.getFilter()) {
+ string id = filterConfig.getId();
+ if (id.compare(string("FILTER_AUDIO_DEFAULT")) == 0) {
+ // overrid default
+ filterMap.erase(string("FILTER_AUDIO_DEFAULT"));
+ }
+ if (id.compare(string("FILTER_VIDEO_DEFAULT")) == 0) {
+ // overrid default
+ filterMap.erase(string("FILTER_VIDEO_DEFAULT"));
+ }
+
+ DemuxFilterType type;
+ DemuxFilterSettings settings;
+ if (!readFilterTypeAndSettings(filterConfig, type, settings)) {
+ ALOGW("[ConfigReader] invalid filter type");
+ return;
+ }
+ filterMap[id].type = type;
+ filterMap[id].bufferSize = filterConfig.getBufferSize();
+ filterMap[id].getMqDesc = filterConfig.getUseFMQ();
+ filterMap[id].settings = settings;
+ }
+ }
+ }
+
+ 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 readLnbConfig1_0(map<string, LnbConfig>& lnbMap) {
+ auto hardwareConfig = getHardwareConfig();
+ if (hardwareConfig.hasLnbs()) {
+ auto lnbs = *hardwareConfig.getFirstLnbs();
+ for (auto lnbConfig : lnbs.getLnb()) {
+ string id = lnbConfig.getId();
+ if (lnbConfig.hasName()) {
+ lnbMap[id].name = lnbConfig.getName();
+ } else {
+ lnbMap[id].name = emptyHardwareId;
+ }
+ lnbMap[id].voltage = static_cast<LnbVoltage>(lnbConfig.getVoltage());
+ lnbMap[id].tone = static_cast<LnbTone>(lnbConfig.getTone());
+ lnbMap[id].position = static_cast<LnbPosition>(lnbConfig.getPosition());
+ }
+ }
+ }
+
+ static void readDescramblerConfig1_0(map<string, DescramblerConfig>& descramblerMap) {
+ auto hardwareConfig = getHardwareConfig();
+ if (hardwareConfig.hasDescramblers()) {
+ auto descramblers = *hardwareConfig.getFirstDescramblers();
+ for (auto descramblerConfig : descramblers.getDescrambler()) {
+ string id = descramblerConfig.getId();
+ descramblerMap[id].casSystemId =
+ static_cast<uint32_t>(descramblerConfig.getCasSystemId());
+ if (descramblerConfig.hasProvisionStr()) {
+ descramblerMap[id].provisionStr = descramblerConfig.getProvisionStr();
+ } else {
+ descramblerMap[id].provisionStr = PROVISION_STR;
+ }
+ if (descramblerConfig.hasSesstionPrivatData()) {
+ auto privateData = descramblerConfig.getSesstionPrivatData();
+ int size = privateData.size();
+ descramblerMap[id].hidlPvtData.resize(size);
+ memcpy(descramblerMap[id].hidlPvtData.data(), privateData.data(), size);
+ } else {
+ descramblerMap[id].hidlPvtData.resize(256);
+ }
+ }
+ }
+ }
+
+ static void readDiseqcMessages(map<string, vector<uint8_t>>& diseqcMsgMap) {
+ auto hardwareConfig = getHardwareConfig();
+ if (hardwareConfig.hasDiseqcMessages()) {
+ auto msgs = *hardwareConfig.getFirstDiseqcMessages();
+ for (auto msgConfig : msgs.getDiseqcMessage()) {
+ string name = msgConfig.getMsgName();
+ for (uint8_t atom : msgConfig.getMsgBody()) {
+ diseqcMsgMap[name].push_back(atom);
+ }
+ }
+ }
+ }
+
+ static void readTimeFilterConfig1_0(map<string, TimeFilterConfig>& timeFilterMap) {
+ auto hardwareConfig = getHardwareConfig();
+ if (hardwareConfig.hasTimeFilters()) {
+ auto timeFilters = *hardwareConfig.getFirstTimeFilters();
+ for (auto timeFilterConfig : timeFilters.getTimeFilter()) {
+ string id = timeFilterConfig.getId();
+ timeFilterMap[id].timeStamp =
+ static_cast<uint64_t>(timeFilterConfig.getTimeStamp());
+ }
+ }
+ }
+
+ static void connectLiveBroadcast(LiveBroadcastHardwareConnections& live) {
+ auto liveConfig = *getDataFlowConfiguration().getFirstClearLiveBroadcast();
+ live.frontendId = liveConfig.getFrontendConnection();
+
+ live.audioFilterId = liveConfig.getAudioFilterConnection();
+ live.videoFilterId = liveConfig.getVideoFilterConnection();
+ if (liveConfig.hasPcrFilterConnection()) {
+ live.pcrFilterId = liveConfig.getPcrFilterConnection();
+ } else {
+ live.pcrFilterId = emptyHardwareId;
+ }
+ if (liveConfig.hasSectionFilterConnection()) {
+ live.sectionFilterId = liveConfig.getSectionFilterConnection();
+ } else {
+ live.sectionFilterId = emptyHardwareId;
+ }
+ if (liveConfig.hasDvrSoftwareFeConnection()) {
+ live.dvrSoftwareFeId = liveConfig.getDvrSoftwareFeConnection();
+ }
+ }
+
+ static void connectScan(ScanHardwareConnections& scan) {
+ auto scanConfig = getDataFlowConfiguration().getFirstScan();
+ scan.frontendId = scanConfig->getFrontendConnection();
+ }
+
+ static void connectDvrPlayback(DvrPlaybackHardwareConnections& playback) {
+ auto dataFlow = getDataFlowConfiguration();
+ if (dataFlow.hasDvrPlayback()) {
+ playback.support = true;
+ } else {
+ return;
+ }
+ auto playbackConfig = *dataFlow.getFirstDvrPlayback();
+ playback.dvrId = playbackConfig.getDvrConnection();
+ playback.audioFilterId = playbackConfig.getAudioFilterConnection();
+ playback.videoFilterId = playbackConfig.getVideoFilterConnection();
+ if (playbackConfig.hasSectionFilterConnection()) {
+ playback.sectionFilterId = playbackConfig.getSectionFilterConnection();
+ } else {
+ playback.sectionFilterId = emptyHardwareId;
+ }
+ }
+
+ static void connectDvrRecord(DvrRecordHardwareConnections& record) {
+ auto dataFlow = getDataFlowConfiguration();
+ if (dataFlow.hasDvrRecord()) {
+ record.support = true;
+ } else {
+ return;
+ }
+ auto recordConfig = *dataFlow.getFirstDvrRecord();
+ record.frontendId = recordConfig.getFrontendConnection();
+ record.recordFilterId = recordConfig.getRecordFilterConnection();
+ record.dvrRecordId = recordConfig.getDvrRecordConnection();
+ if (recordConfig.hasDvrSoftwareFeConnection()) {
+ record.dvrSoftwareFeId = recordConfig.getDvrSoftwareFeConnection();
+ }
+ }
+
+ static void connectDescrambling(DescramblingHardwareConnections& descrambling) {
+ auto dataFlow = getDataFlowConfiguration();
+ if (dataFlow.hasDescrambling()) {
+ descrambling.support = true;
+ } else {
+ return;
+ }
+ auto descConfig = *dataFlow.getFirstDescrambling();
+ descrambling.frontendId = descConfig.getFrontendConnection();
+ descrambling.descramblerId = descConfig.getDescramblerConnection();
+ descrambling.audioFilterId = descConfig.getAudioFilterConnection();
+ descrambling.videoFilterId = descConfig.getVideoFilterConnection();
+ if (descConfig.hasDvrSoftwareFeConnection()) {
+ descrambling.dvrSoftwareFeId = descConfig.getDvrSoftwareFeConnection();
+ }
+ }
+
+ static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) {
+ auto dataFlow = getDataFlowConfiguration();
+ if (dataFlow.hasLnbLive()) {
+ lnbLive.support = true;
+ } else {
+ return;
+ }
+ auto lnbLiveConfig = *dataFlow.getFirstLnbLive();
+ lnbLive.frontendId = lnbLiveConfig.getFrontendConnection();
+ lnbLive.audioFilterId = lnbLiveConfig.getAudioFilterConnection();
+ lnbLive.videoFilterId = lnbLiveConfig.getVideoFilterConnection();
+ lnbLive.lnbId = lnbLiveConfig.getLnbConnection();
+ if (lnbLiveConfig.hasDiseqcMsgSender()) {
+ for (auto msgName : lnbLiveConfig.getDiseqcMsgSender()) {
+ lnbLive.diseqcMsgs.push_back(msgName);
+ }
+ }
+ }
+
+ static void connectLnbRecord(LnbRecordHardwareConnections& lnbRecord) {
+ auto dataFlow = getDataFlowConfiguration();
+ if (dataFlow.hasLnbRecord()) {
+ lnbRecord.support = true;
+ } else {
+ return;
+ }
+ auto lnbRecordConfig = *dataFlow.getFirstLnbRecord();
+ lnbRecord.frontendId = lnbRecordConfig.getFrontendConnection();
+ lnbRecord.recordFilterId = lnbRecordConfig.getRecordFilterConnection();
+ lnbRecord.dvrRecordId = lnbRecordConfig.getDvrRecordConnection();
+ lnbRecord.lnbId = lnbRecordConfig.getLnbConnection();
+ if (lnbRecordConfig.hasDiseqcMsgSender()) {
+ for (auto msgName : lnbRecordConfig.getDiseqcMsgSender()) {
+ lnbRecord.diseqcMsgs.push_back(msgName);
+ }
+ }
+ }
+
+ static void connectTimeFilter(TimeFilterHardwareConnections& timeFilter) {
+ auto dataFlow = getDataFlowConfiguration();
+ if (dataFlow.hasTimeFilter()) {
+ timeFilter.support = true;
+ } else {
+ return;
+ }
+ auto timeFilterConfig = *dataFlow.getFirstTimeFilter();
+ timeFilter.timeFilterId = timeFilterConfig.getTimeFilterConnection();
+ }
+
+ private:
+ static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) {
+ ALOGW("[ConfigReader] fe type is dvbt");
+ FrontendDvbtSettings dvbtSettings{
+ .frequency = (uint32_t)feConfig.getFrequency(),
+ };
+ if (!feConfig.hasDvbtFrontendSettings_optional()) {
+ ALOGW("[ConfigReader] no more dvbt settings");
+ return dvbtSettings;
+ }
+ dvbtSettings.transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
+ feConfig.getFirstDvbtFrontendSettings_optional()->getTransmissionMode());
+ dvbtSettings.bandwidth = static_cast<FrontendDvbtBandwidth>(
+ feConfig.getFirstDvbtFrontendSettings_optional()->getBandwidth());
+ dvbtSettings.isHighPriority =
+ feConfig.getFirstDvbtFrontendSettings_optional()->getIsHighPriority();
+ return dvbtSettings;
+ }
+
+ static FrontendDvbsSettings readDvbsFrontendSettings(Frontend feConfig) {
+ ALOGW("[ConfigReader] fe type is dvbs");
+ FrontendDvbsSettings dvbsSettings{
+ .frequency = (uint32_t)feConfig.getFrequency(),
+ };
+ if (!feConfig.hasDvbsFrontendSettings_optional()) {
+ ALOGW("[ConfigReader] no more dvbs settings");
+ return dvbsSettings;
+ }
+ dvbsSettings.symbolRate = static_cast<uint32_t>(
+ feConfig.getFirstDvbsFrontendSettings_optional()->getSymbolRate());
+ dvbsSettings.inputStreamId = static_cast<uint32_t>(
+ feConfig.getFirstDvbsFrontendSettings_optional()->getInputStreamId());
+ return dvbsSettings;
+ }
+
+ static bool readFilterTypeAndSettings(Filter filterConfig, DemuxFilterType& type,
+ DemuxFilterSettings& settings) {
+ auto mainType = filterConfig.getMainType();
+ auto subType = filterConfig.getSubType();
+ uint32_t pid = static_cast<uint32_t>(filterConfig.getPid());
+ switch (mainType) {
+ case FilterMainTypeEnum::TS: {
+ ALOGW("[ConfigReader] filter main type is ts");
+ type.mainType = DemuxFilterMainType::TS;
+ switch (subType) {
+ case FilterSubTypeEnum::UNDEFINED:
+ break;
+ case FilterSubTypeEnum::SECTION:
+ type.subType.tsFilterType(DemuxTsFilterType::SECTION);
+ settings.ts().filterSettings.section(
+ readSectionFilterSettings(filterConfig));
+ break;
+ case FilterSubTypeEnum::PES:
+ // TODO: b/182519645 support all the filter settings
+ /*settings.ts().filterSettings.pesData(
+ getPesFilterSettings(filterConfig));*/
+ type.subType.tsFilterType(DemuxTsFilterType::PES);
+ break;
+ case FilterSubTypeEnum::TS:
+ type.subType.tsFilterType(DemuxTsFilterType::TS);
+ settings.ts().filterSettings.noinit();
+ break;
+ case FilterSubTypeEnum::PCR:
+ type.subType.tsFilterType(DemuxTsFilterType::PCR);
+ settings.ts().filterSettings.noinit();
+ break;
+ case FilterSubTypeEnum::TEMI:
+ type.subType.tsFilterType(DemuxTsFilterType::TEMI);
+ settings.ts().filterSettings.noinit();
+ break;
+ case FilterSubTypeEnum::AUDIO:
+ type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
+ settings.ts().filterSettings.av(readAvFilterSettings(filterConfig));
+ break;
+ case FilterSubTypeEnum::VIDEO:
+ type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
+ settings.ts().filterSettings.av(readAvFilterSettings(filterConfig));
+ break;
+ case FilterSubTypeEnum::RECORD:
+ type.subType.tsFilterType(DemuxTsFilterType::RECORD);
+ settings.ts().filterSettings.record(readRecordFilterSettings(filterConfig));
+ break;
+ default:
+ ALOGW("[ConfigReader] ts subtype is not supported");
+ return false;
+ }
+ settings.ts().tpid = pid;
+ break;
+ }
+ case FilterMainTypeEnum::MMTP: {
+ ALOGW("[ConfigReader] filter main type is mmtp");
+ type.mainType = DemuxFilterMainType::MMTP;
+ switch (subType) {
+ case FilterSubTypeEnum::UNDEFINED:
+ break;
+ case FilterSubTypeEnum::SECTION:
+ type.subType.mmtpFilterType(DemuxMmtpFilterType::SECTION);
+ settings.mmtp().filterSettings.section(
+ readSectionFilterSettings(filterConfig));
+ break;
+ case FilterSubTypeEnum::PES:
+ type.subType.mmtpFilterType(DemuxMmtpFilterType::PES);
+ // TODO: b/182519645 support all the filter settings
+ /*settings.mmtp().filterSettings.pesData(
+ getPesFilterSettings(filterConfig));*/
+ break;
+ case FilterSubTypeEnum::MMTP:
+ type.subType.mmtpFilterType(DemuxMmtpFilterType::MMTP);
+ settings.mmtp().filterSettings.noinit();
+ break;
+ case FilterSubTypeEnum::AUDIO:
+ type.subType.mmtpFilterType(DemuxMmtpFilterType::AUDIO);
+ settings.mmtp().filterSettings.av(readAvFilterSettings(filterConfig));
+ break;
+ case FilterSubTypeEnum::VIDEO:
+ settings.mmtp().filterSettings.av(readAvFilterSettings(filterConfig));
+ break;
+ case FilterSubTypeEnum::RECORD:
+ type.subType.mmtpFilterType(DemuxMmtpFilterType::RECORD);
+ settings.mmtp().filterSettings.record(
+ readRecordFilterSettings(filterConfig));
+ break;
+ case FilterSubTypeEnum::DOWNLOAD:
+ type.subType.mmtpFilterType(DemuxMmtpFilterType::DOWNLOAD);
+ // TODO: b/182519645 support all the filter settings
+ /*settings.mmtp().filterSettings.download(
+ getDownloadFilterSettings(filterConfig));*/
+ break;
+ default:
+ ALOGW("[ConfigReader] mmtp subtype is not supported");
+ return false;
+ }
+ settings.mmtp().mmtpPid = pid;
+ break;
+ }
+ default:
+ // TODO: b/182519645 support all the filter configs
+ ALOGW("[ConfigReader] filter main type is not supported in dynamic config");
+ return false;
+ }
+ return true;
+ }
+
+ static DemuxFilterSectionSettings readSectionFilterSettings(Filter filterConfig) {
+ DemuxFilterSectionSettings settings;
+ if (!filterConfig.hasSectionFilterSettings_optional()) {
+ return settings;
+ }
+ auto section = filterConfig.getFirstSectionFilterSettings_optional();
+ settings.isCheckCrc = section->getIsCheckCrc();
+ settings.isRepeat = section->getIsRepeat();
+ settings.isRaw = section->getIsRaw();
+ return settings;
+ }
+
+ static DemuxFilterAvSettings readAvFilterSettings(Filter filterConfig) {
+ DemuxFilterAvSettings settings;
+ if (!filterConfig.hasAvFilterSettings_optional()) {
+ return settings;
+ }
+ auto av = filterConfig.getFirstAvFilterSettings_optional();
+ settings.isPassthrough = av->getIsPassthrough();
+ return settings;
+ }
+
+ static DemuxFilterRecordSettings readRecordFilterSettings(Filter filterConfig) {
+ DemuxFilterRecordSettings settings;
+ if (!filterConfig.hasRecordFilterSettings_optional()) {
+ return settings;
+ }
+ auto record = filterConfig.getFirstRecordFilterSettings_optional();
+ settings.tsIndexMask = static_cast<uint32_t>(record->getTsIndexMask());
+ settings.scIndexType = static_cast<DemuxRecordScIndexType>(record->getScIndexType());
+ return settings;
+ }
+
+ 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() {
+ return *getTunerConfig().getFirstHardwareConfiguration();
+ }
+
+ static DataFlowConfiguration getDataFlowConfiguration() {
+ return *getTunerConfig().getFirstDataFlowConfiguration();
+ }
+};
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
new file mode 100644
index 0000000..4255a60
--- /dev/null
+++ b/tv/tuner/config/api/current.txt
@@ -0,0 +1,433 @@
+// Signature format: 2.0
+package android.media.tuner.testing.configuration.V1_0 {
+
+ public class AvFilterSettings {
+ ctor public AvFilterSettings();
+ method @Nullable public boolean getIsPassthrough();
+ method public void setIsPassthrough(@Nullable boolean);
+ }
+
+ public class DataFlowConfiguration {
+ 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 @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.TimeFilter getTimeFilter();
+ 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);
+ method public void setScan(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.Scan);
+ method public void setTimeFilter(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration.TimeFilter);
+ }
+
+ public static class DataFlowConfiguration.ClearLiveBroadcast {
+ ctor public DataFlowConfiguration.ClearLiveBroadcast();
+ method @Nullable public String getAudioFilterConnection();
+ method @Nullable public String getDvrSoftwareFeConnection();
+ method @Nullable public String getFrontendConnection();
+ method @Nullable public String getPcrFilterConnection();
+ method @Nullable public String getSectionFilterConnection();
+ method @Nullable public String getVideoFilterConnection();
+ method public void setAudioFilterConnection(@Nullable String);
+ method public void setDvrSoftwareFeConnection(@Nullable String);
+ method public void setFrontendConnection(@Nullable String);
+ method public void setPcrFilterConnection(@Nullable String);
+ method public void setSectionFilterConnection(@Nullable String);
+ method public void setVideoFilterConnection(@Nullable String);
+ }
+
+ public static class DataFlowConfiguration.Descrambling {
+ ctor public DataFlowConfiguration.Descrambling();
+ method @Nullable public String getAudioFilterConnection();
+ method @Nullable public String getDescramblerConnection();
+ method @Nullable public String getDvrSoftwareFeConnection();
+ method @Nullable public String getFrontendConnection();
+ method @Nullable public String getVideoFilterConnection();
+ method public void setAudioFilterConnection(@Nullable String);
+ method public void setDescramblerConnection(@Nullable String);
+ method public void setDvrSoftwareFeConnection(@Nullable String);
+ method public void setFrontendConnection(@Nullable String);
+ method public void setVideoFilterConnection(@Nullable String);
+ }
+
+ public static class DataFlowConfiguration.DvrPlayback {
+ ctor public DataFlowConfiguration.DvrPlayback();
+ method @Nullable public String getAudioFilterConnection();
+ method @Nullable public String getDvrConnection();
+ method @Nullable public String getSectionFilterConnection();
+ method @Nullable public String getVideoFilterConnection();
+ method public void setAudioFilterConnection(@Nullable String);
+ method public void setDvrConnection(@Nullable String);
+ method public void setSectionFilterConnection(@Nullable String);
+ method public void setVideoFilterConnection(@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 @Nullable public String getRecordFilterConnection();
+ method public void setDvrRecordConnection(@Nullable String);
+ method public void setDvrSoftwareFeConnection(@Nullable String);
+ method public void setFrontendConnection(@Nullable String);
+ method public void setRecordFilterConnection(@Nullable String);
+ }
+
+ public static class DataFlowConfiguration.LnbLive {
+ ctor public DataFlowConfiguration.LnbLive();
+ method @Nullable public String getAudioFilterConnection();
+ method @Nullable public java.util.List<java.lang.String> getDiseqcMsgSender();
+ method @Nullable public String getFrontendConnection();
+ method @Nullable public String getLnbConnection();
+ method @Nullable public String getVideoFilterConnection();
+ method public void setAudioFilterConnection(@Nullable String);
+ method public void setDiseqcMsgSender(@Nullable java.util.List<java.lang.String>);
+ method public void setFrontendConnection(@Nullable String);
+ method public void setLnbConnection(@Nullable String);
+ method public void setVideoFilterConnection(@Nullable String);
+ }
+
+ public static class DataFlowConfiguration.LnbRecord {
+ ctor public DataFlowConfiguration.LnbRecord();
+ method @Nullable public java.util.List<java.lang.String> getDiseqcMsgSender();
+ method @Nullable public String getDvrRecordConnection();
+ method @Nullable public String getFrontendConnection();
+ method @Nullable public String getLnbConnection();
+ method @Nullable public String getRecordFilterConnection();
+ method public void setDiseqcMsgSender(@Nullable java.util.List<java.lang.String>);
+ method public void setDvrRecordConnection(@Nullable String);
+ method public void setFrontendConnection(@Nullable String);
+ method public void setLnbConnection(@Nullable String);
+ method public void setRecordFilterConnection(@Nullable String);
+ }
+
+ public static class DataFlowConfiguration.Scan {
+ ctor public DataFlowConfiguration.Scan();
+ method @Nullable public String getFrontendConnection();
+ method public void setFrontendConnection(@Nullable String);
+ }
+
+ public static class DataFlowConfiguration.TimeFilter {
+ ctor public DataFlowConfiguration.TimeFilter();
+ method @Nullable public String getTimeFilterConnection();
+ method public void setTimeFilterConnection(@Nullable String);
+ }
+
+ public class Descrambler {
+ ctor public Descrambler();
+ method @Nullable public java.math.BigInteger getCasSystemId();
+ method @Nullable public String getId();
+ method @Nullable public String getProvisionStr();
+ method @Nullable public java.util.List<java.lang.Short> getSesstionPrivatData();
+ method public void setCasSystemId(@Nullable java.math.BigInteger);
+ method public void setId(@Nullable String);
+ method public void setProvisionStr(@Nullable String);
+ method public void setSesstionPrivatData(@Nullable java.util.List<java.lang.Short>);
+ }
+
+ public class DiseqcMessage {
+ ctor public DiseqcMessage();
+ method @Nullable public java.util.List<java.lang.Short> getMsgBody();
+ method @Nullable public String getMsgName();
+ method public void setMsgBody(@Nullable java.util.List<java.lang.Short>);
+ method public void setMsgName(@Nullable String);
+ }
+
+ public class DvbsFrontendSettings {
+ ctor public DvbsFrontendSettings();
+ method @Nullable public java.math.BigInteger getInputStreamId();
+ method @Nullable public java.math.BigInteger getSymbolRate();
+ method public void setInputStreamId(@Nullable java.math.BigInteger);
+ method public void setSymbolRate(@Nullable java.math.BigInteger);
+ }
+
+ public class DvbtFrontendSettings {
+ ctor public DvbtFrontendSettings();
+ method @Nullable public java.math.BigInteger getBandwidth();
+ method @Nullable public java.math.BigInteger getIsHighPriority();
+ method @Nullable public java.math.BigInteger getTransmissionMode();
+ method public void setBandwidth(@Nullable java.math.BigInteger);
+ method public void setIsHighPriority(@Nullable java.math.BigInteger);
+ 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 Filter {
+ ctor public Filter();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.AvFilterSettings getAvFilterSettings_optional();
+ method @Nullable public java.math.BigInteger getBufferSize();
+ method @Nullable public String getId();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum getMainType();
+ method @Nullable public java.math.BigInteger getPid();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.RecordFilterSettings getRecordFilterSettings_optional();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.SectionFilterSettings getSectionFilterSettings_optional();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum getSubType();
+ method @Nullable public boolean getUseFMQ();
+ method public void setAvFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AvFilterSettings);
+ method public void setBufferSize(@Nullable java.math.BigInteger);
+ method public void setId(@Nullable String);
+ method public void setMainType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum);
+ method public void setPid(@Nullable java.math.BigInteger);
+ method public void setRecordFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.RecordFilterSettings);
+ method public void setSectionFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.SectionFilterSettings);
+ method public void setSubType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum);
+ method public void setUseFMQ(@Nullable boolean);
+ }
+
+ public enum FilterMainTypeEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum MMTP;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum TS;
+ }
+
+ public enum FilterSubTypeEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum AUDIO;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum DOWNLOAD;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum MMTP;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PCR;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PES;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum RECORD;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum SECTION;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum TEMI;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum TS;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum UNDEFINED;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum VIDEO;
+ }
+
+ public class Frontend {
+ ctor public Frontend();
+ method @Nullable public java.math.BigInteger getConnectToCicamId();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbsFrontendSettings getDvbsFrontendSettings_optional();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbtFrontendSettings getDvbtFrontendSettings_optional();
+ method @Nullable public java.math.BigInteger getEndFrequency();
+ method @Nullable public java.math.BigInteger getFrequency();
+ method @Nullable public String getId();
+ method @Nullable public boolean getIsSoftwareFrontend();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum getType();
+ method public void setConnectToCicamId(@Nullable java.math.BigInteger);
+ method public void setDvbsFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.DvbsFrontendSettings);
+ method public void setDvbtFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.DvbtFrontendSettings);
+ method public void setEndFrequency(@Nullable java.math.BigInteger);
+ method public void setFrequency(@Nullable java.math.BigInteger);
+ method public void setId(@Nullable String);
+ method public void setIsSoftwareFrontend(@Nullable boolean);
+ method public void setType(@Nullable android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum);
+ }
+
+ public enum FrontendTypeEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ANALOG;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ATSC;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ATSC3;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum DTMB;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum DVBC;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum DVBS;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum DVBT;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ISDBS;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ISDBS3;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum ISDBT;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum UNDEFINED;
+ }
+
+ public class HardwareConfiguration {
+ ctor public HardwareConfiguration();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Descramblers getDescramblers();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.DiseqcMessages getDiseqcMessages();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs getDvrs();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Filters getFilters();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends getFrontends();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Lnbs getLnbs();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.TimeFilters getTimeFilters();
+ method public void setDescramblers(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Descramblers);
+ method public void setDiseqcMessages(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.DiseqcMessages);
+ method public void setDvrs(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Dvrs);
+ method public void setFilters(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Filters);
+ method public void setFrontends(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Frontends);
+ method public void setLnbs(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.Lnbs);
+ method public void setTimeFilters(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration.TimeFilters);
+ }
+
+ public static class HardwareConfiguration.Descramblers {
+ ctor public HardwareConfiguration.Descramblers();
+ method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.Descrambler> getDescrambler();
+ }
+
+ public static class HardwareConfiguration.DiseqcMessages {
+ ctor public HardwareConfiguration.DiseqcMessages();
+ method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.DiseqcMessage> getDiseqcMessage();
+ }
+
+ 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.Filters {
+ ctor public HardwareConfiguration.Filters();
+ method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.Filter> getFilter();
+ }
+
+ public static class HardwareConfiguration.Frontends {
+ ctor public HardwareConfiguration.Frontends();
+ method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.Frontend> getFrontend();
+ }
+
+ public static class HardwareConfiguration.Lnbs {
+ ctor public HardwareConfiguration.Lnbs();
+ method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.Lnb> getLnb();
+ }
+
+ public static class HardwareConfiguration.TimeFilters {
+ ctor public HardwareConfiguration.TimeFilters();
+ method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.TimeFilter> getTimeFilter();
+ }
+
+ public class Lnb {
+ ctor public Lnb();
+ method @Nullable public String getId();
+ method @Nullable public String getName();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.LnbPositionEnum getPosition();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.LnbToneEnum getTone();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum getVoltage();
+ method public void setId(@Nullable String);
+ method public void setName(@Nullable String);
+ method public void setPosition(@Nullable android.media.tuner.testing.configuration.V1_0.LnbPositionEnum);
+ method public void setTone(@Nullable android.media.tuner.testing.configuration.V1_0.LnbToneEnum);
+ method public void setVoltage(@Nullable android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum);
+ }
+
+ public enum LnbPositionEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbPositionEnum POSITION_A;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbPositionEnum POSITION_B;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbPositionEnum UNDEFINED;
+ }
+
+ public enum LnbToneEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbToneEnum CONTINUOUS;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbToneEnum NONE;
+ }
+
+ public enum LnbVoltageEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum NONE;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_11V;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_12V;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_13V;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_14V;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_15V;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_18V;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_19V;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.LnbVoltageEnum VOLTAGE_5V;
+ }
+
+ public class RecordFilterSettings {
+ ctor public RecordFilterSettings();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum getScIndexType();
+ method @Nullable public java.math.BigInteger getTsIndexMask();
+ method public void setScIndexType(@Nullable android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum);
+ method public void setTsIndexMask(@Nullable java.math.BigInteger);
+ }
+
+ public enum ScIndexTypeEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum NONE;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum SC;
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.ScIndexTypeEnum SC_HEVC;
+ }
+
+ public class SectionFilterSettings {
+ ctor public SectionFilterSettings();
+ method @Nullable public boolean getIsCheckCrc();
+ method @Nullable public boolean getIsRaw();
+ method @Nullable public boolean getIsRepeat();
+ method public void setIsCheckCrc(@Nullable boolean);
+ method public void setIsRaw(@Nullable boolean);
+ method public void setIsRepeat(@Nullable boolean);
+ }
+
+ public class TimeFilter {
+ ctor public TimeFilter();
+ method @Nullable public String getId();
+ method @Nullable public java.math.BigInteger getTimeStamp();
+ method public void setId(@Nullable String);
+ method public void setTimeStamp(@Nullable java.math.BigInteger);
+ }
+
+ public class TunerConfiguration {
+ ctor public TunerConfiguration();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration getDataFlowConfiguration();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.HardwareConfiguration getHardwareConfiguration();
+ method @Nullable public android.media.tuner.testing.configuration.V1_0.Version getVersion();
+ method public void setDataFlowConfiguration(@Nullable android.media.tuner.testing.configuration.V1_0.DataFlowConfiguration);
+ method public void setHardwareConfiguration(@Nullable android.media.tuner.testing.configuration.V1_0.HardwareConfiguration);
+ method public void setVersion(@Nullable android.media.tuner.testing.configuration.V1_0.Version);
+ }
+
+ public enum Version {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.media.tuner.testing.configuration.V1_0.Version _1_0;
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method @Nullable public static android.media.tuner.testing.configuration.V1_0.TunerConfiguration read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/tv/tuner/config/api/last_current.txt b/tv/tuner/config/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tv/tuner/config/api/last_current.txt
diff --git a/tv/tuner/config/api/last_removed.txt b/tv/tuner/config/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tv/tuner/config/api/last_removed.txt
diff --git a/tv/tuner/config/api/removed.txt b/tv/tuner/config/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/tv/tuner/config/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config.xml
new file mode 100644
index 0000000..570171e
--- /dev/null
+++ b/tv/tuner/config/sample_tuner_vts_config.xml
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 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.
+-->
+
+<!-- The Sample Tuner Testing Configuration.
+ Name the customized xml with "tuner_vts_config.xml" and push into the device
+ "/vendor/etc" path. Please use "tuner_testing_dynamic_configuration.xsd" to verify the xml.
+ The version section contains a “version” tag in the form “major.minor” e.g version=”1.0”
+ This shows the tuner dynamic configuration version. -->
+<TunerConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <!-- Hardware Configuration section contains the configurations of all the hardwares
+ that would be used in the tests. In the "dataFlowConfiguration" section, each data flow
+ under test has its required/optional hardwares. The ids configured in the
+ "dataFlowConfiguration" would be used to connect the hardware to each data flow test. -->
+ <hardwareConfiguration>
+ <!-- Frontends section:
+ This section contains configurations of all the frontends that would be used
+ in the tests.
+ - This section is optional and can be skipped to use the default fe settings.
+ - The default settings can be found in the sample_tuner_vts_configurations.xml.
+ - The users can also override the default frontend settings using id="FE_DEFAULT".
+ - The users can configure 1 or more frontend elements in the frontends sections.
+
+ Each frontend element contain the following attributes:
+ "id": unique id of the frontend that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "type": the frontend type. The enums are defined in the xsd.
+ "isSoftwareFrontend": if the test environment is using hardware or software
+ frontend. If using software, a ts input file path needs to be configured.
+ "softwareFeInputPath": used as the source of the software frontend.
+ "connectToCicamId": if the device supports frontend connecting to cicam, the target
+ cicam id needs to be configured here. Supported in Tuner 1.1 or higher.
+ "frequency": the frequency used to configure tune and scan.
+ "endFrequency": the end frequency of scan. Supported in Tuner 1.1 or higher.
+
+ Each frontend element also contains one and only one type-related "frontendSettings".
+ - The settings type should match the frontend "type" attribute.
+ - For example, when frontend type="DVBT", dvbtFrontendSettings can be configured.
+ - This is optional and skipping the settings would pass a setting with frequency
+ config only to the hal.
+ -->
+ <frontends>
+ <frontend id="FE_DEFAULT" type="DVBT" isSoftwareFrontend="true"
+ connectToCicamId="0" frequency="578000" endFrequency="800000">
+ <dvbtFrontendSettings bandwidth="8" transmissionMode="1" isHighPriority="1"/>
+ </frontend>
+ <frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
+ connectToCicamId="0" frequency="578000" endFrequency="800000">
+ </frontend>
+ </frontends>
+ <!-- Filter section:
+ This section contains configurations of all the filters that would be used in the tests.
+ - This section is optional and can be skipped to use the default filter settings.
+ - The default settings can be found in the sample_tuner_vts_configurations.xml.
+ - The users can also override the default filter settings using
+ - id="FILTER_AUDIO_DEFAULT" or "FILTER_VIDEO_DEFAULT".
+ - The users can configure 1 or more filter elements in the filters sections.
+
+ Each filter element contain the following attributes:
+ "id": unique id of the filter that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "mainType": the main filter type. The enums are defined in the xsd.
+ "subType": the sub filter type. The enums are defined in the xsd.
+ "bufferSize": the buffer size of the filter in hex.
+ "pid": the pid that would be used to configure the filter.
+ "useFMQ": if the filter uses FMQ.
+
+ Each filter element also contains at most one type-related "filterSettings".
+ - The settings type should match the filter "subType" attribute.
+ - For example, when filter subType is audio or video, the avFilterSettings can be
+ configured.
+ - This is optional and skipping the settings would pass a setting with tpid config
+ only to the hal.
+ -->
+ <filters>
+ <filter id="FILTER_AUDIO_DEFAULT" mainType="TS" subType="AUDIO"
+ bufferSize="16777216" pid="257" useFMQ="false">
+ <avFilterSettings isPassthrough="false"/>
+ </filter>
+ <filter id="FILTER_VIDEO_DEFAULT" mainType="TS" subType="VIDEO"
+ bufferSize="16777216" pid="256" useFMQ="false">
+ <avFilterSettings isPassthrough="false"/>
+ </filter>
+ <filter id="FILTER_TS_RECORD_0" mainType="TS" subType="RECORD"
+ bufferSize="16777216" pid="257" useFMQ="false">
+ <recordFilterSettings tsIndexMask="1" scIndexType="NONE"/>
+ </filter>
+ <filter id="FILTER_TS_SECTION_0" mainType="TS" subType="SECTION"
+ bufferSize="16777216" pid="257" useFMQ="true">
+ <sectionFilterSettings isCheckCrc="false" isRepeat="false" isRaw="false"/>
+ </filter>
+ <filter id="FILTER_TS_PCR_0" mainType="TS" subType="PCR"
+ bufferSize="16777216" pid="256" useFMQ="false">
+ </filter>
+ </filters>
+ <!-- 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>
+ <!-- Lnb section:
+ This section contains configurations of all the lnbs that would be used in the tests.
+ - This section is optional and can be skipped if LNB is not supported.
+ - The users can configure 1 or more lnb elements in the lnbs sections.
+
+ Each lnb element contain the following attributes:
+ "id": unique id of the lnb that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "name": the external lnb device name.
+ "voltage": the voltage used to config the lnb.
+ "tone": the voltage used to config the lnb.
+ "position": the voltage used to config the lnb.
+ -->
+ <diseqcMessages>
+ <diseqcMessage msgName="DISEQC_POWER_ON" msgBody="14 0 0 0 0 3"/>
+ </diseqcMessages>
+ <lnbs>
+ <lnb id="LNB_0" voltage="VOLTAGE_12V" tone="NONE" position="UNDEFINED"/>
+ <lnb id="LNB_1" name="default_lnb_external" voltage="VOLTAGE_5V"
+ tone="NONE" position="UNDEFINED"/>
+ </lnbs>
+ <!-- TimeFilter section:
+ This section contains configurations of all the time filters that would be used in
+ the tests.
+ - This section is optional and can be skipped if Time Filter is not supported.
+ - The users can configure 1 or more timeFilter elements in the timeFilters sections.
+
+ Each timeFilter element contain the following attributes:
+ "id": unique id of the time filter that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "timeStamp": the time stamp used to config the time filter.
+ -->
+ <timeFilters>
+ <timeFilter id="TIME_FILTER_0" timeStamp="1"/>
+ </timeFilters>
+ <!-- Descrambler section:
+ This section contains configurations of all the descramblers that would be used in
+ the tests.
+ - This section is optional and can be skipped if Descrambler is not supported.
+ - The users can configure 1 or more descrambler elements in the descramblers sections.
+
+ Each Descrambler element contain the following attributes:
+ "id": unique id of the descrambler that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "casSystemId": the cas system id to connect to the descrambler.
+ "provisionStr": the provision string to use with the cas plugin.
+ "sesstionPrivatData": the session private data used to open the cas session.
+ -->
+ <descramblers>
+ <descrambler id="DESCRAMBLER_0" casSystemId="63192"/>
+ </descramblers>
+ </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"
+ audioFilterConnection="FILTER_AUDIO_DEFAULT"
+ videoFilterConnection="FILTER_VIDEO_DEFAULT"
+ pcrFilterConnection="FILTER_TS_PCR_0"
+ sectionFilterConnection="FILTER_TS_SECTION_0"
+ dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
+ <scan frontendConnection="FE_DEFAULT"/>
+ <descrambling frontendConnection="FE_DEFAULT"
+ descramblerConnection="DESCRAMBLER_0"
+ audioFilterConnection="FILTER_AUDIO_DEFAULT"
+ videoFilterConnection="FILTER_VIDEO_DEFAULT"
+ dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
+ <dvrPlayback dvrConnection="DVR_PLAYBACK_0"
+ audioFilterConnection="FILTER_AUDIO_DEFAULT"
+ videoFilterConnection="FILTER_VIDEO_DEFAULT"
+ sectionFilterConnection="FILTER_TS_SECTION_0"/>
+ <dvrRecord frontendConnection="FE_DEFAULT"
+ recordFilterConnection="FILTER_TS_RECORD_0"
+ dvrRecordConnection="DVR_RECORD_0"
+ dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
+ <lnbLive frontendConnection="FE_DVBS_0"
+ audioFilterConnection="FILTER_AUDIO_DEFAULT"
+ videoFilterConnection="FILTER_VIDEO_DEFAULT"
+ lnbConnection="LNB_1"
+ diseqcMsgSender="DISEQC_POWER_ON"/>
+ <lnbRecord frontendConnection="FE_DVBS_0"
+ recordFilterConnection="FILTER_TS_RECORD_0"
+ dvrRecordConnection="DVR_RECORD_0"
+ lnbConnection="LNB_0"
+ diseqcMsgSender="DISEQC_POWER_ON"/>
+ <timeFilter timeFilterConnection="TIME_FILTER_0"/>
+ </dataFlowConfiguration>
+</TunerConfiguration>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
new file mode 100644
index 0000000..3fe93ff
--- /dev/null
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -0,0 +1,644 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 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.
+-->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <!-- List the dynamic config versions supported by tuner testing. -->
+ <xs:simpleType name="version">
+ <xs:restriction base="xs:decimal">
+ <xs:enumeration value="1.0"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- FRONTEND SESSION -->
+ <xs:simpleType name="frontendId">
+ <!-- Frontend id must be either FE_DEFAULT or FE_TYPE_NUM
+ <frontend id="FE_DVBS_0"/>
+ -->
+ <xs:restriction base="xs:string">
+ <xs:pattern value="FE_DEFAULT|FE_[A-Z]+_[0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="frontendTypeEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="UNDEFINED" />
+ <xs:enumeration value="ANALOG" />
+ <xs:enumeration value="ATSC" />
+ <xs:enumeration value="ATSC3"/>
+ <xs:enumeration value="DVBC"/>
+ <xs:enumeration value="DVBS"/>
+ <xs:enumeration value="DVBT"/>
+ <xs:enumeration value="ISDBS"/>
+ <xs:enumeration value="ISDBS3"/>
+ <xs:enumeration value="ISDBT"/>
+ <xs:enumeration value="DTMB"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="dvbtFrontendSettings">
+ <xs:attribute name="bandwidth" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="transmissionMode" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="isHighPriority" type="xs:nonNegativeInteger" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="dvbsFrontendSettings">
+ <xs:attribute name="inputStreamId" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="symbolRate" type="xs:nonNegativeInteger" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="frontend">
+ <xs:annotation>
+ <xs:documentation>
+ Each frontend element contain the following attributes:
+ "id": unique id of the frontend that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "type": the frontend type. The enums are defined in the xsd.
+ "isSoftwareFrontend": if the test environment is using hardware or software
+ frontend. If using software, a ts input file path needs to be configured.
+ "softwareFeInputPath": used as the source of the software frontend.
+ "connectToCicamId": if the device supports frontend connecting to cicam, the
+ target cicam id needs to be configured here. Supported in Tuner 1.1 or
+ higher.
+ "frequency": the frequency used to configure tune and scan.
+ "endFrequency": the end frequency of scan. Supported in Tuner 1.1 or higher.
+
+ Each frontend element also contains at most one type-related "frontendSettings".
+ - The settings type should match the frontend "type" attribute.
+ - For example, when frontend type="DVBT", dvbtFrontendSettings can be
+ configured.
+ - This is optional and skipping the settings would pass a setting with frequency
+ config only to the hal.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="1">
+ <!-- TODO: b/182519645 finish all the frontend settings structures. -->
+ <!--xs:element name="analog" type="analogSettings"/>
+ <xs:element name="atsc" type="atscSettings"/>
+ <xs:element name="atsc3" type="atsc3Settings"/>
+ <xs:element name="dvbc" type="dvbcSettings"/-->
+ <xs:element name="dvbsFrontendSettings" type="dvbsFrontendSettings"/>
+ <xs:element name="dvbtFrontendSettings" type="dvbtFrontendSettings"/>
+ <!--xs:element name="isdbs" type="isdbsSettings"/>
+ <xs:element name="isdbs3" type="isdbs3Settings"/>
+ <xs:element name="isdbt" type="isdbtSettings"/>
+ <xs:element name="dtmb" type="dtmbSettings"/-->
+ </xs:choice>
+ <xs:attribute name="id" type="frontendId" use="required"/>
+ <xs:attribute name="type" type="frontendTypeEnum" 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>
+
+ <!-- FILTER SESSION -->
+ <xs:simpleType name="filterId">
+ <!-- Filter id must be either FILTER_AUDIO_DEFAULT or FILTER_VIDEO_DEFAULT
+ or FILTER_MAINTYPE_SUBTYPE_NUM
+ <filter id="FILTER_TS_AUDIO_0"/>
+ -->
+ <xs:restriction base="xs:string">
+ <xs:pattern value="FILTER_AUDIO_DEFAULT|FILTER_VIDEO_DEFAULT|FILTER_[A-Z]+_[A-Z]+_[0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <!-- A list of filter ids that could be used in the data flow configurations to connect
+ filters under testing. -->
+ <xs:simpleType name="filterConnections">
+ <xs:list itemType="filterId" />
+ </xs:simpleType>
+ <!-- DemuxFilterRecordSettings::tsIndexMask -->
+ <xs:simpleType name="tsIndexMask">
+ <xs:restriction base="xs:integer">
+ <xs:minInclusive value="0"/>
+ <xs:maxInclusive value="8191"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <!-- DemuxFilterRecordSettings::scIndexType -->
+ <xs:simpleType name="scIndexTypeEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NONE" />
+ <xs:enumeration value="SC" />
+ <xs:enumeration value="SC_HEVC"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="filterMainTypeEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="TS" />
+ <xs:enumeration value="MMTP" />
+ <!-- TODO: b/182519645 Support IP/TLV/ALP filter config
+ <xs:enumeration value="IP"/>
+ <xs:enumeration value="TLV"/>
+ <xs:enumeration value="ALP"/-->
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="filterSubTypeEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="UNDEFINED" />
+ <xs:enumeration value="SECTION" />
+ <xs:enumeration value="PES" />
+ <xs:enumeration value="TS"/>
+ <xs:enumeration value="AUDIO"/>
+ <xs:enumeration value="VIDEO"/>
+ <xs:enumeration value="PCR"/>
+ <xs:enumeration value="RECORD"/>
+ <xs:enumeration value="TEMI"/>
+ <xs:enumeration value="MMTP"/>
+ <xs:enumeration value="DOWNLOAD"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="avFilterSettings">
+ <xs:attribute name="isPassthrough" type="xs:boolean" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="sectionFilterSettings">
+ <xs:attribute name="isCheckCrc" type="xs:boolean" use="required"/>
+ <xs:attribute name="isRepeat" type="xs:boolean" use="required"/>
+ <xs:attribute name="isRaw" type="xs:boolean" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="recordFilterSettings">
+ <xs:attribute name="tsIndexMask" type="tsIndexMask" use="required"/>
+ <xs:attribute name="scIndexType" type="scIndexTypeEnum" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="filter">
+ <xs:annotation>
+ <xs:documentation>
+ Each filter element contain the following attributes:
+ "id": unique id of the filter that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "mainType": the main filter type. The enums are defined in the xsd.
+ "subType": the sub filter type. The enums are defined in the xsd.
+ "bufferSize": the buffer size of the filter in hex.
+ "pid": the pid that would be used to configure the filter.
+ "useFMQ": if the filter uses FMQ.
+
+ Each filter element also contains at most one type-related "filterSettings".
+ - The settings type should match the filter "subType" attribute.
+ - For example, when filter subType is audio or video, the avFilterSettings
+ can be configured.
+ - This is optional and skipping the settings would pass a setting with tpid
+ config only to the hal.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="0" maxOccurs="1">
+ <!-- TODO: b/182519645 finish all the filter settings structures. -->
+ <xs:element name="sectionFilterSettings" type="sectionFilterSettings"/>
+ <xs:element name="avFilterSettings" type="avFilterSettings"/>
+ <xs:element name="recordFilterSettings" type="recordFilterSettings"/>
+ <!--xs:element name="pes" type="pesFilterSettings"/>
+ <xs:element name="download" type="downloadFilterSettings"/-->
+ </xs:choice>
+ <xs:attribute name="id" type="filterId" use="required"/>
+ <xs:attribute name="mainType" type="filterMainTypeEnum" use="required"/>
+ <xs:attribute name="subType" type="filterSubTypeEnum" use="required"/>
+ <xs:attribute name="bufferSize" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="pid" type="xs:nonNegativeInteger" use="optional"/>
+ <xs:attribute name="useFMQ" type="xs:boolean" use="required"/>
+ </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>
+
+ <!-- LNB SESSION -->
+ <xs:simpleType name="lnbId">
+ <!-- Lnb id must be LNB_NUM: <lnb id="LNB_10"/> -->
+ <xs:restriction base="xs:string">
+ <xs:pattern value="LNB_[0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="lnbVoltageEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NONE" />
+ <xs:enumeration value="VOLTAGE_5V" />
+ <xs:enumeration value="VOLTAGE_11V" />
+ <xs:enumeration value="VOLTAGE_12V"/>
+ <xs:enumeration value="VOLTAGE_13V"/>
+ <xs:enumeration value="VOLTAGE_14V"/>
+ <xs:enumeration value="VOLTAGE_15V"/>
+ <xs:enumeration value="VOLTAGE_18V"/>
+ <xs:enumeration value="VOLTAGE_19V"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="lnbToneEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NONE" />
+ <xs:enumeration value="CONTINUOUS" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="lnbPositionEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="UNDEFINED" />
+ <xs:enumeration value="POSITION_A" />
+ <xs:enumeration value="POSITION_B" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Diseqc Messages that would be used to send to the lnb under test. -->
+ <xs:simpleType name="diseqcMsgName">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[A-Z_]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="diseqcMsgBody">
+ <xs:list itemType="xs:unsignedByte"/>
+ </xs:simpleType>
+ <xs:complexType name="diseqcMessage">
+ <xs:attribute name="msgName" type="diseqcMsgName"/>
+ <xs:attribute name="msgBody" type="diseqcMsgBody"/>
+ </xs:complexType>
+ <xs:simpleType name="diseqcMsgSender">
+ <xs:list itemType="diseqcMsgName"/>
+ </xs:simpleType>
+
+ <xs:complexType name="lnb">
+ <xs:annotation>
+ <xs:documentation>
+ Each lnb element contain the following attributes:
+ "id": unique id of the lnb that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "name": the external lnb device name.
+ "voltage": the voltage used to config the lnb.
+ "tone": the voltage used to config the lnb.
+ "position": the voltage used to config the lnb.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="id" type="lnbId" use="required"/>
+ <!-- Only required on external lnb with no device id. -->
+ <xs:attribute name="name" type="xs:string" use="optional"/>
+ <xs:attribute name="voltage" type="lnbVoltageEnum" use="required"/>
+ <xs:attribute name="tone" type="lnbToneEnum" use="required"/>
+ <xs:attribute name="position" type="lnbPositionEnum" use="required"/>
+ </xs:complexType>
+
+ <!-- TIME FILTER SESSION -->
+ <xs:simpleType name="timeFilterId">
+ <!-- Time Filter id must be TIME_FILTER_NUM: <timeFilter id="TIME_FILTER_1"/> -->
+ <xs:restriction base="xs:string">
+ <xs:pattern value="TIME_FILTER_[0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="timeFilter">
+ <xs:annotation>
+ <xs:documentation>
+ Each timeFilter element contain the following attributes:
+ "id": unique id of the time filter that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "timeStamp": the time stamp used to config the time filter.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="id" type="timeFilterId" use="required"/>
+ <xs:attribute name="timeStamp" type="xs:nonNegativeInteger" use="required"/>
+ </xs:complexType>
+
+ <!-- DESCRAMBLER SESSION -->
+ <xs:simpleType name="descramblerId">
+ <!-- Descrambler id must be DESCRAMBLER_NUM: <descrambler id="DESCRAMBLER_2"/> -->
+ <xs:restriction base="xs:string">
+ <xs:pattern value="DESCRAMBLER_[0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="sessionPrivateData">
+ <xs:list itemType="xs:unsignedByte"/>
+ </xs:simpleType>
+
+ <xs:complexType name="descrambler">
+ <xs:annotation>
+ <xs:documentation>
+ Each descrambler element contain the following attributes:
+ "id": unique id of the descrambler that could be used to connect to the test the
+ "dataFlowConfiguration"
+ "casSystemId": the cas system id to connect to the descrambler.
+ "provisionStr": the provision string to use with the cas plugin.
+ "sesstionPrivatData": the session private data used to open the cas session.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="id" type="descramblerId" use="required"/>
+ <xs:attribute name="casSystemId" type="xs:nonNegativeInteger" use="required"/>
+ <xs:attribute name="provisionStr" type="xs:string" use="required"/>
+ <xs:attribute name="sesstionPrivatData" type="sessionPrivateData" use="optional"/>
+ </xs:complexType>
+
+ <!-- HARDWARE CONFIGURATION SESSION -->
+ <xs:complexType name="hardwareConfiguration">
+ <xs:sequence>
+ <xs:element name="frontends" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ This section contains configurations of all the frontends that would be
+ used in the tests.
+ - This section is optional and can be skipped to use the default
+ fe settings.
+ - The default settings can be found in the
+ sample_tuner_vts_configurations.xml.
+ - The users can also override the default frontend settings using
+ id="FE_DEFAULT".
+ - The users can configure 1 or more frontend elements in the
+ frontends sections.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="frontend" type="frontend" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="filters" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ This section contains configurations of all the filters that would be
+ used in the tests.
+ - This section is optional and can be skipped to use the default
+ filter settings.
+ - The default settings can be found in the
+ sample_tuner_vts_configurations.xml.
+ - The users can also override the default filter settings using
+ - id="FILTER_AUDIO_DEFAULT" or "FILTER_VIDEO_DEFAULT".
+ - The users can configure 1 or more filter elements in the filters
+ sections.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="filter" type="filter" minOccurs="1" maxOccurs="unbounded"/>
+ </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:element name="diseqcMessages" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ This section contains configurations of all the diseqc messages that
+ would be used in the lnb tests.
+ - This section is optional and can be skipped if lnb is not suppoted
+ - The users can configure 1 or more message elements in the
+ diseqcMessages sections.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="diseqcMessage" type="diseqcMessage" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="lnbs" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ This section contains configurations of all the lnbs that would be used
+ in the tests.
+ - This section is optional and can be skipped if lnb is not suppoted
+ - The users can configure 1 or more lnb elements in the lnbs
+ sections.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="lnb" type="lnb" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="timeFilters" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ This section contains configurations of all the time filters that would
+ be used in the tests.
+ - This section is optional and can be skipped if time filter is
+ not supported.
+ - The users can configure 1 or more time filter elements in the
+ time filters sections.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="timeFilter" type="timeFilter" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="descramblers" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ This section contains configurations of all the descramblers that would
+ be used in the tests.
+ - This section is optional and can be skipped if descrambling is not
+ supported.
+ - The users can configure 1 or more descrambler elements in the
+ descramblers sections.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="descrambler" type="descrambler" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- DATA FLOW CONFIGURATION SESSION -->
+ <xs:complexType name="dataFlowConfiguration">
+ <xs:sequence>
+ <xs:element name="clearLiveBroadcast" minOccurs="1" maxOccurs="1">
+ <xs:complexType>
+ <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ <xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="pcrFilterConnection" type="filterId" use="optional"/>
+ <xs:attribute name="sectionFilterConnection" type="filterId" use="optional"/>
+ <!-- TODO: b/182519645 allow the users to insert extra filters -->
+ <!-- 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">
+ <xs:complexType>
+ <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="descrambling" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ <xs:attribute name="descramblerConnection" type="descramblerId" use="required"/>
+ <xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
+ <!-- TODO: b/182519645 allow the users to insert extra filters -->
+ <!-- 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:attribute name="audioFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="sectionFilterConnection" type="filterId" use="optional"/>
+ <!-- TODO: b/182519645 allow the users to insert extra filters -->
+ </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:attribute name="recordFilterConnection" type="filterId" use="required"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="lnbLive" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ <xs:attribute name="audioFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="lnbConnection" type="lnbId" use="required"/>
+ <xs:attribute name="diseqcMsgSender" type="diseqcMsgSender" use="optional"/>
+ <!-- TODO: b/182519645 allow the users to insert extra filters -->
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="lnbRecord" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:attribute name="frontendConnection" type="frontendId" use="required"/>
+ <xs:attribute name="recordFilterConnection" type="filterId" use="required"/>
+ <xs:attribute name="dvrRecordConnection" type="dvrId" use="required"/>
+ <xs:attribute name="lnbConnection" type="lnbId" use="required"/>
+ <xs:attribute name="diseqcMsgSender" type="diseqcMsgSender" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="timeFilter" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:attribute name="timeFilterConnection" type="timeFilterId" use="required"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Full Tuner Configuration. This is the root element of the configuration xml. -->
+ <xs:element name="TunerConfiguration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="hardwareConfiguration" type="hardwareConfiguration" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="dataFlowConfiguration" type="dataFlowConfiguration" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="version" type="version"/>
+ </xs:complexType>
+ <xs:key name="frontendIdUniqueness">
+ <xs:selector xpath="hardwareConfiguration/frontends/frontend"/>
+ <xs:field xpath="@id"/>
+ </xs:key>
+ <xs:key name="filterIdUniqueness">
+ <xs:selector xpath="hardwareConfiguration/filters/filter"/>
+ <xs:field xpath="@id"/>
+ </xs:key>
+ <xs:key name="dvrIdUniqueness">
+ <xs:selector xpath="hardwareConfiguration/dvrs/dvr"/>
+ <xs:field xpath="@id"/>
+ </xs:key>
+ <xs:key name="lnbIdUniqueness">
+ <xs:selector xpath="hardwareConfiguration/lnbs/lnb"/>
+ <xs:field xpath="@id"/>
+ </xs:key>
+ <xs:key name="timeFilterIdUniqueness">
+ <xs:selector xpath="hardwareConfiguration/timeFilters/timeFilter"/>
+ <xs:field xpath="@id"/>
+ </xs:key>
+ <xs:key name="descramblerIdUniqueness">
+ <xs:selector xpath="hardwareConfiguration/descramblers/descrambler"/>
+ <xs:field xpath="@id"/>
+ </xs:key>
+ </xs:element>
+</xs:schema>