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