/** * 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. */ //#define LOG_NDEBUG 0 #define LOG_TAG "TunerHidlFrontend" #include "TunerHidlFrontend.h" #include #include "TunerHidlLnb.h" #include "TunerHidlService.h" using ::aidl::android::hardware::tv::tuner::FrontendAnalogSettings; using ::aidl::android::hardware::tv::tuner::FrontendAnalogSifStandard; using ::aidl::android::hardware::tv::tuner::FrontendAnalogType; using ::aidl::android::hardware::tv::tuner::FrontendAtsc3Bandwidth; using ::aidl::android::hardware::tv::tuner::FrontendAtsc3CodeRate; using ::aidl::android::hardware::tv::tuner::FrontendAtsc3Fec; using ::aidl::android::hardware::tv::tuner::FrontendAtsc3Modulation; using ::aidl::android::hardware::tv::tuner::FrontendAtsc3PlpSettings; using ::aidl::android::hardware::tv::tuner::FrontendAtsc3Settings; using ::aidl::android::hardware::tv::tuner::FrontendAtsc3TimeInterleaveMode; using ::aidl::android::hardware::tv::tuner::FrontendAtscModulation; using ::aidl::android::hardware::tv::tuner::FrontendAtscSettings; using ::aidl::android::hardware::tv::tuner::FrontendBandwidth; using ::aidl::android::hardware::tv::tuner::FrontendCableTimeInterleaveMode; using ::aidl::android::hardware::tv::tuner::FrontendDtmbBandwidth; using ::aidl::android::hardware::tv::tuner::FrontendDtmbGuardInterval; using ::aidl::android::hardware::tv::tuner::FrontendDtmbModulation; using ::aidl::android::hardware::tv::tuner::FrontendDtmbSettings; using ::aidl::android::hardware::tv::tuner::FrontendDtmbTimeInterleaveMode; using ::aidl::android::hardware::tv::tuner::FrontendDtmbTransmissionMode; using ::aidl::android::hardware::tv::tuner::FrontendDvbcAnnex; using ::aidl::android::hardware::tv::tuner::FrontendDvbcBandwidth; using ::aidl::android::hardware::tv::tuner::FrontendDvbcModulation; using ::aidl::android::hardware::tv::tuner::FrontendDvbcSettings; using ::aidl::android::hardware::tv::tuner::FrontendDvbsModulation; using ::aidl::android::hardware::tv::tuner::FrontendDvbsRolloff; using ::aidl::android::hardware::tv::tuner::FrontendDvbsSettings; using ::aidl::android::hardware::tv::tuner::FrontendDvbsStandard; using ::aidl::android::hardware::tv::tuner::FrontendDvbtBandwidth; using ::aidl::android::hardware::tv::tuner::FrontendDvbtConstellation; using ::aidl::android::hardware::tv::tuner::FrontendDvbtGuardInterval; using ::aidl::android::hardware::tv::tuner::FrontendDvbtHierarchy; using ::aidl::android::hardware::tv::tuner::FrontendDvbtSettings; using ::aidl::android::hardware::tv::tuner::FrontendDvbtStandard; using ::aidl::android::hardware::tv::tuner::FrontendDvbtTransmissionMode; using ::aidl::android::hardware::tv::tuner::FrontendGuardInterval; using ::aidl::android::hardware::tv::tuner::FrontendInnerFec; using ::aidl::android::hardware::tv::tuner::FrontendInterleaveMode; using ::aidl::android::hardware::tv::tuner::FrontendIsdbs3Modulation; using ::aidl::android::hardware::tv::tuner::FrontendIsdbs3Rolloff; using ::aidl::android::hardware::tv::tuner::FrontendIsdbs3Settings; using ::aidl::android::hardware::tv::tuner::FrontendIsdbsModulation; using ::aidl::android::hardware::tv::tuner::FrontendIsdbsRolloff; using ::aidl::android::hardware::tv::tuner::FrontendIsdbsSettings; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtBandwidth; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtCoderate; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtGuardInterval; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtMode; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtModulation; using ::aidl::android::hardware::tv::tuner::FrontendIsdbtSettings; using ::aidl::android::hardware::tv::tuner::FrontendModulation; using ::aidl::android::hardware::tv::tuner::FrontendModulationStatus; using ::aidl::android::hardware::tv::tuner::FrontendRollOff; using ::aidl::android::hardware::tv::tuner::FrontendScanAtsc3PlpInfo; using ::aidl::android::hardware::tv::tuner::FrontendScanMessageStandard; using ::aidl::android::hardware::tv::tuner::FrontendSpectralInversion; using ::aidl::android::hardware::tv::tuner::FrontendStatusAtsc3PlpInfo; using ::aidl::android::hardware::tv::tuner::FrontendTransmissionMode; using ::aidl::android::hardware::tv::tuner::Result; using HidlFrontendStatusAtsc3PlpInfo = ::aidl::android::hardware::tv::tuner::FrontendStatusAtsc3PlpInfo; using HidlFrontendAnalogSifStandard = ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard; using HidlFrontendAnalogType = ::android::hardware::tv::tuner::V1_0::FrontendAnalogType; using HidlFrontendAtscModulation = ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation; using HidlFrontendAtsc3Bandwidth = ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Bandwidth; using HidlFrontendAtsc3CodeRate = ::android::hardware::tv::tuner::V1_0::FrontendAtsc3CodeRate; using HidlFrontendAtsc3DemodOutputFormat = ::android::hardware::tv::tuner::V1_0::FrontendAtsc3DemodOutputFormat; using HidlFrontendAtsc3Fec = ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Fec; using HidlFrontendAtsc3Modulation = ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Modulation; using HidlFrontendAtsc3TimeInterleaveMode = ::android::hardware::tv::tuner::V1_0::FrontendAtsc3TimeInterleaveMode; using HidlFrontendDvbcAnnex = ::android::hardware::tv::tuner::V1_0::FrontendDvbcAnnex; using HidlFrontendDvbcModulation = ::android::hardware::tv::tuner::V1_0::FrontendDvbcModulation; using HidlFrontendDvbcOuterFec = ::android::hardware::tv::tuner::V1_0::FrontendDvbcOuterFec; using HidlFrontendDvbcSpectralInversion = ::android::hardware::tv::tuner::V1_0::FrontendDvbcSpectralInversion; using HidlFrontendDvbsModulation = ::android::hardware::tv::tuner::V1_0::FrontendDvbsModulation; using HidlFrontendDvbsPilot = ::android::hardware::tv::tuner::V1_0::FrontendDvbsPilot; using HidlFrontendDvbsRolloff = ::android::hardware::tv::tuner::V1_0::FrontendDvbsRolloff; using HidlFrontendDvbsSettings = ::android::hardware::tv::tuner::V1_0::FrontendDvbsSettings; using HidlFrontendDvbsStandard = ::android::hardware::tv::tuner::V1_0::FrontendDvbsStandard; using HidlFrontendDvbsVcmMode = ::android::hardware::tv::tuner::V1_0::FrontendDvbsVcmMode; using HidlFrontendDvbtBandwidth = ::android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth; using HidlFrontendDvbtCoderate = ::android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate; using HidlFrontendDvbtConstellation = ::android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation; using HidlFrontendDvbtGuardInterval = ::android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval; using HidlFrontendDvbtHierarchy = ::android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy; using HidlFrontendDvbtPlpMode = ::android::hardware::tv::tuner::V1_0::FrontendDvbtPlpMode; using HidlFrontendDvbtSettings = ::android::hardware::tv::tuner::V1_0::FrontendDvbtSettings; using HidlFrontendDvbtStandard = ::android::hardware::tv::tuner::V1_0::FrontendDvbtStandard; using HidlFrontendDvbtTransmissionMode = ::android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode; using HidlFrontendInnerFec = ::android::hardware::tv::tuner::V1_0::FrontendInnerFec; using HidlFrontendIsdbs3Coderate = ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Coderate; using HidlFrontendIsdbs3Modulation = ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Modulation; using HidlFrontendIsdbs3Rolloff = ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Rolloff; using HidlFrontendIsdbs3Settings = ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Settings; using HidlFrontendIsdbsCoderate = ::android::hardware::tv::tuner::V1_0::FrontendIsdbsCoderate; using HidlFrontendIsdbsModulation = ::android::hardware::tv::tuner::V1_0::FrontendIsdbsModulation; using HidlFrontendIsdbsRolloff = ::android::hardware::tv::tuner::V1_0::FrontendIsdbsRolloff; using HidlFrontendIsdbsSettings = ::android::hardware::tv::tuner::V1_0::FrontendIsdbsSettings; using HidlFrontendIsdbsStreamIdType = ::android::hardware::tv::tuner::V1_0::FrontendIsdbsStreamIdType; using HidlFrontendIsdbtBandwidth = ::android::hardware::tv::tuner::V1_0::FrontendIsdbtBandwidth; using HidlFrontendIsdbtCoderate = ::android::hardware::tv::tuner::V1_0::FrontendIsdbtCoderate; using HidlFrontendIsdbtGuardInterval = ::android::hardware::tv::tuner::V1_0::FrontendIsdbtGuardInterval; using HidlFrontendIsdbtMode = ::android::hardware::tv::tuner::V1_0::FrontendIsdbtMode; using HidlFrontendIsdbtModulation = ::android::hardware::tv::tuner::V1_0::FrontendIsdbtModulation; using HidlFrontendIsdbtSettings = ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings; using HidlFrontendModulationStatus = ::android::hardware::tv::tuner::V1_0::FrontendModulationStatus; using HidlFrontendScanAtsc3PlpInfo = ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo; using HidlFrontendScanType = ::android::hardware::tv::tuner::V1_0::FrontendScanType; using HidlFrontendStatusType = ::android::hardware::tv::tuner::V1_0::FrontendStatusType; using HidlResult = ::android::hardware::tv::tuner::V1_0::Result; using HidlFrontendAnalogAftFlag = ::android::hardware::tv::tuner::V1_1::FrontendAnalogAftFlag; using HidlFrontendBandwidth = ::android::hardware::tv::tuner::V1_1::FrontendBandwidth; using HidlFrontendCableTimeInterleaveMode = ::android::hardware::tv::tuner::V1_1::FrontendCableTimeInterleaveMode; using HidlFrontendDvbcBandwidth = ::android::hardware::tv::tuner::V1_1::FrontendDvbcBandwidth; using HidlFrontendDtmbBandwidth = ::android::hardware::tv::tuner::V1_1::FrontendDtmbBandwidth; using HidlFrontendDtmbCodeRate = ::android::hardware::tv::tuner::V1_1::FrontendDtmbCodeRate; using HidlFrontendDtmbGuardInterval = ::android::hardware::tv::tuner::V1_1::FrontendDtmbGuardInterval; using HidlFrontendDtmbModulation = ::android::hardware::tv::tuner::V1_1::FrontendDtmbModulation; using HidlFrontendDtmbTimeInterleaveMode = ::android::hardware::tv::tuner::V1_1::FrontendDtmbTimeInterleaveMode; using HidlFrontendDtmbTransmissionMode = ::android::hardware::tv::tuner::V1_1::FrontendDtmbTransmissionMode; using HidlFrontendDvbsScanType = ::android::hardware::tv::tuner::V1_1::FrontendDvbsScanType; using HidlFrontendGuardInterval = ::android::hardware::tv::tuner::V1_1::FrontendGuardInterval; using HidlFrontendInterleaveMode = ::android::hardware::tv::tuner::V1_1::FrontendInterleaveMode; using HidlFrontendModulation = ::android::hardware::tv::tuner::V1_1::FrontendModulation; using HidlFrontendRollOff = ::android::hardware::tv::tuner::V1_1::FrontendRollOff; using HidlFrontendTransmissionMode = ::android::hardware::tv::tuner::V1_1::FrontendTransmissionMode; using HidlFrontendSpectralInversion = ::android::hardware::tv::tuner::V1_1::FrontendSpectralInversion; using HidlFrontendStatusTypeExt1_1 = ::android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1; using namespace std; namespace aidl { namespace android { namespace media { namespace tv { namespace tuner { TunerHidlFrontend::TunerHidlFrontend(const sp frontend, const int id, const shared_ptr tuner) { mFrontend = frontend; mFrontend_1_1 = ::android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend); mId = id; mTunerService = tuner; } TunerHidlFrontend::~TunerHidlFrontend() { mFrontend = nullptr; mFrontend_1_1 = nullptr; mId = -1; mTunerService = nullptr; } ::ndk::ScopedAStatus TunerHidlFrontend::setCallback( const shared_ptr& tunerFrontendCallback) { if (tunerFrontendCallback == nullptr) { return ::ndk::ScopedAStatus::fromServiceSpecificError( static_cast(Result::INVALID_ARGUMENT)); } sp frontendCallback = new FrontendCallback(tunerFrontendCallback); HidlResult status = mFrontend->setCallback(frontendCallback); if (status == HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::ok(); } return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(status)); } ::ndk::ScopedAStatus TunerHidlFrontend::tune(const FrontendSettings& settings) { HidlResult status; HidlFrontendSettings frontendSettings; HidlFrontendSettingsExt1_1 frontendSettingsExt; getHidlFrontendSettings(settings, frontendSettings, frontendSettingsExt); if (mFrontend_1_1 != nullptr) { status = mFrontend_1_1->tune_1_1(frontendSettings, frontendSettingsExt); } else { status = mFrontend->tune(frontendSettings); } if (status == HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::ok(); } return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(status)); } ::ndk::ScopedAStatus TunerHidlFrontend::stopTune() { HidlResult status = mFrontend->stopTune(); if (status == HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::ok(); } return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(status)); } ::ndk::ScopedAStatus TunerHidlFrontend::scan(const FrontendSettings& settings, FrontendScanType frontendScanType) { HidlResult status; HidlFrontendSettings frontendSettings; HidlFrontendSettingsExt1_1 frontendSettingsExt; getHidlFrontendSettings(settings, frontendSettings, frontendSettingsExt); if (mFrontend_1_1 != nullptr) { status = mFrontend_1_1->scan_1_1(frontendSettings, static_cast(frontendScanType), frontendSettingsExt); } else { status = mFrontend->scan(frontendSettings, static_cast(frontendScanType)); } if (status == HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::ok(); } return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(status)); } ::ndk::ScopedAStatus TunerHidlFrontend::stopScan() { HidlResult status = mFrontend->stopScan(); if (status == HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::ok(); } return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(status)); } ::ndk::ScopedAStatus TunerHidlFrontend::setLnb(const shared_ptr& lnb) { if (lnb == nullptr) { return ::ndk::ScopedAStatus::fromServiceSpecificError( static_cast(Result::INVALID_ARGUMENT)); } HidlResult status = mFrontend->setLnb(static_cast(lnb.get())->getId()); if (status == HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::ok(); } return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(status)); } ::ndk::ScopedAStatus TunerHidlFrontend::linkCiCamToFrontend(int32_t ciCamId, int32_t* _aidl_return) { if (mFrontend_1_1 == nullptr) { ALOGD("IFrontend_1_1 is not initialized"); return ::ndk::ScopedAStatus::fromServiceSpecificError( static_cast(Result::UNAVAILABLE)); } int ltsId; HidlResult status; mFrontend_1_1->linkCiCam(static_cast(ciCamId), [&](HidlResult r, uint32_t id) { status = r; ltsId = id; }); if (status == HidlResult::SUCCESS) { *_aidl_return = ltsId; return ::ndk::ScopedAStatus::ok(); } return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(status)); } ::ndk::ScopedAStatus TunerHidlFrontend::unlinkCiCamToFrontend(int32_t ciCamId) { if (mFrontend_1_1 == nullptr) { ALOGD("IFrontend_1_1 is not initialized"); return ::ndk::ScopedAStatus::fromServiceSpecificError( static_cast(Result::UNAVAILABLE)); } HidlResult status = mFrontend_1_1->unlinkCiCam(ciCamId); if (status == HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::ok(); } return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(status)); } ::ndk::ScopedAStatus TunerHidlFrontend::close() { mTunerService->removeFrontend(this->ref()); HidlResult status = mFrontend->close(); if (status != HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(status)); } return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus TunerHidlFrontend::getStatus(const vector& in_statusTypes, vector* _aidl_return) { HidlResult res; vector status; vector statusExt; vector types; vector typesExt; for (auto s : in_statusTypes) { if (static_cast(s) <= static_cast(HidlFrontendStatusType::ATSC3_PLP_INFO)) { types.push_back(static_cast(s)); } else { typesExt.push_back(static_cast(s)); } } mFrontend->getStatus(types, [&](HidlResult r, const hidl_vec& ss) { res = r; for (auto s : ss) { status.push_back(s); } }); if (res != HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(res)); } if (mFrontend_1_1 != nullptr) { mFrontend_1_1->getStatusExt1_1( typesExt, [&](HidlResult r, const hidl_vec& ss) { res = r; for (auto s : ss) { statusExt.push_back(s); } }); if (res != HidlResult::SUCCESS) { return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast(res)); } } getAidlFrontendStatus(status, statusExt, *_aidl_return); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus TunerHidlFrontend::getFrontendId(int32_t* _aidl_return) { *_aidl_return = mId; return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus TunerHidlFrontend::getHardwareInfo(std::string* _aidl_return) { _aidl_return->clear(); return ::ndk::ScopedAStatus::fromServiceSpecificError( static_cast(Result::UNAVAILABLE)); } ::ndk::ScopedAStatus TunerHidlFrontend::removeOutputPid(int32_t /* in_pid */) { return ::ndk::ScopedAStatus::fromServiceSpecificError( static_cast(Result::UNAVAILABLE)); } ::ndk::ScopedAStatus TunerHidlFrontend::getFrontendStatusReadiness( const std::vector& /* in_statusTypes */, std::vector* _aidl_return) { _aidl_return->clear(); return ::ndk::ScopedAStatus::fromServiceSpecificError( static_cast(Result::UNAVAILABLE)); } void TunerHidlFrontend::setLna(bool bEnable) { mFrontend->setLna(bEnable); } /////////////// FrontendCallback /////////////////////// Return TunerHidlFrontend::FrontendCallback::onEvent(HidlFrontendEventType frontendEventType) { ALOGV("FrontendCallback::onEvent, type=%d", frontendEventType); mTunerFrontendCallback->onEvent(static_cast(frontendEventType)); return Void(); } Return TunerHidlFrontend::FrontendCallback::onScanMessage( HidlFrontendScanMessageType type, const HidlFrontendScanMessage& message) { ALOGV("FrontendCallback::onScanMessage, type=%d", type); FrontendScanMessage scanMessage; switch (type) { case HidlFrontendScanMessageType::LOCKED: { scanMessage.set(message.isLocked()); break; } case HidlFrontendScanMessageType::END: { scanMessage.set(message.isEnd()); break; } case HidlFrontendScanMessageType::PROGRESS_PERCENT: { scanMessage.set(message.progressPercent()); break; } case HidlFrontendScanMessageType::FREQUENCY: { const vector& f = message.frequencies(); vector lf(begin(f), end(f)); scanMessage.set(lf); break; } case HidlFrontendScanMessageType::SYMBOL_RATE: { const vector& s = message.symbolRates(); vector symbolRates(begin(s), end(s)); scanMessage.set(symbolRates); break; } case HidlFrontendScanMessageType::HIERARCHY: { scanMessage.set( static_cast(message.hierarchy())); break; } case HidlFrontendScanMessageType::ANALOG_TYPE: { scanMessage.set( static_cast(message.analogType())); break; } case HidlFrontendScanMessageType::PLP_IDS: { const vector& p = message.plpIds(); vector plpIds(begin(p), end(p)); scanMessage.set(plpIds); break; } case HidlFrontendScanMessageType::GROUP_IDS: { const vector& g = message.groupIds(); vector groupIds(begin(g), end(g)); scanMessage.set(groupIds); break; } case HidlFrontendScanMessageType::INPUT_STREAM_IDS: { const vector& i = message.inputStreamIds(); vector streamIds(begin(i), end(i)); scanMessage.set(streamIds); break; } case HidlFrontendScanMessageType::STANDARD: { const HidlFrontendScanMessage::Standard& std = message.std(); FrontendScanMessageStandard standard; if (std.getDiscriminator() == HidlFrontendScanMessage::Standard::hidl_discriminator::sStd) { standard.set( static_cast(std.sStd())); } else if (std.getDiscriminator() == HidlFrontendScanMessage::Standard::hidl_discriminator::tStd) { standard.set( static_cast(std.tStd())); } else if (std.getDiscriminator() == HidlFrontendScanMessage::Standard::hidl_discriminator::sifStd) { standard.set( static_cast(std.sifStd())); } scanMessage.set(standard); break; } case HidlFrontendScanMessageType::ATSC3_PLP_INFO: { const vector& plpInfos = message.atsc3PlpInfos(); vector tunerPlpInfos; for (int i = 0; i < plpInfos.size(); i++) { FrontendScanAtsc3PlpInfo plpInfo{ .plpId = static_cast(plpInfos[i].plpId), .bLlsFlag = plpInfos[i].bLlsFlag, }; tunerPlpInfos.push_back(plpInfo); } scanMessage.set(tunerPlpInfos); break; } default: break; } mTunerFrontendCallback->onScanMessage(static_cast(type), scanMessage); return Void(); } Return TunerHidlFrontend::FrontendCallback::onScanMessageExt1_1( HidlFrontendScanMessageTypeExt1_1 type, const HidlFrontendScanMessageExt1_1& message) { ALOGV("onScanMessageExt1_1::onScanMessage, type=%d", type); FrontendScanMessage scanMessage; switch (type) { case HidlFrontendScanMessageTypeExt1_1::MODULATION: { HidlFrontendModulation m = message.modulation(); FrontendModulation modulation; switch (m.getDiscriminator()) { case HidlFrontendModulation::hidl_discriminator::dvbc: { modulation.set(static_cast(m.dvbc())); break; } case HidlFrontendModulation::hidl_discriminator::dvbt: { modulation.set( static_cast(m.dvbt())); break; } case HidlFrontendModulation::hidl_discriminator::dvbs: { modulation.set(static_cast(m.dvbs())); break; } case HidlFrontendModulation::hidl_discriminator::isdbs: { modulation.set( static_cast(m.isdbs())); break; } case HidlFrontendModulation::hidl_discriminator::isdbs3: { modulation.set( static_cast(m.isdbs3())); break; } case HidlFrontendModulation::hidl_discriminator::isdbt: { modulation.set( static_cast(m.isdbt())); break; } case HidlFrontendModulation::hidl_discriminator::atsc: { modulation.set(static_cast(m.atsc())); break; } case HidlFrontendModulation::hidl_discriminator::atsc3: { modulation.set( static_cast(m.atsc3())); break; } case HidlFrontendModulation::hidl_discriminator::dtmb: { modulation.set(static_cast(m.dtmb())); break; } } scanMessage.set(modulation); break; } case HidlFrontendScanMessageTypeExt1_1::DVBC_ANNEX: { scanMessage.set( static_cast(message.annex())); break; } case HidlFrontendScanMessageTypeExt1_1::HIGH_PRIORITY: { scanMessage.set(message.isHighPriority()); break; } default: { break; } } mTunerFrontendCallback->onScanMessage(static_cast(type), scanMessage); return Void(); } /////////////// TunerHidlFrontend Helper Methods /////////////////////// void TunerHidlFrontend::getAidlFrontendStatus(const vector& hidlStatus, const vector& hidlStatusExt, vector& aidlStatus) { for (HidlFrontendStatus s : hidlStatus) { FrontendStatus status; switch (s.getDiscriminator()) { case HidlFrontendStatus::hidl_discriminator::isDemodLocked: { status.set(s.isDemodLocked()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::snr: { status.set((int)s.snr()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::ber: { status.set((int)s.ber()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::per: { status.set((int)s.per()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::preBer: { status.set((int)s.preBer()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::signalQuality: { status.set((int)s.signalQuality()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::signalStrength: { status.set((int)s.signalStrength()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::symbolRate: { status.set((int)s.symbolRate()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::innerFec: { status.set(static_cast(s.innerFec())); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::modulation: { FrontendModulationStatus modulationStatus; switch (s.modulation().getDiscriminator()) { case HidlFrontendModulationStatus::hidl_discriminator::dvbc: modulationStatus.set( static_cast(s.modulation().dvbc())); break; case HidlFrontendModulationStatus::hidl_discriminator::dvbs: modulationStatus.set( static_cast(s.modulation().dvbs())); break; case HidlFrontendModulationStatus::hidl_discriminator::isdbs: modulationStatus.set( static_cast(s.modulation().isdbs())); break; case HidlFrontendModulationStatus::hidl_discriminator::isdbs3: modulationStatus.set( static_cast(s.modulation().isdbs3())); break; case HidlFrontendModulationStatus::hidl_discriminator::isdbt: modulationStatus.set( static_cast(s.modulation().isdbt())); break; } status.set(modulationStatus); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::inversion: { status.set( static_cast(s.inversion())); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::lnbVoltage: { status.set(static_cast(s.lnbVoltage())); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::plpId: { status.set((int32_t)s.plpId()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::isEWBS: { status.set(s.isEWBS()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::agc: { status.set((int32_t)s.agc()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::isLnaOn: { status.set(s.isLnaOn()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::isLayerError: { vector e(s.isLayerError().begin(), s.isLayerError().end()); status.set(e); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::mer: { status.set(static_cast(s.mer())); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::freqOffset: { status.set(static_cast(s.freqOffset())); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::hierarchy: { status.set( static_cast(s.hierarchy())); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::isRfLocked: { status.set(s.isRfLocked()); aidlStatus.push_back(status); break; } case HidlFrontendStatus::hidl_discriminator::plpInfo: { vector info; for (auto i : s.plpInfo()) { info.push_back({ .plpId = static_cast(i.plpId), .isLocked = i.isLocked, .uec = static_cast(i.uec), }); } status.set(info); aidlStatus.push_back(status); break; } } } for (HidlFrontendStatusExt1_1 s : hidlStatusExt) { FrontendStatus status; switch (s.getDiscriminator()) { case HidlFrontendStatusExt1_1::hidl_discriminator::modulations: { vector aidlMod; for (auto m : s.modulations()) { switch (m.getDiscriminator()) { case HidlFrontendModulation::hidl_discriminator::dvbc: aidlMod.push_back(static_cast(m.dvbc())); break; case HidlFrontendModulation::hidl_discriminator::dvbs: aidlMod.push_back(static_cast(m.dvbs())); break; case HidlFrontendModulation::hidl_discriminator::dvbt: aidlMod.push_back(static_cast(m.dvbt())); break; case HidlFrontendModulation::hidl_discriminator::isdbs: aidlMod.push_back(static_cast(m.isdbs())); break; case HidlFrontendModulation::hidl_discriminator::isdbs3: aidlMod.push_back(static_cast(m.isdbs3())); break; case HidlFrontendModulation::hidl_discriminator::isdbt: aidlMod.push_back(static_cast(m.isdbt())); break; case HidlFrontendModulation::hidl_discriminator::atsc: aidlMod.push_back(static_cast(m.atsc())); break; case HidlFrontendModulation::hidl_discriminator::atsc3: aidlMod.push_back(static_cast(m.atsc3())); break; case HidlFrontendModulation::hidl_discriminator::dtmb: aidlMod.push_back(static_cast(m.dtmb())); break; } } status.set(aidlMod); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::bers: { vector b(s.bers().begin(), s.bers().end()); status.set(b); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::codeRates: { vector codeRates; for (auto c : s.codeRates()) { codeRates.push_back(static_cast(c)); } status.set(codeRates); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::bandwidth: { FrontendBandwidth bandwidth; switch (s.bandwidth().getDiscriminator()) { case HidlFrontendBandwidth::hidl_discriminator::atsc3: bandwidth.set( static_cast(s.bandwidth().atsc3())); break; case HidlFrontendBandwidth::hidl_discriminator::dvbc: bandwidth.set( static_cast(s.bandwidth().dvbc())); break; case HidlFrontendBandwidth::hidl_discriminator::dvbt: bandwidth.set( static_cast(s.bandwidth().dvbt())); break; case HidlFrontendBandwidth::hidl_discriminator::isdbt: bandwidth.set( static_cast(s.bandwidth().isdbt())); break; case HidlFrontendBandwidth::hidl_discriminator::dtmb: bandwidth.set( static_cast(s.bandwidth().dtmb())); break; } status.set(bandwidth); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::interval: { FrontendGuardInterval interval; switch (s.interval().getDiscriminator()) { case HidlFrontendGuardInterval::hidl_discriminator::dvbt: interval.set( static_cast(s.interval().dvbt())); break; case HidlFrontendGuardInterval::hidl_discriminator::isdbt: interval.set( static_cast(s.interval().isdbt())); break; case HidlFrontendGuardInterval::hidl_discriminator::dtmb: interval.set( static_cast(s.interval().dtmb())); break; } status.set(interval); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::transmissionMode: { FrontendTransmissionMode transmissionMode; switch (s.transmissionMode().getDiscriminator()) { case HidlFrontendTransmissionMode::hidl_discriminator::dvbt: transmissionMode.set( static_cast(s.transmissionMode().dvbt())); break; case HidlFrontendTransmissionMode::hidl_discriminator::isdbt: transmissionMode.set( static_cast(s.transmissionMode().isdbt())); break; case HidlFrontendTransmissionMode::hidl_discriminator::dtmb: transmissionMode.set( static_cast(s.transmissionMode().dtmb())); break; } status.set(transmissionMode); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::uec: { status.set(static_cast(s.uec())); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::systemId: { status.set(static_cast(s.systemId())); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::interleaving: { vector aidlInter; for (auto i : s.interleaving()) { FrontendInterleaveMode leaveMode; switch (i.getDiscriminator()) { case HidlFrontendInterleaveMode::hidl_discriminator::atsc3: leaveMode.set( static_cast(i.atsc3())); break; case HidlFrontendInterleaveMode::hidl_discriminator::dvbc: leaveMode.set( static_cast(i.dvbc())); break; case HidlFrontendInterleaveMode::hidl_discriminator::dtmb: leaveMode.set( static_cast(i.dtmb())); break; } aidlInter.push_back(leaveMode); } status.set(aidlInter); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::isdbtSegment: { const vector& seg = s.isdbtSegment(); vector i(seg.begin(), seg.end()); status.set(i); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::tsDataRate: { vector ts(s.tsDataRate().begin(), s.tsDataRate().end()); status.set(ts); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::rollOff: { FrontendRollOff rollOff; switch (s.rollOff().getDiscriminator()) { case HidlFrontendRollOff::hidl_discriminator::dvbs: rollOff.set( static_cast(s.rollOff().dvbs())); break; case HidlFrontendRollOff::hidl_discriminator::isdbs: rollOff.set( static_cast(s.rollOff().isdbs())); break; case HidlFrontendRollOff::hidl_discriminator::isdbs3: rollOff.set( static_cast(s.rollOff().isdbs3())); break; } status.set(rollOff); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::isMiso: { status.set(s.isMiso()); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::isLinear: { status.set(s.isLinear()); aidlStatus.push_back(status); break; } case HidlFrontendStatusExt1_1::hidl_discriminator::isShortFrames: { status.set(s.isShortFrames()); aidlStatus.push_back(status); break; } } } } hidl_vec TunerHidlFrontend::getAtsc3PlpSettings( const FrontendAtsc3Settings& settings) { int len = settings.plpSettings.size(); hidl_vec plps = hidl_vec(len); // parse PLP settings for (int i = 0; i < len; i++) { uint8_t plpId = static_cast(settings.plpSettings[i].plpId); HidlFrontendAtsc3Modulation modulation = static_cast(settings.plpSettings[i].modulation); HidlFrontendAtsc3TimeInterleaveMode interleaveMode = static_cast( settings.plpSettings[i].interleaveMode); HidlFrontendAtsc3CodeRate codeRate = static_cast(settings.plpSettings[i].codeRate); HidlFrontendAtsc3Fec fec = static_cast(settings.plpSettings[i].fec); HidlFrontendAtsc3PlpSettings frontendAtsc3PlpSettings{ .plpId = plpId, .modulation = modulation, .interleaveMode = interleaveMode, .codeRate = codeRate, .fec = fec, }; plps[i] = frontendAtsc3PlpSettings; } return plps; } HidlFrontendDvbsCodeRate TunerHidlFrontend::getDvbsCodeRate(const FrontendDvbsCodeRate& codeRate) { HidlFrontendInnerFec innerFec = static_cast(codeRate.fec); bool isLinear = codeRate.isLinear; bool isShortFrames = codeRate.isShortFrames; uint32_t bitsPer1000Symbol = static_cast(codeRate.bitsPer1000Symbol); HidlFrontendDvbsCodeRate coderate{ .fec = innerFec, .isLinear = isLinear, .isShortFrames = isShortFrames, .bitsPer1000Symbol = bitsPer1000Symbol, }; return coderate; } void TunerHidlFrontend::getHidlFrontendSettings(const FrontendSettings& aidlSettings, HidlFrontendSettings& settings, HidlFrontendSettingsExt1_1& settingsExt) { switch (aidlSettings.getTag()) { case FrontendSettings::analog: { const FrontendAnalogSettings& analog = aidlSettings.get(); settings.analog({ .frequency = static_cast(analog.frequency), .type = static_cast(analog.type), .sifStandard = static_cast(analog.sifStandard), }); settingsExt.settingExt.analog({ .aftFlag = static_cast(analog.aftFlag), }); settingsExt.endFrequency = static_cast(analog.endFrequency); settingsExt.inversion = static_cast(analog.inversion); break; } case FrontendSettings::atsc: { const FrontendAtscSettings& atsc = aidlSettings.get(); settings.atsc({ .frequency = static_cast(atsc.frequency), .modulation = static_cast(atsc.modulation), }); settingsExt.endFrequency = static_cast(atsc.endFrequency); settingsExt.inversion = static_cast(atsc.inversion); settingsExt.settingExt.noinit(); break; } case FrontendSettings::atsc3: { const FrontendAtsc3Settings& atsc3 = aidlSettings.get(); settings.atsc3({ .frequency = static_cast(atsc3.frequency), .bandwidth = static_cast(atsc3.bandwidth), .demodOutputFormat = static_cast(atsc3.demodOutputFormat), .plpSettings = getAtsc3PlpSettings(atsc3), }); settingsExt.endFrequency = static_cast(atsc3.endFrequency); settingsExt.inversion = static_cast(atsc3.inversion); settingsExt.settingExt.noinit(); break; } case FrontendSettings::dvbc: { const FrontendDvbcSettings& dvbc = aidlSettings.get(); settings.dvbc({ .frequency = static_cast(dvbc.frequency), .modulation = static_cast(dvbc.modulation), .fec = static_cast(dvbc.fec), .symbolRate = static_cast(dvbc.symbolRate), .outerFec = static_cast(dvbc.outerFec), .annex = static_cast(dvbc.annex), .spectralInversion = static_cast(dvbc.inversion), }); settingsExt.settingExt.dvbc({ .interleaveMode = static_cast(dvbc.interleaveMode), .bandwidth = static_cast(dvbc.bandwidth), }); settingsExt.endFrequency = static_cast(dvbc.endFrequency); settingsExt.inversion = static_cast(dvbc.inversion); break; } case FrontendSettings::dvbs: { const FrontendDvbsSettings& dvbs = aidlSettings.get(); settings.dvbs({ .frequency = static_cast(dvbs.frequency), .modulation = static_cast(dvbs.modulation), .coderate = getDvbsCodeRate(dvbs.coderate), .symbolRate = static_cast(dvbs.symbolRate), .rolloff = static_cast(dvbs.rolloff), .pilot = static_cast(dvbs.pilot), .inputStreamId = static_cast(dvbs.inputStreamId), .standard = static_cast(dvbs.standard), .vcmMode = static_cast(dvbs.vcmMode), }); settingsExt.settingExt.dvbs({ .scanType = static_cast(dvbs.scanType), .isDiseqcRxMessage = dvbs.isDiseqcRxMessage, }); settingsExt.endFrequency = static_cast(dvbs.endFrequency); settingsExt.inversion = static_cast(dvbs.inversion); break; } case FrontendSettings::dvbt: { const FrontendDvbtSettings& dvbt = aidlSettings.get(); settings.dvbt({ .frequency = static_cast(dvbt.frequency), .transmissionMode = static_cast(dvbt.transmissionMode), .bandwidth = static_cast(dvbt.bandwidth), .constellation = static_cast(dvbt.constellation), .hierarchy = static_cast(dvbt.hierarchy), .hpCoderate = static_cast(dvbt.hpCoderate), .lpCoderate = static_cast(dvbt.lpCoderate), .guardInterval = static_cast(dvbt.guardInterval), .isHighPriority = dvbt.isHighPriority, .standard = static_cast(dvbt.standard), .isMiso = dvbt.isMiso, .plpMode = static_cast(dvbt.plpMode), .plpId = static_cast(dvbt.plpId), .plpGroupId = static_cast(dvbt.plpGroupId), }); settingsExt.settingExt.dvbt({ .constellation = static_cast< ::android::hardware::tv::tuner::V1_1::FrontendDvbtConstellation>( dvbt.constellation), .transmissionMode = static_cast< ::android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode>( dvbt.transmissionMode), }); settingsExt.endFrequency = static_cast(dvbt.endFrequency); settingsExt.inversion = static_cast(dvbt.inversion); break; } case FrontendSettings::isdbs: { const FrontendIsdbsSettings& isdbs = aidlSettings.get(); settings.isdbs({ .frequency = static_cast(isdbs.frequency), .streamId = static_cast(isdbs.streamId), .streamIdType = static_cast(isdbs.streamIdType), .modulation = static_cast(isdbs.modulation), .coderate = static_cast(isdbs.coderate), .symbolRate = static_cast(isdbs.symbolRate), .rolloff = static_cast(isdbs.rolloff), }); settingsExt.endFrequency = static_cast(isdbs.endFrequency); settingsExt.settingExt.noinit(); break; } case FrontendSettings::isdbs3: { const FrontendIsdbs3Settings& isdbs3 = aidlSettings.get(); settings.isdbs3({ .frequency = static_cast(isdbs3.frequency), .streamId = static_cast(isdbs3.streamId), .streamIdType = static_cast(isdbs3.streamIdType), .modulation = static_cast(isdbs3.modulation), .coderate = static_cast(isdbs3.coderate), .symbolRate = static_cast(isdbs3.symbolRate), .rolloff = static_cast(isdbs3.rolloff), }); settingsExt.endFrequency = static_cast(isdbs3.endFrequency); settingsExt.settingExt.noinit(); break; } case FrontendSettings::isdbt: { const FrontendIsdbtSettings& isdbt = aidlSettings.get(); HidlFrontendIsdbtModulation modulation = HidlFrontendIsdbtModulation::UNDEFINED; HidlFrontendIsdbtCoderate coderate = HidlFrontendIsdbtCoderate::UNDEFINED; if (isdbt.layerSettings.size() > 0) { modulation = static_cast(isdbt.layerSettings[0].modulation); coderate = static_cast(isdbt.layerSettings[0].coderate); } settings.isdbt({ .frequency = static_cast(isdbt.frequency), .modulation = modulation, .bandwidth = static_cast(isdbt.bandwidth), .mode = static_cast(isdbt.mode), .coderate = coderate, .guardInterval = static_cast(isdbt.guardInterval), .serviceAreaId = static_cast(isdbt.serviceAreaId), }); settingsExt.endFrequency = static_cast(isdbt.endFrequency); settingsExt.inversion = static_cast(isdbt.inversion); settingsExt.settingExt.noinit(); break; } case FrontendSettings::dtmb: { const FrontendDtmbSettings& dtmb = aidlSettings.get(); settingsExt.settingExt.dtmb({ .frequency = static_cast(dtmb.frequency), .transmissionMode = static_cast(dtmb.transmissionMode), .bandwidth = static_cast(dtmb.bandwidth), .modulation = static_cast(dtmb.modulation), .codeRate = static_cast(dtmb.codeRate), .guardInterval = static_cast(dtmb.guardInterval), .interleaveMode = static_cast(dtmb.interleaveMode), }); settingsExt.endFrequency = static_cast(dtmb.endFrequency); settingsExt.inversion = static_cast(dtmb.inversion); break; } default: break; } } } // namespace tuner } // namespace tv } // namespace media } // namespace android } // namespace aidl