• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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_NDEBUG 0
18 #define LOG_TAG "android.hardware.tv.tuner-service.example-Frontend"
19 
20 #include <aidl/android/hardware/tv/tuner/Result.h>
21 #include <utils/Log.h>
22 
23 #include "Frontend.h"
24 
25 namespace aidl {
26 namespace android {
27 namespace hardware {
28 namespace tv {
29 namespace tuner {
30 
Frontend(FrontendType type,int32_t id,std::shared_ptr<Tuner> tuner)31 Frontend::Frontend(FrontendType type, int32_t id, std::shared_ptr<Tuner> tuner) {
32     mType = type;
33     mId = id;
34     mTuner = tuner;
35     // Init callback to nullptr
36     mCallback = nullptr;
37 
38     switch (mType) {
39         case FrontendType::ISDBS: {
40             mFrontendCaps.set<FrontendCapabilities::Tag::isdbsCaps>(FrontendIsdbsCapabilities());
41             mFrontendStatusCaps = {
42                     FrontendStatusType::DEMOD_LOCK,
43                     FrontendStatusType::SNR,
44                     FrontendStatusType::FEC,
45                     FrontendStatusType::MODULATION,
46                     FrontendStatusType::MODULATIONS,
47                     FrontendStatusType::ROLL_OFF,
48                     FrontendStatusType::STREAM_ID_LIST,
49             };
50             break;
51         }
52         case FrontendType::ATSC3: {
53             mFrontendCaps.set<FrontendCapabilities::Tag::atsc3Caps>(FrontendAtsc3Capabilities());
54             mFrontendStatusCaps = {
55                     FrontendStatusType::BER,
56                     FrontendStatusType::PER,
57                     FrontendStatusType::ATSC3_PLP_INFO,
58                     FrontendStatusType::MODULATIONS,
59                     FrontendStatusType::BERS,
60                     FrontendStatusType::INTERLEAVINGS,
61                     FrontendStatusType::BANDWIDTH,
62                     FrontendStatusType::ATSC3_ALL_PLP_INFO,
63             };
64             break;
65         }
66         case FrontendType::DVBC: {
67             mFrontendCaps.set<FrontendCapabilities::Tag::dvbcCaps>(FrontendDvbcCapabilities());
68             mFrontendStatusCaps = {
69                     FrontendStatusType::PRE_BER,       FrontendStatusType::SIGNAL_QUALITY,
70                     FrontendStatusType::MODULATION,    FrontendStatusType::SPECTRAL,
71                     FrontendStatusType::MODULATIONS,   FrontendStatusType::CODERATES,
72                     FrontendStatusType::INTERLEAVINGS, FrontendStatusType::BANDWIDTH,
73             };
74             break;
75         }
76         case FrontendType::DVBS: {
77             mFrontendCaps.set<FrontendCapabilities::Tag::dvbsCaps>(FrontendDvbsCapabilities());
78             mFrontendStatusCaps = {
79                     FrontendStatusType::SIGNAL_STRENGTH, FrontendStatusType::SYMBOL_RATE,
80                     FrontendStatusType::MODULATION,      FrontendStatusType::MODULATIONS,
81                     FrontendStatusType::ROLL_OFF,        FrontendStatusType::IS_MISO,
82             };
83             break;
84         }
85         case FrontendType::DVBT: {
86             mFrontendCaps.set<FrontendCapabilities::Tag::dvbtCaps>(FrontendDvbtCapabilities());
87             mFrontendStatusCaps = {
88                     FrontendStatusType::EWBS,
89                     FrontendStatusType::PLP_ID,
90                     FrontendStatusType::HIERARCHY,
91                     FrontendStatusType::MODULATIONS,
92                     FrontendStatusType::BANDWIDTH,
93                     FrontendStatusType::GUARD_INTERVAL,
94                     FrontendStatusType::TRANSMISSION_MODE,
95                     FrontendStatusType::T2_SYSTEM_ID,
96                     FrontendStatusType::DVBT_CELL_IDS,
97             };
98             break;
99         }
100         case FrontendType::ISDBT: {
101             FrontendIsdbtCapabilities isdbtCaps{
102                     .modeCap = (int)FrontendIsdbtMode::MODE_1 | (int)FrontendIsdbtMode::MODE_2,
103                     .bandwidthCap = (int)FrontendIsdbtBandwidth::BANDWIDTH_6MHZ,
104                     .modulationCap = (int)FrontendIsdbtModulation::MOD_16QAM,
105                     .coderateCap = (int)FrontendIsdbtCoderate::CODERATE_4_5 |
106                                    (int)FrontendIsdbtCoderate::CODERATE_6_7,
107                     .guardIntervalCap = (int)FrontendIsdbtGuardInterval::INTERVAL_1_128,
108                     .timeInterleaveCap = (int)FrontendIsdbtTimeInterleaveMode::AUTO |
109                                          (int)FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0,
110                     .isSegmentAuto = true,
111                     .isFullSegment = true,
112             };
113             mFrontendCaps.set<FrontendCapabilities::Tag::isdbtCaps>(isdbtCaps);
114             mFrontendStatusCaps = {
115                     FrontendStatusType::AGC,
116                     FrontendStatusType::LNA,
117                     FrontendStatusType::MODULATION,
118                     FrontendStatusType::MODULATIONS,
119                     FrontendStatusType::BANDWIDTH,
120                     FrontendStatusType::GUARD_INTERVAL,
121                     FrontendStatusType::TRANSMISSION_MODE,
122                     FrontendStatusType::ISDBT_SEGMENTS,
123                     FrontendStatusType::ISDBT_MODE,
124                     FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG,
125                     FrontendStatusType::INTERLEAVINGS,
126             };
127             break;
128         }
129         case FrontendType::ANALOG: {
130             mFrontendCaps.set<FrontendCapabilities::Tag::analogCaps>(FrontendAnalogCapabilities());
131             mFrontendStatusCaps = {
132                     FrontendStatusType::LAYER_ERROR,
133                     FrontendStatusType::MER,
134                     FrontendStatusType::UEC,
135                     FrontendStatusType::TS_DATA_RATES,
136             };
137             break;
138         }
139         case FrontendType::ATSC: {
140             mFrontendCaps.set<FrontendCapabilities::Tag::atscCaps>(FrontendAtscCapabilities());
141             mFrontendStatusCaps = {
142                     FrontendStatusType::FREQ_OFFSET,
143                     FrontendStatusType::RF_LOCK,
144                     FrontendStatusType::MODULATIONS,
145                     FrontendStatusType::IS_LINEAR,
146             };
147             break;
148         }
149         case FrontendType::ISDBS3: {
150             mFrontendCaps.set<FrontendCapabilities::Tag::isdbs3Caps>(FrontendIsdbs3Capabilities());
151             mFrontendStatusCaps = {
152                     FrontendStatusType::DEMOD_LOCK,      FrontendStatusType::MODULATION,
153                     FrontendStatusType::MODULATIONS,     FrontendStatusType::ROLL_OFF,
154                     FrontendStatusType::IS_SHORT_FRAMES, FrontendStatusType::STREAM_ID_LIST,
155             };
156             break;
157         }
158         case FrontendType::DTMB: {
159             mFrontendCaps.set<FrontendCapabilities::Tag::dtmbCaps>(FrontendDtmbCapabilities());
160             mFrontendStatusCaps = {
161                     FrontendStatusType::MODULATIONS,       FrontendStatusType::INTERLEAVINGS,
162                     FrontendStatusType::BANDWIDTH,         FrontendStatusType::GUARD_INTERVAL,
163                     FrontendStatusType::TRANSMISSION_MODE,
164             };
165             break;
166         }
167         default: {
168             break;
169         }
170     }
171 }
172 
~Frontend()173 Frontend::~Frontend() {}
174 
close()175 ::ndk::ScopedAStatus Frontend::close() {
176     ALOGV("%s", __FUNCTION__);
177     // Reset callback
178     mCallback = nullptr;
179     mIsLocked = false;
180     mTuner->removeFrontend(mId);
181 
182     return ::ndk::ScopedAStatus::ok();
183 }
184 
setCallback(const std::shared_ptr<IFrontendCallback> & in_callback)185 ::ndk::ScopedAStatus Frontend::setCallback(const std::shared_ptr<IFrontendCallback>& in_callback) {
186     ALOGV("%s", __FUNCTION__);
187     if (in_callback == nullptr) {
188         ALOGW("[   WARN   ] Set Frontend callback with nullptr");
189         return ::ndk::ScopedAStatus::fromServiceSpecificError(
190                 static_cast<int32_t>(Result::INVALID_ARGUMENT));
191     }
192 
193     mCallback = in_callback;
194     return ::ndk::ScopedAStatus::ok();
195 }
196 
tune(const FrontendSettings &)197 ::ndk::ScopedAStatus Frontend::tune(const FrontendSettings& /* in_settings */) {
198     ALOGV("%s", __FUNCTION__);
199     if (mCallback == nullptr) {
200         ALOGW("[   WARN   ] Frontend callback is not set when tune");
201         return ::ndk::ScopedAStatus::fromServiceSpecificError(
202                 static_cast<int32_t>(Result::INVALID_STATE));
203     }
204 
205     mTuner->frontendStartTune(mId);
206     mCallback->onEvent(FrontendEventType::LOCKED);
207     mIsLocked = true;
208 
209     return ::ndk::ScopedAStatus::ok();
210 }
211 
stopTune()212 ::ndk::ScopedAStatus Frontend::stopTune() {
213     ALOGV("%s", __FUNCTION__);
214 
215     mTuner->frontendStopTune(mId);
216     mIsLocked = false;
217 
218     return ::ndk::ScopedAStatus::ok();
219 }
220 
scan(const FrontendSettings & in_settings,FrontendScanType in_type)221 ::ndk::ScopedAStatus Frontend::scan(const FrontendSettings& in_settings, FrontendScanType in_type) {
222     ALOGV("%s", __FUNCTION__);
223 
224     // If it's in middle of scanning, stop it first.
225     if (mScanThread.joinable()) {
226         mScanThread.join();
227     }
228 
229     mFrontendSettings = in_settings;
230     mFrontendScanType = in_type;
231     mScanThread = std::thread(&Frontend::scanThreadLoop, this);
232 
233     return ::ndk::ScopedAStatus::ok();
234 }
235 
scanThreadLoop()236 void Frontend::scanThreadLoop() {
237     if (mIsLocked) {
238         FrontendScanMessage msg;
239         msg.set<FrontendScanMessage::Tag::isEnd>(true);
240         mCallback->onScanMessage(FrontendScanMessageType::END, msg);
241         return;
242     }
243 
244     int64_t frequency = 0;
245     switch (mFrontendSettings.getTag()) {
246         case FrontendSettings::Tag::analog:
247             frequency = mFrontendSettings.get<FrontendSettings::Tag::analog>().frequency;
248             break;
249         case FrontendSettings::Tag::atsc:
250             frequency = mFrontendSettings.get<FrontendSettings::Tag::atsc>().frequency;
251             break;
252         case FrontendSettings::Tag::atsc3:
253             frequency = mFrontendSettings.get<FrontendSettings::Tag::atsc3>().frequency;
254             break;
255         case FrontendSettings::Tag::dvbs:
256             frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbs>().frequency;
257             break;
258         case FrontendSettings::Tag::dvbc:
259             frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbc>().frequency;
260             break;
261         case FrontendSettings::Tag::dvbt:
262             frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbt>().frequency;
263             break;
264         case FrontendSettings::Tag::isdbs:
265             frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbs>().frequency;
266             break;
267         case FrontendSettings::Tag::isdbs3:
268             frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbs3>().frequency;
269             break;
270         case FrontendSettings::Tag::isdbt:
271             frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbt>().frequency;
272             break;
273         default:
274             break;
275     }
276 
277     if (mFrontendScanType == FrontendScanType::SCAN_BLIND) {
278         frequency += 100 * 1000;
279     }
280 
281     {
282         FrontendScanMessage msg;
283         vector<int64_t> frequencies = {frequency};
284         msg.set<FrontendScanMessage::Tag::frequencies>(frequencies);
285         mCallback->onScanMessage(FrontendScanMessageType::FREQUENCY, msg);
286     }
287 
288     {
289         FrontendScanMessage msg;
290         msg.set<FrontendScanMessage::Tag::progressPercent>(20);
291         mCallback->onScanMessage(FrontendScanMessageType::PROGRESS_PERCENT, msg);
292     }
293 
294     {
295         FrontendScanMessage msg;
296         vector<int32_t> symbolRates = {30};
297         msg.set<FrontendScanMessage::Tag::symbolRates>(symbolRates);
298         mCallback->onScanMessage(FrontendScanMessageType::SYMBOL_RATE, msg);
299     }
300 
301     if (mType == FrontendType::DVBT) {
302         FrontendScanMessage msg;
303         msg.set<FrontendScanMessage::Tag::hierarchy>(FrontendDvbtHierarchy::HIERARCHY_NON_NATIVE);
304         mCallback->onScanMessage(FrontendScanMessageType::HIERARCHY, msg);
305     }
306 
307     if (mType == FrontendType::ANALOG) {
308         FrontendScanMessage msg;
309         msg.set<FrontendScanMessage::Tag::analogType>(FrontendAnalogType::PAL);
310         mCallback->onScanMessage(FrontendScanMessageType::ANALOG_TYPE, msg);
311     }
312 
313     {
314         FrontendScanMessage msg;
315         vector<int32_t> plpIds = {2};
316         msg.set<FrontendScanMessage::Tag::plpIds>(plpIds);
317         mCallback->onScanMessage(FrontendScanMessageType::PLP_IDS, msg);
318     }
319 
320     {
321         FrontendScanMessage msg;
322         vector<int32_t> groupIds = {3};
323         msg.set<FrontendScanMessage::Tag::groupIds>(groupIds);
324         mCallback->onScanMessage(FrontendScanMessageType::GROUP_IDS, msg);
325     }
326 
327     {
328         FrontendScanMessage msg;
329         vector<int32_t> inputStreamIds = {1};
330         msg.set<FrontendScanMessage::Tag::inputStreamIds>(inputStreamIds);
331         mCallback->onScanMessage(FrontendScanMessageType::INPUT_STREAM_IDS, msg);
332     }
333 
334     switch (mType) {
335         case FrontendType::DVBT: {
336             FrontendScanMessage msg;
337             FrontendScanMessageStandard std;
338             std.set<FrontendScanMessageStandard::Tag::tStd>(FrontendDvbtStandard::AUTO);
339             msg.set<FrontendScanMessage::Tag::std>(std);
340             mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
341             break;
342         }
343         case FrontendType::DVBS: {
344             FrontendScanMessage msg;
345             FrontendScanMessageStandard std;
346             std.set<FrontendScanMessageStandard::Tag::sStd>(FrontendDvbsStandard::AUTO);
347             msg.set<FrontendScanMessage::Tag::std>(std);
348             mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
349             break;
350         }
351         case FrontendType::ANALOG: {
352             FrontendScanMessage msg;
353             FrontendScanMessageStandard std;
354             std.set<FrontendScanMessageStandard::Tag::sifStd>(FrontendAnalogSifStandard::AUTO);
355             msg.set<FrontendScanMessage::Tag::std>(std);
356             mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
357             break;
358         }
359         default:
360             break;
361     }
362 
363     {
364         FrontendScanMessage msg;
365         FrontendScanAtsc3PlpInfo info;
366         info.plpId = 1;
367         info.bLlsFlag = false;
368         vector<FrontendScanAtsc3PlpInfo> atsc3PlpInfos = {info};
369         msg.set<FrontendScanMessage::Tag::atsc3PlpInfos>(atsc3PlpInfos);
370         mCallback->onScanMessage(FrontendScanMessageType::ATSC3_PLP_INFO, msg);
371     }
372 
373     {
374         FrontendScanMessage msg;
375         FrontendModulation modulation;
376         modulation.set<FrontendModulation::Tag::dvbc>(FrontendDvbcModulation::MOD_16QAM);
377         msg.set<FrontendScanMessage::Tag::modulation>(modulation);
378         mCallback->onScanMessage(FrontendScanMessageType::MODULATION, msg);
379     }
380 
381     {
382         FrontendScanMessage msg;
383         msg.set<FrontendScanMessage::Tag::isHighPriority>(true);
384         mCallback->onScanMessage(FrontendScanMessageType::HIGH_PRIORITY, msg);
385     }
386 
387     if (mType == FrontendType::DVBT) {
388         FrontendScanMessage msg;
389         vector<int32_t> dvbtCellIds = {0, 1};
390         msg.set<FrontendScanMessage::Tag::dvbtCellIds>(dvbtCellIds);
391         mCallback->onScanMessage(FrontendScanMessageType::DVBT_CELL_IDS, msg);
392     }
393 
394     {
395         FrontendScanMessage msg;
396         msg.set<FrontendScanMessage::Tag::isLocked>(false);
397         mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
398         mIsLocked = false;
399     }
400 
401     {
402         FrontendScanMessage msg;
403         msg.set<FrontendScanMessage::Tag::isLocked>(true);
404         mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
405         mIsLocked = true;
406     }
407 }
408 
stopScan()409 ::ndk::ScopedAStatus Frontend::stopScan() {
410     ALOGV("%s", __FUNCTION__);
411 
412     if (mScanThread.joinable()) {
413         mScanThread.join();
414     }
415 
416     mIsLocked = false;
417     return ::ndk::ScopedAStatus::ok();
418 }
419 
getStatus(const std::vector<FrontendStatusType> & in_statusTypes,std::vector<FrontendStatus> * _aidl_return)420 ::ndk::ScopedAStatus Frontend::getStatus(const std::vector<FrontendStatusType>& in_statusTypes,
421                                          std::vector<FrontendStatus>* _aidl_return) {
422     ALOGV("%s", __FUNCTION__);
423 
424     for (int i = 0; i < in_statusTypes.size(); i++) {
425         FrontendStatusType type = in_statusTypes[i];
426         FrontendStatus status;
427         // assign randomly selected values for testing.
428         switch (type) {
429             case FrontendStatusType::DEMOD_LOCK: {
430                 status.set<FrontendStatus::isDemodLocked>(true);
431                 break;
432             }
433             case FrontendStatusType::SNR: {
434                 status.set<FrontendStatus::snr>(221);
435                 break;
436             }
437             case FrontendStatusType::BER: {
438                 status.set<FrontendStatus::ber>(1);
439                 break;
440             }
441             case FrontendStatusType::PER: {
442                 status.set<FrontendStatus::per>(2);
443                 break;
444             }
445             case FrontendStatusType::PRE_BER: {
446                 status.set<FrontendStatus::preBer>(3);
447                 break;
448             }
449             case FrontendStatusType::SIGNAL_QUALITY: {
450                 status.set<FrontendStatus::signalQuality>(4);
451                 break;
452             }
453             case FrontendStatusType::SIGNAL_STRENGTH: {
454                 status.set<FrontendStatus::signalStrength>(5);
455                 break;
456             }
457             case FrontendStatusType::SYMBOL_RATE: {
458                 status.set<FrontendStatus::symbolRate>(6);
459                 break;
460             }
461             case FrontendStatusType::FEC: {
462                 status.set<FrontendStatus::innerFec>(FrontendInnerFec::FEC_2_9);  // value = 1 << 7
463                 break;
464             }
465             case FrontendStatusType::MODULATION: {
466                 switch (mType) {
467                     case FrontendType::ISDBS: {
468                         FrontendModulationStatus modulationStatus;
469                         modulationStatus.set<FrontendModulationStatus::Tag::isdbs>(
470                                 FrontendIsdbsModulation::MOD_BPSK);  // value = 1 << 1
471                         status.set<FrontendStatus::modulationStatus>(modulationStatus);
472                         break;
473                     }
474                     case FrontendType::DVBC: {
475                         FrontendModulationStatus modulationStatus;
476                         modulationStatus.set<FrontendModulationStatus::Tag::dvbc>(
477                                 FrontendDvbcModulation::MOD_16QAM);  // value = 1 << 1
478                         status.set<FrontendStatus::modulationStatus>(modulationStatus);
479                         break;
480                     }
481                     case FrontendType::DVBS: {
482                         FrontendModulationStatus modulationStatus;
483                         modulationStatus.set<FrontendModulationStatus::Tag::dvbs>(
484                                 FrontendDvbsModulation::MOD_QPSK);  // value = 1 << 1
485                         status.set<FrontendStatus::modulationStatus>(modulationStatus);
486                         break;
487                     }
488                     case FrontendType::ISDBS3: {
489                         FrontendModulationStatus modulationStatus;
490                         modulationStatus.set<FrontendModulationStatus::Tag::isdbs3>(
491                                 FrontendIsdbs3Modulation::MOD_BPSK);  // value = 1 << 1
492                         status.set<FrontendStatus::modulationStatus>(modulationStatus);
493                         break;
494                     }
495                     case FrontendType::ISDBT: {
496                         FrontendModulationStatus modulationStatus;
497                         modulationStatus.set<FrontendModulationStatus::Tag::isdbt>(
498                                 FrontendIsdbtModulation::MOD_DQPSK);  // value = 1 << 1
499                         status.set<FrontendStatus::modulationStatus>(modulationStatus);
500                         break;
501                     }
502                     default:
503                         break;
504                 }
505                 break;
506             }
507             case FrontendStatusType::SPECTRAL: {
508                 status.set<FrontendStatus::inversion>(FrontendSpectralInversion::NORMAL);
509                 break;
510             }
511             case FrontendStatusType::LNB_VOLTAGE: {
512                 status.set<FrontendStatus::lnbVoltage>(LnbVoltage::VOLTAGE_5V);
513                 break;
514             }
515             case FrontendStatusType::PLP_ID: {
516                 status.set<FrontendStatus::plpId>(101);
517                 break;
518             }
519             case FrontendStatusType::EWBS: {
520                 status.set<FrontendStatus::isEWBS>(false);
521                 break;
522             }
523             case FrontendStatusType::AGC: {
524                 status.set<FrontendStatus::agc>(7);
525                 break;
526             }
527             case FrontendStatusType::LNA: {
528                 status.set<FrontendStatus::isLnaOn>(false);
529                 break;
530             }
531             case FrontendStatusType::LAYER_ERROR: {
532                 vector<bool> v = {false, true, true};
533                 status.set<FrontendStatus::isLayerError>(v);
534                 break;
535             }
536             case FrontendStatusType::MER: {
537                 status.set<FrontendStatus::mer>(8);
538                 break;
539             }
540             case FrontendStatusType::FREQ_OFFSET: {
541                 status.set<FrontendStatus::freqOffset>(9);
542                 break;
543             }
544             case FrontendStatusType::HIERARCHY: {
545                 status.set<FrontendStatus::hierarchy>(FrontendDvbtHierarchy::HIERARCHY_1_NATIVE);
546                 break;
547             }
548             case FrontendStatusType::RF_LOCK: {
549                 status.set<FrontendStatus::isRfLocked>(false);
550                 break;
551             }
552             case FrontendStatusType::ATSC3_PLP_INFO: {
553                 FrontendStatusAtsc3PlpInfo info1;
554                 info1.plpId = 3;
555                 info1.isLocked = false;
556                 info1.uec = 313;
557                 FrontendStatusAtsc3PlpInfo info2;
558                 info2.plpId = 5;
559                 info2.isLocked = true;
560                 info2.uec = 515;
561                 vector<FrontendStatusAtsc3PlpInfo> infos = {info1, info2};
562                 status.set<FrontendStatus::plpInfo>(infos);
563                 break;
564             }
565             case FrontendStatusType::MODULATIONS: {
566                 FrontendModulation modulation;
567                 vector<FrontendModulation> modulations;
568                 switch (mType) {
569                     case FrontendType::ISDBS: {
570                         modulation.set<FrontendModulation::Tag::isdbs>(
571                                 FrontendIsdbsModulation::MOD_BPSK);  // value = 1 << 1
572                         modulations.push_back(modulation);
573                         status.set<FrontendStatus::modulations>(modulations);
574                         break;
575                     }
576                     case FrontendType::DVBC: {
577                         modulation.set<FrontendModulation::Tag::dvbc>(
578                                 FrontendDvbcModulation::MOD_16QAM);  // value = 1 << 1
579                         modulations.push_back(modulation);
580                         status.set<FrontendStatus::modulations>(modulations);
581                         break;
582                     }
583                     case FrontendType::DVBS: {
584                         modulation.set<FrontendModulation::Tag::dvbs>(
585                                 FrontendDvbsModulation::MOD_QPSK);  // value = 1 << 1
586                         modulations.push_back(modulation);
587                         status.set<FrontendStatus::modulations>(modulations);
588                         break;
589                     }
590                     case FrontendType::DVBT: {
591                         modulation.set<FrontendModulation::Tag::dvbt>(
592                                 FrontendDvbtConstellation::CONSTELLATION_16QAM_R);  // value = 1 <<
593                                                                                     // 16
594                         modulations.push_back(modulation);
595                         status.set<FrontendStatus::modulations>(modulations);
596                         break;
597                     }
598                     case FrontendType::ISDBS3: {
599                         modulation.set<FrontendModulation::Tag::isdbs3>(
600                                 FrontendIsdbs3Modulation::MOD_BPSK);  //  value = 1 << 1
601                         modulations.push_back(modulation);
602                         status.set<FrontendStatus::modulations>(modulations);
603                         break;
604                     }
605                     case FrontendType::ISDBT: {
606                         modulation.set<FrontendModulation::Tag::isdbt>(
607                                 FrontendIsdbtModulation::MOD_DQPSK);  // value = 1 << 1
608                         modulations.push_back(modulation);
609                         status.set<FrontendStatus::modulations>(modulations);
610                         break;
611                     }
612                     case FrontendType::ATSC: {
613                         modulation.set<FrontendModulation::Tag::atsc>(
614                                 FrontendAtscModulation::MOD_8VSB);  // value = 1 << 2
615                         modulations.push_back(modulation);
616                         status.set<FrontendStatus::modulations>(modulations);
617                         break;
618                     }
619                     case FrontendType::ATSC3: {
620                         modulation.set<FrontendModulation::Tag::atsc3>(
621                                 FrontendAtsc3Modulation::MOD_QPSK);  // value = 1 << 1
622                         modulations.push_back(modulation);
623                         status.set<FrontendStatus::modulations>(modulations);
624                         break;
625                     }
626                     case FrontendType::DTMB: {
627                         modulation.set<FrontendModulation::Tag::dtmb>(
628                                 FrontendDtmbModulation::CONSTELLATION_4QAM);  // value = 1 << 1
629                         modulations.push_back(modulation);
630                         status.set<FrontendStatus::modulations>(modulations);
631                         break;
632                     }
633                     default:
634                         break;
635                 }
636                 break;
637             }
638             case FrontendStatusType::BERS: {
639                 vector<int32_t> bers = {1};
640                 status.set<FrontendStatus::bers>(bers);
641                 break;
642             }
643             case FrontendStatusType::CODERATES: {
644                 vector<FrontendInnerFec> rates;
645                 rates.push_back(FrontendInnerFec::FEC_6_15);  // value = 1 << 39
646                 status.set<FrontendStatus::codeRates>(rates);
647                 break;
648             }
649             case FrontendStatusType::BANDWIDTH: {
650                 FrontendBandwidth bandwidth;
651                 switch (mType) {
652                     case FrontendType::DVBC: {
653                         bandwidth.set<FrontendBandwidth::Tag::dvbc>(
654                                 FrontendDvbcBandwidth::BANDWIDTH_6MHZ);  // value = 1 << 1
655                         status.set<FrontendStatus::bandwidth>(bandwidth);
656                         break;
657                     }
658                     case FrontendType::DVBT: {
659                         bandwidth.set<FrontendBandwidth::Tag::dvbt>(
660                                 FrontendDvbtBandwidth::BANDWIDTH_8MHZ);  // value = 1 << 1
661                         status.set<FrontendStatus::bandwidth>(bandwidth);
662                         break;
663                     }
664                     case FrontendType::ISDBT: {
665                         bandwidth.set<FrontendBandwidth::Tag::isdbt>(
666                                 FrontendIsdbtBandwidth::BANDWIDTH_8MHZ);  // value = 1 << 1
667                         status.set<FrontendStatus::bandwidth>(bandwidth);
668                         break;
669                     }
670                     case FrontendType::ATSC3: {
671                         bandwidth.set<FrontendBandwidth::Tag::atsc3>(
672                                 FrontendAtsc3Bandwidth::BANDWIDTH_6MHZ);  // value = 1 << 1
673                         status.set<FrontendStatus::bandwidth>(bandwidth);
674                         break;
675                     }
676                     case FrontendType::DTMB: {
677                         bandwidth.set<FrontendBandwidth::Tag::dtmb>(
678                                 FrontendDtmbBandwidth::BANDWIDTH_8MHZ);  // value = 1 << 1
679                         status.set<FrontendStatus::bandwidth>(bandwidth);
680                         break;
681                     }
682                     default:
683                         break;
684                 }
685                 break;
686             }
687             case FrontendStatusType::GUARD_INTERVAL: {
688                 FrontendGuardInterval interval;
689                 switch (mType) {
690                     case FrontendType::DVBT: {
691                         interval.set<FrontendGuardInterval::Tag::dvbt>(
692                                 FrontendDvbtGuardInterval::INTERVAL_1_32);  // value = 1 << 1
693                         status.set<FrontendStatus::interval>(interval);
694                         break;
695                     }
696                     case FrontendType::ISDBT: {
697                         interval.set<FrontendGuardInterval::Tag::isdbt>(
698                                 FrontendIsdbtGuardInterval::INTERVAL_1_32);  // value = 1 << 1
699                         status.set<FrontendStatus::interval>(interval);
700                         break;
701                     }
702                     case FrontendType::DTMB: {
703                         interval.set<FrontendGuardInterval::Tag::dtmb>(
704                                 FrontendDtmbGuardInterval::PN_420_VARIOUS);  // value = 1 << 1
705                         status.set<FrontendStatus::interval>(interval);
706                         break;
707                     }
708                     default:
709                         break;
710                 }
711                 break;
712             }
713             case FrontendStatusType::TRANSMISSION_MODE: {
714                 FrontendTransmissionMode transMode;
715                 switch (mType) {
716                     case FrontendType::DVBT: {
717                         transMode.set<FrontendTransmissionMode::Tag::dvbt>(
718                                 FrontendDvbtTransmissionMode::MODE_16K_E);  // value = 1 << 8
719                         status.set<FrontendStatus::transmissionMode>(transMode);
720                         break;
721                     }
722                     case FrontendType::ISDBT: {
723                         transMode.set<FrontendTransmissionMode::Tag::isdbt>(
724                                 FrontendIsdbtMode::MODE_1);  // value = 1 << 1
725                         status.set<FrontendStatus::transmissionMode>(transMode);
726                         break;
727                     }
728                     case FrontendType::DTMB: {
729                         transMode.set<FrontendTransmissionMode::Tag::dtmb>(
730                                 FrontendDtmbTransmissionMode::C1);  // value = 1 << 1
731                         status.set<FrontendStatus::transmissionMode>(transMode);
732                         break;
733                     }
734                     default:
735                         break;
736                 }
737                 break;
738             }
739             case FrontendStatusType::UEC: {
740                 status.set<FrontendStatus::uec>(4);
741                 break;
742             }
743             case FrontendStatusType::T2_SYSTEM_ID: {
744                 status.set<FrontendStatus::systemId>(5);
745                 break;
746             }
747             case FrontendStatusType::INTERLEAVINGS: {
748                 FrontendInterleaveMode interleave;
749                 vector<FrontendInterleaveMode> interleaves;
750                 switch (mType) {
751                     case FrontendType::DVBC: {
752                         // value = 1 << 1
753                         interleave.set<FrontendInterleaveMode::Tag::dvbc>(
754                                 FrontendCableTimeInterleaveMode::INTERLEAVING_128_1_0);
755                         interleaves.push_back(interleave);
756                         status.set<FrontendStatus::interleaving>(interleaves);
757                         break;
758                     }
759                     case FrontendType::ATSC3: {
760                         interleave.set<FrontendInterleaveMode::Tag::atsc3>(
761                                 FrontendAtsc3TimeInterleaveMode::CTI);  // value = 1 << 1
762                         interleaves.push_back(interleave);
763                         status.set<FrontendStatus::interleaving>(interleaves);
764                         break;
765                     }
766                     case FrontendType::DTMB: {
767                         interleave.set<FrontendInterleaveMode::Tag::dtmb>(
768                                 FrontendDtmbTimeInterleaveMode::TIMER_INT_240);  // value = 1 << 1
769                         interleaves.push_back(interleave);
770                         status.set<FrontendStatus::interleaving>(interleaves);
771                         break;
772                     }
773                     case FrontendType::ISDBT: {
774                         interleave.set<FrontendInterleaveMode::Tag::isdbt>(
775                                 FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0); // value = 1 << 1
776                         interleaves.push_back(interleave);
777                         status.set<FrontendStatus::interleaving>(interleaves);
778                         break;
779                     }
780                     default:
781                         break;
782                 }
783                 break;
784             }
785             case FrontendStatusType::ISDBT_SEGMENTS: {
786                 vector<int32_t> segments = {2, 3};
787                 status.set<FrontendStatus::isdbtSegment>(segments);
788                 break;
789             }
790             case FrontendStatusType::TS_DATA_RATES: {
791                 vector<int32_t> dataRates = {4, 5};
792                 status.set<FrontendStatus::tsDataRate>(dataRates);
793                 break;
794             }
795             case FrontendStatusType::ROLL_OFF: {
796                 FrontendRollOff rollOff;
797                 switch (mType) {
798                     case FrontendType::DVBS: {
799                         rollOff.set<FrontendRollOff::Tag::dvbs>(
800                                 FrontendDvbsRolloff::ROLLOFF_0_35);  // value = 1
801                         status.set<FrontendStatus::rollOff>(rollOff);
802                         break;
803                     }
804                     case FrontendType::ISDBS: {
805                         rollOff.set<FrontendRollOff::Tag::isdbs>(
806                                 FrontendIsdbsRolloff::ROLLOFF_0_35);  // value = 1
807                         status.set<FrontendStatus::rollOff>(rollOff);
808                         break;
809                     }
810                     case FrontendType::ISDBS3: {
811                         rollOff.set<FrontendRollOff::Tag::isdbs3>(
812                                 FrontendIsdbs3Rolloff::ROLLOFF_0_03);  // value = 1
813                         status.set<FrontendStatus::rollOff>(rollOff);
814                         break;
815                     }
816                     default:
817                         break;
818                 }
819                 break;
820             }
821             case FrontendStatusType::IS_MISO: {
822                 status.set<FrontendStatus::isMiso>(true);
823                 break;
824             }
825             case FrontendStatusType::IS_LINEAR: {
826                 status.set<FrontendStatus::isLinear>(true);
827                 break;
828             }
829             case FrontendStatusType::IS_SHORT_FRAMES: {
830                 status.set<FrontendStatus::isShortFrames>(true);
831                 break;
832             }
833             case FrontendStatusType::ISDBT_MODE: {
834                 status.set<FrontendStatus::isdbtMode>(FrontendIsdbtMode::AUTO);
835                 break;
836             }
837             case FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG: {
838                 status.set<FrontendStatus::partialReceptionFlag>(
839                         FrontendIsdbtPartialReceptionFlag::AUTO);
840                 break;
841             }
842             case FrontendStatusType::STREAM_ID_LIST: {
843                 vector<int32_t> streamIds = {0, 1};
844                 status.set<FrontendStatus::streamIdList>(streamIds);
845                 break;
846             }
847             case FrontendStatusType::DVBT_CELL_IDS: {
848                 vector<int32_t> dvbtCellIds = {0, 1};
849                 status.set<FrontendStatus::dvbtCellIds>(dvbtCellIds);
850                 break;
851             }
852             case FrontendStatusType::ATSC3_ALL_PLP_INFO: {
853                 FrontendScanAtsc3PlpInfo info1;
854                 info1.plpId = 1;
855                 info1.bLlsFlag = false;
856                 FrontendScanAtsc3PlpInfo info2;
857                 info2.plpId = 2;
858                 info2.bLlsFlag = true;
859                 FrontendScanAtsc3PlpInfo info3;
860                 info3.plpId = 3;
861                 info3.bLlsFlag = false;
862                 vector<FrontendScanAtsc3PlpInfo> infos = {info1, info2, info3};
863                 status.set<FrontendStatus::allPlpInfo>(infos);
864                 break;
865             }
866             default: {
867                 continue;
868             }
869         }
870         _aidl_return->push_back(status);
871     }
872 
873     return ::ndk::ScopedAStatus::ok();
874 }
875 
setLnb(int32_t)876 ::ndk::ScopedAStatus Frontend::setLnb(int32_t /* in_lnbId */) {
877     ALOGV("%s", __FUNCTION__);
878     if (!supportsSatellite()) {
879         return ::ndk::ScopedAStatus::fromServiceSpecificError(
880                 static_cast<int32_t>(Result::INVALID_STATE));
881     }
882     return ::ndk::ScopedAStatus::ok();
883 }
884 
linkCiCam(int32_t in_ciCamId,int32_t * _aidl_return)885 ::ndk::ScopedAStatus Frontend::linkCiCam(int32_t in_ciCamId, int32_t* _aidl_return) {
886     ALOGV("%s", __FUNCTION__);
887 
888     mCiCamId = in_ciCamId;
889     *_aidl_return = 0;
890 
891     return ::ndk::ScopedAStatus::ok();
892 }
893 
unlinkCiCam(int32_t)894 ::ndk::ScopedAStatus Frontend::unlinkCiCam(int32_t /* in_ciCamId */) {
895     ALOGV("%s", __FUNCTION__);
896 
897     mCiCamId = -1;
898 
899     return ::ndk::ScopedAStatus::ok();
900 }
901 
dump(int fd,const char **,uint32_t)902 binder_status_t Frontend::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
903     dprintf(fd, "  Frontend %d\n", mId);
904     dprintf(fd, "    mType: %d\n", mType);
905     dprintf(fd, "    mIsLocked: %d\n", mIsLocked);
906     dprintf(fd, "    mCiCamId: %d\n", mCiCamId);
907     dprintf(fd, "    mFrontendStatusCaps:");
908     for (int i = 0; i < mFrontendStatusCaps.size(); i++) {
909         dprintf(fd, "        %d\n", mFrontendStatusCaps[i]);
910     }
911     return STATUS_OK;
912 }
913 
getHardwareInfo(std::string * _aidl_return)914 ::ndk::ScopedAStatus Frontend::getHardwareInfo(std::string* _aidl_return) {
915     ALOGV("%s", __FUNCTION__);
916 
917     *_aidl_return = "Sample Frontend";
918     return ::ndk::ScopedAStatus::ok();
919 }
920 
removeOutputPid(int32_t)921 ::ndk::ScopedAStatus Frontend::removeOutputPid(int32_t /* in_pid */) {
922     ALOGV("%s", __FUNCTION__);
923 
924     return ::ndk::ScopedAStatus::fromServiceSpecificError(
925             static_cast<int32_t>(Result::UNAVAILABLE));
926 }
927 
getFrontendStatusReadiness(const std::vector<FrontendStatusType> & in_statusTypes,std::vector<FrontendStatusReadiness> * _aidl_return)928 ::ndk::ScopedAStatus Frontend::getFrontendStatusReadiness(
929         const std::vector<FrontendStatusType>& in_statusTypes,
930         std::vector<FrontendStatusReadiness>* _aidl_return) {
931     ALOGV("%s", __FUNCTION__);
932 
933     _aidl_return->resize(in_statusTypes.size());
934     for (int i = 0; i < in_statusTypes.size(); i++) {
935         int j = 0;
936         while (j < mFrontendStatusCaps.size()) {
937             if (in_statusTypes[i] == mFrontendStatusCaps[j]) {
938                 (*_aidl_return)[i] = FrontendStatusReadiness::STABLE;
939                 break;
940             }
941             j++;
942         }
943         if (j >= mFrontendStatusCaps.size()) {
944             (*_aidl_return)[i] = FrontendStatusReadiness::UNSUPPORTED;
945         }
946     }
947 
948     return ::ndk::ScopedAStatus::ok();
949 }
950 
getFrontendType()951 FrontendType Frontend::getFrontendType() {
952     return mType;
953 }
954 
getFrontendId()955 int32_t Frontend::getFrontendId() {
956     return mId;
957 }
958 
supportsSatellite()959 bool Frontend::supportsSatellite() {
960     return mType == FrontendType::DVBS || mType == FrontendType::ISDBS ||
961            mType == FrontendType::ISDBS3;
962 }
963 
isLocked()964 bool Frontend::isLocked() {
965     return mIsLocked;
966 }
967 
getFrontendInfo(FrontendInfo * _aidl_return)968 void Frontend::getFrontendInfo(FrontendInfo* _aidl_return) {
969     // assign randomly selected values for testing.
970     *_aidl_return = {
971             .type = mType,
972             .minFrequency = 139000000,
973             .maxFrequency = 1139000000,
974             .minSymbolRate = 45,
975             .maxSymbolRate = 1145,
976             .acquireRange = 30,
977             .exclusiveGroupId = 57,
978             .statusCaps = mFrontendStatusCaps,
979             .frontendCaps = mFrontendCaps,
980     };
981 }
982 
983 }  // namespace tuner
984 }  // namespace tv
985 }  // namespace hardware
986 }  // namespace android
987 }  // namespace aidl
988