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