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