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