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