• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2020, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "TunerFrontend"
18 
19 #include "TunerFrontend.h"
20 #include "TunerLnb.h"
21 
22 using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3PlpSettings;
23 using ::aidl::android::media::tv::tuner::TunerFrontendScanAtsc3PlpInfo;
24 using ::aidl::android::media::tv::tuner::TunerFrontendStatusAtsc3PlpInfo;
25 using ::aidl::android::media::tv::tuner::TunerFrontendUnionSettings;
26 using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard;
27 using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType;
28 using ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
29 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Bandwidth;
30 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3CodeRate;
31 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3DemodOutputFormat;
32 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Fec;
33 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Modulation;
34 using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3TimeInterleaveMode;
35 using ::android::hardware::tv::tuner::V1_0::FrontendDvbcAnnex;
36 using ::android::hardware::tv::tuner::V1_0::FrontendDvbcModulation;
37 using ::android::hardware::tv::tuner::V1_0::FrontendDvbcOuterFec;
38 using ::android::hardware::tv::tuner::V1_0::FrontendDvbcSpectralInversion;
39 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsModulation;
40 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsPilot;
41 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsRolloff;
42 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsSettings;
43 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsStandard;
44 using ::android::hardware::tv::tuner::V1_0::FrontendDvbsVcmMode;
45 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
46 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
47 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
48 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
49 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
50 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtPlpMode;
51 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
52 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
53 using ::android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
54 using ::android::hardware::tv::tuner::V1_0::FrontendInnerFec;
55 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Coderate;
56 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Modulation;
57 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Rolloff;
58 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Settings;
59 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsCoderate;
60 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsModulation;
61 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsRolloff;
62 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsSettings;
63 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsStreamIdType;
64 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtBandwidth;
65 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtCoderate;
66 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtGuardInterval;
67 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtMode;
68 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtModulation;
69 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings;
70 using ::android::hardware::tv::tuner::V1_0::FrontendModulationStatus;
71 using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo;
72 using ::android::hardware::tv::tuner::V1_0::FrontendScanType;
73 using ::android::hardware::tv::tuner::V1_0::FrontendStatusType;
74 using ::android::hardware::tv::tuner::V1_0::Result;
75 using ::android::hardware::tv::tuner::V1_1::FrontendAnalogAftFlag;
76 using ::android::hardware::tv::tuner::V1_1::FrontendBandwidth;
77 using ::android::hardware::tv::tuner::V1_1::FrontendCableTimeInterleaveMode;
78 using ::android::hardware::tv::tuner::V1_1::FrontendDvbcBandwidth;
79 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbBandwidth;
80 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbCodeRate;
81 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbGuardInterval;
82 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbModulation;
83 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbTimeInterleaveMode;
84 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbTransmissionMode;
85 using ::android::hardware::tv::tuner::V1_1::FrontendDvbsScanType;
86 using ::android::hardware::tv::tuner::V1_1::FrontendGuardInterval;
87 using ::android::hardware::tv::tuner::V1_1::FrontendInterleaveMode;
88 using ::android::hardware::tv::tuner::V1_1::FrontendModulation;
89 using ::android::hardware::tv::tuner::V1_1::FrontendRollOff;
90 using ::android::hardware::tv::tuner::V1_1::FrontendTransmissionMode;
91 using ::android::hardware::tv::tuner::V1_1::FrontendSpectralInversion;
92 using ::android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1;
93 
94 namespace android {
95 
TunerFrontend(sp<IFrontend> frontend,int id)96 TunerFrontend::TunerFrontend(sp<IFrontend> frontend, int id) {
97     mFrontend = frontend;
98     mFrontend_1_1 = ::android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
99     mId = id;
100 }
101 
~TunerFrontend()102 TunerFrontend::~TunerFrontend() {
103     mFrontend = NULL;
104     mFrontend_1_1 = NULL;
105     mId = -1;
106 }
107 
setCallback(const shared_ptr<ITunerFrontendCallback> & tunerFrontendCallback)108 Status TunerFrontend::setCallback(
109         const shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) {
110     if (mFrontend == NULL) {
111         ALOGE("IFrontend is not initialized");
112         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
113     }
114 
115     if (tunerFrontendCallback == NULL) {
116         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_ARGUMENT));
117     }
118 
119     sp<IFrontendCallback> frontendCallback = new FrontendCallback(tunerFrontendCallback);
120     Result status = mFrontend->setCallback(frontendCallback);
121     if (status == Result::SUCCESS) {
122         return Status::ok();
123     }
124 
125     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
126 }
127 
tune(const TunerFrontendSettings & settings)128 Status TunerFrontend::tune(const TunerFrontendSettings& settings) {
129     if (mFrontend == NULL) {
130         ALOGE("IFrontend is not initialized");
131         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
132     }
133 
134     Result status;
135     FrontendSettings frontendSettings = getHidlFrontendSettings(settings);
136     if (settings.isExtended) {
137         if (mFrontend_1_1 == NULL) {
138             ALOGE("IFrontend_1_1 is not initialized");
139             return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
140         }
141         FrontendSettingsExt1_1 frontendSettingsExt = getHidlFrontendSettingsExt(settings);
142         status = mFrontend_1_1->tune_1_1(frontendSettings, frontendSettingsExt);
143     } else {
144         status = mFrontend->tune(frontendSettings);
145     }
146 
147     if (status == Result::SUCCESS) {
148         return Status::ok();
149     }
150 
151     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
152 }
153 
stopTune()154 Status TunerFrontend::stopTune() {
155     if (mFrontend == NULL) {
156         ALOGD("IFrontend is not initialized");
157         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
158     }
159 
160     Result status = mFrontend->stopTune();
161     if (status == Result::SUCCESS) {
162         return Status::ok();
163     }
164 
165     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
166 }
167 
scan(const TunerFrontendSettings & settings,int frontendScanType)168 Status TunerFrontend::scan(const TunerFrontendSettings& settings, int frontendScanType) {
169     if (mFrontend == NULL) {
170         ALOGD("IFrontend is not initialized");
171         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
172     }
173 
174     Result status;
175     FrontendSettings frontendSettings = getHidlFrontendSettings(settings);
176     if (settings.isExtended) {
177         if (mFrontend_1_1 == NULL) {
178             ALOGE("IFrontend_1_1 is not initialized");
179             return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
180         }
181         FrontendSettingsExt1_1 frontendSettingsExt = getHidlFrontendSettingsExt(settings);
182         status = mFrontend_1_1->scan_1_1(frontendSettings,
183                 static_cast<FrontendScanType>(frontendScanType), frontendSettingsExt);
184     } else {
185         status = mFrontend->scan(
186                 frontendSettings, static_cast<FrontendScanType>(frontendScanType));
187     }
188 
189     if (status == Result::SUCCESS) {
190         return Status::ok();
191     }
192 
193     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
194 }
195 
stopScan()196 Status TunerFrontend::stopScan() {
197     if (mFrontend == NULL) {
198         ALOGD("IFrontend is not initialized");
199         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
200     }
201 
202     Result status = mFrontend->stopScan();
203     if (status == Result::SUCCESS) {
204         return Status::ok();
205     }
206 
207     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
208 }
209 
setLnb(const shared_ptr<ITunerLnb> & lnb)210 Status TunerFrontend::setLnb(const shared_ptr<ITunerLnb>& lnb) {
211     if (mFrontend == NULL) {
212         ALOGD("IFrontend is not initialized");
213         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
214     }
215 
216     Result status = mFrontend->setLnb(static_cast<TunerLnb*>(lnb.get())->getId());
217     if (status == Result::SUCCESS) {
218         return Status::ok();
219     }
220 
221     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
222 }
223 
setLna(bool bEnable)224 Status TunerFrontend::setLna(bool bEnable) {
225     if (mFrontend == NULL) {
226         ALOGD("IFrontend is not initialized");
227         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
228     }
229 
230     Result status = mFrontend->setLna(bEnable);
231     if (status == Result::SUCCESS) {
232         return Status::ok();
233     }
234 
235     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
236 }
237 
linkCiCamToFrontend(int ciCamId,int32_t * _aidl_return)238 Status TunerFrontend::linkCiCamToFrontend(int ciCamId, int32_t* _aidl_return) {
239     if (mFrontend_1_1 == NULL) {
240         ALOGD("IFrontend_1_1 is not initialized");
241         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
242     }
243 
244     int ltsId;
245     Result status;
246     mFrontend_1_1->linkCiCam(static_cast<uint32_t>(ciCamId),
247             [&](Result r, uint32_t id) {
248                 status = r;
249                 ltsId = id;
250             });
251 
252     if (status == Result::SUCCESS) {
253         *_aidl_return = ltsId;
254         return Status::ok();
255     }
256 
257     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
258 }
259 
unlinkCiCamToFrontend(int ciCamId)260 Status TunerFrontend::unlinkCiCamToFrontend(int ciCamId) {
261     if (mFrontend_1_1 == NULL) {
262         ALOGD("IFrontend_1_1 is not initialized");
263         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
264     }
265 
266     Result status = mFrontend_1_1->unlinkCiCam(ciCamId);
267     if (status == Result::SUCCESS) {
268         return Status::ok();
269     }
270 
271     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
272 }
273 
close()274 Status TunerFrontend::close() {
275     if (mFrontend == NULL) {
276         ALOGD("IFrontend is not initialized");
277         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
278     }
279 
280     Result status = mFrontend->close();
281     mFrontend = NULL;
282     mFrontend_1_1 = NULL;
283 
284     if (status != Result::SUCCESS) {
285         return Status::fromServiceSpecificError(static_cast<int32_t>(status));
286     }
287     return Status::ok();
288 }
289 
getStatus(const vector<int32_t> & statusTypes,vector<TunerFrontendStatus> * _aidl_return)290 Status TunerFrontend::getStatus(const vector<int32_t>& statusTypes,
291         vector<TunerFrontendStatus>* _aidl_return) {
292     if (mFrontend == NULL) {
293         ALOGD("IFrontend is not initialized");
294         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
295     }
296 
297     Result res;
298     vector<FrontendStatus> status;
299     vector<FrontendStatusType> types;
300     for (auto s : statusTypes) {
301         types.push_back(static_cast<FrontendStatusType>(s));
302     }
303 
304     mFrontend->getStatus(types, [&](Result r, const hidl_vec<FrontendStatus>& s) {
305         res = r;
306         status = s;
307     });
308     if (res != Result::SUCCESS) {
309         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
310     }
311 
312     getAidlFrontendStatus(status, *_aidl_return);
313     return Status::ok();
314 }
315 
getStatusExtended_1_1(const vector<int32_t> & statusTypes,vector<TunerFrontendStatus> * _aidl_return)316 Status TunerFrontend::getStatusExtended_1_1(const vector<int32_t>& statusTypes,
317         vector<TunerFrontendStatus>* _aidl_return) {
318     if (mFrontend_1_1 == NULL) {
319         ALOGD("IFrontend_1_1 is not initialized");
320         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
321     }
322 
323     Result res;
324     vector<FrontendStatusExt1_1> status;
325     vector<FrontendStatusTypeExt1_1> types;
326     for (auto s : statusTypes) {
327         types.push_back(static_cast<FrontendStatusTypeExt1_1>(s));
328     }
329 
330     mFrontend_1_1->getStatusExt1_1(types, [&](Result r, const hidl_vec<FrontendStatusExt1_1>& s) {
331         res = r;
332         status = s;
333     });
334     if (res != Result::SUCCESS) {
335         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
336     }
337 
338     getAidlFrontendStatusExt(status, *_aidl_return);
339     return Status::ok();
340 }
341 
getFrontendId(int * _aidl_return)342 Status TunerFrontend::getFrontendId(int* _aidl_return) {
343     *_aidl_return = mId;
344     return Status::ok();
345 }
346 
347 /////////////// FrontendCallback ///////////////////////
348 
onEvent(FrontendEventType frontendEventType)349 Return<void> TunerFrontend::FrontendCallback::onEvent(FrontendEventType frontendEventType) {
350     ALOGD("FrontendCallback::onEvent, type=%d", frontendEventType);
351     mTunerFrontendCallback->onEvent((int)frontendEventType);
352     return Void();
353 }
354 
onScanMessage(FrontendScanMessageType type,const FrontendScanMessage & message)355 Return<void> TunerFrontend::FrontendCallback::onScanMessage(
356         FrontendScanMessageType type, const FrontendScanMessage& message) {
357     ALOGD("FrontendCallback::onScanMessage, type=%d", type);
358     TunerFrontendScanMessage scanMessage;
359     switch(type) {
360         case FrontendScanMessageType::LOCKED: {
361             scanMessage.set<TunerFrontendScanMessage::isLocked>(message.isLocked());
362             break;
363         }
364         case FrontendScanMessageType::END: {
365             scanMessage.set<TunerFrontendScanMessage::isEnd>(message.isEnd());
366             break;
367         }
368         case FrontendScanMessageType::PROGRESS_PERCENT: {
369             scanMessage.set<TunerFrontendScanMessage::progressPercent>(message.progressPercent());
370             break;
371         }
372         case FrontendScanMessageType::FREQUENCY: {
373             auto f = message.frequencies();
374             vector<int> frequencies(begin(f), end(f));
375             scanMessage.set<TunerFrontendScanMessage::frequencies>(frequencies);
376             break;
377         }
378         case FrontendScanMessageType::SYMBOL_RATE: {
379             auto s = message.symbolRates();
380             vector<int> symbolRates(begin(s), end(s));
381             scanMessage.set<TunerFrontendScanMessage::symbolRates>(symbolRates);
382             break;
383         }
384         case FrontendScanMessageType::HIERARCHY: {
385             scanMessage.set<TunerFrontendScanMessage::hierarchy>((int)message.hierarchy());
386             break;
387         }
388         case FrontendScanMessageType::ANALOG_TYPE: {
389             scanMessage.set<TunerFrontendScanMessage::analogType>((int)message.analogType());
390             break;
391         }
392         case FrontendScanMessageType::PLP_IDS: {
393             auto p = message.plpIds();
394             vector<uint8_t> plpIds(begin(p), end(p));
395             scanMessage.set<TunerFrontendScanMessage::plpIds>(plpIds);
396             break;
397         }
398         case FrontendScanMessageType::GROUP_IDS: {
399             auto g = message.groupIds();
400             vector<uint8_t> groupIds(begin(g), end(g));
401             scanMessage.set<TunerFrontendScanMessage::groupIds>(groupIds);
402             break;
403         }
404         case FrontendScanMessageType::INPUT_STREAM_IDS: {
405             auto i = message.inputStreamIds();
406             vector<char16_t> streamIds(begin(i), end(i));
407             scanMessage.set<TunerFrontendScanMessage::inputStreamIds>(streamIds);
408             break;
409         }
410         case FrontendScanMessageType::STANDARD: {
411             FrontendScanMessage::Standard std = message.std();
412             int standard;
413             if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) {
414                 standard = (int) std.sStd();
415             } else if (std.getDiscriminator() ==
416                     FrontendScanMessage::Standard::hidl_discriminator::tStd) {
417                 standard = (int) std.tStd();
418             } else if (std.getDiscriminator() ==
419                     FrontendScanMessage::Standard::hidl_discriminator::sifStd) {
420                 standard = (int) std.sifStd();
421             }
422             scanMessage.set<TunerFrontendScanMessage::std>(standard);
423             break;
424         }
425         case FrontendScanMessageType::ATSC3_PLP_INFO: {
426             vector<FrontendScanAtsc3PlpInfo> plpInfos = message.atsc3PlpInfos();
427             vector<TunerFrontendScanAtsc3PlpInfo> tunerPlpInfos;
428             for (int i = 0; i < plpInfos.size(); i++) {
429                 auto info = plpInfos[i];
430                 int8_t plpId = (int8_t) info.plpId;
431                 bool lls = (bool) info.bLlsFlag;
432                 TunerFrontendScanAtsc3PlpInfo plpInfo{
433                     .plpId = plpId,
434                     .llsFlag = lls,
435                 };
436                 tunerPlpInfos.push_back(plpInfo);
437             }
438             scanMessage.set<TunerFrontendScanMessage::atsc3PlpInfos>(tunerPlpInfos);
439             break;
440         }
441         default:
442             break;
443     }
444     mTunerFrontendCallback->onScanMessage((int)type, scanMessage);
445     return Void();
446 }
447 
onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type,const FrontendScanMessageExt1_1 & message)448 Return<void> TunerFrontend::FrontendCallback::onScanMessageExt1_1(
449         FrontendScanMessageTypeExt1_1 type, const FrontendScanMessageExt1_1& message) {
450     ALOGD("onScanMessageExt1_1::onScanMessage, type=%d", type);
451     TunerFrontendScanMessage scanMessage;
452     switch(type) {
453         case FrontendScanMessageTypeExt1_1::MODULATION: {
454             FrontendModulation m = message.modulation();
455             int modulation;
456             switch (m.getDiscriminator()) {
457                 case FrontendModulation::hidl_discriminator::dvbc:
458                     modulation = (int) m.dvbc();
459                     break;
460                 case FrontendModulation::hidl_discriminator::dvbt:
461                     modulation = (int) m.dvbt();
462                     break;
463                 case FrontendModulation::hidl_discriminator::dvbs:
464                     modulation = (int) m.dvbs();
465                     break;
466                 case FrontendModulation::hidl_discriminator::isdbs:
467                     modulation = (int) m.isdbs();
468                     break;
469                 case FrontendModulation::hidl_discriminator::isdbs3:
470                     modulation = (int) m.isdbs3();
471                     break;
472                 case FrontendModulation::hidl_discriminator::isdbt:
473                     modulation = (int) m.isdbt();
474                     break;
475                 case FrontendModulation::hidl_discriminator::atsc:
476                     modulation = (int) m.atsc();
477                     break;
478                 case FrontendModulation::hidl_discriminator::atsc3:
479                     modulation = (int) m.atsc3();
480                     break;
481                 case FrontendModulation::hidl_discriminator::dtmb:
482                     modulation = (int) m.dtmb();
483                     break;
484             }
485             scanMessage.set<TunerFrontendScanMessage::modulation>(modulation);
486             break;
487         }
488         case FrontendScanMessageTypeExt1_1::DVBC_ANNEX: {
489             scanMessage.set<TunerFrontendScanMessage::annex>((int)message.annex());
490             break;
491         }
492         case FrontendScanMessageTypeExt1_1::HIGH_PRIORITY: {
493             scanMessage.set<TunerFrontendScanMessage::isHighPriority>(message.isHighPriority());
494             break;
495         }
496         default:
497             break;
498     }
499     mTunerFrontendCallback->onScanMessage((int)type, scanMessage);
500     return Void();
501 }
502 
503 /////////////// TunerFrontend Helper Methods ///////////////////////
504 
getAidlFrontendStatus(vector<FrontendStatus> & hidlStatus,vector<TunerFrontendStatus> & aidlStatus)505 void TunerFrontend::getAidlFrontendStatus(
506         vector<FrontendStatus>& hidlStatus, vector<TunerFrontendStatus>& aidlStatus) {
507     for (FrontendStatus s : hidlStatus) {
508         TunerFrontendStatus status;
509         switch (s.getDiscriminator()) {
510             case FrontendStatus::hidl_discriminator::isDemodLocked: {
511                 status.set<TunerFrontendStatus::isDemodLocked>(s.isDemodLocked());
512                 aidlStatus.push_back(status);
513                 break;
514             }
515             case FrontendStatus::hidl_discriminator::snr: {
516                 status.set<TunerFrontendStatus::snr>((int)s.snr());
517                 aidlStatus.push_back(status);
518                 break;
519             }
520             case FrontendStatus::hidl_discriminator::ber: {
521                 status.set<TunerFrontendStatus::ber>((int)s.ber());
522                 aidlStatus.push_back(status);
523                 break;
524             }
525             case FrontendStatus::hidl_discriminator::per: {
526                 status.set<TunerFrontendStatus::per>((int)s.per());
527                 aidlStatus.push_back(status);
528                 break;
529             }
530             case FrontendStatus::hidl_discriminator::preBer: {
531                 status.set<TunerFrontendStatus::preBer>((int)s.preBer());
532                 aidlStatus.push_back(status);
533                 break;
534             }
535             case FrontendStatus::hidl_discriminator::signalQuality: {
536                 status.set<TunerFrontendStatus::signalQuality>((int)s.signalQuality());
537                 aidlStatus.push_back(status);
538                 break;
539             }
540             case FrontendStatus::hidl_discriminator::signalStrength: {
541                 status.set<TunerFrontendStatus::signalStrength>((int)s.signalStrength());
542                 aidlStatus.push_back(status);
543                 break;
544             }
545             case FrontendStatus::hidl_discriminator::symbolRate: {
546                 status.set<TunerFrontendStatus::symbolRate>((int)s.symbolRate());
547                 aidlStatus.push_back(status);
548                 break;
549             }
550             case FrontendStatus::hidl_discriminator::innerFec: {
551                 status.set<TunerFrontendStatus::innerFec>((long)s.innerFec());
552                 aidlStatus.push_back(status);
553                 break;
554             }
555             case FrontendStatus::hidl_discriminator::modulation: {
556                 switch (s.modulation().getDiscriminator()) {
557                     case FrontendModulationStatus::hidl_discriminator::dvbc:
558                         status.set<TunerFrontendStatus::modulation>((int)s.modulation().dvbc());
559                         aidlStatus.push_back(status);
560                         break;
561                     case FrontendModulationStatus::hidl_discriminator::dvbs:
562                         status.set<TunerFrontendStatus::modulation>((int)s.modulation().dvbs());
563                         aidlStatus.push_back(status);
564                         break;
565                     case FrontendModulationStatus::hidl_discriminator::isdbs:
566                         status.set<TunerFrontendStatus::modulation>((int)s.modulation().isdbs());
567                         aidlStatus.push_back(status);
568                         break;
569                     case FrontendModulationStatus::hidl_discriminator::isdbs3:
570                         status.set<TunerFrontendStatus::modulation>((int)s.modulation().isdbs3());
571                         aidlStatus.push_back(status);
572                         break;
573                     case FrontendModulationStatus::hidl_discriminator::isdbt:
574                         status.set<TunerFrontendStatus::modulation>((int)s.modulation().isdbt());
575                         aidlStatus.push_back(status);
576                         break;
577                 }
578                 break;
579             }
580             case FrontendStatus::hidl_discriminator::inversion: {
581                 status.set<TunerFrontendStatus::inversion>((int)s.inversion());
582                 aidlStatus.push_back(status);
583                 break;
584             }
585             case FrontendStatus::hidl_discriminator::lnbVoltage: {
586                 status.set<TunerFrontendStatus::lnbVoltage>((int)s.lnbVoltage());
587                 aidlStatus.push_back(status);
588                 break;
589             }
590             case FrontendStatus::hidl_discriminator::plpId: {
591                 status.set<TunerFrontendStatus::plpId>((int8_t)s.plpId());
592                 aidlStatus.push_back(status);
593                 break;
594             }
595             case FrontendStatus::hidl_discriminator::isEWBS: {
596                 status.set<TunerFrontendStatus::isEWBS>(s.isEWBS());
597                 aidlStatus.push_back(status);
598                 break;
599             }
600             case FrontendStatus::hidl_discriminator::agc: {
601                 status.set<TunerFrontendStatus::agc>((int8_t)s.agc());
602                 aidlStatus.push_back(status);
603                 break;
604             }
605             case FrontendStatus::hidl_discriminator::isLnaOn: {
606                 status.set<TunerFrontendStatus::isLnaOn>(s.isLnaOn());
607                 aidlStatus.push_back(status);
608                 break;
609             }
610             case FrontendStatus::hidl_discriminator::isLayerError: {
611                 vector<bool> e(s.isLayerError().begin(), s.isLayerError().end());
612                 status.set<TunerFrontendStatus::isLayerError>(e);
613                 aidlStatus.push_back(status);
614                 break;
615             }
616             case FrontendStatus::hidl_discriminator::mer: {
617                 status.set<TunerFrontendStatus::mer>((int)s.mer());
618                 aidlStatus.push_back(status);
619                 break;
620             }
621             case FrontendStatus::hidl_discriminator::freqOffset: {
622                 status.set<TunerFrontendStatus::freqOffset>((int)s.freqOffset());
623                 aidlStatus.push_back(status);
624                 break;
625             }
626             case FrontendStatus::hidl_discriminator::hierarchy: {
627                 status.set<TunerFrontendStatus::hierarchy>((int)s.hierarchy());
628                 aidlStatus.push_back(status);
629                 break;
630             }
631             case FrontendStatus::hidl_discriminator::isRfLocked: {
632                 status.set<TunerFrontendStatus::isRfLocked>(s.isRfLocked());
633                 aidlStatus.push_back(status);
634                 break;
635             }
636             case FrontendStatus::hidl_discriminator::plpInfo: {
637                 vector<TunerFrontendStatusAtsc3PlpInfo> info;
638                 for (auto i : s.plpInfo()) {
639                     info.push_back({
640                         .plpId = (int8_t)i.plpId,
641                         .isLocked = i.isLocked,
642                         .uec = (int)i.uec,
643                     });
644                 }
645                 status.set<TunerFrontendStatus::plpInfo>(info);
646                 aidlStatus.push_back(status);
647                 break;
648             }
649         }
650     }
651 }
652 
getAidlFrontendStatusExt(vector<FrontendStatusExt1_1> & hidlStatus,vector<TunerFrontendStatus> & aidlStatus)653 void TunerFrontend::getAidlFrontendStatusExt(
654         vector<FrontendStatusExt1_1>& hidlStatus, vector<TunerFrontendStatus>& aidlStatus) {
655     for (FrontendStatusExt1_1 s : hidlStatus) {
656         TunerFrontendStatus status;
657         switch (s.getDiscriminator()) {
658             case FrontendStatusExt1_1::hidl_discriminator::modulations: {
659                 vector<int> aidlMod;
660                 for (auto m : s.modulations()) {
661                     switch (m.getDiscriminator()) {
662                         case FrontendModulation::hidl_discriminator::dvbc:
663                             aidlMod.push_back((int)m.dvbc());
664                             break;
665                         case FrontendModulation::hidl_discriminator::dvbs:
666                             aidlMod.push_back((int)m.dvbs());
667                             break;
668                         case FrontendModulation::hidl_discriminator::dvbt:
669                             aidlMod.push_back((int)m.dvbt());
670                             break;
671                         case FrontendModulation::hidl_discriminator::isdbs:
672                             aidlMod.push_back((int)m.isdbs());
673                             break;
674                         case FrontendModulation::hidl_discriminator::isdbs3:
675                             aidlMod.push_back((int)m.isdbs3());
676                             break;
677                         case FrontendModulation::hidl_discriminator::isdbt:
678                             aidlMod.push_back((int)m.isdbt());
679                             break;
680                         case FrontendModulation::hidl_discriminator::atsc:
681                             aidlMod.push_back((int)m.atsc());
682                             break;
683                         case FrontendModulation::hidl_discriminator::atsc3:
684                             aidlMod.push_back((int)m.atsc3());
685                             break;
686                         case FrontendModulation::hidl_discriminator::dtmb:
687                             aidlMod.push_back((int)m.dtmb());
688                             break;
689                     }
690                 }
691                 status.set<TunerFrontendStatus::modulations>(aidlMod);
692                 aidlStatus.push_back(status);
693                 break;
694             }
695             case FrontendStatusExt1_1::hidl_discriminator::bers: {
696                 vector<int> b(s.bers().begin(), s.bers().end());
697                 status.set<TunerFrontendStatus::bers>(b);
698                 aidlStatus.push_back(status);
699                 break;
700             }
701             case FrontendStatusExt1_1::hidl_discriminator::codeRates: {
702                 vector<int64_t> codeRates;
703                 for (auto c : s.codeRates()) {
704                     codeRates.push_back((long)c);
705                 }
706                 status.set<TunerFrontendStatus::codeRates>(codeRates);
707                 aidlStatus.push_back(status);
708                 break;
709             }
710             case FrontendStatusExt1_1::hidl_discriminator::bandwidth: {
711                 switch (s.bandwidth().getDiscriminator()) {
712                     case FrontendBandwidth::hidl_discriminator::atsc3:
713                         status.set<TunerFrontendStatus::bandwidth>((int)s.bandwidth().atsc3());
714                         break;
715                     case FrontendBandwidth::hidl_discriminator::dvbc:
716                         status.set<TunerFrontendStatus::bandwidth>((int)s.bandwidth().dvbc());
717                         break;
718                     case FrontendBandwidth::hidl_discriminator::dvbt:
719                         status.set<TunerFrontendStatus::bandwidth>((int)s.bandwidth().dvbt());
720                         break;
721                     case FrontendBandwidth::hidl_discriminator::isdbt:
722                         status.set<TunerFrontendStatus::bandwidth>((int)s.bandwidth().isdbt());
723                         break;
724                     case FrontendBandwidth::hidl_discriminator::dtmb:
725                         status.set<TunerFrontendStatus::bandwidth>((int)s.bandwidth().dtmb());
726                         break;
727                 }
728                 aidlStatus.push_back(status);
729                 break;
730             }
731             case FrontendStatusExt1_1::hidl_discriminator::interval: {
732                 switch (s.interval().getDiscriminator()) {
733                     case FrontendGuardInterval::hidl_discriminator::dvbt:
734                         status.set<TunerFrontendStatus::interval>((int)s.interval().dvbt());
735                         break;
736                     case FrontendGuardInterval::hidl_discriminator::isdbt:
737                         status.set<TunerFrontendStatus::interval>((int)s.interval().isdbt());
738                         break;
739                     case FrontendGuardInterval::hidl_discriminator::dtmb:
740                         status.set<TunerFrontendStatus::interval>((int)s.interval().dtmb());
741                         break;
742                 }
743                 aidlStatus.push_back(status);
744                 break;
745             }
746             case FrontendStatusExt1_1::hidl_discriminator::transmissionMode: {
747                 switch (s.transmissionMode().getDiscriminator()) {
748                     case FrontendTransmissionMode::hidl_discriminator::dvbt:
749                         status.set<TunerFrontendStatus::transmissionMode>(
750                                 (int)s.transmissionMode().dvbt());
751                         break;
752                     case FrontendTransmissionMode::hidl_discriminator::isdbt:
753                         status.set<TunerFrontendStatus::transmissionMode>(
754                                 (int)s.transmissionMode().isdbt());
755                         break;
756                     case FrontendTransmissionMode::hidl_discriminator::dtmb:
757                         status.set<TunerFrontendStatus::transmissionMode>(
758                                 (int)s.transmissionMode().dtmb());
759                         break;
760                 }
761                 aidlStatus.push_back(status);
762                 break;
763             }
764             case FrontendStatusExt1_1::hidl_discriminator::uec: {
765                 status.set<TunerFrontendStatus::uec>((int)s.uec());
766                 aidlStatus.push_back(status);
767                 break;
768             }
769             case FrontendStatusExt1_1::hidl_discriminator::systemId: {
770                 status.set<TunerFrontendStatus::systemId>((char16_t)s.systemId());
771                 aidlStatus.push_back(status);
772                 break;
773             }
774             case FrontendStatusExt1_1::hidl_discriminator::interleaving: {
775                 vector<int> aidlInter;
776                 for (auto i : s.interleaving()) {
777                     switch (i.getDiscriminator()) {
778                         case FrontendInterleaveMode::hidl_discriminator::atsc3:
779                             aidlInter.push_back((int)i.atsc3());
780                             break;
781                         case FrontendInterleaveMode::hidl_discriminator::dvbc:
782                             aidlInter.push_back((int)i.dvbc());
783                             break;
784                         case FrontendInterleaveMode::hidl_discriminator::dtmb:
785                             aidlInter.push_back((int)i.dtmb());
786                             break;
787                     }
788                 }
789                 status.set<TunerFrontendStatus::interleaving>(aidlInter);
790                 aidlStatus.push_back(status);
791                 break;
792             }
793             case FrontendStatusExt1_1::hidl_discriminator::isdbtSegment: {
794                 auto seg = s.isdbtSegment();
795                 vector<uint8_t> i(seg.begin(), seg.end());
796                 status.set<TunerFrontendStatus::isdbtSegment>(i);
797                 aidlStatus.push_back(status);
798                 break;
799             }
800             case FrontendStatusExt1_1::hidl_discriminator::tsDataRate: {
801                 vector<int> ts(s.tsDataRate().begin(), s.tsDataRate().end());
802                 status.set<TunerFrontendStatus::tsDataRate>(ts);
803                 aidlStatus.push_back(status);
804                 break;
805             }
806             case FrontendStatusExt1_1::hidl_discriminator::rollOff: {
807                 switch (s.rollOff().getDiscriminator()) {
808                     case FrontendRollOff::hidl_discriminator::dvbs:
809                         status.set<TunerFrontendStatus::rollOff>((int)s.rollOff().dvbs());
810                         break;
811                     case FrontendRollOff::hidl_discriminator::isdbs:
812                         status.set<TunerFrontendStatus::rollOff>((int)s.rollOff().isdbs());
813                         break;
814                     case FrontendRollOff::hidl_discriminator::isdbs3:
815                         status.set<TunerFrontendStatus::rollOff>((int)s.rollOff().isdbs3());
816                         break;
817                 }
818                 aidlStatus.push_back(status);
819                 break;
820             }
821             case FrontendStatusExt1_1::hidl_discriminator::isMiso: {
822                 status.set<TunerFrontendStatus::isMiso>(s.isMiso());
823                 aidlStatus.push_back(status);
824                 break;
825             }
826             case FrontendStatusExt1_1::hidl_discriminator::isLinear: {
827                 status.set<TunerFrontendStatus::isLinear>(s.isLinear());
828                 aidlStatus.push_back(status);
829                 break;
830             }
831             case FrontendStatusExt1_1::hidl_discriminator::isShortFrames: {
832                 status.set<TunerFrontendStatus::isShortFrames>(s.isShortFrames());
833                 aidlStatus.push_back(status);
834                 break;
835             }
836         }
837     }
838 }
839 
getAtsc3PlpSettings(const TunerFrontendAtsc3Settings & settings)840 hidl_vec<FrontendAtsc3PlpSettings> TunerFrontend::getAtsc3PlpSettings(
841         const TunerFrontendAtsc3Settings& settings) {
842     int len = settings.plpSettings.size();
843     hidl_vec<FrontendAtsc3PlpSettings> plps = hidl_vec<FrontendAtsc3PlpSettings>(len);
844     // parse PLP settings
845     for (int i = 0; i < len; i++) {
846         uint8_t plpId = static_cast<uint8_t>(settings.plpSettings[i].plpId);
847         FrontendAtsc3Modulation modulation =
848                 static_cast<FrontendAtsc3Modulation>(settings.plpSettings[i].modulation);
849         FrontendAtsc3TimeInterleaveMode interleaveMode =
850                 static_cast<FrontendAtsc3TimeInterleaveMode>(
851                         settings.plpSettings[i].interleaveMode);
852         FrontendAtsc3CodeRate codeRate =
853                 static_cast<FrontendAtsc3CodeRate>(settings.plpSettings[i].codeRate);
854         FrontendAtsc3Fec fec =
855                 static_cast<FrontendAtsc3Fec>(settings.plpSettings[i].fec);
856         FrontendAtsc3PlpSettings frontendAtsc3PlpSettings {
857                 .plpId = plpId,
858                 .modulation = modulation,
859                 .interleaveMode = interleaveMode,
860                 .codeRate = codeRate,
861                 .fec = fec,
862         };
863         plps[i] = frontendAtsc3PlpSettings;
864     }
865     return plps;
866 }
867 
getDvbsCodeRate(const TunerFrontendDvbsCodeRate & codeRate)868 FrontendDvbsCodeRate TunerFrontend::getDvbsCodeRate(const TunerFrontendDvbsCodeRate& codeRate) {
869     FrontendInnerFec innerFec = static_cast<FrontendInnerFec>(codeRate.fec);
870     bool isLinear = codeRate.isLinear;
871     bool isShortFrames = codeRate.isShortFrames;
872     uint32_t bitsPer1000Symbol = static_cast<uint32_t>(codeRate.bitsPer1000Symbol);
873     FrontendDvbsCodeRate coderate {
874             .fec = innerFec,
875             .isLinear = isLinear,
876             .isShortFrames = isShortFrames,
877             .bitsPer1000Symbol = bitsPer1000Symbol,
878     };
879     return coderate;
880 }
881 
getHidlFrontendSettings(const TunerFrontendSettings & aidlSettings)882 FrontendSettings TunerFrontend::getHidlFrontendSettings(const TunerFrontendSettings& aidlSettings) {
883     auto settings = aidlSettings.settings;
884     FrontendSettings frontendSettings;
885 
886     switch (settings.getTag()) {
887         case TunerFrontendUnionSettings::analog: {
888             auto analog = settings.get<TunerFrontendUnionSettings::analog>();
889             frontendSettings.analog({
890                 .frequency = static_cast<uint32_t>(analog.frequency),
891                 .type = static_cast<FrontendAnalogType>(analog.signalType),
892                 .sifStandard = static_cast<FrontendAnalogSifStandard>(analog.sifStandard),
893             });
894             break;
895         }
896         case TunerFrontendUnionSettings::atsc: {
897             auto atsc = settings.get<TunerFrontendUnionSettings::atsc>();
898             frontendSettings.atsc({
899                 .frequency = static_cast<uint32_t>(atsc.frequency),
900                 .modulation = static_cast<FrontendAtscModulation>(atsc.modulation),
901             });
902             break;
903         }
904         case TunerFrontendUnionSettings::atsc3: {
905             auto atsc3 = settings.get<TunerFrontendUnionSettings::atsc3>();
906             frontendSettings.atsc3({
907                 .frequency = static_cast<uint32_t>(atsc3.frequency),
908                 .bandwidth = static_cast<FrontendAtsc3Bandwidth>(atsc3.bandwidth),
909                 .demodOutputFormat = static_cast<FrontendAtsc3DemodOutputFormat>(
910                         atsc3.demodOutputFormat),
911                 .plpSettings = getAtsc3PlpSettings(atsc3),
912             });
913             break;
914         }
915         case TunerFrontendUnionSettings::cable: {
916             auto dvbc = settings.get<TunerFrontendUnionSettings::cable>();
917             frontendSettings.dvbc({
918                 .frequency = static_cast<uint32_t>(dvbc.frequency),
919                 .modulation = static_cast<FrontendDvbcModulation>(dvbc.modulation),
920                 .fec = static_cast<FrontendInnerFec>(dvbc.innerFec),
921                 .symbolRate = static_cast<uint32_t>(dvbc.symbolRate),
922                 .outerFec = static_cast<FrontendDvbcOuterFec>(dvbc.outerFec),
923                 .annex = static_cast<FrontendDvbcAnnex>(dvbc.annex),
924                 .spectralInversion = static_cast<FrontendDvbcSpectralInversion>(
925                         dvbc.spectralInversion),
926             });
927             break;
928         }
929         case TunerFrontendUnionSettings::dvbs: {
930             auto dvbs = settings.get<TunerFrontendUnionSettings::dvbs>();
931             frontendSettings.dvbs({
932                 .frequency = static_cast<uint32_t>(dvbs.frequency),
933                 .modulation = static_cast<FrontendDvbsModulation>(dvbs.modulation),
934                 .coderate = getDvbsCodeRate(dvbs.codeRate),
935                 .symbolRate = static_cast<uint32_t>(dvbs.symbolRate),
936                 .rolloff = static_cast<FrontendDvbsRolloff>(dvbs.rolloff),
937                 .pilot = static_cast<FrontendDvbsPilot>(dvbs.pilot),
938                 .inputStreamId = static_cast<uint32_t>(dvbs.inputStreamId),
939                 .standard = static_cast<FrontendDvbsStandard>(dvbs.standard),
940                 .vcmMode = static_cast<FrontendDvbsVcmMode>(dvbs.vcm),
941             });
942             break;
943         }
944         case TunerFrontendUnionSettings::dvbt: {
945             auto dvbt = settings.get<TunerFrontendUnionSettings::dvbt>();
946             frontendSettings.dvbt({
947                 .frequency = static_cast<uint32_t>(dvbt.frequency),
948                 .transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
949                         dvbt.transmissionMode),
950                 .bandwidth = static_cast<FrontendDvbtBandwidth>(dvbt.bandwidth),
951                 .constellation = static_cast<FrontendDvbtConstellation>(dvbt.constellation),
952                 .hierarchy = static_cast<FrontendDvbtHierarchy>(dvbt.hierarchy),
953                 .hpCoderate = static_cast<FrontendDvbtCoderate>(dvbt.hpCodeRate),
954                 .lpCoderate = static_cast<FrontendDvbtCoderate>(dvbt.lpCodeRate),
955                 .guardInterval = static_cast<FrontendDvbtGuardInterval>(dvbt.guardInterval),
956                 .isHighPriority = dvbt.isHighPriority,
957                 .standard = static_cast<FrontendDvbtStandard>(dvbt.standard),
958                 .isMiso = dvbt.isMiso,
959                 .plpMode = static_cast<FrontendDvbtPlpMode>(dvbt.plpMode),
960                 .plpId = static_cast<uint8_t>(dvbt.plpId),
961                 .plpGroupId = static_cast<uint8_t>(dvbt.plpGroupId),
962             });
963             break;
964         }
965         case TunerFrontendUnionSettings::isdbs: {
966             auto isdbs = settings.get<TunerFrontendUnionSettings::isdbs>();
967             frontendSettings.isdbs({
968                 .frequency = static_cast<uint32_t>(isdbs.frequency),
969                 .streamId = static_cast<uint16_t>(isdbs.streamId),
970                 .streamIdType = static_cast<FrontendIsdbsStreamIdType>(isdbs.streamIdType),
971                 .modulation = static_cast<FrontendIsdbsModulation>(isdbs.modulation),
972                 .coderate = static_cast<FrontendIsdbsCoderate>(isdbs.codeRate),
973                 .symbolRate = static_cast<uint32_t>(isdbs.symbolRate),
974                 .rolloff = static_cast<FrontendIsdbsRolloff>(isdbs.rolloff),
975             });
976             break;
977         }
978         case TunerFrontendUnionSettings::isdbs3: {
979             auto isdbs3 = settings.get<TunerFrontendUnionSettings::isdbs3>();
980             frontendSettings.isdbs3({
981                 .frequency = static_cast<uint32_t>(isdbs3.frequency),
982                 .streamId = static_cast<uint16_t>(isdbs3.streamId),
983                 .streamIdType = static_cast<FrontendIsdbsStreamIdType>(isdbs3.streamIdType),
984                 .modulation = static_cast<FrontendIsdbs3Modulation>(isdbs3.modulation),
985                 .coderate = static_cast<FrontendIsdbs3Coderate>(isdbs3.codeRate),
986                 .symbolRate = static_cast<uint32_t>(isdbs3.symbolRate),
987                 .rolloff = static_cast<FrontendIsdbs3Rolloff>(isdbs3.rolloff),
988             });
989             break;
990         }
991         case TunerFrontendUnionSettings::isdbt: {
992             auto isdbt = settings.get<TunerFrontendUnionSettings::isdbt>();
993             frontendSettings.isdbt({
994                 .frequency = static_cast<uint32_t>(isdbt.frequency),
995                 .modulation = static_cast<FrontendIsdbtModulation>(isdbt.modulation),
996                 .bandwidth = static_cast<FrontendIsdbtBandwidth>(isdbt.bandwidth),
997                 .mode = static_cast<FrontendIsdbtMode>(isdbt.mode),
998                 .coderate = static_cast<FrontendIsdbtCoderate>(isdbt.codeRate),
999                 .guardInterval = static_cast<FrontendIsdbtGuardInterval>(isdbt.guardInterval),
1000                 .serviceAreaId = static_cast<uint32_t>(isdbt.serviceAreaId),
1001             });
1002             break;
1003         }
1004         default:
1005             break;
1006     }
1007 
1008     return frontendSettings;
1009 }
1010 
getHidlFrontendSettingsExt(const TunerFrontendSettings & aidlSettings)1011 FrontendSettingsExt1_1 TunerFrontend::getHidlFrontendSettingsExt(
1012         const TunerFrontendSettings& aidlSettings) {
1013     FrontendSettingsExt1_1 frontendSettingsExt{
1014         .endFrequency = static_cast<uint32_t>(aidlSettings.endFrequency),
1015         .inversion = static_cast<FrontendSpectralInversion>(aidlSettings.inversion),
1016     };
1017 
1018     auto settings = aidlSettings.settings;
1019     switch (settings.getTag()) {
1020         case TunerFrontendUnionSettings::analog: {
1021             auto analog = settings.get<TunerFrontendUnionSettings::analog>();
1022             if (analog.isExtended) {
1023                 frontendSettingsExt.settingExt.analog({
1024                     .aftFlag = static_cast<FrontendAnalogAftFlag>(analog.aftFlag),
1025                 });
1026             } else {
1027                 frontendSettingsExt.settingExt.noinit();
1028             }
1029             break;
1030         }
1031         case TunerFrontendUnionSettings::cable: {
1032             auto dvbc = settings.get<TunerFrontendUnionSettings::cable>();
1033             if (dvbc.isExtended) {
1034                 frontendSettingsExt.settingExt.dvbc({
1035                     .interleaveMode = static_cast<FrontendCableTimeInterleaveMode>(
1036                             dvbc.interleaveMode),
1037                     .bandwidth = static_cast<FrontendDvbcBandwidth>(
1038                             dvbc.bandwidth),
1039                 });
1040             } else {
1041                 frontendSettingsExt.settingExt.noinit();
1042             }
1043             break;
1044         }
1045         case TunerFrontendUnionSettings::dvbs: {
1046             auto dvbs = settings.get<TunerFrontendUnionSettings::dvbs>();
1047             if (dvbs.isExtended) {
1048                 frontendSettingsExt.settingExt.dvbs({
1049                     .scanType = static_cast<FrontendDvbsScanType>(dvbs.scanType),
1050                     .isDiseqcRxMessage = dvbs.isDiseqcRxMessage,
1051                 });
1052             } else {
1053                 frontendSettingsExt.settingExt.noinit();
1054             }
1055             break;
1056         }
1057         case TunerFrontendUnionSettings::dvbt: {
1058             auto dvbt = settings.get<TunerFrontendUnionSettings::dvbt>();
1059             if (dvbt.isExtended) {
1060                 frontendSettingsExt.settingExt.dvbt({
1061                     .constellation =
1062                             static_cast<hardware::tv::tuner::V1_1::FrontendDvbtConstellation>(
1063                                     dvbt.constellation),
1064                     .transmissionMode =
1065                             static_cast<hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode>(
1066                                     dvbt.transmissionMode),
1067                 });
1068             } else {
1069                 frontendSettingsExt.settingExt.noinit();
1070             }
1071             break;
1072         }
1073         case TunerFrontendUnionSettings::dtmb: {
1074             auto dtmb = settings.get<TunerFrontendUnionSettings::dtmb>();
1075             frontendSettingsExt.settingExt.dtmb({
1076                 .frequency = static_cast<uint32_t>(dtmb.frequency),
1077                 .transmissionMode = static_cast<FrontendDtmbTransmissionMode>(
1078                         dtmb.transmissionMode),
1079                 .bandwidth = static_cast<FrontendDtmbBandwidth>(dtmb.bandwidth),
1080                 .modulation = static_cast<FrontendDtmbModulation>(dtmb.modulation),
1081                 .codeRate = static_cast<FrontendDtmbCodeRate>(dtmb.codeRate),
1082                 .guardInterval = static_cast<FrontendDtmbGuardInterval>(dtmb.guardInterval),
1083                 .interleaveMode = static_cast<FrontendDtmbTimeInterleaveMode>(dtmb.interleaveMode),
1084             });
1085             break;
1086         }
1087         default:
1088             frontendSettingsExt.settingExt.noinit();
1089             break;
1090     }
1091 
1092     return frontendSettingsExt;
1093 }
1094 }  // namespace android
1095