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