blob: d6d64f6f2c8e8c9a3d2924cf6b31ee9b40e84d13 [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;
92 // TODO: handle error message.
93 mTunerFrontend->tune(settings);
94 return Result::SUCCESS;
95 }
96
97 Result result;
98 if (mFrontend_1_1 != NULL) {
99 result = mFrontend_1_1->tune_1_1(settings, settingsExt1_1);
100 return result;
101 }
102
103 if (mFrontend != NULL) {
104 result = mFrontend->tune(settings);
105 return result;
106 }
107
108 return Result::INVALID_STATE;
Amy Zhangbf68a162020-11-23 17:42:40 -0800109}
Amy Zhanga6734682020-11-30 16:14:38 -0800110
111Result FrontendClient::stopTune() {
112 if (mTunerFrontend != NULL) {
113 // TODO: handle error message.
114 mTunerFrontend->stopTune();
115 return Result::SUCCESS;
116 }
117
118 if (mFrontend != NULL) {
119 Result result = mFrontend->stopTune();
120 return result;
121 }
122
123 return Result::INVALID_STATE;
124}
125
Amy Zhangd08c2732021-01-08 17:22:59 -0800126Result FrontendClient::scan(const FrontendSettings& settings, FrontendScanType type,
127 const FrontendSettingsExt1_1& settingsExt1_1) {
128 if (mTunerFrontend != NULL) {
129 // TODO: parse hidl settings to aidl settings
130 // TODO: aidl frontend settings to include Tuner HAL 1.1 settings
131 TunerFrontendSettings settings;
132 // TODO: handle error message.
133 mTunerFrontend->scan(settings, (int)type);
134 return Result::SUCCESS;
135 }
136
137 Result result;
138 if (mFrontend_1_1 != NULL) {
139 result = mFrontend_1_1->scan_1_1(settings, type, settingsExt1_1);
140 return result;
141 }
142
143 if (mFrontend != NULL) {
144 result = mFrontend->scan(settings, type);
145 return result;
146 }
147
148 return Result::INVALID_STATE;
149}
150
151Result FrontendClient::stopScan() {
152 if (mTunerFrontend != NULL) {
153 // TODO: handle error message.
154 mTunerFrontend->stopScan();
155 return Result::SUCCESS;
156 }
157
158 if (mFrontend != NULL) {
159 Result result = mFrontend->stopScan();
160 return result;
161 }
162
163 return Result::INVALID_STATE;
164}
165
166vector<FrontendStatus> FrontendClient::getStatus(vector<FrontendStatusType> statusTypes) {
167 vector<FrontendStatus> status;
168
169 if (mTunerFrontend != NULL) {
170 // TODO: handle error message.
171 /*status = mTunerFrontend->getStatus(statusTypes);
172 return status;*/
173 }
174
175 if (mFrontend != NULL && statusTypes.size() > 0) {
176 Result res;
177 mFrontend->getStatus(statusTypes,
178 [&](Result r, const hidl_vec<FrontendStatus>& s) {
179 res = r;
180 status = s;
181 });
182 if (res != Result::SUCCESS) {
183 status.clear();
184 return status;
185 }
186 }
187
188 return status;
189}
190vector<FrontendStatusExt1_1> FrontendClient::getStatusExtended_1_1(
191 vector<FrontendStatusTypeExt1_1> statusTypes) {
192 vector<FrontendStatusExt1_1> status;
193
194 if (mTunerFrontend != NULL) {
195 // TODO: handle error message.
196 /*status = mTunerFrontend->getStatusExtended_1_1(statusTypes);
197 return status;*/
198 }
199
200 if (mFrontend_1_1 != NULL && statusTypes.size() > 0) {
201 Result res;
202 mFrontend_1_1->getStatusExt1_1(statusTypes,
203 [&](Result r, const hidl_vec<FrontendStatusExt1_1>& s) {
204 res = r;
205 status = s;
206 });
207 if (res != Result::SUCCESS) {
208 status.clear();
209 return status;
210 }
211 }
212
213 return status;
214}
215
Amy Zhangd3d57b42021-01-07 11:14:43 -0800216Result FrontendClient::setLnb(sp<LnbClient> lnbClient) {
217 if (mTunerFrontend != NULL) {
218 // TODO: handle error message.
219 /*mTunerFrontend->setLnb(lnbClient->getAidlLnb());
220 return Result::SUCCESS;*/
221 }
222
223 if (mFrontend != NULL) {
224 Result result = mFrontend->setLnb(lnbClient->getId());
225 return result;
226 }
227
228 return Result::INVALID_STATE;
229}
230
Amy Zhangd08c2732021-01-08 17:22:59 -0800231Result FrontendClient::setLna(bool bEnable) {
232 if (mTunerFrontend != NULL) {
233 // TODO: handle error message.
234 /*mTunerFrontend->setLna(bEnable);
235 return Result::SUCCESS;*/
236 }
237
238 if (mFrontend != NULL) {
239 Result result = mFrontend->setLna(bEnable);
240 return result;
241 }
242
243 return Result::INVALID_STATE;
244}
245
246int FrontendClient::linkCiCamToFrontend(int ciCamId) {
247 int ltsId = (int)Constant::INVALID_LTS_ID;
248
249 if (mTunerFrontend != NULL) {
250 // TODO: handle error message.
251 /*mTunerFrontend->linkCiCamToFrontend(ciCamId, ltsId);
252 return ltsId;*/
253 }
254
255 if (mFrontend_1_1 != NULL) {
256 Result res;
257 mFrontend_1_1->linkCiCam(static_cast<uint32_t>(ciCamId),
258 [&](Result r, uint32_t id) {
259 res = r;
260 ltsId = id;
261 });
262 if (res != Result::SUCCESS) {
263 return (int)Constant::INVALID_LTS_ID;
264 }
265 }
266
267 return ltsId;
268}
269
270Result FrontendClient::unlinkCiCamToFrontend(int ciCamId) {
271 if (mTunerFrontend != NULL) {
272 // TODO: handle error message.
273 /*mTunerFrontend->unlinkCiCamToFrontend(ciCamId);
274 return Result::SUCCESS;*/
275 }
276
277 if (mFrontend_1_1 != NULL) {
278 return mFrontend_1_1->unlinkCiCam(static_cast<uint32_t>(ciCamId));
279 }
280
281 return Result::INVALID_STATE;
282}
283
Amy Zhanga6734682020-11-30 16:14:38 -0800284Result FrontendClient::close() {
285 if (mTunerFrontend != NULL) {
286 // TODO: handle error message.
287 mTunerFrontend->close();
288 return Result::SUCCESS;
289 }
290
291 if (mFrontend != NULL) {
292 Result result = mFrontend->close();
293 if (result == Result::SUCCESS) {
294 mFrontend = NULL;
295 mFrontend_1_1 = NULL;
296 }
297 return result;
298 }
299
300 return Result::INVALID_STATE;
301}
302
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800303shared_ptr<ITunerFrontend> FrontendClient::getAidlFrontend() {
304 return mTunerFrontend;
305}
306
307int FrontendClient::getId() {
Amy Zhang210c26a2021-01-12 11:25:27 -0800308 return mId;
Amy Zhang6bfeaa02020-11-30 15:16:39 -0800309}
310
Amy Zhanga6734682020-11-30 16:14:38 -0800311/////////////// TunerFrontendCallback ///////////////////////
312
313TunerFrontendCallback::TunerFrontendCallback(sp<FrontendClientCallback> frontendClientCallback)
314 : mFrontendClientCallback(frontendClientCallback) {}
315
316Status TunerFrontendCallback::onEvent(int frontendEventType) {
317 if (mFrontendClientCallback != NULL) {
318 mFrontendClientCallback->onEvent(static_cast<FrontendEventType>(frontendEventType));
319 return Status::ok();
320 }
321 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
322}
323
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800324Status TunerFrontendCallback::onScanMessage(int messageType,
325 const TunerFrontendScanMessage& message) {
326 if (mFrontendClientCallback != NULL) {
327 if (!is1_1ExtendedScanMessage(messageType)) {
328 mFrontendClientCallback->onScanMessage(
329 static_cast<FrontendScanMessageType>(messageType),
330 getHalScanMessage(messageType, message));
331 } else {
332 mFrontendClientCallback->onScanMessageExt1_1(
333 static_cast<FrontendScanMessageTypeExt1_1>(messageType),
334 getHalScanMessageExt1_1(messageType, message));
335 }
336 return Status::ok();
337 }
338 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::INVALID_STATE));
Amy Zhanga6734682020-11-30 16:14:38 -0800339}
340
341/////////////// IFrontendCallback ///////////////////////
342
343HidlFrontendCallback::HidlFrontendCallback(sp<FrontendClientCallback> frontendClientCallback)
344 : mFrontendClientCallback(frontendClientCallback) {}
345
346Return<void> HidlFrontendCallback::onEvent(FrontendEventType frontendEventType) {
347 if (mFrontendClientCallback != NULL) {
348 mFrontendClientCallback->onEvent(frontendEventType);
349 }
350 return Void();
351}
352
353Return<void> HidlFrontendCallback::onScanMessage(FrontendScanMessageType type,
354 const FrontendScanMessage& message) {
355 if (mFrontendClientCallback != NULL) {
356 mFrontendClientCallback->onScanMessage(type, message);
357 }
358 return Void();
359}
360
361Return<void> HidlFrontendCallback::onScanMessageExt1_1(FrontendScanMessageTypeExt1_1 type,
362 const FrontendScanMessageExt1_1& message) {
363 if (mFrontendClientCallback != NULL) {
364 mFrontendClientCallback->onScanMessageExt1_1(type, message);
365 }
366 return Void();
367}
Amy Zhangb9f3cab2021-01-13 15:24:14 -0800368
369/////////////// FrontendClientCallback Helper Methods ///////////////////////
370
371FrontendScanMessage TunerFrontendCallback::getHalScanMessage(
372 int messageType, const TunerFrontendScanMessage& message) {
373 FrontendScanMessage scanMessage;
374 switch (messageType) {
375 case (int) FrontendScanMessageType::LOCKED:
376 scanMessage.isLocked(message.get<TunerFrontendScanMessage::isLocked>());
377 break;
378 case (int) FrontendScanMessageType::END:
379 scanMessage.isEnd(message.get<TunerFrontendScanMessage::isEnd>());
380 break;
381 case (int) FrontendScanMessageType::PROGRESS_PERCENT:
382 scanMessage.progressPercent(message.get<TunerFrontendScanMessage::progressPercent>());
383 break;
384 case (int) FrontendScanMessageType::FREQUENCY: {
385 vector<int> f = message.get<TunerFrontendScanMessage::frequencies>();
386 hidl_vec<uint32_t> frequencies(begin(f), end(f));
387 scanMessage.frequencies(frequencies);
388 break;
389 }
390 case (int) FrontendScanMessageType::SYMBOL_RATE: {
391 vector<int> s = message.get<TunerFrontendScanMessage::symbolRates>();
392 hidl_vec<uint32_t> symbolRates(begin(s), end(s));
393 scanMessage.symbolRates(symbolRates);
394 break;
395 }
396 case (int) FrontendScanMessageType::HIERARCHY:
397 scanMessage.hierarchy(static_cast<FrontendDvbtHierarchy>(
398 message.get<TunerFrontendScanMessage::hierarchy>()));
399 break;
400 case (int) FrontendScanMessageType::ANALOG_TYPE:
401 scanMessage.analogType(static_cast<FrontendAnalogType>(
402 message.get<TunerFrontendScanMessage::analogType>()));
403 break;
404 case (int) FrontendScanMessageType::PLP_IDS: {
405 vector<uint8_t> p = message.get<TunerFrontendScanMessage::plpIds>();
406 hidl_vec<uint8_t> plpIds(begin(p), end(p));
407 scanMessage.plpIds(plpIds);
408 break;
409 }
410 case (int) FrontendScanMessageType::GROUP_IDS: {
411 vector<uint8_t> g = message.get<TunerFrontendScanMessage::groupIds>();
412 hidl_vec<uint8_t> groupIds(begin(g), end(g));
413 scanMessage.groupIds(groupIds);
414 break;
415 }
416 case (int) FrontendScanMessageType::INPUT_STREAM_IDS: {
417 vector<char16_t> i = message.get<TunerFrontendScanMessage::inputStreamIds>();
418 hidl_vec<uint16_t> inputStreamIds(begin(i), end(i));
419 scanMessage.inputStreamIds(inputStreamIds);
420 break;
421 }
422 case (int) FrontendScanMessageType::STANDARD: {
423 FrontendScanMessage::Standard std;
424 int standard = message.get<TunerFrontendScanMessage::std>();
425 switch (mType) {
426 case (int) FrontendType::DVBS:
427 std.sStd(static_cast<FrontendDvbsStandard>(standard));
428 scanMessage.std(std);
429 break;
430 case (int) FrontendType::DVBT:
431 std.tStd(static_cast<FrontendDvbtStandard>(standard));
432 scanMessage.std(std);
433 break;
434 case (int) FrontendType::ANALOG:
435 std.sifStd(static_cast<FrontendAnalogSifStandard>(standard));
436 scanMessage.std(std);
437 break;
438 default:
439 break;
440 }
441 break;
442 }
443 case (int) FrontendScanMessageType::ATSC3_PLP_INFO: {
444 vector<TunerFrontendScanAtsc3PlpInfo> plp =
445 message.get<TunerFrontendScanMessage::atsc3PlpInfos>();
446 hidl_vec<FrontendScanAtsc3PlpInfo> plpInfo;
447 for (TunerFrontendScanAtsc3PlpInfo info : plp) {
448 FrontendScanAtsc3PlpInfo p{
449 .plpId = static_cast<uint8_t>(info.plpId),
450 .bLlsFlag = info.llsFlag,
451 };
452 int size = plpInfo.size();
453 plpInfo.resize(size + 1);
454 plpInfo[size] = p;
455 }
456 scanMessage.atsc3PlpInfos(plpInfo);
457 break;
458 }
459 default:
460 break;
461 }
462 return scanMessage;
463}
464
465FrontendScanMessageExt1_1 TunerFrontendCallback::getHalScanMessageExt1_1(
466 int messageType, const TunerFrontendScanMessage& message) {
467 FrontendScanMessageExt1_1 scanMessage;
468 switch (messageType) {
469 case (int) FrontendScanMessageTypeExt1_1::HIGH_PRIORITY:
470 scanMessage.isHighPriority(message.get<TunerFrontendScanMessage::isHighPriority>());
471 break;
472 case (int) FrontendScanMessageTypeExt1_1::DVBC_ANNEX:
473 scanMessage.annex(static_cast<FrontendDvbcAnnex>(
474 message.get<TunerFrontendScanMessage::annex>()));
475 break;
476 case (int) FrontendScanMessageTypeExt1_1::MODULATION: {
477 FrontendModulation m;
478 int modulation = message.get<TunerFrontendScanMessage::modulation>();
479 switch (mType) {
480 case (int) FrontendType::DVBC:
481 m.dvbc(static_cast<FrontendDvbcModulation>(modulation));
482 scanMessage.modulation(m);
483 break;
484 case (int) FrontendType::DVBS:
485 m.dvbs(static_cast<FrontendDvbsModulation>(modulation));
486 scanMessage.modulation(m);
487 break;
488 case (int) FrontendType::DVBT:
489 m.dvbt(static_cast<FrontendDvbtConstellation>(modulation));
490 scanMessage.modulation(m);
491 break;
492 case (int) FrontendType::ISDBS:
493 m.isdbs(static_cast<FrontendIsdbsModulation>(modulation));
494 scanMessage.modulation(m);
495 break;
496 case (int) FrontendType::ISDBS3:
497 m.isdbs3(static_cast<FrontendIsdbs3Modulation>(modulation));
498 scanMessage.modulation(m);
499 break;
500 case (int) FrontendType::ISDBT:
501 m.isdbt(static_cast<FrontendIsdbtModulation>(modulation));
502 scanMessage.modulation(m);
503 break;
504 case (int) FrontendType::ATSC:
505 m.atsc(static_cast<FrontendAtscModulation>(modulation));
506 scanMessage.modulation(m);
507 break;
508 case (int) FrontendType::ATSC3:
509 m.atsc3(static_cast<FrontendAtsc3Modulation>(modulation));
510 scanMessage.modulation(m);
511 break;
512 case (int) hardware::tv::tuner::V1_1::FrontendType::DTMB:
513 m.dtmb(static_cast<FrontendDtmbModulation>(modulation));
514 scanMessage.modulation(m);
515 break;
516 default:
517 break;
518 }
519 break;
520 }
521 default:
522 break;
523 }
524 return scanMessage;
525}
526
527bool TunerFrontendCallback::is1_1ExtendedScanMessage(int messageType) {
528 return messageType >= (int)FrontendScanMessageTypeExt1_1::MODULATION
529 && messageType <= (int)FrontendScanMessageTypeExt1_1::HIGH_PRIORITY;
530}
Amy Zhanga6734682020-11-30 16:14:38 -0800531} // namespace android