diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal index f39eb5de48..e9c5e190f5 100644 --- a/tv/tuner/1.1/IFrontend.hal +++ b/tv/tuner/1.1/IFrontend.hal @@ -82,4 +82,20 @@ interface IFrontend extends @1.0::IFrontend { * UNKNOWN_ERROR if failed for other reasons. */ linkCiCam(uint32_t ciCamId) generates (Result result); + + /** + * Get the v1_1 extended statuses of the frontend. + * + * This retrieve the extended statuses of the frontend for given extended status types. + * + * @param statusTypes an array of the extended status types which the caller request. + * + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if tuning can't be applied at current stage, + * UNKNOWN_ERROR if tuning failed for other reasons. + * @return statuses an array of extended statuses the caller requests for. + */ + getStatusExt1_1(vec statusTypes) + generates (Result result, vec statuses); }; diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp index 0b8311ff69..c5aeace1b5 100644 --- a/tv/tuner/1.1/default/Frontend.cpp +++ b/tv/tuner/1.1/default/Frontend.cpp @@ -259,6 +259,83 @@ Return Frontend::getStatus(const hidl_vec& statusTypes return Void(); } +Return Frontend::getStatusExt1_1(const hidl_vec& statusTypes, + V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb) { + ALOGV("%s", __FUNCTION__); + + vector statuses; + for (int i = 0; i < statusTypes.size(); i++) { + V1_1::FrontendStatusTypeExt1_1 type = statusTypes[i]; + V1_1::FrontendStatusExt1_1 status; + // assign randomly selected values for testing. + switch (type) { + case V1_1::FrontendStatusTypeExt1_1::MODULATIONS: { + vector modulations; + V1_1::FrontendModulation modulation; + modulation.isdbt(FrontendIsdbtModulation::MOD_16QAM); // value = 1 << 3 + modulations.push_back(modulation); + status.modulations(modulations); + break; + } + case V1_1::FrontendStatusTypeExt1_1::BERS: { + vector bers = {1}; + status.bers(bers); + break; + } + case V1_1::FrontendStatusTypeExt1_1::CODERATES: { + // value = 1 << 39 + vector codeRates = {V1_1::FrontendInnerFec::FEC_6_15}; + status.codeRates(codeRates); + break; + } + case V1_1::FrontendStatusTypeExt1_1::GUARD_INTERVAL: { + V1_1::FrontendGuardInterval interval; + interval.dvbt(FrontendDvbtGuardInterval::INTERVAL_1_32); // value = 1 << 1 + status.interval(interval); + break; + } + case V1_1::FrontendStatusTypeExt1_1::TRANSMISSION_MODE: { + V1_1::FrontendTransmissionMode transMode; + transMode.dvbt(V1_1::FrontendDvbtTransmissionMode::AUTO); // value = 1 << 0 + status.transmissionMode(transMode); + break; + } + case V1_1::FrontendStatusTypeExt1_1::UEC: { + status.uec(4); + break; + } + case V1_1::FrontendStatusTypeExt1_1::T2_SYSTEM_ID: { + status.systemId(5); + break; + } + case V1_1::FrontendStatusTypeExt1_1::INTERLEAVINGS: { + V1_1::FrontendInterleaveMode interleave; + interleave.atsc3(FrontendAtsc3TimeInterleaveMode::AUTO); + vector interleaving = {interleave}; + status.interleaving(interleaving); + break; + } + case V1_1::FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: { + vector segments = {2, 3}; + status.isdbtSegment(segments); + break; + } + case V1_1::FrontendStatusTypeExt1_1::TS_DATA_RATES: { + vector dataRates = {4, 5}; + status.tsDataRate(dataRates); + break; + } + default: { + continue; + } + } + statuses.push_back(status); + } + _hidl_cb(Result::SUCCESS, statuses); + + return Void(); +} + Return Frontend::setLna(bool /* bEnable */) { ALOGV("%s", __FUNCTION__); diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h index a843f6587c..4c357189e4 100644 --- a/tv/tuner/1.1/default/Frontend.h +++ b/tv/tuner/1.1/default/Frontend.h @@ -58,6 +58,10 @@ class Frontend : public V1_1::IFrontend { virtual Return getStatus(const hidl_vec& statusTypes, getStatus_cb _hidl_cb) override; + virtual Return getStatusExt1_1( + const hidl_vec& statusTypes, + V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb) override; + virtual Return setLna(bool bEnable) override; virtual Return setLnb(uint32_t lnb) override; diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal index d9c22f8eb9..938751351a 100644 --- a/tv/tuner/1.1/types.hal +++ b/tv/tuner/1.1/types.hal @@ -19,9 +19,25 @@ package android.hardware.tv.tuner@1.1; import @1.0::Constant; import @1.0::DemuxFilterMmtpRecordEvent; import @1.0::DemuxFilterTsRecordEvent; +import @1.0::FrontendAtsc3Bandwidth; +import @1.0::FrontendAtsc3Modulation; +import @1.0::FrontendAtsc3TimeInterleaveMode; +import @1.0::FrontendAtscModulation; +import @1.0::FrontendDvbcModulation; +import @1.0::FrontendDvbtBandwidth; import @1.0::FrontendDvbcSpectralInversion; +import @1.0::FrontendDvbsModulation; import @1.0::FrontendDvbtConstellation; import @1.0::FrontendDvbtTransmissionMode; +import @1.0::FrontendDvbtGuardInterval; +import @1.0::FrontendInnerFec; +import @1.0::FrontendIsdbs3Modulation; +import @1.0::FrontendIsdbsModulation; +import @1.0::FrontendIsdbtBandwidth; +import @1.0::FrontendIsdbtGuardInterval; +import @1.0::FrontendIsdbtMode; +import @1.0::FrontendIsdbtModulation; +import @1.0::FrontendStatusType; import @1.0::FrontendType; import android.hidl.safe_union@1.0; import android.hidl.safe_union@1.0::Monostate; @@ -65,8 +81,7 @@ enum Constant64Bit : uint64_t { struct DemuxFilterRecordEventExt { /** * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz - * and has the same format as the PTS in ISO/IEC 13818-1. It is used only for the SC and - * the SC_HEVC. + * and has the same format as the PTS in ISO/IEC 13818-1. */ uint64_t pts; @@ -148,6 +163,8 @@ enum FrontendDvbtConstellation : @1.0::FrontendDvbtConstellation { */ struct FrontendDvbsSettingsExt1_1 { FrontendDvbsScanType scanType; + + bool isDiseqcRxMessage; }; /** @@ -325,3 +342,183 @@ struct FrontendDtmbCapabilities { bitfield interleaveModeCap; }; + +safe_union FrontendModulation { + @1.0::FrontendDvbcModulation dvbc; + + @1.0::FrontendDvbsModulation dvbs; + + FrontendDvbtConstellation dvbt; + + @1.0::FrontendIsdbsModulation isdbs; + + @1.0::FrontendIsdbs3Modulation isdbs3; + + @1.0::FrontendIsdbtModulation isdbt; + + @1.0::FrontendAtscModulation atsc; + + @1.0::FrontendAtsc3Modulation atsc3; + + FrontendDtmbModulation dtmb; +}; + +safe_union FrontendInterleaveMode { + @1.0::FrontendAtsc3TimeInterleaveMode atsc3; + + FrontendDtmbTimeInterleaveMode dtmb; +}; + +@export +enum FrontendInnerFec : @1.0::FrontendInnerFec { + FEC_2_15 = 1 << 36, + FEC_3_15 = 1 << 37, + FEC_5_15 = 1 << 38, + FEC_6_15 = 1 << 39, + FEC_9_15 = 1 << 40, + FEC_10_15 = 1 << 41, + FEC_12_15 = 1 << 42, + FEC_13_15 = 1 << 43, + FEC_18_30 = 1 << 44, + FEC_20_30 = 1 << 45, + FEC_90_180 = 1 << 46, + FEC_96_180 = 1 << 47, + FEC_104_180 = 1 << 48, + FEC_128_180 = 1 << 49, + FEC_132_180 = 1 << 50, + FEC_135_180 = 1 << 51, + FEC_140_180 = 1 << 52, +}; + +safe_union FrontendBandwidth { + @1.0::FrontendAtsc3Bandwidth atsc3; + + @1.0::FrontendDvbtBandwidth dvbt; + + @1.0::FrontendIsdbtBandwidth isdbt; + + FrontendDtmbBandwidth dtmb; +}; + +safe_union FrontendGuardInterval { + @1.0::FrontendDvbtGuardInterval dvbt; + + @1.0::FrontendIsdbtGuardInterval isdbt; + + FrontendDtmbGuardInterval dtmb; +}; + +safe_union FrontendTransmissionMode { + FrontendDvbtTransmissionMode dvbt; + + @1.0::FrontendIsdbtMode isdbt; + + FrontendDtmbTransmissionMode dtmb; +}; + +@export +enum FrontendStatusTypeExt1_1 : uint32_t { + /** + * Modulation Types. + */ + MODULATIONS = @1.0::FrontendStatusType:ATSC3_PLP_INFO + 1, + /** + * Bit Error Ratios. + */ + BERS, + /** + * Code Rates. + */ + CODERATES, + /** + * Extended Bandwidth. + */ + BANDWIDTH, + /** + * Extended Guard Intervals. + */ + GUARD_INTERVAL, + /** + * Extended Transmission Mode. + */ + TRANSMISSION_MODE, + /** + * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP) + * since the last tune operation. + */ + UEC, + /** + * DVB-T2 System Id. + */ + T2_SYSTEM_ID, + /** + * Frontend Interleaving Modes. + */ + INTERLEAVINGS, + /** + * Segments in ISDB-T Specification of all the channels. + */ + ISDBT_SEGMENTS, + /** + * Transport Stream Data Rate in BPS of the current channel. + */ + TS_DATA_RATES, +}; + +safe_union FrontendStatusExt1_1 { + /** + * Extended modulation status. + */ + vec modulations; + + /** + * Extended bit error ratio status. + */ + vec bers; + + /** + * Extended code rate status. + */ + vec codeRates; + + /** + * Extended bandwidth status. + */ + FrontendBandwidth bandwidth; + + /** + * Extended guard interval status. + */ + FrontendGuardInterval interval; + + /** + * Extended transmission mode status. + */ + FrontendTransmissionMode transmissionMode; + + /** + * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP) + * since the last tune operation. + */ + uint32_t uec; + + /** + * The current DVB-T2 system id status. + */ + uint16_t systemId; + + /** + * Frontend Interleaving Modes. + */ + vec interleaving; + + /** + * Segments in ISDB-T Specification of all the channels. + */ + vec isdbtSegment; + + /** + * Transport Stream Data Rate in BPS of the current channel. + */ + vec tsDataRate; +}; diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp index bb91e4a771..1700e43553 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp +++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp @@ -254,115 +254,81 @@ AssertionResult FrontendTests::getFrontendDtmbCaps(uint32_t id) { return AssertionResult(status == Result::SUCCESS); } -void FrontendTests::verifyFrontendStatus(vector statusTypes, - vector expectStatuses) { +void FrontendTests::verifyFrontendStatusExt1_1(vector statusTypes, + vector expectStatuses) { ASSERT_TRUE(mFrontend) << "Frontend is not opened yet."; Result status; - vector realStatuses; + vector realStatuses; - mFrontend->getStatus(statusTypes, [&](Result result, const hidl_vec& statuses) { - status = result; - realStatuses = statuses; - }); + sp frontend_1_1; + frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend); + if (frontend_1_1 == nullptr) { + EXPECT_TRUE(false) << "Couldn't get 1.1 IFrontend from the Hal implementation."; + return; + } + + frontend_1_1->getStatusExt1_1( + statusTypes, [&](Result result, const hidl_vec& statuses) { + status = result; + realStatuses = statuses; + }); ASSERT_TRUE(realStatuses.size() == statusTypes.size()); for (int i = 0; i < statusTypes.size(); i++) { - FrontendStatusType type = statusTypes[i]; + FrontendStatusTypeExt1_1 type = statusTypes[i]; switch (type) { - case FrontendStatusType::DEMOD_LOCK: { - ASSERT_TRUE(realStatuses[i].isDemodLocked() == expectStatuses[i].isDemodLocked()); + case FrontendStatusTypeExt1_1::MODULATIONS: { + // TODO: verify modulations break; } - case FrontendStatusType::SNR: { - ASSERT_TRUE(realStatuses[i].snr() == expectStatuses[i].snr()); + case FrontendStatusTypeExt1_1::BERS: { + ASSERT_TRUE(std::equal(realStatuses[i].bers().begin(), realStatuses[i].bers().end(), + expectStatuses[i].bers().begin())); break; } - case FrontendStatusType::BER: { - ASSERT_TRUE(realStatuses[i].ber() == expectStatuses[i].ber()); + case FrontendStatusTypeExt1_1::CODERATES: { + ASSERT_TRUE(std::equal(realStatuses[i].codeRates().begin(), + realStatuses[i].codeRates().end(), + expectStatuses[i].codeRates().begin())); break; } - case FrontendStatusType::PER: { - ASSERT_TRUE(realStatuses[i].per() == expectStatuses[i].per()); + case FrontendStatusTypeExt1_1::GUARD_INTERVAL: { + // TODO: verify interval break; } - case FrontendStatusType::PRE_BER: { - ASSERT_TRUE(realStatuses[i].preBer() == expectStatuses[i].preBer()); + case FrontendStatusTypeExt1_1::TRANSMISSION_MODE: { + // TODO: verify tranmission mode break; } - case FrontendStatusType::SIGNAL_QUALITY: { - ASSERT_TRUE(realStatuses[i].signalQuality() == expectStatuses[i].signalQuality()); + case FrontendStatusTypeExt1_1::UEC: { + ASSERT_TRUE(realStatuses[i].uec() == expectStatuses[i].uec()); break; } - case FrontendStatusType::SIGNAL_STRENGTH: { - ASSERT_TRUE(realStatuses[i].signalStrength() == expectStatuses[i].signalStrength()); + case FrontendStatusTypeExt1_1::T2_SYSTEM_ID: { + ASSERT_TRUE(realStatuses[i].systemId() == expectStatuses[i].systemId()); break; } - case FrontendStatusType::SYMBOL_RATE: { - ASSERT_TRUE(realStatuses[i].symbolRate() == expectStatuses[i].symbolRate()); + case FrontendStatusTypeExt1_1::INTERLEAVINGS: { + ASSERT_TRUE(std::equal(realStatuses[i].interleaving().begin(), + realStatuses[i].interleaving().end(), + expectStatuses[i].interleaving().begin())); break; } - case FrontendStatusType::FEC: { - ASSERT_TRUE(realStatuses[i].innerFec() == expectStatuses[i].innerFec()); + case FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: { + ASSERT_TRUE(std::equal(realStatuses[i].isdbtSegment().begin(), + realStatuses[i].isdbtSegment().end(), + expectStatuses[i].isdbtSegment().begin())); break; } - case FrontendStatusType::MODULATION: { - // TODO: check modulation status + case FrontendStatusTypeExt1_1::TS_DATA_RATES: { + ASSERT_TRUE(std::equal(realStatuses[i].tsDataRate().begin(), + realStatuses[i].tsDataRate().end(), + expectStatuses[i].tsDataRate().begin())); break; } - case FrontendStatusType::SPECTRAL: { - ASSERT_TRUE(realStatuses[i].inversion() == expectStatuses[i].inversion()); - break; - } - case FrontendStatusType::LNB_VOLTAGE: { - ASSERT_TRUE(realStatuses[i].lnbVoltage() == expectStatuses[i].lnbVoltage()); - break; - } - case FrontendStatusType::PLP_ID: { - ASSERT_TRUE(realStatuses[i].plpId() == expectStatuses[i].plpId()); - break; - } - case FrontendStatusType::EWBS: { - ASSERT_TRUE(realStatuses[i].isEWBS() == expectStatuses[i].isEWBS()); - break; - } - case FrontendStatusType::AGC: { - ASSERT_TRUE(realStatuses[i].agc() == expectStatuses[i].agc()); - break; - } - case FrontendStatusType::LNA: { - ASSERT_TRUE(realStatuses[i].isLnaOn() == expectStatuses[i].isLnaOn()); - break; - } - case FrontendStatusType::LAYER_ERROR: { - vector realLayberError = realStatuses[i].isLayerError(); - vector expectLayerError = expectStatuses[i].isLayerError(); - ASSERT_TRUE(realLayberError.size() == expectLayerError.size()); - for (int i = 0; i < realLayberError.size(); i++) { - ASSERT_TRUE(realLayberError[i] == expectLayerError[i]); - } - break; - } - case FrontendStatusType::MER: { - ASSERT_TRUE(realStatuses[i].mer() == expectStatuses[i].mer()); - break; - } - case FrontendStatusType::FREQ_OFFSET: { - ASSERT_TRUE(realStatuses[i].freqOffset() == expectStatuses[i].freqOffset()); - break; - } - case FrontendStatusType::HIERARCHY: { - ASSERT_TRUE(realStatuses[i].hierarchy() == expectStatuses[i].hierarchy()); - break; - } - case FrontendStatusType::RF_LOCK: { - ASSERT_TRUE(realStatuses[i].isRfLocked() == expectStatuses[i].isRfLocked()); - break; - } - case FrontendStatusType::ATSC3_PLP_INFO: - // TODO: verify plpinfo - break; - default: + default: { continue; + } } } ASSERT_TRUE(status == Result::SUCCESS); @@ -433,7 +399,7 @@ void FrontendTests::tuneTest(FrontendConfig frontendConf) { ASSERT_TRUE(openFrontendById(feId)); ASSERT_TRUE(setFrontendCallback()); ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/)); - verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses); + verifyFrontendStatusExt1_1(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses); ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/)); ASSERT_TRUE(closeFrontend()); } diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h index cb238e8d00..106f653303 100644 --- a/tv/tuner/1.1/vts/functional/FrontendTests.h +++ b/tv/tuner/1.1/vts/functional/FrontendTests.h @@ -110,8 +110,8 @@ class FrontendTests { AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type); AssertionResult stopScanFrontend(); AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux); - void verifyFrontendStatus(vector statusTypes, - vector expectStatuses); + void verifyFrontendStatusExt1_1(vector statusTypes, + vector expectStatuses); AssertionResult stopTuneFrontend(bool testWithDemux); AssertionResult closeFrontend(); AssertionResult getFrontendDtmbCaps(uint32_t); diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h index c6ebecb189..a3bfa1f87a 100644 --- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h +++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h @@ -43,12 +43,12 @@ 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::PlaybackSettings; using android::hardware::tv::tuner::V1_0::RecordSettings; using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1; +using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1; +using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1; using namespace std; @@ -101,8 +101,8 @@ struct FrontendConfig { FrontendType type; FrontendSettings settings; FrontendSettingsExt1_1 settingsExt1_1; - vector tuneStatusTypes; - vector expectTuneStatuses; + vector tuneStatusTypes; + vector expectTuneStatuses; }; struct DvrConfig { @@ -132,11 +132,11 @@ inline void initFrontendConfig() { .standard = FrontendDvbtStandard::T, }; frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings); - vector types; - types.push_back(FrontendStatusType::DEMOD_LOCK); - FrontendStatus status; - status.isDemodLocked(true); - vector statuses; + vector types; + types.push_back(FrontendStatusTypeExt1_1::UEC); + FrontendStatusExt1_1 status; + status.uec(4); + vector statuses; statuses.push_back(status); frontendArray[DVBT].tuneStatusTypes = types; frontendArray[DVBT].expectTuneStatuses = statuses;