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 "android.hardware.tv.tuner@1.1-Frontend"
18 
19 #include "Frontend.h"
20 #include <android/hardware/tv/tuner/1.1/IFrontendCallback.h>
21 #include <utils/Log.h>
22 
23 namespace android {
24 namespace hardware {
25 namespace tv {
26 namespace tuner {
27 namespace V1_0 {
28 namespace implementation {
29 
Frontend(FrontendType type,FrontendId id,sp<Tuner> tuner)30 Frontend::Frontend(FrontendType type, FrontendId id, sp<Tuner> tuner) {
31     mType = type;
32     mId = id;
33     mTunerService = tuner;
34     // Init callback to nullptr
35     mCallback = nullptr;
36 }
37 
~Frontend()38 Frontend::~Frontend() {}
39 
close()40 Return<Result> Frontend::close() {
41     ALOGV("%s", __FUNCTION__);
42     // Reset callback
43     mCallback = nullptr;
44     mIsLocked = false;
45     mTunerService->removeFrontend(mId);
46 
47     return Result::SUCCESS;
48 }
49 
setCallback(const sp<IFrontendCallback> & callback)50 Return<Result> Frontend::setCallback(const sp<IFrontendCallback>& callback) {
51     ALOGV("%s", __FUNCTION__);
52     if (callback == nullptr) {
53         ALOGW("[   WARN   ] Set Frontend callback with nullptr");
54         return Result::INVALID_ARGUMENT;
55     }
56 
57     mCallback = callback;
58     return Result::SUCCESS;
59 }
60 
tune(const FrontendSettings &)61 Return<Result> Frontend::tune(const FrontendSettings& /* settings */) {
62     ALOGV("%s", __FUNCTION__);
63     if (mCallback == nullptr) {
64         ALOGW("[   WARN   ] Frontend callback is not set when tune");
65         return Result::INVALID_STATE;
66     }
67 
68     mTunerService->frontendStartTune(mId);
69     mCallback->onEvent(FrontendEventType::LOCKED);
70     mIsLocked = true;
71     return Result::SUCCESS;
72 }
73 
tune_1_1(const FrontendSettings & settings,const V1_1::FrontendSettingsExt1_1 &)74 Return<Result> Frontend::tune_1_1(const FrontendSettings& settings,
75                                   const V1_1::FrontendSettingsExt1_1& /*settingsExt1_1*/) {
76     ALOGV("%s", __FUNCTION__);
77     return tune(settings);
78 }
79 
stopTune()80 Return<Result> Frontend::stopTune() {
81     ALOGV("%s", __FUNCTION__);
82 
83     mTunerService->frontendStopTune(mId);
84     mIsLocked = false;
85 
86     return Result::SUCCESS;
87 }
88 
scan(const FrontendSettings & settings,FrontendScanType type)89 Return<Result> Frontend::scan(const FrontendSettings& settings, FrontendScanType type) {
90     ALOGV("%s", __FUNCTION__);
91     FrontendScanMessage msg;
92 
93     if (mIsLocked) {
94         msg.isEnd(true);
95         mCallback->onScanMessage(FrontendScanMessageType::END, msg);
96         return Result::SUCCESS;
97     }
98 
99     uint32_t frequency;
100     switch (settings.getDiscriminator()) {
101         case FrontendSettings::hidl_discriminator::analog:
102             frequency = settings.analog().frequency;
103             break;
104         case FrontendSettings::hidl_discriminator::atsc:
105             frequency = settings.atsc().frequency;
106             break;
107         case FrontendSettings::hidl_discriminator::atsc3:
108             frequency = settings.atsc3().frequency;
109             break;
110         case FrontendSettings::hidl_discriminator::dvbs:
111             frequency = settings.dvbs().frequency;
112             break;
113         case FrontendSettings::hidl_discriminator::dvbc:
114             frequency = settings.dvbc().frequency;
115             break;
116         case FrontendSettings::hidl_discriminator::dvbt:
117             frequency = settings.dvbt().frequency;
118             break;
119         case FrontendSettings::hidl_discriminator::isdbs:
120             frequency = settings.isdbs().frequency;
121             break;
122         case FrontendSettings::hidl_discriminator::isdbs3:
123             frequency = settings.isdbs3().frequency;
124             break;
125         case FrontendSettings::hidl_discriminator::isdbt:
126             frequency = settings.isdbt().frequency;
127             break;
128     }
129 
130     if (type == FrontendScanType::SCAN_BLIND) {
131         frequency += 100;
132     }
133 
134     msg.frequencies({frequency});
135     mCallback->onScanMessage(FrontendScanMessageType::FREQUENCY, msg);
136 
137     msg.progressPercent(20);
138     mCallback->onScanMessage(FrontendScanMessageType::PROGRESS_PERCENT, msg);
139 
140     msg.symbolRates({30});
141     mCallback->onScanMessage(FrontendScanMessageType::SYMBOL_RATE, msg);
142 
143     if (mType == FrontendType::DVBT) {
144         msg.hierarchy(FrontendDvbtHierarchy::HIERARCHY_NON_NATIVE);
145         mCallback->onScanMessage(FrontendScanMessageType::HIERARCHY, msg);
146     }
147 
148     if (mType == FrontendType::ANALOG) {
149         msg.analogType(FrontendAnalogType::PAL);
150         mCallback->onScanMessage(FrontendScanMessageType::ANALOG_TYPE, msg);
151     }
152 
153     msg.plpIds({3});
154     mCallback->onScanMessage(FrontendScanMessageType::PLP_IDS, msg);
155 
156     msg.groupIds({2});
157     mCallback->onScanMessage(FrontendScanMessageType::GROUP_IDS, msg);
158 
159     msg.inputStreamIds({1});
160     mCallback->onScanMessage(FrontendScanMessageType::INPUT_STREAM_IDS, msg);
161 
162     FrontendScanMessage::Standard s;
163     switch (mType) {
164         case FrontendType::DVBT:
165             s.tStd(FrontendDvbtStandard::AUTO);
166             msg.std(s);
167             mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
168             break;
169         case FrontendType::DVBS:
170             s.sStd(FrontendDvbsStandard::AUTO);
171             msg.std(s);
172             mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
173             break;
174         case FrontendType::ANALOG:
175             s.sifStd(FrontendAnalogSifStandard::AUTO);
176             msg.std(s);
177             mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
178             break;
179         default:
180             break;
181     }
182 
183     FrontendScanAtsc3PlpInfo info{
184             .plpId = 1,
185             .bLlsFlag = false,
186     };
187     msg.atsc3PlpInfos({info});
188     mCallback->onScanMessage(FrontendScanMessageType::ATSC3_PLP_INFO, msg);
189 
190     sp<V1_1::IFrontendCallback> frontendCallback_v1_1 =
191             V1_1::IFrontendCallback::castFrom(mCallback);
192     if (frontendCallback_v1_1 != NULL) {
193         V1_1::FrontendScanMessageExt1_1 msg;
194         msg.modulation().dvbc(FrontendDvbcModulation::MOD_16QAM);
195         frontendCallback_v1_1->onScanMessageExt1_1(V1_1::FrontendScanMessageTypeExt1_1::MODULATION,
196                                                    msg);
197         msg.isHighPriority(true);
198         frontendCallback_v1_1->onScanMessageExt1_1(
199                 V1_1::FrontendScanMessageTypeExt1_1::HIGH_PRIORITY, msg);
200     } else {
201         ALOGD("[Frontend] Couldn't cast to V1_1 IFrontendCallback");
202     }
203 
204     msg.isLocked(true);
205     mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
206     mIsLocked = true;
207 
208     return Result::SUCCESS;
209 }
210 
scan_1_1(const FrontendSettings & settings,FrontendScanType type,const V1_1::FrontendSettingsExt1_1 & settingsExt1_1)211 Return<Result> Frontend::scan_1_1(const FrontendSettings& settings, FrontendScanType type,
212                                   const V1_1::FrontendSettingsExt1_1& settingsExt1_1) {
213     ALOGV("%s", __FUNCTION__);
214     ALOGD("[Frontend] scan_1_1 end frequency %d", settingsExt1_1.endFrequency);
215     return scan(settings, type);
216 }
217 
stopScan()218 Return<Result> Frontend::stopScan() {
219     ALOGV("%s", __FUNCTION__);
220 
221     mIsLocked = false;
222     return Result::SUCCESS;
223 }
224 
getStatus(const hidl_vec<FrontendStatusType> & statusTypes,getStatus_cb _hidl_cb)225 Return<void> Frontend::getStatus(const hidl_vec<FrontendStatusType>& statusTypes,
226                                  getStatus_cb _hidl_cb) {
227     ALOGV("%s", __FUNCTION__);
228 
229     vector<FrontendStatus> statuses;
230     for (int i = 0; i < statusTypes.size(); i++) {
231         FrontendStatusType type = statusTypes[i];
232         FrontendStatus status;
233         // assign randomly selected values for testing.
234         switch (type) {
235             case FrontendStatusType::DEMOD_LOCK: {
236                 status.isDemodLocked(true);
237                 break;
238             }
239             case FrontendStatusType::SNR: {
240                 status.snr(221);
241                 break;
242             }
243             case FrontendStatusType::BER: {
244                 status.ber(1);
245                 break;
246             }
247             case FrontendStatusType::PER: {
248                 status.per(2);
249                 break;
250             }
251             case FrontendStatusType::PRE_BER: {
252                 status.preBer(3);
253                 break;
254             }
255             case FrontendStatusType::SIGNAL_QUALITY: {
256                 status.signalQuality(4);
257                 break;
258             }
259             case FrontendStatusType::SIGNAL_STRENGTH: {
260                 status.signalStrength(5);
261                 break;
262             }
263             case FrontendStatusType::SYMBOL_RATE: {
264                 status.symbolRate(6);
265                 break;
266             }
267             case FrontendStatusType::FEC: {
268                 status.innerFec(FrontendInnerFec::FEC_2_9);  // value = 1 << 7
269                 break;
270             }
271             case FrontendStatusType::MODULATION: {
272                 FrontendModulationStatus modulationStatus;
273                 switch (mType) {
274                     case FrontendType::ISDBS: {
275                         modulationStatus.isdbs(
276                                 FrontendIsdbsModulation::MOD_BPSK);  // value = 1 << 1
277                         status.modulation(modulationStatus);
278                         break;
279                     }
280                     case FrontendType::DVBC: {
281                         modulationStatus.dvbc(FrontendDvbcModulation::MOD_16QAM);  // value = 1 << 1
282                         status.modulation(modulationStatus);
283                         break;
284                     }
285                     case FrontendType::DVBS: {
286                         modulationStatus.dvbs(FrontendDvbsModulation::MOD_QPSK);  // value = 1 << 1
287                         status.modulation(modulationStatus);
288                         break;
289                     }
290                     case FrontendType::ISDBS3: {
291                         modulationStatus.isdbs3(
292                                 FrontendIsdbs3Modulation::MOD_BPSK);  // value = 1 << 1
293                         status.modulation(modulationStatus);
294                         break;
295                     }
296                     case FrontendType::ISDBT: {
297                         modulationStatus.isdbt(
298                                 FrontendIsdbtModulation::MOD_DQPSK);  // value = 1 << 1
299                         status.modulation(modulationStatus);
300                         break;
301                     }
302                     default:
303                         break;
304                 }
305                 break;
306             }
307             case FrontendStatusType::SPECTRAL: {
308                 status.inversion(FrontendDvbcSpectralInversion::NORMAL);
309                 break;
310             }
311             case FrontendStatusType::LNB_VOLTAGE: {
312                 status.lnbVoltage(LnbVoltage::VOLTAGE_5V);
313                 break;
314             }
315             case FrontendStatusType::PLP_ID: {
316                 status.plpId(101);  // type uint8_t
317                 break;
318             }
319             case FrontendStatusType::EWBS: {
320                 status.isEWBS(false);
321                 break;
322             }
323             case FrontendStatusType::AGC: {
324                 status.agc(7);
325                 break;
326             }
327             case FrontendStatusType::LNA: {
328                 status.isLnaOn(false);
329                 break;
330             }
331             case FrontendStatusType::LAYER_ERROR: {
332                 vector<bool> v = {false, true, true};
333                 status.isLayerError(v);
334                 break;
335             }
336             case FrontendStatusType::MER: {
337                 status.mer(8);
338                 break;
339             }
340             case FrontendStatusType::FREQ_OFFSET: {
341                 status.freqOffset(9);
342                 break;
343             }
344             case FrontendStatusType::HIERARCHY: {
345                 status.hierarchy(FrontendDvbtHierarchy::HIERARCHY_1_NATIVE);
346                 break;
347             }
348             case FrontendStatusType::RF_LOCK: {
349                 status.isRfLocked(false);
350                 break;
351             }
352             case FrontendStatusType::ATSC3_PLP_INFO: {
353                 vector<FrontendStatusAtsc3PlpInfo> v;
354                 FrontendStatusAtsc3PlpInfo info1{
355                         .plpId = 3,
356                         .isLocked = false,
357                         .uec = 313,
358                 };
359                 FrontendStatusAtsc3PlpInfo info2{
360                         .plpId = 5,
361                         .isLocked = true,
362                         .uec = 515,
363                 };
364                 v.push_back(info1);
365                 v.push_back(info2);
366                 status.plpInfo(v);
367                 break;
368             }
369             default: {
370                 continue;
371             }
372         }
373         statuses.push_back(status);
374     }
375     _hidl_cb(Result::SUCCESS, statuses);
376 
377     return Void();
378 }
379 
getStatusExt1_1(const hidl_vec<V1_1::FrontendStatusTypeExt1_1> & statusTypes,V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb)380 Return<void> Frontend::getStatusExt1_1(const hidl_vec<V1_1::FrontendStatusTypeExt1_1>& statusTypes,
381                                        V1_1::IFrontend::getStatusExt1_1_cb _hidl_cb) {
382     ALOGV("%s", __FUNCTION__);
383 
384     vector<V1_1::FrontendStatusExt1_1> statuses;
385     for (int i = 0; i < statusTypes.size(); i++) {
386         V1_1::FrontendStatusTypeExt1_1 type = statusTypes[i];
387         V1_1::FrontendStatusExt1_1 status;
388 
389         switch (type) {
390             case V1_1::FrontendStatusTypeExt1_1::MODULATIONS: {
391                 vector<V1_1::FrontendModulation> modulations;
392                 V1_1::FrontendModulation modulation;
393                 switch ((int)mType) {
394                     case (int)FrontendType::ISDBS: {
395                         modulation.isdbs(FrontendIsdbsModulation::MOD_BPSK);  // value = 1 << 1
396                         modulations.push_back(modulation);
397                         status.modulations(modulations);
398                         break;
399                     }
400                     case (int)FrontendType::DVBC: {
401                         modulation.dvbc(FrontendDvbcModulation::MOD_16QAM);  // value = 1 << 1
402                         modulations.push_back(modulation);
403                         status.modulations(modulations);
404                         break;
405                     }
406                     case (int)FrontendType::DVBS: {
407                         modulation.dvbs(FrontendDvbsModulation::MOD_QPSK);  // value = 1 << 1
408                         modulations.push_back(modulation);
409                         status.modulations(modulations);
410                         break;
411                     }
412                     case (int)FrontendType::DVBT: {
413                         // value = 1 << 16
414                         modulation.dvbt(V1_1::FrontendDvbtConstellation::CONSTELLATION_16QAM_R);
415                         modulations.push_back(modulation);
416                         status.modulations(modulations);
417                         break;
418                     }
419                     case (int)FrontendType::ISDBS3: {
420                         modulation.isdbs3(FrontendIsdbs3Modulation::MOD_BPSK);  //  value = 1 << 1
421                         modulations.push_back(modulation);
422                         status.modulations(modulations);
423                         break;
424                     }
425                     case (int)FrontendType::ISDBT: {
426                         modulation.isdbt(FrontendIsdbtModulation::MOD_DQPSK);  // value = 1 << 1
427                         modulations.push_back(modulation);
428                         status.modulations(modulations);
429                         break;
430                     }
431                     case (int)FrontendType::ATSC: {
432                         modulation.atsc(FrontendAtscModulation::MOD_8VSB);  // value = 1 << 2
433                         modulations.push_back(modulation);
434                         status.modulations(modulations);
435                         break;
436                     }
437                     case (int)FrontendType::ATSC3: {
438                         modulation.atsc3(FrontendAtsc3Modulation::MOD_QPSK);  // value = 1 << 1
439                         modulations.push_back(modulation);
440                         status.modulations(modulations);
441                         break;
442                     }
443                     case (int)V1_1::FrontendType::DTMB: {
444                         // value = 1 << 1
445                         modulation.dtmb(V1_1::FrontendDtmbModulation::CONSTELLATION_4QAM);
446                         modulations.push_back(modulation);
447                         status.modulations(modulations);
448                         break;
449                     }
450                     default:
451                         break;
452                 }
453                 break;
454             }
455             case V1_1::FrontendStatusTypeExt1_1::BERS: {
456                 vector<uint32_t> bers = {1};
457                 status.bers(bers);
458                 break;
459             }
460             case V1_1::FrontendStatusTypeExt1_1::CODERATES: {
461                 // value = 1 << 39
462                 vector<V1_1::FrontendInnerFec> codeRates = {V1_1::FrontendInnerFec::FEC_6_15};
463                 status.codeRates(codeRates);
464                 break;
465             }
466             case V1_1::FrontendStatusTypeExt1_1::BANDWIDTH: {
467                 V1_1::FrontendBandwidth bandwidth;
468                 switch ((int)mType) {
469                     case (int)FrontendType::DVBC: {
470                         // value = 1 << 1
471                         bandwidth.dvbc(V1_1::FrontendDvbcBandwidth::BANDWIDTH_6MHZ);
472                         status.bandwidth(bandwidth);
473                         break;
474                     }
475                     case (int)FrontendType::DVBT: {
476                         // value = 1 << 1
477                         bandwidth.dvbt(FrontendDvbtBandwidth::BANDWIDTH_8MHZ);
478                         status.bandwidth(bandwidth);
479                         break;
480                     }
481                     case (int)FrontendType::ISDBT: {
482                         bandwidth.isdbt(FrontendIsdbtBandwidth::BANDWIDTH_8MHZ);  // value = 1 << 1
483                         status.bandwidth(bandwidth);
484                         break;
485                     }
486                     case (int)FrontendType::ATSC3: {
487                         bandwidth.atsc3(FrontendAtsc3Bandwidth::BANDWIDTH_6MHZ);  // value = 1 << 1
488                         status.bandwidth(bandwidth);
489                         break;
490                     }
491                     case (int)V1_1::FrontendType::DTMB: {
492                         // value = 1 << 1
493                         bandwidth.dtmb(V1_1::FrontendDtmbBandwidth::BANDWIDTH_8MHZ);
494                         status.bandwidth(bandwidth);
495                         break;
496                     }
497                     default:
498                         break;
499                 }
500                 break;
501             }
502             case V1_1::FrontendStatusTypeExt1_1::GUARD_INTERVAL: {
503                 V1_1::FrontendGuardInterval interval;
504                 switch ((int)mType) {
505                     case (int)FrontendType::DVBT: {
506                         interval.dvbt(FrontendDvbtGuardInterval::INTERVAL_1_32);  // value = 1 << 1
507                         status.interval(interval);
508                         break;
509                     }
510                     case (int)FrontendType::ISDBT: {
511                         interval.isdbt(FrontendDvbtGuardInterval::INTERVAL_1_32);  // value = 1 << 1
512                         status.interval(interval);
513                         break;
514                     }
515                     case (int)V1_1::FrontendType::DTMB: {
516                         // value = 1 << 1
517                         interval.dtmb(V1_1::FrontendDtmbGuardInterval::PN_420_VARIOUS);
518                         status.interval(interval);
519                         break;
520                     }
521                     default:
522                         break;
523                 }
524                 break;
525             }
526             case V1_1::FrontendStatusTypeExt1_1::TRANSMISSION_MODE: {
527                 V1_1::FrontendTransmissionMode transMode;
528                 switch ((int)mType) {
529                     case (int)FrontendType::DVBT: {
530                         // value = 1 << 8
531                         transMode.dvbt(V1_1::FrontendDvbtTransmissionMode::MODE_16K_E);
532                         status.transmissionMode(transMode);
533                         break;
534                     }
535                     case (int)FrontendType::ISDBT: {
536                         transMode.isdbt(FrontendIsdbtMode::MODE_1);  // value = 1 << 1
537                         status.transmissionMode(transMode);
538                         break;
539                     }
540                     case (int)V1_1::FrontendType::DTMB: {
541                         transMode.dtmb(V1_1::FrontendDtmbTransmissionMode::C1);  // value = 1 << 1
542                         status.transmissionMode(transMode);
543                         break;
544                     }
545                     default:
546                         break;
547                 }
548                 break;
549             }
550             case V1_1::FrontendStatusTypeExt1_1::UEC: {
551                 status.uec(4);
552                 break;
553             }
554             case V1_1::FrontendStatusTypeExt1_1::T2_SYSTEM_ID: {
555                 status.systemId(5);
556                 break;
557             }
558             case V1_1::FrontendStatusTypeExt1_1::INTERLEAVINGS: {
559                 V1_1::FrontendInterleaveMode interleave;
560                 switch ((int)mType) {
561                     case (int)FrontendType::DVBC: {
562                         // value = 1 << 1
563                         interleave.dvbc(
564                                 V1_1::FrontendCableTimeInterleaveMode::INTERLEAVING_128_1_0);
565                         vector<V1_1::FrontendInterleaveMode> interleaving = {interleave};
566                         status.interleaving(interleaving);
567                         break;
568                     }
569                     case (int)FrontendType::ATSC3: {
570                         // value = 1 << 1
571                         interleave.atsc3(FrontendAtsc3TimeInterleaveMode::CTI);
572                         vector<V1_1::FrontendInterleaveMode> interleaving = {interleave};
573                         status.interleaving(interleaving);
574                         break;
575                     }
576                     case (int)V1_1::FrontendType::DTMB: {
577                         // value = 1 << 1
578                         interleave.dtmb(V1_1::FrontendDtmbTimeInterleaveMode::TIMER_INT_240);
579                         vector<V1_1::FrontendInterleaveMode> interleaving = {interleave};
580                         status.interleaving(interleaving);
581                         break;
582                     }
583                     default:
584                         break;
585                 }
586                 break;
587             }
588             case V1_1::FrontendStatusTypeExt1_1::ISDBT_SEGMENTS: {
589                 vector<uint8_t> segments = {2, 3};
590                 status.isdbtSegment(segments);
591                 break;
592             }
593             case V1_1::FrontendStatusTypeExt1_1::TS_DATA_RATES: {
594                 vector<uint32_t> dataRates = {4, 5};
595                 status.tsDataRate(dataRates);
596                 break;
597             }
598             case V1_1::FrontendStatusTypeExt1_1::ROLL_OFF: {
599                 V1_1::FrontendRollOff rollOff;
600                 switch (mType) {
601                     case FrontendType::DVBS: {
602                         // value = 1
603                         rollOff.dvbs(FrontendDvbsRolloff::ROLLOFF_0_35);
604                         status.rollOff(rollOff);
605                         break;
606                     }
607                     case FrontendType::ISDBS: {
608                         // value = 1
609                         rollOff.isdbs(FrontendIsdbsRolloff::ROLLOFF_0_35);
610                         status.rollOff(rollOff);
611                         break;
612                     }
613                     case FrontendType::ISDBS3: {
614                         // value = 1
615                         rollOff.isdbs3(FrontendIsdbs3Rolloff::ROLLOFF_0_03);
616                         status.rollOff(rollOff);
617                         break;
618                     }
619                     default:
620                         break;
621                 }
622                 break;
623             }
624             case V1_1::FrontendStatusTypeExt1_1::IS_MISO: {
625                 status.isMiso(true);
626                 break;
627             }
628             case V1_1::FrontendStatusTypeExt1_1::IS_LINEAR: {
629                 status.isLinear(true);
630                 break;
631             }
632             case V1_1::FrontendStatusTypeExt1_1::IS_SHORT_FRAMES: {
633                 status.isShortFrames(true);
634                 break;
635             }
636             default: {
637                 continue;
638             }
639         }
640         statuses.push_back(status);
641     }
642     _hidl_cb(Result::SUCCESS, statuses);
643 
644     return Void();
645 }
646 
setLna(bool)647 Return<Result> Frontend::setLna(bool /* bEnable */) {
648     ALOGV("%s", __FUNCTION__);
649 
650     return Result::SUCCESS;
651 }
652 
setLnb(uint32_t)653 Return<Result> Frontend::setLnb(uint32_t /* lnb */) {
654     ALOGV("%s", __FUNCTION__);
655     if (!supportsSatellite()) {
656         return Result::INVALID_STATE;
657     }
658     return Result::SUCCESS;
659 }
660 
linkCiCam(uint32_t ciCamId,linkCiCam_cb _hidl_cb)661 Return<void> Frontend::linkCiCam(uint32_t ciCamId, linkCiCam_cb _hidl_cb) {
662     ALOGV("%s", __FUNCTION__);
663 
664     mCiCamId = ciCamId;
665     _hidl_cb(Result::SUCCESS, 0 /*ltsId*/);
666 
667     return Void();
668 }
669 
unlinkCiCam(uint32_t)670 Return<Result> Frontend::unlinkCiCam(uint32_t /*ciCamId*/) {
671     ALOGV("%s", __FUNCTION__);
672 
673     mCiCamId = -1;
674 
675     return Result::SUCCESS;
676 }
677 
getFrontendType()678 FrontendType Frontend::getFrontendType() {
679     return mType;
680 }
681 
getFrontendId()682 FrontendId Frontend::getFrontendId() {
683     return mId;
684 }
685 
supportsSatellite()686 bool Frontend::supportsSatellite() {
687     return mType == FrontendType::DVBS || mType == FrontendType::ISDBS ||
688            mType == FrontendType::ISDBS3;
689 }
690 
isLocked()691 bool Frontend::isLocked() {
692     return mIsLocked;
693 }
694 }  // namespace implementation
695 }  // namespace V1_0
696 }  // namespace tuner
697 }  // namespace tv
698 }  // namespace hardware
699 }  // namespace android
700