blob: ef8f57f69f31c870521855ea85695d540b56828f [file] [log] [blame]
Amy Zhangbf68a162020-11-23 17:42:40 -08001/*
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 "FrontendClient"
18
19#include <android-base/logging.h>
20#include <utils/Log.h>
21
22#include "FrontendClient.h"
23
Amy Zhangb9f3cab2021-01-13 15:24:14 -080024using ::aidl::android::media::tv::tuner::TunerFrontendScanAtsc3PlpInfo;
Amy Zhanga6734682020-11-30 16:14:38 -080025using ::aidl::android::media::tv::tuner::TunerFrontendSettings;
Amy Zhangb9f3cab2021-01-13 15:24:14 -080026
27using ::android::hardware::tv::tuner::V1_0::FrontendAnalogSifStandard;
28using ::android::hardware::tv::tuner::V1_0::FrontendAnalogType;
29using ::android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
30using ::android::hardware::tv::tuner::V1_0::FrontendAtsc3Modulation;
31using ::android::hardware::tv::tuner::V1_0::FrontendDvbcAnnex;
32using ::android::hardware::tv::tuner::V1_0::FrontendDvbcModulation;
33using ::android::hardware::tv::tuner::V1_0::FrontendDvbsModulation;
34using ::android::hardware::tv::tuner::V1_0::FrontendDvbsStandard;
35using ::android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
36using ::android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
37using ::android::hardware::tv::tuner::V1_0::FrontendIsdbsModulation;
38using ::android::hardware::tv::tuner::V1_0::FrontendIsdbs3Modulation;
39using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtModulation;
40using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo;
41using ::android::hardware::tv::tuner::V1_0::FrontendType;
Amy Zhangd08c2732021-01-08 17:22:59 -080042using ::android::hardware::tv::tuner::V1_1::Constant;
Amy Zhangb9f3cab2021-01-13 15:24:14 -080043using ::android::hardware::tv::tuner::V1_1::FrontendDtmbModulation;
44using ::android::hardware::tv::tuner::V1_1::FrontendDvbtConstellation;
45using ::android::hardware::tv::tuner::V1_1::FrontendModulation;
Amy Zhanga6734682020-11-30 16:14:38 -080046
Amy Zhangbf68a162020-11-23 17:42:40 -080047namespace android {
48
Amy Zhanga6734682020-11-30 16:14:38 -080049/////////////// FrontendClient ///////////////////////
50
Amy Zhangb9f3cab2021-01-13 15:24:14 -080051FrontendClient::FrontendClient(shared_ptr<ITunerFrontend> tunerFrontend, int id, int type) {
Amy Zhangbf68a162020-11-23 17:42:40 -080052 mTunerFrontend = tunerFrontend;
Amy Zhanga6734682020-11-30 16:14:38 -080053 mAidlCallback = NULL;
54 mHidlCallback = NULL;
Amy Zhang210c26a2021-01-12 11:25:27 -080055 mId = id;
Amy Zhangb9f3cab2021-01-13 15:24:14 -080056 mType = type;
Amy Zhangbf68a162020-11-23 17:42:40 -080057}
58
59FrontendClient::~FrontendClient() {
60 mTunerFrontend = NULL;
61 mFrontend = NULL;
62 mFrontend_1_1 = NULL;
Amy Zhanga6734682020-11-30 16:14:38 -080063 mAidlCallback = NULL;
64 mHidlCallback = NULL;
Amy Zhang210c26a2021-01-12 11:25:27 -080065 mId = -1;
Amy Zhangb9f3cab2021-01-13 15:24:14 -080066 mType = -1;
Amy Zhanga6734682020-11-30 16:14:38 -080067}
68
69Result FrontendClient::setCallback(sp<FrontendClientCallback> frontendClientCallback) {
70 if (mTunerFrontend != NULL) {
71 mAidlCallback = ::ndk::SharedRefBase::make<TunerFrontendCallback>(frontendClientCallback);
Amy Zhangb9f3cab2021-01-13 15:24:14 -080072 mAidlCallback->setFrontendType(mType);
Amy Zhanga6734682020-11-30 16:14:38 -080073 mTunerFrontend->setCallback(mAidlCallback);
74 return Result::SUCCESS;
75 }
76
77 mHidlCallback = new HidlFrontendCallback(frontendClientCallback);
78 return mFrontend->setCallback(mHidlCallback);
Amy Zhangbf68a162020-11-23 17:42:40 -080079}
80
81void FrontendClient::setHidlFrontend(sp<IFrontend> frontend) {
82 mFrontend = frontend;
83 mFrontend_1_1 = ::android::hardware::tv::tuner::V1_1::IFrontend::castFrom(mFrontend);
84}
Amy Zhanga6734682020-11-30 16:14:38 -080085
86Result FrontendClient::tune(const FrontendSettings& settings,
87 const FrontendSettingsExt1_1& settingsExt1_1) {
88 if (mTunerFrontend != NULL) {
89 // TODO: parse hidl settings to aidl settings
90 // TODO: aidl frontend settings to include Tuner HAL 1.1 settings
91 TunerFrontendSettings settings;
Amy Zhang4a07e802021-01-21 17:10:21 -080092 Status s = mTunerFrontend->tune(settings);
93 return ClientHelper::getServiceSpecificErrorCode(s);
Amy Zhanga6734682020-11-30 16:14:38 -080094 }
95
96 Result result;
97 if (mFrontend_1_1 != NULL) {
98 result = mFrontend_1_1->tune_1_1(settings, settingsExt1_1);
99 return result;
100 }
101
102 if (mFrontend != NULL) {
103 result = mFrontend->tune(settings);
104 return result;
105 }
106
107 return Result::INVALID_STATE;
Amy Zhangbf68a162020-11-23 17:42:40 -0800108}
Amy Zhanga6734682020-11-30 16:14:38 -0800109
110Result FrontendClient::stopTune() {
111 if (mTunerFrontend != NULL) {
Amy Zhang4a07e802021-01-21 17:10:21 -0800112 Status s = mTunerFrontend->stopTune();
113 return ClientHelper::getServiceSpecificErrorCode(s);
Amy Zhanga6734682020-11-30 16:14:38 -0800114 }
115
116 if (mFrontend != NULL) {
117 Result result = mFrontend->stopTune();
118 return result;
119 }
120
121 return Result::INVALID_STATE;
122}
123
Amy Zhangd08c2732021-01-08 17:22:59 -0800124Result FrontendClient::scan(const FrontendSettings& settings, FrontendScanType type,
125 const FrontendSettingsExt1_1& settingsExt1_1) {
126 if (mTunerFrontend != NULL) {
127 // TODO: parse hidl settings to aidl settings
128 // TODO: aidl frontend settings to include Tuner HAL 1.1 settings
129 TunerFrontendSettings settings;
Amy Zhang4a07e802021-01-21 17:10:21 -0800130 Status s = mTunerFrontend->scan(settings, (int)type);
131 return ClientHelper::getServiceSpecificErrorCode(s);
Amy Zhangd08c2732021-01-08 17:22:59 -0800132 }
133
134 Result result;
135 if (mFrontend_1_1 != NULL) {
136 result = mFrontend_1_1->scan_1_1(settings, type, settingsExt1_1);
137 return result;
138 }
139
140 if (mFrontend != NULL) {
141 result = mFrontend->scan(settings, type);
142 return result;
143 }
144
145 return Result::INVALID_STATE;
146}
147
148Result FrontendClient::stopScan() {
149 if (mTunerFrontend != NULL) {
Amy Zhang4a07e802021-01-21 17:10:21 -0800150 Status s = mTunerFrontend->stopScan();
151 return ClientHelper::getServiceSpecificErrorCode(s);
Amy Zhangd08c2732021-01-08 17:22:59 -0800152 }
153
154 if (mFrontend != NULL) {
155 Result result = mFrontend->stopScan();
156 return result;
157 }
158
159 return Result::INVALID_STATE;
160}
161
162vector<FrontendStatus> FrontendClient::getStatus(vector<FrontendStatusType> statusTypes) {
163 vector<FrontendStatus> status;
164
165 if (mTunerFrontend != NULL) {
166 // TODO: handle error message.
167 /*status = mTunerFrontend->getStatus(statusTypes);
168 return status;*/
169 }
170
171 if (mFrontend != NULL && statusTypes.size() > 0) {
172 Result res;
173 mFrontend->getStatus(statusTypes,
174 [&](Result r, const hidl_vec<FrontendStatus>& s) {
175 res = r;
176 status = s;
177 });
178 if (res != Result::SUCCESS) {
179 status.clear();
180 return status;
181 }
182 }
183
184 return status;
185}
186vector<FrontendStatusExt1_1> FrontendClient::getStatusExtended_1_1(
187 vector<FrontendStatusTypeExt1_1> statusTypes) {
188 vector<FrontendStatusExt1_1> status;
189
190 if (mTunerFrontend != NULL) {
191 // TODO: handle error message.
192 /*status = mTunerFrontend->getStatusExtended_1_1(statusTypes);
193 return status;*/
194 }
195
196 if (mFrontend_1_1 != NULL && statusTypes.size() > 0) {
197 Result res;
198 mFrontend_1_1->getStatusExt1_1(statusTypes,
199 [&](Result r, const hidl_vec<FrontendStatusExt1_1>& s) {
200 res = r;
201 status = s;
202 });
203 if (res != Result::SUCCESS) {
204 status.clear();
205 return status;
206 }
207 }
208
209 return status;
210}
211
Amy Zhangd3d57b42021-01-07 11:14:43 -0800212Result FrontendClient::setLnb(sp<LnbClient> lnbClient) {
213 if (mTunerFrontend != NULL) {
214 // TODO: handle error message.
215 /*mTunerFrontend->setLnb(lnbClient->getAidlLnb());
216 return Result::SUCCESS;*/
217 }
218
219 if (mFrontend != NULL) {
220 Result result = mFrontend->setLnb(lnbClient->getId());
221 return result;
222 }
223
224 return Result::INVALID_STATE;
225}
226
Amy Zhangd08c2732021-01-08 17:22:59 -0800227Result FrontendClient::setLna(bool bEnable) {
228 if (mTunerFrontend != NULL) {
229 // TODO: handle error message.
230 /*mTunerFrontend->setLna(bEnable);
231 return Result::SUCCESS;*/
232 }
233
234 if (mFrontend != NULL) {
235 Result result = mFrontend->setLna(bEnable);
236 return result;
237 }
238
239 return Result::INVALID_STATE;
240}
241
242int FrontendClient::linkCiCamToFrontend(int ciCamId) {
243 int ltsId = (int)Constant::INVALID_LTS_ID;
244
245 if (mTunerFrontend != NULL) {
246 // TODO: handle error message.
247 /*mTunerFrontend->linkCiCamToFrontend(ciCamId, ltsId);
248 return ltsId;*/
249 }
250
251 if (mFrontend_1_1 != NULL) {
252 Result res;
253 mFrontend_1_1->linkCiCam(static_cast<uint32_t>(ciCamId),
254 [&](Result r, uint32_t id) {
255 res = r;
256 ltsId = id;
257 });
258 if (res != Result::SUCCESS) {
259 return (int)Constant::INVALID_LTS_ID;
260 }
261 }
262
263 return ltsId;
264}
265
266Result FrontendClient::unlinkCiCamToFrontend(int ciCamId) {
267 if (mTunerFrontend != NULL) {
268 // TODO: handle error message.
269 /*mTunerFrontend->unlinkCiCamToFrontend(ciCamId);
270 return Result::SUCCESS;*/
271 }
272
273 if (mFrontend_1_1 != NULL) {
274 return mFrontend_1_1->unlinkCiCam(static_cast<uint32_t>(ciCamId));
275 }
276
277 return Result::INVALID_STATE;
278}
279
Amy Zhanga6734682020-11-30 16:14:38 -0800280Result FrontendClient::close() {
281 if (mTunerFrontend != NULL) {
282 // TODO: handle error message.
Amy Zhang4a07e802021-01-21 17:10:21 -0800283 Status s = mTunerFrontend->close();
284 return ClientHelper::getServiceSpecificErrorCode(s);
Amy Zhanga6734682020-11-30 16:14:38 -0800285 }
286
287 if (mFrontend != NULL) {
288 Result result = mFrontend->close();
289 if (result == Result::SUCCESS) {
290 mFrontend = NULL;
291 mFrontend_1_1 = NULL;
292 }
293 return result;
294 }
295
296 return Result::INVALID_STATE;
297}
298
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800299shared_ptr<ITunerFrontend> FrontendClient::getAidlFrontend() {
300 return mTunerFrontend;
301}
302
303int FrontendClient::getId() {
Amy Zhang210c26a2021-01-12 11:25:27 -0800304 return mId;
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800305}
306
Amy Zhanga6734682020-11-30 16:14:38 -0800307/////////////// TunerFrontendCallback ///////////////////////
308
309TunerFrontendCallback::TunerFrontendCallback(sp<FrontendClientCallback> frontendClientCallback)
310 : mFrontendClientCallback(frontendClientCallback) {}
311
312Status TunerFrontendCallback::onEvent(int frontendEventType) {
313 if (mFrontendClientCallback != NULL) {
314 mFrontendClientCallback->onEvent(static_cast<FrontendEventType>(frontendEventType));
315 return Status::ok();
316 }
317 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
318}
319
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800320Status TunerFrontendCallback::onScanMessage(int messageType,
321 const TunerFrontendScanMessage& message) {
322 if (mFrontendClientCallback != NULL) {
323 if (!is1_1ExtendedScanMessage(messageType)) {
324 mFrontendClientCallback->onScanMessage(
325 static_cast<FrontendScanMessageType>(messageType),
326 getHalScanMessage(messageType, message));
327 } else {
328 mFrontendClientCallback->onScanMessageExt1_1(
329 static_cast<FrontendScanMessageTypeExt1_1>(messageType),
330 getHalScanMessageExt1_1(messageType, message));
331 }
332 return Status::ok();
333 }
334 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
Amy Zhanga6734682020-11-30 16:14:38 -0800335}
336
337/////////////// IFrontendCallback ///////////////////////
338
339HidlFrontendCallback::HidlFrontendCallback(sp<FrontendClientCallback> frontendClientCallback)
340 : mFrontendClientCallback(frontendClientCallback) {}
341
342Return<void> HidlFrontendCallback::onEvent(FrontendEventType frontendEventType) {
343 if (mFrontendClientCallback != NULL) {
344 mFrontendClientCallback->onEvent(frontendEventType);
345 }
346 return Void();
347}
348
349Return<void> HidlFrontendCallback::onScanMessage(FrontendScanMessageType type,
350 const FrontendScanMessage& message) {
351 if (mFrontendClientCallback != NULL) {
352 mFrontendClientCallback->onScanMessage(type, message);
353 }
354 return Void();
355}
356
357Return<void> HidlFrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type,
358 const FrontendScanMessageExt1_1& message) {
359 if (mFrontendClientCallback != NULL) {
360 mFrontendClientCallback->onScanMessageExt1_1(type, message);
361 }
362 return Void();
363}
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800364
365/////////////// FrontendClientCallback Helper Methods ///////////////////////
366
367FrontendScanMessage TunerFrontendCallback::getHalScanMessage(
368 int messageType, const TunerFrontendScanMessage& message) {
369 FrontendScanMessage scanMessage;
370 switch (messageType) {
371 case (int) FrontendScanMessageType::LOCKED:
372 scanMessage.isLocked(message.get<TunerFrontendScanMessage::isLocked>());
373 break;
374 case (int) FrontendScanMessageType::END:
375 scanMessage.isEnd(message.get<TunerFrontendScanMessage::isEnd>());
376 break;
377 case (int) FrontendScanMessageType::PROGRESS_PERCENT:
378 scanMessage.progressPercent(message.get<TunerFrontendScanMessage::progressPercent>());
379 break;
380 case (int) FrontendScanMessageType::FREQUENCY: {
381 vector<int> f = message.get<TunerFrontendScanMessage::frequencies>();
382 hidl_vec<uint32_t> frequencies(begin(f), end(f));
383 scanMessage.frequencies(frequencies);
384 break;
385 }
386 case (int) FrontendScanMessageType::SYMBOL_RATE: {
387 vector<int> s = message.get<TunerFrontendScanMessage::symbolRates>();
388 hidl_vec<uint32_t> symbolRates(begin(s), end(s));
389 scanMessage.symbolRates(symbolRates);
390 break;
391 }
392 case (int) FrontendScanMessageType::HIERARCHY:
393 scanMessage.hierarchy(static_cast<FrontendDvbtHierarchy>(
394 message.get<TunerFrontendScanMessage::hierarchy>()));
395 break;
396 case (int) FrontendScanMessageType::ANALOG_TYPE:
397 scanMessage.analogType(static_cast<FrontendAnalogType>(
398 message.get<TunerFrontendScanMessage::analogType>()));
399 break;
400 case (int) FrontendScanMessageType::PLP_IDS: {
401 vector<uint8_t> p = message.get<TunerFrontendScanMessage::plpIds>();
402 hidl_vec<uint8_t> plpIds(begin(p), end(p));
403 scanMessage.plpIds(plpIds);
404 break;
405 }
406 case (int) FrontendScanMessageType::GROUP_IDS: {
407 vector<uint8_t> g = message.get<TunerFrontendScanMessage::groupIds>();
408 hidl_vec<uint8_t> groupIds(begin(g), end(g));
409 scanMessage.groupIds(groupIds);
410 break;
411 }
412 case (int) FrontendScanMessageType::INPUT_STREAM_IDS: {
413 vector<char16_t> i = message.get<TunerFrontendScanMessage::inputStreamIds>();
414 hidl_vec<uint16_t> inputStreamIds(begin(i), end(i));
415 scanMessage.inputStreamIds(inputStreamIds);
416 break;
417 }
418 case (int) FrontendScanMessageType::STANDARD: {
419 FrontendScanMessage::Standard std;
420 int standard = message.get<TunerFrontendScanMessage::std>();
421 switch (mType) {
422 case (int) FrontendType::DVBS:
423 std.sStd(static_cast<FrontendDvbsStandard>(standard));
424 scanMessage.std(std);
425 break;
426 case (int) FrontendType::DVBT:
427 std.tStd(static_cast<FrontendDvbtStandard>(standard));
428 scanMessage.std(std);
429 break;
430 case (int) FrontendType::ANALOG:
431 std.sifStd(static_cast<FrontendAnalogSifStandard>(standard));
432 scanMessage.std(std);
433 break;
434 default:
435 break;
436 }
437 break;
438 }
439 case (int) FrontendScanMessageType::ATSC3_PLP_INFO: {
440 vector<TunerFrontendScanAtsc3PlpInfo> plp =
441 message.get<TunerFrontendScanMessage::atsc3PlpInfos>();
442 hidl_vec<FrontendScanAtsc3PlpInfo> plpInfo;
443 for (TunerFrontendScanAtsc3PlpInfo info : plp) {
444 FrontendScanAtsc3PlpInfo p{
445 .plpId = static_cast<uint8_t>(info.plpId),
446 .bLlsFlag = info.llsFlag,
447 };
448 int size = plpInfo.size();
449 plpInfo.resize(size + 1);
450 plpInfo[size] = p;
451 }
452 scanMessage.atsc3PlpInfos(plpInfo);
453 break;
454 }
455 default:
456 break;
457 }
458 return scanMessage;
459}
460
461FrontendScanMessageExt1_1 TunerFrontendCallback::getHalScanMessageExt1_1(
462 int messageType, const TunerFrontendScanMessage& message) {
463 FrontendScanMessageExt1_1 scanMessage;
464 switch (messageType) {
465 case (int) FrontendScanMessageTypeExt1_1::HIGH_PRIORITY:
466 scanMessage.isHighPriority(message.get<TunerFrontendScanMessage::isHighPriority>());
467 break;
468 case (int) FrontendScanMessageTypeExt1_1::DVBC_ANNEX:
469 scanMessage.annex(static_cast<FrontendDvbcAnnex>(
470 message.get<TunerFrontendScanMessage::annex>()));
471 break;
472 case (int) FrontendScanMessageTypeExt1_1::MODULATION: {
473 FrontendModulation m;
474 int modulation = message.get<TunerFrontendScanMessage::modulation>();
475 switch (mType) {
476 case (int) FrontendType::DVBC:
477 m.dvbc(static_cast<FrontendDvbcModulation>(modulation));
478 scanMessage.modulation(m);
479 break;
480 case (int) FrontendType::DVBS:
481 m.dvbs(static_cast<FrontendDvbsModulation>(modulation));
482 scanMessage.modulation(m);
483 break;
484 case (int) FrontendType::DVBT:
485 m.dvbt(static_cast<FrontendDvbtConstellation>(modulation));
486 scanMessage.modulation(m);
487 break;
488 case (int) FrontendType::ISDBS:
489 m.isdbs(static_cast<FrontendIsdbsModulation>(modulation));
490 scanMessage.modulation(m);
491 break;
492 case (int) FrontendType::ISDBS3:
493 m.isdbs3(static_cast<FrontendIsdbs3Modulation>(modulation));
494 scanMessage.modulation(m);
495 break;
496 case (int) FrontendType::ISDBT:
497 m.isdbt(static_cast<FrontendIsdbtModulation>(modulation));
498 scanMessage.modulation(m);
499 break;
500 case (int) FrontendType::ATSC:
501 m.atsc(static_cast<FrontendAtscModulation>(modulation));
502 scanMessage.modulation(m);
503 break;
504 case (int) FrontendType::ATSC3:
505 m.atsc3(static_cast<FrontendAtsc3Modulation>(modulation));
506 scanMessage.modulation(m);
507 break;
508 case (int) hardware::tv::tuner::V1_1::FrontendType::DTMB:
509 m.dtmb(static_cast<FrontendDtmbModulation>(modulation));
510 scanMessage.modulation(m);
511 break;
512 default:
513 break;
514 }
515 break;
516 }
517 default:
518 break;
519 }
520 return scanMessage;
521}
522
523bool TunerFrontendCallback::is1_1ExtendedScanMessage(int messageType) {
524 return messageType >= (int)FrontendScanMessageTypeExt1_1::MODULATION
525 && messageType <= (int)FrontendScanMessageTypeExt1_1::HIGH_PRIORITY;
526}
Amy Zhanga6734682020-11-30 16:14:38 -0800527} // namespace android