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