blob: 6bdbac55ffe049500d6335119649073100dc3d54 [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
sadiqsada56c98292023-11-02 16:45:31 -0700216void Frontend::readTuneByte(dtv_streamer* streamer, void* buf, size_t buf_size, int timeout_ms) {
217 ssize_t bytes_read = mIptvPluginInterface->read_stream(streamer, buf, buf_size, timeout_ms);
218 if (bytes_read == 0) {
219 ALOGI("[ ERROR ] Tune byte couldn't be read.");
220 return;
221 }
222 mCallback->onEvent(FrontendEventType::LOCKED);
223 mIsLocked = true;
224}
225
226::ndk::ScopedAStatus Frontend::tune(const FrontendSettings& in_settings) {
Hongguang4092f2f2021-07-08 18:49:12 -0700227 if (mCallback == nullptr) {
sadiqsada56c98292023-11-02 16:45:31 -0700228 ALOGW("[ WARN ] Frontend callback is not set for tunin0g");
Hongguange423acd2021-07-27 16:56:47 -0700229 return ::ndk::ScopedAStatus::fromServiceSpecificError(
230 static_cast<int32_t>(Result::INVALID_STATE));
Hongguang4092f2f2021-07-08 18:49:12 -0700231 }
232
sadiqsada1448ad42023-01-31 16:14:04 -0800233 if (mType != FrontendType::IPTV) {
234 mTuner->frontendStartTune(mId);
sadiqsada56c98292023-11-02 16:45:31 -0700235 mCallback->onEvent(FrontendEventType::LOCKED);
236 mIsLocked = true;
237 } else {
238 // This is a reference implementation for IPTV. It uses an additional socket buffer.
239 // Vendors can use hardware memory directly to make the implementation more performant.
240 ALOGI("[ INFO ] Frontend type is set to IPTV, tag = %d id=%d", in_settings.getTag(),
241 mId);
Hongguang4092f2f2021-07-08 18:49:12 -0700242
sadiqsada56c98292023-11-02 16:45:31 -0700243 // load udp plugin for reading TS data
244 const char* path = "/vendor/lib/iptv_udp_plugin.so";
245 DtvPlugin* plugin = new DtvPlugin(path);
246 if (!plugin) {
247 ALOGE("Failed to create DtvPlugin, plugin_path is invalid");
248 return ::ndk::ScopedAStatus::fromServiceSpecificError(
249 static_cast<int32_t>(Result::INVALID_ARGUMENT));
250 }
251 bool plugin_loaded = plugin->load();
252 if (!plugin_loaded) {
253 ALOGE("Failed to load plugin");
254 return ::ndk::ScopedAStatus::fromServiceSpecificError(
255 static_cast<int32_t>(Result::INVALID_ARGUMENT));
256 }
257 mIptvPluginInterface = plugin->interface();
258
259 // validate content_url format
260 std::string content_url = in_settings.get<FrontendSettings::Tag::iptv>()->contentUrl;
261 std::string transport_desc = "{ \"uri\": \"" + content_url + "\"}";
262 ALOGI("[ INFO ] transport_desc: %s", transport_desc.c_str());
263 bool is_transport_desc_valid = plugin->validate(transport_desc.c_str());
264 if (!is_transport_desc_valid) { // not of format protocol://ip:port
265 ALOGE("[ INFO ] transport_desc is not valid");
266 return ::ndk::ScopedAStatus::fromServiceSpecificError(
267 static_cast<int32_t>(Result::INVALID_ARGUMENT));
268 }
269 mIptvTransportDescription = transport_desc;
270
271 // create a streamer and open it for reading data
272 dtv_streamer* streamer = mIptvPluginInterface->create_streamer();
273 mIptvPluginStreamer = streamer;
274 int open_fd = mIptvPluginInterface->open_stream(streamer, transport_desc.c_str());
275 if (open_fd < 0) {
276 ALOGE("[ INFO ] could not open stream");
277 return ::ndk::ScopedAStatus::fromServiceSpecificError(
278 static_cast<int32_t>(Result::INVALID_ARGUMENT));
279 }
280 ALOGI("[ INFO ] open_stream successful, open_fd=%d", open_fd);
281
282 size_t buf_size = 1;
283 int timeout_ms = 2000;
284 void* buf = malloc(sizeof(char) * buf_size);
285 if (buf == nullptr) ALOGI("malloc buf failed [TUNE]");
286 ALOGI("[ INFO ] [Tune] Allocated buffer of size %zu", buf_size);
287 mIptvFrontendTuneThread =
288 std::thread(&Frontend::readTuneByte, this, streamer, buf, buf_size, timeout_ms);
289 if (mIptvFrontendTuneThread.joinable()) mIptvFrontendTuneThread.join();
290 free(buf);
291 }
Sadiq Sada6c46c892023-11-02 23:03:43 +0000292
Hongguang4092f2f2021-07-08 18:49:12 -0700293 return ::ndk::ScopedAStatus::ok();
294}
295
296::ndk::ScopedAStatus Frontend::stopTune() {
297 ALOGV("%s", __FUNCTION__);
298
Hongguange423acd2021-07-27 16:56:47 -0700299 mTuner->frontendStopTune(mId);
Hongguang4092f2f2021-07-08 18:49:12 -0700300 mIsLocked = false;
301
302 return ::ndk::ScopedAStatus::ok();
303}
304
305::ndk::ScopedAStatus Frontend::scan(const FrontendSettings& in_settings, FrontendScanType in_type) {
306 ALOGV("%s", __FUNCTION__);
Hongguang4092f2f2021-07-08 18:49:12 -0700307
Hongguang6c09bff2021-12-23 10:50:03 -0800308 // If it's in middle of scanning, stop it first.
309 if (mScanThread.joinable()) {
310 mScanThread.join();
311 }
312
313 mFrontendSettings = in_settings;
314 mFrontendScanType = in_type;
315 mScanThread = std::thread(&Frontend::scanThreadLoop, this);
316
317 return ::ndk::ScopedAStatus::ok();
318}
319
Hongguang4a8ac292022-08-09 14:02:03 -0700320void Frontend::setTunerService(std::shared_ptr<Tuner> tuner) {
321 mTuner = tuner;
322}
323
Hongguang6c09bff2021-12-23 10:50:03 -0800324void Frontend::scanThreadLoop() {
Hongguang4092f2f2021-07-08 18:49:12 -0700325 if (mIsLocked) {
Hongguange423acd2021-07-27 16:56:47 -0700326 FrontendScanMessage msg;
Hongguang4092f2f2021-07-08 18:49:12 -0700327 msg.set<FrontendScanMessage::Tag::isEnd>(true);
328 mCallback->onScanMessage(FrontendScanMessageType::END, msg);
Hongguang6c09bff2021-12-23 10:50:03 -0800329 return;
Hongguang4092f2f2021-07-08 18:49:12 -0700330 }
331
Hongguang11da2cb2021-08-05 19:05:12 -0700332 int64_t frequency = 0;
Hongguang6c09bff2021-12-23 10:50:03 -0800333 switch (mFrontendSettings.getTag()) {
Hongguang4092f2f2021-07-08 18:49:12 -0700334 case FrontendSettings::Tag::analog:
Hongguang6c09bff2021-12-23 10:50:03 -0800335 frequency = mFrontendSettings.get<FrontendSettings::Tag::analog>().frequency;
Hongguang4092f2f2021-07-08 18:49:12 -0700336 break;
337 case FrontendSettings::Tag::atsc:
Hongguang6c09bff2021-12-23 10:50:03 -0800338 frequency = mFrontendSettings.get<FrontendSettings::Tag::atsc>().frequency;
Hongguang4092f2f2021-07-08 18:49:12 -0700339 break;
340 case FrontendSettings::Tag::atsc3:
Hongguang6c09bff2021-12-23 10:50:03 -0800341 frequency = mFrontendSettings.get<FrontendSettings::Tag::atsc3>().frequency;
Hongguang4092f2f2021-07-08 18:49:12 -0700342 break;
343 case FrontendSettings::Tag::dvbs:
Hongguang6c09bff2021-12-23 10:50:03 -0800344 frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbs>().frequency;
Hongguang4092f2f2021-07-08 18:49:12 -0700345 break;
346 case FrontendSettings::Tag::dvbc:
Hongguang6c09bff2021-12-23 10:50:03 -0800347 frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbc>().frequency;
Hongguang4092f2f2021-07-08 18:49:12 -0700348 break;
349 case FrontendSettings::Tag::dvbt:
Hongguang6c09bff2021-12-23 10:50:03 -0800350 frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbt>().frequency;
Hongguang4092f2f2021-07-08 18:49:12 -0700351 break;
352 case FrontendSettings::Tag::isdbs:
Hongguang6c09bff2021-12-23 10:50:03 -0800353 frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbs>().frequency;
Hongguang4092f2f2021-07-08 18:49:12 -0700354 break;
355 case FrontendSettings::Tag::isdbs3:
Hongguang6c09bff2021-12-23 10:50:03 -0800356 frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbs3>().frequency;
Hongguang4092f2f2021-07-08 18:49:12 -0700357 break;
358 case FrontendSettings::Tag::isdbt:
Hongguang6c09bff2021-12-23 10:50:03 -0800359 frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbt>().frequency;
Hongguang4092f2f2021-07-08 18:49:12 -0700360 break;
361 default:
362 break;
363 }
364
Hongguang6c09bff2021-12-23 10:50:03 -0800365 if (mFrontendScanType == FrontendScanType::SCAN_BLIND) {
Gareth Fenn282fb372021-09-27 15:14:11 +0100366 frequency += 100 * 1000;
Hongguang4092f2f2021-07-08 18:49:12 -0700367 }
368
369 {
370 FrontendScanMessage msg;
Hongguang11da2cb2021-08-05 19:05:12 -0700371 vector<int64_t> frequencies = {frequency};
Hongguang4092f2f2021-07-08 18:49:12 -0700372 msg.set<FrontendScanMessage::Tag::frequencies>(frequencies);
373 mCallback->onScanMessage(FrontendScanMessageType::FREQUENCY, msg);
374 }
375
376 {
377 FrontendScanMessage msg;
378 msg.set<FrontendScanMessage::Tag::progressPercent>(20);
379 mCallback->onScanMessage(FrontendScanMessageType::PROGRESS_PERCENT, msg);
380 }
381
382 {
383 FrontendScanMessage msg;
384 vector<int32_t> symbolRates = {30};
385 msg.set<FrontendScanMessage::Tag::symbolRates>(symbolRates);
386 mCallback->onScanMessage(FrontendScanMessageType::SYMBOL_RATE, msg);
387 }
388
389 if (mType == FrontendType::DVBT) {
390 FrontendScanMessage msg;
391 msg.set<FrontendScanMessage::Tag::hierarchy>(FrontendDvbtHierarchy::HIERARCHY_NON_NATIVE);
392 mCallback->onScanMessage(FrontendScanMessageType::HIERARCHY, msg);
393 }
394
395 if (mType == FrontendType::ANALOG) {
396 FrontendScanMessage msg;
397 msg.set<FrontendScanMessage::Tag::analogType>(FrontendAnalogType::PAL);
398 mCallback->onScanMessage(FrontendScanMessageType::ANALOG_TYPE, msg);
399 }
400
401 {
402 FrontendScanMessage msg;
Hongguang11da2cb2021-08-05 19:05:12 -0700403 vector<int32_t> plpIds = {2};
Hongguang4092f2f2021-07-08 18:49:12 -0700404 msg.set<FrontendScanMessage::Tag::plpIds>(plpIds);
405 mCallback->onScanMessage(FrontendScanMessageType::PLP_IDS, msg);
406 }
407
408 {
409 FrontendScanMessage msg;
Hongguang11da2cb2021-08-05 19:05:12 -0700410 vector<int32_t> groupIds = {3};
Hongguang4092f2f2021-07-08 18:49:12 -0700411 msg.set<FrontendScanMessage::Tag::groupIds>(groupIds);
412 mCallback->onScanMessage(FrontendScanMessageType::GROUP_IDS, msg);
413 }
414
415 {
416 FrontendScanMessage msg;
Hongguang11da2cb2021-08-05 19:05:12 -0700417 vector<int32_t> inputStreamIds = {1};
Hongguang4092f2f2021-07-08 18:49:12 -0700418 msg.set<FrontendScanMessage::Tag::inputStreamIds>(inputStreamIds);
419 mCallback->onScanMessage(FrontendScanMessageType::INPUT_STREAM_IDS, msg);
420 }
421
422 switch (mType) {
423 case FrontendType::DVBT: {
424 FrontendScanMessage msg;
425 FrontendScanMessageStandard std;
426 std.set<FrontendScanMessageStandard::Tag::tStd>(FrontendDvbtStandard::AUTO);
427 msg.set<FrontendScanMessage::Tag::std>(std);
428 mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
429 break;
430 }
431 case FrontendType::DVBS: {
432 FrontendScanMessage msg;
433 FrontendScanMessageStandard std;
434 std.set<FrontendScanMessageStandard::Tag::sStd>(FrontendDvbsStandard::AUTO);
435 msg.set<FrontendScanMessage::Tag::std>(std);
436 mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
437 break;
438 }
439 case FrontendType::ANALOG: {
440 FrontendScanMessage msg;
441 FrontendScanMessageStandard std;
442 std.set<FrontendScanMessageStandard::Tag::sifStd>(FrontendAnalogSifStandard::AUTO);
443 msg.set<FrontendScanMessage::Tag::std>(std);
444 mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
445 break;
446 }
447 default:
448 break;
449 }
450
451 {
452 FrontendScanMessage msg;
453 FrontendScanAtsc3PlpInfo info;
454 info.plpId = 1;
455 info.bLlsFlag = false;
456 vector<FrontendScanAtsc3PlpInfo> atsc3PlpInfos = {info};
457 msg.set<FrontendScanMessage::Tag::atsc3PlpInfos>(atsc3PlpInfos);
458 mCallback->onScanMessage(FrontendScanMessageType::ATSC3_PLP_INFO, msg);
459 }
460
461 {
462 FrontendScanMessage msg;
463 FrontendModulation modulation;
464 modulation.set<FrontendModulation::Tag::dvbc>(FrontendDvbcModulation::MOD_16QAM);
465 msg.set<FrontendScanMessage::Tag::modulation>(modulation);
466 mCallback->onScanMessage(FrontendScanMessageType::MODULATION, msg);
467 }
468
469 {
470 FrontendScanMessage msg;
471 msg.set<FrontendScanMessage::Tag::isHighPriority>(true);
472 mCallback->onScanMessage(FrontendScanMessageType::HIGH_PRIORITY, msg);
473 }
474
Hongguang7eda7822021-12-20 14:48:14 -0800475 if (mType == FrontendType::DVBT) {
476 FrontendScanMessage msg;
477 vector<int32_t> dvbtCellIds = {0, 1};
478 msg.set<FrontendScanMessage::Tag::dvbtCellIds>(dvbtCellIds);
479 mCallback->onScanMessage(FrontendScanMessageType::DVBT_CELL_IDS, msg);
480 }
481
Hongguang4092f2f2021-07-08 18:49:12 -0700482 {
483 FrontendScanMessage msg;
Hongguangc8438c02022-01-28 19:05:34 -0800484 msg.set<FrontendScanMessage::Tag::isLocked>(false);
485 mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
486 mIsLocked = false;
487 }
488
489 {
490 FrontendScanMessage msg;
Hongguang4092f2f2021-07-08 18:49:12 -0700491 msg.set<FrontendScanMessage::Tag::isLocked>(true);
492 mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
493 mIsLocked = true;
494 }
Hongguang4092f2f2021-07-08 18:49:12 -0700495}
496
497::ndk::ScopedAStatus Frontend::stopScan() {
498 ALOGV("%s", __FUNCTION__);
499
Hongguang6c09bff2021-12-23 10:50:03 -0800500 if (mScanThread.joinable()) {
501 mScanThread.join();
502 }
503
Hongguang4092f2f2021-07-08 18:49:12 -0700504 mIsLocked = false;
505 return ::ndk::ScopedAStatus::ok();
506}
507
508::ndk::ScopedAStatus Frontend::getStatus(const std::vector<FrontendStatusType>& in_statusTypes,
509 std::vector<FrontendStatus>* _aidl_return) {
510 ALOGV("%s", __FUNCTION__);
511
512 for (int i = 0; i < in_statusTypes.size(); i++) {
513 FrontendStatusType type = in_statusTypes[i];
514 FrontendStatus status;
515 // assign randomly selected values for testing.
516 switch (type) {
517 case FrontendStatusType::DEMOD_LOCK: {
518 status.set<FrontendStatus::isDemodLocked>(true);
519 break;
520 }
521 case FrontendStatusType::SNR: {
522 status.set<FrontendStatus::snr>(221);
523 break;
524 }
525 case FrontendStatusType::BER: {
526 status.set<FrontendStatus::ber>(1);
527 break;
528 }
529 case FrontendStatusType::PER: {
530 status.set<FrontendStatus::per>(2);
531 break;
532 }
533 case FrontendStatusType::PRE_BER: {
534 status.set<FrontendStatus::preBer>(3);
535 break;
536 }
537 case FrontendStatusType::SIGNAL_QUALITY: {
538 status.set<FrontendStatus::signalQuality>(4);
539 break;
540 }
541 case FrontendStatusType::SIGNAL_STRENGTH: {
542 status.set<FrontendStatus::signalStrength>(5);
543 break;
544 }
545 case FrontendStatusType::SYMBOL_RATE: {
546 status.set<FrontendStatus::symbolRate>(6);
547 break;
548 }
549 case FrontendStatusType::FEC: {
550 status.set<FrontendStatus::innerFec>(FrontendInnerFec::FEC_2_9); // value = 1 << 7
551 break;
552 }
553 case FrontendStatusType::MODULATION: {
554 switch (mType) {
555 case FrontendType::ISDBS: {
556 FrontendModulationStatus modulationStatus;
557 modulationStatus.set<FrontendModulationStatus::Tag::isdbs>(
558 FrontendIsdbsModulation::MOD_BPSK); // value = 1 << 1
559 status.set<FrontendStatus::modulationStatus>(modulationStatus);
560 break;
561 }
562 case FrontendType::DVBC: {
563 FrontendModulationStatus modulationStatus;
564 modulationStatus.set<FrontendModulationStatus::Tag::dvbc>(
565 FrontendDvbcModulation::MOD_16QAM); // value = 1 << 1
566 status.set<FrontendStatus::modulationStatus>(modulationStatus);
567 break;
568 }
569 case FrontendType::DVBS: {
570 FrontendModulationStatus modulationStatus;
571 modulationStatus.set<FrontendModulationStatus::Tag::dvbs>(
572 FrontendDvbsModulation::MOD_QPSK); // value = 1 << 1
573 status.set<FrontendStatus::modulationStatus>(modulationStatus);
574 break;
575 }
576 case FrontendType::ISDBS3: {
577 FrontendModulationStatus modulationStatus;
578 modulationStatus.set<FrontendModulationStatus::Tag::isdbs3>(
579 FrontendIsdbs3Modulation::MOD_BPSK); // value = 1 << 1
580 status.set<FrontendStatus::modulationStatus>(modulationStatus);
581 break;
582 }
583 case FrontendType::ISDBT: {
584 FrontendModulationStatus modulationStatus;
585 modulationStatus.set<FrontendModulationStatus::Tag::isdbt>(
586 FrontendIsdbtModulation::MOD_DQPSK); // value = 1 << 1
587 status.set<FrontendStatus::modulationStatus>(modulationStatus);
588 break;
589 }
590 default:
591 break;
592 }
593 break;
594 }
595 case FrontendStatusType::SPECTRAL: {
596 status.set<FrontendStatus::inversion>(FrontendSpectralInversion::NORMAL);
597 break;
598 }
599 case FrontendStatusType::LNB_VOLTAGE: {
600 status.set<FrontendStatus::lnbVoltage>(LnbVoltage::VOLTAGE_5V);
601 break;
602 }
603 case FrontendStatusType::PLP_ID: {
Hongguang11da2cb2021-08-05 19:05:12 -0700604 status.set<FrontendStatus::plpId>(101);
Hongguang4092f2f2021-07-08 18:49:12 -0700605 break;
606 }
607 case FrontendStatusType::EWBS: {
608 status.set<FrontendStatus::isEWBS>(false);
609 break;
610 }
611 case FrontendStatusType::AGC: {
612 status.set<FrontendStatus::agc>(7);
613 break;
614 }
615 case FrontendStatusType::LNA: {
616 status.set<FrontendStatus::isLnaOn>(false);
617 break;
618 }
619 case FrontendStatusType::LAYER_ERROR: {
620 vector<bool> v = {false, true, true};
621 status.set<FrontendStatus::isLayerError>(v);
622 break;
623 }
624 case FrontendStatusType::MER: {
625 status.set<FrontendStatus::mer>(8);
626 break;
627 }
628 case FrontendStatusType::FREQ_OFFSET: {
629 status.set<FrontendStatus::freqOffset>(9);
630 break;
631 }
632 case FrontendStatusType::HIERARCHY: {
633 status.set<FrontendStatus::hierarchy>(FrontendDvbtHierarchy::HIERARCHY_1_NATIVE);
634 break;
635 }
636 case FrontendStatusType::RF_LOCK: {
637 status.set<FrontendStatus::isRfLocked>(false);
638 break;
639 }
640 case FrontendStatusType::ATSC3_PLP_INFO: {
641 FrontendStatusAtsc3PlpInfo info1;
642 info1.plpId = 3;
643 info1.isLocked = false;
644 info1.uec = 313;
645 FrontendStatusAtsc3PlpInfo info2;
646 info2.plpId = 5;
647 info2.isLocked = true;
648 info2.uec = 515;
649 vector<FrontendStatusAtsc3PlpInfo> infos = {info1, info2};
650 status.set<FrontendStatus::plpInfo>(infos);
651 break;
652 }
653 case FrontendStatusType::MODULATIONS: {
654 FrontendModulation modulation;
655 vector<FrontendModulation> modulations;
656 switch (mType) {
657 case FrontendType::ISDBS: {
658 modulation.set<FrontendModulation::Tag::isdbs>(
659 FrontendIsdbsModulation::MOD_BPSK); // value = 1 << 1
660 modulations.push_back(modulation);
661 status.set<FrontendStatus::modulations>(modulations);
662 break;
663 }
664 case FrontendType::DVBC: {
665 modulation.set<FrontendModulation::Tag::dvbc>(
666 FrontendDvbcModulation::MOD_16QAM); // value = 1 << 1
667 modulations.push_back(modulation);
668 status.set<FrontendStatus::modulations>(modulations);
669 break;
670 }
671 case FrontendType::DVBS: {
672 modulation.set<FrontendModulation::Tag::dvbs>(
673 FrontendDvbsModulation::MOD_QPSK); // value = 1 << 1
674 modulations.push_back(modulation);
675 status.set<FrontendStatus::modulations>(modulations);
676 break;
677 }
678 case FrontendType::DVBT: {
679 modulation.set<FrontendModulation::Tag::dvbt>(
680 FrontendDvbtConstellation::CONSTELLATION_16QAM_R); // value = 1 <<
681 // 16
682 modulations.push_back(modulation);
683 status.set<FrontendStatus::modulations>(modulations);
684 break;
685 }
686 case FrontendType::ISDBS3: {
687 modulation.set<FrontendModulation::Tag::isdbs3>(
688 FrontendIsdbs3Modulation::MOD_BPSK); // value = 1 << 1
689 modulations.push_back(modulation);
690 status.set<FrontendStatus::modulations>(modulations);
691 break;
692 }
693 case FrontendType::ISDBT: {
694 modulation.set<FrontendModulation::Tag::isdbt>(
695 FrontendIsdbtModulation::MOD_DQPSK); // value = 1 << 1
696 modulations.push_back(modulation);
697 status.set<FrontendStatus::modulations>(modulations);
698 break;
699 }
700 case FrontendType::ATSC: {
701 modulation.set<FrontendModulation::Tag::atsc>(
702 FrontendAtscModulation::MOD_8VSB); // value = 1 << 2
703 modulations.push_back(modulation);
704 status.set<FrontendStatus::modulations>(modulations);
705 break;
706 }
707 case FrontendType::ATSC3: {
708 modulation.set<FrontendModulation::Tag::atsc3>(
709 FrontendAtsc3Modulation::MOD_QPSK); // value = 1 << 1
710 modulations.push_back(modulation);
711 status.set<FrontendStatus::modulations>(modulations);
712 break;
713 }
714 case FrontendType::DTMB: {
715 modulation.set<FrontendModulation::Tag::dtmb>(
716 FrontendDtmbModulation::CONSTELLATION_4QAM); // value = 1 << 1
717 modulations.push_back(modulation);
718 status.set<FrontendStatus::modulations>(modulations);
719 break;
720 }
721 default:
722 break;
723 }
724 break;
725 }
726 case FrontendStatusType::BERS: {
727 vector<int32_t> bers = {1};
728 status.set<FrontendStatus::bers>(bers);
729 break;
730 }
731 case FrontendStatusType::CODERATES: {
732 vector<FrontendInnerFec> rates;
733 rates.push_back(FrontendInnerFec::FEC_6_15); // value = 1 << 39
734 status.set<FrontendStatus::codeRates>(rates);
735 break;
736 }
737 case FrontendStatusType::BANDWIDTH: {
738 FrontendBandwidth bandwidth;
739 switch (mType) {
740 case FrontendType::DVBC: {
741 bandwidth.set<FrontendBandwidth::Tag::dvbc>(
742 FrontendDvbcBandwidth::BANDWIDTH_6MHZ); // value = 1 << 1
743 status.set<FrontendStatus::bandwidth>(bandwidth);
744 break;
745 }
746 case FrontendType::DVBT: {
747 bandwidth.set<FrontendBandwidth::Tag::dvbt>(
748 FrontendDvbtBandwidth::BANDWIDTH_8MHZ); // value = 1 << 1
749 status.set<FrontendStatus::bandwidth>(bandwidth);
750 break;
751 }
752 case FrontendType::ISDBT: {
753 bandwidth.set<FrontendBandwidth::Tag::isdbt>(
754 FrontendIsdbtBandwidth::BANDWIDTH_8MHZ); // value = 1 << 1
755 status.set<FrontendStatus::bandwidth>(bandwidth);
756 break;
757 }
758 case FrontendType::ATSC3: {
759 bandwidth.set<FrontendBandwidth::Tag::atsc3>(
760 FrontendAtsc3Bandwidth::BANDWIDTH_6MHZ); // value = 1 << 1
761 status.set<FrontendStatus::bandwidth>(bandwidth);
762 break;
763 }
764 case FrontendType::DTMB: {
765 bandwidth.set<FrontendBandwidth::Tag::dtmb>(
766 FrontendDtmbBandwidth::BANDWIDTH_8MHZ); // value = 1 << 1
767 status.set<FrontendStatus::bandwidth>(bandwidth);
768 break;
769 }
770 default:
771 break;
772 }
773 break;
774 }
775 case FrontendStatusType::GUARD_INTERVAL: {
776 FrontendGuardInterval interval;
777 switch (mType) {
778 case FrontendType::DVBT: {
779 interval.set<FrontendGuardInterval::Tag::dvbt>(
780 FrontendDvbtGuardInterval::INTERVAL_1_32); // value = 1 << 1
781 status.set<FrontendStatus::interval>(interval);
782 break;
783 }
784 case FrontendType::ISDBT: {
785 interval.set<FrontendGuardInterval::Tag::isdbt>(
Hongguange69a3b22021-08-03 14:23:42 -0700786 FrontendIsdbtGuardInterval::INTERVAL_1_32); // value = 1 << 1
Hongguang4092f2f2021-07-08 18:49:12 -0700787 status.set<FrontendStatus::interval>(interval);
788 break;
789 }
790 case FrontendType::DTMB: {
791 interval.set<FrontendGuardInterval::Tag::dtmb>(
792 FrontendDtmbGuardInterval::PN_420_VARIOUS); // value = 1 << 1
793 status.set<FrontendStatus::interval>(interval);
794 break;
795 }
796 default:
797 break;
798 }
799 break;
800 }
801 case FrontendStatusType::TRANSMISSION_MODE: {
802 FrontendTransmissionMode transMode;
803 switch (mType) {
804 case FrontendType::DVBT: {
805 transMode.set<FrontendTransmissionMode::Tag::dvbt>(
806 FrontendDvbtTransmissionMode::MODE_16K_E); // value = 1 << 8
807 status.set<FrontendStatus::transmissionMode>(transMode);
808 break;
809 }
810 case FrontendType::ISDBT: {
811 transMode.set<FrontendTransmissionMode::Tag::isdbt>(
812 FrontendIsdbtMode::MODE_1); // value = 1 << 1
813 status.set<FrontendStatus::transmissionMode>(transMode);
814 break;
815 }
816 case FrontendType::DTMB: {
817 transMode.set<FrontendTransmissionMode::Tag::dtmb>(
818 FrontendDtmbTransmissionMode::C1); // value = 1 << 1
819 status.set<FrontendStatus::transmissionMode>(transMode);
820 break;
821 }
822 default:
823 break;
824 }
825 break;
826 }
827 case FrontendStatusType::UEC: {
828 status.set<FrontendStatus::uec>(4);
829 break;
830 }
831 case FrontendStatusType::T2_SYSTEM_ID: {
832 status.set<FrontendStatus::systemId>(5);
833 break;
834 }
835 case FrontendStatusType::INTERLEAVINGS: {
836 FrontendInterleaveMode interleave;
837 vector<FrontendInterleaveMode> interleaves;
838 switch (mType) {
839 case FrontendType::DVBC: {
840 // value = 1 << 1
841 interleave.set<FrontendInterleaveMode::Tag::dvbc>(
842 FrontendCableTimeInterleaveMode::INTERLEAVING_128_1_0);
843 interleaves.push_back(interleave);
844 status.set<FrontendStatus::interleaving>(interleaves);
845 break;
846 }
847 case FrontendType::ATSC3: {
848 interleave.set<FrontendInterleaveMode::Tag::atsc3>(
849 FrontendAtsc3TimeInterleaveMode::CTI); // value = 1 << 1
850 interleaves.push_back(interleave);
851 status.set<FrontendStatus::interleaving>(interleaves);
852 break;
853 }
854 case FrontendType::DTMB: {
855 interleave.set<FrontendInterleaveMode::Tag::dtmb>(
856 FrontendDtmbTimeInterleaveMode::TIMER_INT_240); // value = 1 << 1
857 interleaves.push_back(interleave);
858 status.set<FrontendStatus::interleaving>(interleaves);
859 break;
860 }
Hongguang788284f2021-10-28 15:03:29 -0700861 case FrontendType::ISDBT: {
862 interleave.set<FrontendInterleaveMode::Tag::isdbt>(
863 FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0); // value = 1 << 1
864 interleaves.push_back(interleave);
865 status.set<FrontendStatus::interleaving>(interleaves);
866 break;
867 }
Hongguang4092f2f2021-07-08 18:49:12 -0700868 default:
869 break;
870 }
871 break;
872 }
873 case FrontendStatusType::ISDBT_SEGMENTS: {
Hongguang11da2cb2021-08-05 19:05:12 -0700874 vector<int32_t> segments = {2, 3};
Hongguang4092f2f2021-07-08 18:49:12 -0700875 status.set<FrontendStatus::isdbtSegment>(segments);
876 break;
877 }
878 case FrontendStatusType::TS_DATA_RATES: {
879 vector<int32_t> dataRates = {4, 5};
880 status.set<FrontendStatus::tsDataRate>(dataRates);
881 break;
882 }
883 case FrontendStatusType::ROLL_OFF: {
884 FrontendRollOff rollOff;
885 switch (mType) {
886 case FrontendType::DVBS: {
887 rollOff.set<FrontendRollOff::Tag::dvbs>(
888 FrontendDvbsRolloff::ROLLOFF_0_35); // value = 1
889 status.set<FrontendStatus::rollOff>(rollOff);
890 break;
891 }
892 case FrontendType::ISDBS: {
893 rollOff.set<FrontendRollOff::Tag::isdbs>(
894 FrontendIsdbsRolloff::ROLLOFF_0_35); // value = 1
895 status.set<FrontendStatus::rollOff>(rollOff);
896 break;
897 }
898 case FrontendType::ISDBS3: {
899 rollOff.set<FrontendRollOff::Tag::isdbs3>(
900 FrontendIsdbs3Rolloff::ROLLOFF_0_03); // value = 1
901 status.set<FrontendStatus::rollOff>(rollOff);
902 break;
903 }
904 default:
905 break;
906 }
907 break;
908 }
909 case FrontendStatusType::IS_MISO: {
910 status.set<FrontendStatus::isMiso>(true);
911 break;
912 }
913 case FrontendStatusType::IS_LINEAR: {
914 status.set<FrontendStatus::isLinear>(true);
915 break;
916 }
917 case FrontendStatusType::IS_SHORT_FRAMES: {
918 status.set<FrontendStatus::isShortFrames>(true);
919 break;
920 }
Hongguang788284f2021-10-28 15:03:29 -0700921 case FrontendStatusType::ISDBT_MODE: {
922 status.set<FrontendStatus::isdbtMode>(FrontendIsdbtMode::AUTO);
923 break;
924 }
925 case FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG: {
926 status.set<FrontendStatus::partialReceptionFlag>(
927 FrontendIsdbtPartialReceptionFlag::AUTO);
928 break;
929 }
Hongguang2ecfc392021-11-23 10:29:15 -0800930 case FrontendStatusType::STREAM_ID_LIST: {
931 vector<int32_t> streamIds = {0, 1};
932 status.set<FrontendStatus::streamIdList>(streamIds);
933 break;
934 }
Hongguang7eda7822021-12-20 14:48:14 -0800935 case FrontendStatusType::DVBT_CELL_IDS: {
936 vector<int32_t> dvbtCellIds = {0, 1};
937 status.set<FrontendStatus::dvbtCellIds>(dvbtCellIds);
938 break;
939 }
Hongguangd99c82d2022-01-13 12:42:52 -0800940 case FrontendStatusType::ATSC3_ALL_PLP_INFO: {
941 FrontendScanAtsc3PlpInfo info1;
942 info1.plpId = 1;
943 info1.bLlsFlag = false;
944 FrontendScanAtsc3PlpInfo info2;
945 info2.plpId = 2;
946 info2.bLlsFlag = true;
947 FrontendScanAtsc3PlpInfo info3;
948 info3.plpId = 3;
949 info3.bLlsFlag = false;
950 vector<FrontendScanAtsc3PlpInfo> infos = {info1, info2, info3};
951 status.set<FrontendStatus::allPlpInfo>(infos);
952 break;
953 }
sadiqsadaaff01d72023-01-12 11:02:34 -0800954 case FrontendStatusType::IPTV_CONTENT_URL: {
955 status.set<FrontendStatus::iptvContentUrl>("");
956 break;
957 }
958 case FrontendStatusType::IPTV_PACKETS_LOST: {
959 status.set<FrontendStatus::iptvPacketsLost>(5);
960 break;
961 }
962 case FrontendStatusType::IPTV_PACKETS_RECEIVED: {
963 status.set<FrontendStatus::iptvPacketsReceived>(5);
964 break;
965 }
966 case FrontendStatusType::IPTV_WORST_JITTER_MS: {
967 status.set<FrontendStatus::iptvWorstJitterMs>(5);
968 break;
969 }
970 case FrontendStatusType::IPTV_AVERAGE_JITTER_MS: {
971 status.set<FrontendStatus::iptvAverageJitterMs>(5);
972 break;
973 }
Hongguang4092f2f2021-07-08 18:49:12 -0700974 default: {
975 continue;
976 }
977 }
978 _aidl_return->push_back(status);
979 }
980
981 return ::ndk::ScopedAStatus::ok();
982}
983
Hongguang4092f2f2021-07-08 18:49:12 -0700984::ndk::ScopedAStatus Frontend::setLnb(int32_t /* in_lnbId */) {
985 ALOGV("%s", __FUNCTION__);
986 if (!supportsSatellite()) {
Hongguange423acd2021-07-27 16:56:47 -0700987 return ::ndk::ScopedAStatus::fromServiceSpecificError(
988 static_cast<int32_t>(Result::INVALID_STATE));
Hongguang4092f2f2021-07-08 18:49:12 -0700989 }
990 return ::ndk::ScopedAStatus::ok();
991}
992
993::ndk::ScopedAStatus Frontend::linkCiCam(int32_t in_ciCamId, int32_t* _aidl_return) {
994 ALOGV("%s", __FUNCTION__);
995
996 mCiCamId = in_ciCamId;
997 *_aidl_return = 0;
998
999 return ::ndk::ScopedAStatus::ok();
1000}
1001
1002::ndk::ScopedAStatus Frontend::unlinkCiCam(int32_t /* in_ciCamId */) {
1003 ALOGV("%s", __FUNCTION__);
1004
1005 mCiCamId = -1;
1006
1007 return ::ndk::ScopedAStatus::ok();
1008}
1009
Hongguang2ecfc392021-11-23 10:29:15 -08001010binder_status_t Frontend::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
1011 dprintf(fd, " Frontend %d\n", mId);
1012 dprintf(fd, " mType: %d\n", mType);
1013 dprintf(fd, " mIsLocked: %d\n", mIsLocked);
1014 dprintf(fd, " mCiCamId: %d\n", mCiCamId);
Hongguang881190f2022-01-14 13:23:37 -08001015 dprintf(fd, " mFrontendStatusCaps:");
1016 for (int i = 0; i < mFrontendStatusCaps.size(); i++) {
1017 dprintf(fd, " %d\n", mFrontendStatusCaps[i]);
1018 }
Hongguang2ecfc392021-11-23 10:29:15 -08001019 return STATUS_OK;
1020}
1021
Hongguangfcedda02021-12-13 17:08:02 -08001022::ndk::ScopedAStatus Frontend::getHardwareInfo(std::string* _aidl_return) {
1023 ALOGV("%s", __FUNCTION__);
1024
1025 *_aidl_return = "Sample Frontend";
1026 return ::ndk::ScopedAStatus::ok();
1027}
1028
Hongguange106f472022-01-11 12:09:22 -08001029::ndk::ScopedAStatus Frontend::removeOutputPid(int32_t /* in_pid */) {
1030 ALOGV("%s", __FUNCTION__);
1031
1032 return ::ndk::ScopedAStatus::fromServiceSpecificError(
1033 static_cast<int32_t>(Result::UNAVAILABLE));
1034}
1035
Hongguang881190f2022-01-14 13:23:37 -08001036::ndk::ScopedAStatus Frontend::getFrontendStatusReadiness(
1037 const std::vector<FrontendStatusType>& in_statusTypes,
1038 std::vector<FrontendStatusReadiness>* _aidl_return) {
1039 ALOGV("%s", __FUNCTION__);
1040
1041 _aidl_return->resize(in_statusTypes.size());
1042 for (int i = 0; i < in_statusTypes.size(); i++) {
1043 int j = 0;
1044 while (j < mFrontendStatusCaps.size()) {
1045 if (in_statusTypes[i] == mFrontendStatusCaps[j]) {
1046 (*_aidl_return)[i] = FrontendStatusReadiness::STABLE;
1047 break;
1048 }
1049 j++;
1050 }
1051 if (j >= mFrontendStatusCaps.size()) {
1052 (*_aidl_return)[i] = FrontendStatusReadiness::UNSUPPORTED;
1053 }
1054 }
1055
1056 return ::ndk::ScopedAStatus::ok();
1057}
1058
Hongguang4092f2f2021-07-08 18:49:12 -07001059FrontendType Frontend::getFrontendType() {
1060 return mType;
1061}
1062
1063int32_t Frontend::getFrontendId() {
1064 return mId;
1065}
1066
sadiqsada56c98292023-11-02 16:45:31 -07001067dtv_plugin* Frontend::getIptvPluginInterface() {
1068 return mIptvPluginInterface;
1069}
1070
1071string Frontend::getIptvTransportDescription() {
1072 return mIptvTransportDescription;
1073}
1074
1075dtv_streamer* Frontend::getIptvPluginStreamer() {
1076 return mIptvPluginStreamer;
1077}
1078
Hongguang4092f2f2021-07-08 18:49:12 -07001079bool Frontend::supportsSatellite() {
1080 return mType == FrontendType::DVBS || mType == FrontendType::ISDBS ||
1081 mType == FrontendType::ISDBS3;
1082}
1083
1084bool Frontend::isLocked() {
1085 return mIsLocked;
1086}
1087
Hongguang881190f2022-01-14 13:23:37 -08001088void Frontend::getFrontendInfo(FrontendInfo* _aidl_return) {
1089 // assign randomly selected values for testing.
1090 *_aidl_return = {
1091 .type = mType,
1092 .minFrequency = 139000000,
1093 .maxFrequency = 1139000000,
1094 .minSymbolRate = 45,
1095 .maxSymbolRate = 1145,
1096 .acquireRange = 30,
1097 .exclusiveGroupId = 57,
1098 .statusCaps = mFrontendStatusCaps,
1099 .frontendCaps = mFrontendCaps,
1100 };
1101}
1102
Hongguang4092f2f2021-07-08 18:49:12 -07001103} // namespace tuner
1104} // namespace tv
1105} // namespace hardware
1106} // namespace android
1107} // namespace aidl