blob: ba4553b366331367ed9d984e65aaae22e64988c9 [file] [log] [blame]
Amy Zhang0f04c452020-10-30 13:36:44 -07001/**
2 * Copyright 2020, 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_TAG "TunerFrontend"
18
19#include "TunerFrontend.h"
20#include "TunerService.h"
21
22using ::aidl::android::media::tv::tuner::TunerAtsc3PlpInfo;
23using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3PlpSettings;
24using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard;
25using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType;
26using ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
27using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Bandwidth;
28using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3CodeRate;
29using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3DemodOutputFormat;
30using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Fec;
31using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Modulation;
32using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3TimeInterleaveMode;
33using ::android::hardware::tv::tuner::V1_0::FrontendDvbcAnnex;
34using ::android::hardware::tv::tuner::V1_0::FrontendDvbcModulation;
35using ::android::hardware::tv::tuner::V1_0::FrontendDvbcOuterFec;
36using ::android::hardware::tv::tuner::V1_0::FrontendDvbcSpectralInversion;
37using ::android::hardware::tv::tuner::V1_0::FrontendDvbsModulation;
38using ::android::hardware::tv::tuner::V1_0::FrontendDvbsPilot;
39using ::android::hardware::tv::tuner::V1_0::FrontendDvbsRolloff;
40using ::android::hardware::tv::tuner::V1_0::FrontendDvbsSettings;
41using ::android::hardware::tv::tuner::V1_0::FrontendDvbsStandard;
42using ::android::hardware::tv::tuner::V1_0::FrontendDvbsVcmMode;
43using ::android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
44using ::android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
45using ::android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
46using ::android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
47using ::android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
48using ::android::hardware::tv::tuner::V1_0::FrontendDvbtPlpMode;
49using ::android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
50using ::android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
51using ::android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
52using ::android::hardware::tv::tuner::V1_0::FrontendInnerFec;
53using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Coderate;
54using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Modulation;
55using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Rolloff;
56using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Settings;
57using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsCoderate;
58using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsModulation;
59using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsRolloff;
60using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsSettings;
61using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsStreamIdType;
62using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtBandwidth;
63using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtCoderate;
64using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtGuardInterval;
65using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtMode;
66using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtModulation;
67using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings;
68using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo;
69using ::android::hardware::tv::tuner::V1_0::FrontendScanType;
70using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
71using ::android::hardware::tv::tuner::V1_0::Result;
72
73namespace android {
74
75TunerFrontend::TunerFrontend(sp<ITuner> tuner, int frontendHandle) {
76 mTuner = tuner;
77 mId = TunerService::getResourceIdFromHandle(frontendHandle);
78
79 if (mTuner != NULL) {
80 Result status;
81 mTuner->openFrontendById(mId, [&](Result result, const sp<IFrontend>& frontend) {
82 mFrontend = frontend;
83 status = result;
84 });
85 if (status != Result::SUCCESS) {
86 mFrontend = NULL;
87 }
88 }
89}
90
91TunerFrontend::~TunerFrontend() {}
92
93Status TunerFrontend::setCallback(
94 const std::shared_ptr<ITunerFrontendCallback>& tunerFrontendCallback) {
95 if (mFrontend == NULL) {
96 ALOGE("IFrontend is not initialized");
97 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
98 }
99
100 if (tunerFrontendCallback == NULL) {
101 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_ARGUMENT));
102 }
103
104 sp<IFrontendCallback> frontendCallback = new FrontendCallback(tunerFrontendCallback);
105 Result status = mFrontend->setCallback(frontendCallback);
106 if (status == Result::SUCCESS) {
107 return Status::ok();
108 }
109
110 return Status::fromServiceSpecificError(static_cast<int32_t>(status));
111}
112
113Status TunerFrontend::tune(const TunerFrontendSettings& /*settings*/) {
114 return Status::ok();
115}
116
117Status TunerFrontend::stopTune() {
118 return Status::ok();
119}
120
121Status TunerFrontend::scan(const TunerFrontendSettings& settings, int frontendScanType) {
122 if (mFrontend == NULL) {
123 ALOGD("IFrontend is not initialized");
124 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
125 }
126
127 FrontendSettings frontendSettings;
128 switch (settings.getTag()) {
129 case TunerFrontendSettings::analog:
130 frontendSettings.analog({
131 .frequency = static_cast<uint32_t>(
132 settings.get<TunerFrontendSettings::analog>().frequency),
133 .type = static_cast<FrontendAnalogType>(
134 settings.get<TunerFrontendSettings::analog>().signalType),
135 .sifStandard = static_cast<FrontendAnalogSifStandard>(
136 settings.get<TunerFrontendSettings::analog>().sifStandard),
137 });
138 break;
139 case TunerFrontendSettings::atsc:
140 frontendSettings.atsc({
141 .frequency = static_cast<uint32_t>(
142 settings.get<TunerFrontendSettings::atsc>().frequency),
143 .modulation = static_cast<FrontendAtscModulation>(
144 settings.get<TunerFrontendSettings::atsc>().modulation),
145 });
146 break;
147 case TunerFrontendSettings::atsc3:
148 frontendSettings.atsc3({
149 .frequency = static_cast<uint32_t>(
150 settings.get<TunerFrontendSettings::atsc3>().frequency),
151 .bandwidth = static_cast<FrontendAtsc3Bandwidth>(
152 settings.get<TunerFrontendSettings::atsc3>().bandwidth),
153 .demodOutputFormat = static_cast<FrontendAtsc3DemodOutputFormat>(
154 settings.get<TunerFrontendSettings::atsc3>().demodOutputFormat),
155 .plpSettings = getAtsc3PlpSettings(settings.get<TunerFrontendSettings::atsc3>()),
156 });
157 break;
158 case TunerFrontendSettings::cable:
159 frontendSettings.dvbc({
160 .frequency = static_cast<uint32_t>(
161 settings.get<TunerFrontendSettings::cable>().frequency),
162 .modulation = static_cast<FrontendDvbcModulation>(
163 settings.get<TunerFrontendSettings::cable>().modulation),
164 .fec = static_cast<FrontendInnerFec>(
165 settings.get<TunerFrontendSettings::cable>().innerFec),
166 .symbolRate = static_cast<uint32_t>(
167 settings.get<TunerFrontendSettings::cable>().symbolRate),
168 .outerFec = static_cast<FrontendDvbcOuterFec>(
169 settings.get<TunerFrontendSettings::cable>().outerFec),
170 .annex = static_cast<FrontendDvbcAnnex>(
171 settings.get<TunerFrontendSettings::cable>().annex),
172 .spectralInversion = static_cast<FrontendDvbcSpectralInversion>(
173 settings.get<TunerFrontendSettings::cable>().spectralInversion),
174 });
175 break;
176 case TunerFrontendSettings::dvbs:
177 frontendSettings.dvbs({
178 .frequency = static_cast<uint32_t>(
179 settings.get<TunerFrontendSettings::dvbs>().frequency),
180 .modulation = static_cast<FrontendDvbsModulation>(
181 settings.get<TunerFrontendSettings::dvbs>().modulation),
182 .coderate = getDvbsCodeRate(
183 settings.get<TunerFrontendSettings::dvbs>().codeRate),
184 .symbolRate = static_cast<uint32_t>(
185 settings.get<TunerFrontendSettings::dvbs>().symbolRate),
186 .rolloff = static_cast<FrontendDvbsRolloff>(
187 settings.get<TunerFrontendSettings::dvbs>().rolloff),
188 .pilot = static_cast<FrontendDvbsPilot>(
189 settings.get<TunerFrontendSettings::dvbs>().pilot),
190 .inputStreamId = static_cast<uint32_t>(
191 settings.get<TunerFrontendSettings::dvbs>().inputStreamId),
192 .standard = static_cast<FrontendDvbsStandard>(
193 settings.get<TunerFrontendSettings::dvbs>().standard),
194 .vcmMode = static_cast<FrontendDvbsVcmMode>(
195 settings.get<TunerFrontendSettings::dvbs>().vcm),
196 });
197 break;
198 case TunerFrontendSettings::dvbt:
199 frontendSettings.dvbt({
200 .frequency = static_cast<uint32_t>(
201 settings.get<TunerFrontendSettings::dvbt>().frequency),
202 .transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
203 settings.get<TunerFrontendSettings::dvbt>().transmissionMode),
204 .bandwidth = static_cast<FrontendDvbtBandwidth>(
205 settings.get<TunerFrontendSettings::dvbt>().bandwidth),
206 .constellation = static_cast<FrontendDvbtConstellation>(
207 settings.get<TunerFrontendSettings::dvbt>().constellation),
208 .hierarchy = static_cast<FrontendDvbtHierarchy>(
209 settings.get<TunerFrontendSettings::dvbt>().hierarchy),
210 .hpCoderate = static_cast<FrontendDvbtCoderate>(
211 settings.get<TunerFrontendSettings::dvbt>().hpCodeRate),
212 .lpCoderate = static_cast<FrontendDvbtCoderate>(
213 settings.get<TunerFrontendSettings::dvbt>().lpCodeRate),
214 .guardInterval = static_cast<FrontendDvbtGuardInterval>(
215 settings.get<TunerFrontendSettings::dvbt>().guardInterval),
216 .isHighPriority = settings.get<TunerFrontendSettings::dvbt>().isHighPriority,
217 .standard = static_cast<FrontendDvbtStandard>(
218 settings.get<TunerFrontendSettings::dvbt>().standard),
219 .isMiso = settings.get<TunerFrontendSettings::dvbt>().isMiso,
220 .plpMode = static_cast<FrontendDvbtPlpMode>(
221 settings.get<TunerFrontendSettings::dvbt>().plpMode),
222 .plpId = static_cast<uint8_t>(
223 settings.get<TunerFrontendSettings::dvbt>().plpId),
224 .plpGroupId = static_cast<uint8_t>(
225 settings.get<TunerFrontendSettings::dvbt>().plpGroupId),
226 });
227 break;
228 case TunerFrontendSettings::isdbs:
229 frontendSettings.isdbs({
230 .frequency = static_cast<uint32_t>(
231 settings.get<TunerFrontendSettings::isdbs>().frequency),
232 .streamId = static_cast<uint16_t>(
233 settings.get<TunerFrontendSettings::isdbs>().streamId),
234 .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
235 settings.get<TunerFrontendSettings::isdbs>().streamIdType),
236 .modulation = static_cast<FrontendIsdbsModulation>(
237 settings.get<TunerFrontendSettings::isdbs>().modulation),
238 .coderate = static_cast<FrontendIsdbsCoderate>(
239 settings.get<TunerFrontendSettings::isdbs>().codeRate),
240 .symbolRate = static_cast<uint32_t>(
241 settings.get<TunerFrontendSettings::isdbs>().symbolRate),
242 .rolloff = static_cast<FrontendIsdbsRolloff>(
243 settings.get<TunerFrontendSettings::isdbs>().rolloff),
244 });
245 break;
246 case TunerFrontendSettings::isdbs3:
247 frontendSettings.isdbs3({
248 .frequency = static_cast<uint32_t>(
249 settings.get<TunerFrontendSettings::isdbs3>().frequency),
250 .streamId = static_cast<uint16_t>(
251 settings.get<TunerFrontendSettings::isdbs3>().streamId),
252 .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
253 settings.get<TunerFrontendSettings::isdbs3>().streamIdType),
254 .modulation = static_cast<FrontendIsdbs3Modulation>(
255 settings.get<TunerFrontendSettings::isdbs3>().modulation),
256 .coderate = static_cast<FrontendIsdbs3Coderate>(
257 settings.get<TunerFrontendSettings::isdbs3>().codeRate),
258 .symbolRate = static_cast<uint32_t>(
259 settings.get<TunerFrontendSettings::isdbs3>().symbolRate),
260 .rolloff = static_cast<FrontendIsdbs3Rolloff>(
261 settings.get<TunerFrontendSettings::isdbs3>().rolloff),
262 });
263 break;
264 case TunerFrontendSettings::isdbt:
265 frontendSettings.isdbt({
266 .frequency = static_cast<uint32_t>(
267 settings.get<TunerFrontendSettings::isdbt>().frequency),
268 .modulation = static_cast<FrontendIsdbtModulation>(
269 settings.get<TunerFrontendSettings::isdbt>().modulation),
270 .bandwidth = static_cast<FrontendIsdbtBandwidth>(
271 settings.get<TunerFrontendSettings::isdbt>().bandwidth),
272 .mode = static_cast<FrontendIsdbtMode>(
273 settings.get<TunerFrontendSettings::isdbt>().mode),
274 .coderate = static_cast<FrontendIsdbtCoderate>(
275 settings.get<TunerFrontendSettings::isdbt>().codeRate),
276 .guardInterval = static_cast<FrontendIsdbtGuardInterval>(
277 settings.get<TunerFrontendSettings::isdbt>().guardInterval),
278 .serviceAreaId = static_cast<uint32_t>(
279 settings.get<TunerFrontendSettings::isdbt>().serviceAreaId),
280 });
281 break;
282 default:
283 break;
284 }
285 Result status = mFrontend->scan(
286 frontendSettings, static_cast<FrontendScanType>(frontendScanType));
287 if (status == Result::SUCCESS) {
288 return Status::ok();
289 }
290
291 return Status::fromServiceSpecificError(static_cast<int32_t>(status));
292}
293
294Status TunerFrontend::stopScan() {
295 return Status::ok();
296}
297
298Status TunerFrontend::setLnb(int /*lnbHandle*/) {
299 return Status::ok();
300}
301
302Status TunerFrontend::setLna(bool /*bEnable*/) {
303 return Status::ok();
304}
305
306Status TunerFrontend::close() {
307 return Status::ok();
308}
309
310Status TunerFrontend::getStatus(const std::vector<int32_t>& /*statusTypes*/,
311 std::vector<TunerFrontendStatus>* /*_aidl_return*/) {
312 return Status::ok();
313}
314
315/////////////// FrontendCallback ///////////////////////
316
317Return<void> TunerFrontend::FrontendCallback::onEvent(FrontendEventType frontendEventType) {
318 ALOGD("FrontendCallback::onEvent, type=%d", frontendEventType);
319 mTunerFrontendCallback->onEvent((int)frontendEventType);
320 return Void();
321}
322
323Return<void> TunerFrontend::FrontendCallback::onScanMessage(
324 FrontendScanMessageType type, const FrontendScanMessage& message) {
325 ALOGD("FrontendCallback::onScanMessage, type=%d", type);
326 switch(type) {
327 case FrontendScanMessageType::LOCKED: {
328 if (message.isLocked()) {
329 mTunerFrontendCallback->onLocked();
330 }
331 break;
332 }
333 case FrontendScanMessageType::END: {
334 if (message.isEnd()) {
335 mTunerFrontendCallback->onScanStopped();
336 }
337 break;
338 }
339 case FrontendScanMessageType::PROGRESS_PERCENT: {
340 mTunerFrontendCallback->onProgress((int)message.progressPercent());
341 break;
342 }
343 case FrontendScanMessageType::FREQUENCY: {
344 auto f = message.frequencies();
345 std::vector<int32_t> frequencies(std::begin(f), std::end(f));
346 mTunerFrontendCallback->onFrequenciesReport(frequencies);
347 break;
348 }
349 case FrontendScanMessageType::SYMBOL_RATE: {
350 auto s = message.symbolRates();
351 std::vector<int32_t> symbolRates(std::begin(s), std::end(s));
352 mTunerFrontendCallback->onSymbolRates(symbolRates);
353 break;
354 }
355 case FrontendScanMessageType::HIERARCHY: {
356 mTunerFrontendCallback->onHierarchy((int)message.hierarchy());
357 break;
358 }
359 case FrontendScanMessageType::ANALOG_TYPE: {
360 mTunerFrontendCallback->onSignalType((int)message.analogType());
361 break;
362 }
363 case FrontendScanMessageType::PLP_IDS: {
364 auto p = message.plpIds();
365 std::vector<int32_t> plpIds(std::begin(p), std::end(p));
366 mTunerFrontendCallback->onPlpIds(plpIds);
367 break;
368 }
369 case FrontendScanMessageType::GROUP_IDS: {
370 auto g = message.groupIds();
371 std::vector<int32_t> groupIds(std::begin(g), std::end(g));
372 mTunerFrontendCallback->onGroupIds(groupIds);
373 break;
374 }
375 case FrontendScanMessageType::INPUT_STREAM_IDS: {
376 auto i = message.inputStreamIds();
377 std::vector<int32_t> streamIds(std::begin(i), std::end(i));
378 mTunerFrontendCallback->onInputStreamIds(streamIds);
379 break;
380 }
381 case FrontendScanMessageType::STANDARD: {
382 FrontendScanMessage::Standard std = message.std();
383 int standard;
384 if (std.getDiscriminator() == FrontendScanMessage::Standard::hidl_discriminator::sStd) {
385 standard = (int) std.sStd();
386 mTunerFrontendCallback->onDvbsStandard(standard);
387 } else if (std.getDiscriminator() ==
388 FrontendScanMessage::Standard::hidl_discriminator::tStd) {
389 standard = (int) std.tStd();
390 mTunerFrontendCallback->onDvbsStandard(standard);
391 } else if (std.getDiscriminator() ==
392 FrontendScanMessage::Standard::hidl_discriminator::sifStd) {
393 standard = (int) std.sifStd();
394 mTunerFrontendCallback->onAnalogSifStandard(standard);
395 }
396 break;
397 }
398 case FrontendScanMessageType::ATSC3_PLP_INFO: {
399 std::vector<FrontendScanAtsc3PlpInfo> plpInfos = message.atsc3PlpInfos();
400 std::vector<TunerAtsc3PlpInfo> tunerPlpInfos;
401 for (int i = 0; i < plpInfos.size(); i++) {
402 auto info = plpInfos[i];
403 int plpId = (int) info.plpId;
404 bool lls = (bool) info.bLlsFlag;
405 TunerAtsc3PlpInfo plpInfo{
406 .plpId = plpId,
407 .llsFlag = lls,
408 };
409 tunerPlpInfos.push_back(plpInfo);
410 }
411 mTunerFrontendCallback->onAtsc3PlpInfos(tunerPlpInfos);
412 break;
413 }
414 default:
415 break;
416 }
417 return Void();
418}
419
420////////////////////////////////////////////////////////////////////////////////
421
422hidl_vec<FrontendAtsc3PlpSettings> TunerFrontend::getAtsc3PlpSettings(
423 const TunerFrontendAtsc3Settings& settings) {
424 int len = settings.plpSettings.size();
425 hidl_vec<FrontendAtsc3PlpSettings> plps = hidl_vec<FrontendAtsc3PlpSettings>(len);
426 // parse PLP settings
427 for (int i = 0; i < len; i++) {
428 uint8_t plpId = static_cast<uint8_t>(settings.plpSettings[i].plpId);
429 FrontendAtsc3Modulation modulation =
430 static_cast<FrontendAtsc3Modulation>(settings.plpSettings[i].modulation);
431 FrontendAtsc3TimeInterleaveMode interleaveMode =
432 static_cast<FrontendAtsc3TimeInterleaveMode>(
433 settings.plpSettings[i].interleaveMode);
434 FrontendAtsc3CodeRate codeRate =
435 static_cast<FrontendAtsc3CodeRate>(settings.plpSettings[i].codeRate);
436 FrontendAtsc3Fec fec =
437 static_cast<FrontendAtsc3Fec>(settings.plpSettings[i].fec);
438 FrontendAtsc3PlpSettings frontendAtsc3PlpSettings {
439 .plpId = plpId,
440 .modulation = modulation,
441 .interleaveMode = interleaveMode,
442 .codeRate = codeRate,
443 .fec = fec,
444 };
445 plps[i] = frontendAtsc3PlpSettings;
446 }
447 return plps;
448}
449
450FrontendDvbsCodeRate TunerFrontend::getDvbsCodeRate(const TunerFrontendDvbsCodeRate& codeRate) {
451 FrontendInnerFec innerFec = static_cast<FrontendInnerFec>(codeRate.fec);
452 bool isLinear = codeRate.isLinear;
453 bool isShortFrames = codeRate.isShortFrames;
454 uint32_t bitsPer1000Symbol = static_cast<uint32_t>(codeRate.bitsPer1000Symbol);
455 FrontendDvbsCodeRate coderate {
456 .fec = innerFec,
457 .isLinear = isLinear,
458 .isShortFrames = isShortFrames,
459 .bitsPer1000Symbol = bitsPer1000Symbol,
460 };
461 return coderate;
462}
463} // namespace android