blob: 8d4053a37957bdfe1ec6b27991daf0ed13735dd6 [file] [log] [blame]
Hongguang093c5f32021-08-09 19:46:34 -07001/**
2 * Copyright (c) 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 "TunerHidlService"
19
20#include "TunerHidlService.h"
21
22#include <aidl/android/hardware/tv/tuner/Result.h>
23#include <android/binder_manager.h>
Hongguang34a479e2021-10-04 16:14:47 -070024#include <binder/IPCThreadState.h>
25#include <binder/PermissionCache.h>
Hongguang093c5f32021-08-09 19:46:34 -070026#include <utils/Log.h>
27
28#include "TunerHelper.h"
29#include "TunerHidlDemux.h"
30#include "TunerHidlDescrambler.h"
31#include "TunerHidlFrontend.h"
32#include "TunerHidlLnb.h"
33
34using ::aidl::android::hardware::tv::tuner::FrontendAnalogCapabilities;
35using ::aidl::android::hardware::tv::tuner::FrontendAtsc3Capabilities;
36using ::aidl::android::hardware::tv::tuner::FrontendAtscCapabilities;
37using ::aidl::android::hardware::tv::tuner::FrontendCapabilities;
38using ::aidl::android::hardware::tv::tuner::FrontendDtmbCapabilities;
39using ::aidl::android::hardware::tv::tuner::FrontendDvbcCapabilities;
40using ::aidl::android::hardware::tv::tuner::FrontendDvbsCapabilities;
41using ::aidl::android::hardware::tv::tuner::FrontendDvbtCapabilities;
42using ::aidl::android::hardware::tv::tuner::FrontendIsdbs3Capabilities;
43using ::aidl::android::hardware::tv::tuner::FrontendIsdbsCapabilities;
44using ::aidl::android::hardware::tv::tuner::FrontendIsdbtCapabilities;
45using ::aidl::android::hardware::tv::tuner::FrontendType;
46using ::aidl::android::hardware::tv::tuner::Result;
47using ::aidl::android::media::tv::tunerresourcemanager::TunerFrontendInfo;
Hongguang34a479e2021-10-04 16:14:47 -070048using ::android::IPCThreadState;
49using ::android::PermissionCache;
Hongguang093c5f32021-08-09 19:46:34 -070050using ::android::hardware::hidl_vec;
51
52using HidlFrontendId = ::android::hardware::tv::tuner::V1_0::FrontendId;
53using HidlLnbId = ::android::hardware::tv::tuner::V1_0::LnbId;
54using HidlFrontendType = ::android::hardware::tv::tuner::V1_1::FrontendType;
55
56using namespace std;
57
58namespace aidl {
59namespace android {
60namespace media {
61namespace tv {
62namespace tuner {
63
Hongguang34a479e2021-10-04 16:14:47 -070064shared_ptr<TunerHidlService> TunerHidlService::sTunerService = nullptr;
65
Hongguang093c5f32021-08-09 19:46:34 -070066TunerHidlService::TunerHidlService() {
67 if (!TunerHelper::checkTunerFeature()) {
68 ALOGD("Device doesn't have tuner hardware.");
69 return;
70 }
71
72 updateTunerResources();
73}
74
75TunerHidlService::~TunerHidlService() {}
76
77binder_status_t TunerHidlService::instantiate() {
78 if (HidlITuner::getService() == nullptr) {
79 ALOGD("Failed to get ITuner HIDL HAL");
80 return STATUS_NAME_NOT_FOUND;
81 }
82
Hongguang34a479e2021-10-04 16:14:47 -070083 sTunerService = ::ndk::SharedRefBase::make<TunerHidlService>();
84 return AServiceManager_addService(sTunerService->asBinder().get(), getServiceName());
85}
86
87shared_ptr<TunerHidlService> TunerHidlService::getTunerService() {
88 return sTunerService;
Hongguang093c5f32021-08-09 19:46:34 -070089}
90
91bool TunerHidlService::hasITuner() {
92 ALOGV("hasITuner");
93 if (mTuner != nullptr) {
94 return true;
95 }
96
97 mTuner = HidlITuner::getService();
98 if (mTuner == nullptr) {
99 ALOGE("Failed to get ITuner service");
100 return false;
101 }
102 mTunerVersion = TUNER_HAL_VERSION_1_0;
103
104 mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::castFrom(mTuner);
105 if (mTuner_1_1 != nullptr) {
106 mTunerVersion = TUNER_HAL_VERSION_1_1;
107 } else {
108 ALOGD("Failed to get ITuner_1_1 service");
109 }
110
111 return true;
112}
113
114bool TunerHidlService::hasITuner_1_1() {
115 ALOGV("hasITuner_1_1");
116 hasITuner();
117 return (mTunerVersion == TUNER_HAL_VERSION_1_1);
118}
119
120::ndk::ScopedAStatus TunerHidlService::openDemux(int32_t /* in_demuxHandle */,
121 shared_ptr<ITunerDemux>* _aidl_return) {
122 ALOGV("openDemux");
123 if (!hasITuner()) {
124 return ::ndk::ScopedAStatus::fromServiceSpecificError(
125 static_cast<int32_t>(Result::UNAVAILABLE));
126 }
127
128 HidlResult res;
129 uint32_t id;
130 sp<IDemux> demuxSp = nullptr;
131 mTuner->openDemux([&](HidlResult r, uint32_t demuxId, const sp<IDemux>& demux) {
132 demuxSp = demux;
133 id = demuxId;
134 res = r;
135 ALOGD("open demux, id = %d", demuxId);
136 });
137 if (res == HidlResult::SUCCESS) {
138 *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlDemux>(demuxSp, id);
139 return ::ndk::ScopedAStatus::ok();
140 }
141
142 ALOGW("open demux failed, res = %d", res);
143 return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
144}
145
146::ndk::ScopedAStatus TunerHidlService::getDemuxCaps(DemuxCapabilities* _aidl_return) {
147 ALOGV("getDemuxCaps");
148 if (!hasITuner()) {
149 return ::ndk::ScopedAStatus::fromServiceSpecificError(
150 static_cast<int32_t>(Result::UNAVAILABLE));
151 }
152
153 HidlResult res;
154 HidlDemuxCapabilities caps;
155 mTuner->getDemuxCaps([&](HidlResult r, const HidlDemuxCapabilities& demuxCaps) {
156 caps = demuxCaps;
157 res = r;
158 });
159 if (res == HidlResult::SUCCESS) {
160 *_aidl_return = getAidlDemuxCaps(caps);
161 return ::ndk::ScopedAStatus::ok();
162 }
163
164 ALOGW("Get demux caps failed, res = %d", res);
165 return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
166}
167
168::ndk::ScopedAStatus TunerHidlService::getFrontendIds(vector<int32_t>* ids) {
169 if (!hasITuner()) {
170 return ::ndk::ScopedAStatus::fromServiceSpecificError(
171 static_cast<int32_t>(Result::UNAVAILABLE));
172 }
173
174 hidl_vec<HidlFrontendId> feIds;
175 HidlResult res = getHidlFrontendIds(feIds);
176 if (res != HidlResult::SUCCESS) {
177 return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
178 }
179 ids->resize(feIds.size());
180 copy(feIds.begin(), feIds.end(), ids->begin());
181
182 return ::ndk::ScopedAStatus::ok();
183}
184
185::ndk::ScopedAStatus TunerHidlService::getFrontendInfo(int32_t id, FrontendInfo* _aidl_return) {
186 if (!hasITuner()) {
187 ALOGE("ITuner service is not init.");
188 return ::ndk::ScopedAStatus::fromServiceSpecificError(
189 static_cast<int32_t>(Result::UNAVAILABLE));
190 }
191
192 HidlFrontendInfo info;
193 HidlResult res = getHidlFrontendInfo(id, info);
194 if (res != HidlResult::SUCCESS) {
195 return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
196 }
197
198 HidlFrontendDtmbCapabilities dtmbCaps;
199 if (static_cast<HidlFrontendType>(info.type) == HidlFrontendType::DTMB) {
200 if (!hasITuner_1_1()) {
201 ALOGE("ITuner_1_1 service is not init.");
202 return ::ndk::ScopedAStatus::fromServiceSpecificError(
203 static_cast<int32_t>(Result::UNAVAILABLE));
204 }
205
206 mTuner_1_1->getFrontendDtmbCapabilities(
207 id, [&](HidlResult r, const HidlFrontendDtmbCapabilities& caps) {
208 dtmbCaps = caps;
209 res = r;
210 });
211 if (res != HidlResult::SUCCESS) {
212 return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
213 }
214 }
215
216 *_aidl_return = getAidlFrontendInfo(info, dtmbCaps);
217 return ::ndk::ScopedAStatus::ok();
218}
219
220::ndk::ScopedAStatus TunerHidlService::openFrontend(int32_t frontendHandle,
221 shared_ptr<ITunerFrontend>* _aidl_return) {
222 if (!hasITuner()) {
223 ALOGE("ITuner service is not init.");
224 return ::ndk::ScopedAStatus::fromServiceSpecificError(
225 static_cast<int32_t>(Result::UNAVAILABLE));
226 }
227
228 HidlResult status;
229 sp<HidlIFrontend> frontend;
230 int id = TunerHelper::getResourceIdFromHandle(frontendHandle, FRONTEND);
231 mTuner->openFrontendById(id, [&](HidlResult result, const sp<HidlIFrontend>& fe) {
232 frontend = fe;
233 status = result;
234 });
235 if (status != HidlResult::SUCCESS) {
236 return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
237 }
238 *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlFrontend>(frontend, id);
239 return ::ndk::ScopedAStatus::ok();
240}
241
242::ndk::ScopedAStatus TunerHidlService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
243 if (!hasITuner()) {
244 ALOGD("get ITuner failed");
245 return ::ndk::ScopedAStatus::fromServiceSpecificError(
246 static_cast<int32_t>(Result::UNAVAILABLE));
247 }
248
249 HidlResult status;
250 sp<HidlILnb> lnb;
251 int id = TunerHelper::getResourceIdFromHandle(lnbHandle, LNB);
252 mTuner->openLnbById(id, [&](HidlResult result, const sp<HidlILnb>& lnbSp) {
253 lnb = lnbSp;
254 status = result;
255 });
256 if (status != HidlResult::SUCCESS) {
257 return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
258 }
259
260 *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlLnb>(lnb, id);
261 return ::ndk::ScopedAStatus::ok();
262}
263
264::ndk::ScopedAStatus TunerHidlService::openLnbByName(const string& lnbName,
265 shared_ptr<ITunerLnb>* _aidl_return) {
266 if (!hasITuner()) {
267 ALOGE("get ITuner failed");
268 return ::ndk::ScopedAStatus::fromServiceSpecificError(
269 static_cast<int32_t>(Result::UNAVAILABLE));
270 }
271
272 int lnbId;
273 HidlResult status;
274 sp<HidlILnb> lnb;
275 mTuner->openLnbByName(lnbName, [&](HidlResult r, HidlLnbId id, const sp<HidlILnb>& lnbSp) {
276 status = r;
277 lnb = lnbSp;
278 lnbId = static_cast<int32_t>(id);
279 });
280 if (status != HidlResult::SUCCESS) {
281 return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
282 }
283
284 *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlLnb>(lnb, lnbId);
285 return ::ndk::ScopedAStatus::ok();
286}
287
288::ndk::ScopedAStatus TunerHidlService::openDescrambler(
289 int32_t /*descramblerHandle*/, shared_ptr<ITunerDescrambler>* _aidl_return) {
290 if (!hasITuner()) {
291 ALOGD("get ITuner failed");
292 return ::ndk::ScopedAStatus::fromServiceSpecificError(
293 static_cast<int32_t>(Result::UNAVAILABLE));
294 }
295
296 HidlResult status;
297 sp<HidlIDescrambler> descrambler;
298 //int id = TunerHelper::getResourceIdFromHandle(descramblerHandle, DESCRAMBLER);
299 mTuner->openDescrambler([&](HidlResult r, const sp<HidlIDescrambler>& descramblerSp) {
300 status = r;
301 descrambler = descramblerSp;
302 });
303 if (status != HidlResult::SUCCESS) {
304 return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
305 }
306
307 *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlDescrambler>(descrambler);
308 return ::ndk::ScopedAStatus::ok();
309}
310
311::ndk::ScopedAStatus TunerHidlService::getTunerHalVersion(int* _aidl_return) {
312 hasITuner();
313 *_aidl_return = mTunerVersion;
314 return ::ndk::ScopedAStatus::ok();
315}
316
Hongguang34a479e2021-10-04 16:14:47 -0700317::ndk::ScopedAStatus TunerHidlService::openSharedFilter(
318 const string& in_filterToken, const shared_ptr<ITunerFilterCallback>& in_cb,
319 shared_ptr<ITunerFilter>* _aidl_return) {
320 if (!hasITuner()) {
321 ALOGE("get ITuner failed");
322 return ::ndk::ScopedAStatus::fromServiceSpecificError(
323 static_cast<int32_t>(Result::UNAVAILABLE));
324 }
325
326 if (!PermissionCache::checkCallingPermission(sSharedFilterPermission)) {
327 ALOGE("Request requires android.permission.ACCESS_TV_SHARED_FILTER");
328 return ::ndk::ScopedAStatus::fromServiceSpecificError(
329 static_cast<int32_t>(Result::UNAVAILABLE));
330 }
331
332 Mutex::Autolock _l(mSharedFiltersLock);
333 if (mSharedFilters.find(in_filterToken) == mSharedFilters.end()) {
334 *_aidl_return = nullptr;
335 ALOGD("fail to find %s", in_filterToken.c_str());
336 return ::ndk::ScopedAStatus::fromServiceSpecificError(
337 static_cast<int32_t>(Result::INVALID_STATE));
338 }
339
340 shared_ptr<TunerHidlFilter> filter = mSharedFilters.at(in_filterToken);
341 IPCThreadState* ipc = IPCThreadState::self();
342 const int pid = ipc->getCallingPid();
343 if (!filter->isSharedFilterAllowed(pid)) {
344 *_aidl_return = nullptr;
345 ALOGD("shared filter %s is opened in the same process", in_filterToken.c_str());
346 return ::ndk::ScopedAStatus::fromServiceSpecificError(
347 static_cast<int32_t>(Result::INVALID_STATE));
348 }
349
350 filter->attachSharedFilterCallback(in_cb);
351
352 *_aidl_return = filter;
353 return ::ndk::ScopedAStatus::ok();
354}
355
356string TunerHidlService::addFilterToShared(const shared_ptr<TunerHidlFilter>& sharedFilter) {
357 Mutex::Autolock _l(mSharedFiltersLock);
358
359 // Use sharedFilter address as token.
360 string token = to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get()));
361 mSharedFilters[token] = sharedFilter;
362
363 return token;
364}
365
366void TunerHidlService::removeSharedFilter(const shared_ptr<TunerHidlFilter>& sharedFilter) {
367 Mutex::Autolock _l(mSharedFiltersLock);
368
369 // Use sharedFilter address as token.
370 mSharedFilters.erase(to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get())));
371}
372
Hongguang093c5f32021-08-09 19:46:34 -0700373void TunerHidlService::updateTunerResources() {
374 if (!hasITuner()) {
375 ALOGE("Failed to updateTunerResources");
376 return;
377 }
378
379 TunerHelper::updateTunerResources(getTRMFrontendInfos(), getTRMLnbHandles());
380}
381
382vector<TunerFrontendInfo> TunerHidlService::getTRMFrontendInfos() {
383 vector<TunerFrontendInfo> infos;
384 hidl_vec<HidlFrontendId> ids;
385 HidlResult res = getHidlFrontendIds(ids);
386 if (res != HidlResult::SUCCESS) {
387 return infos;
388 }
389
390 for (int i = 0; i < ids.size(); i++) {
391 HidlFrontendInfo frontendInfo;
392 HidlResult res = getHidlFrontendInfo(static_cast<int32_t>(ids[i]), frontendInfo);
393 if (res != HidlResult::SUCCESS) {
394 continue;
395 }
396 TunerFrontendInfo tunerFrontendInfo{
397 .handle = TunerHelper::getResourceHandleFromId(static_cast<int32_t>(ids[i]),
398 FRONTEND),
399 .type = static_cast<int32_t>(frontendInfo.type),
400 .exclusiveGroupId = static_cast<int32_t>(frontendInfo.exclusiveGroupId),
401 };
402 infos.push_back(tunerFrontendInfo);
403 }
404
405 return infos;
406}
407
408vector<int32_t> TunerHidlService::getTRMLnbHandles() {
409 vector<int32_t> lnbHandles;
410 if (mTuner != nullptr) {
411 HidlResult res;
412 vector<HidlLnbId> lnbIds;
413 mTuner->getLnbIds([&](HidlResult r, const hidl_vec<HidlLnbId>& ids) {
414 lnbIds = ids;
415 res = r;
416 });
417 if (res == HidlResult::SUCCESS && lnbIds.size() > 0) {
418 for (int i = 0; i < lnbIds.size(); i++) {
419 lnbHandles.push_back(
420 TunerHelper::getResourceHandleFromId(static_cast<int32_t>(lnbIds[i]), LNB));
421 }
422 }
423 }
424
425 return lnbHandles;
426}
427
428HidlResult TunerHidlService::getHidlFrontendIds(hidl_vec<HidlFrontendId>& ids) {
429 if (mTuner == nullptr) {
430 return HidlResult::NOT_INITIALIZED;
431 }
432 HidlResult res;
433 mTuner->getFrontendIds([&](HidlResult r, const hidl_vec<HidlFrontendId>& frontendIds) {
434 ids = frontendIds;
435 res = r;
436 });
437 return res;
438}
439
440HidlResult TunerHidlService::getHidlFrontendInfo(const int id, HidlFrontendInfo& info) {
441 if (mTuner == nullptr) {
442 return HidlResult::NOT_INITIALIZED;
443 }
444 HidlResult res;
445 mTuner->getFrontendInfo(id, [&](HidlResult r, const HidlFrontendInfo& feInfo) {
446 info = feInfo;
447 res = r;
448 });
449 return res;
450}
451
452DemuxCapabilities TunerHidlService::getAidlDemuxCaps(const HidlDemuxCapabilities& caps) {
453 DemuxCapabilities aidlCaps{
454 .numDemux = static_cast<int32_t>(caps.numDemux),
455 .numRecord = static_cast<int32_t>(caps.numRecord),
456 .numPlayback = static_cast<int32_t>(caps.numPlayback),
457 .numTsFilter = static_cast<int32_t>(caps.numTsFilter),
458 .numSectionFilter = static_cast<int32_t>(caps.numSectionFilter),
459 .numAudioFilter = static_cast<int32_t>(caps.numAudioFilter),
460 .numVideoFilter = static_cast<int32_t>(caps.numVideoFilter),
461 .numPesFilter = static_cast<int32_t>(caps.numPesFilter),
462 .numPcrFilter = static_cast<int32_t>(caps.numPcrFilter),
463 .numBytesInSectionFilter = static_cast<int64_t>(caps.numBytesInSectionFilter),
464 .filterCaps = static_cast<int32_t>(caps.filterCaps),
465 .bTimeFilter = caps.bTimeFilter,
466 };
467 aidlCaps.linkCaps.resize(caps.linkCaps.size());
468 copy(caps.linkCaps.begin(), caps.linkCaps.end(), aidlCaps.linkCaps.begin());
469 return aidlCaps;
470}
471
472FrontendInfo TunerHidlService::getAidlFrontendInfo(
473 const HidlFrontendInfo& halInfo, const HidlFrontendDtmbCapabilities& halDtmbCaps) {
474 FrontendInfo info{
475 .type = static_cast<FrontendType>(halInfo.type),
476 .minFrequency = static_cast<int64_t>(halInfo.minFrequency),
477 .maxFrequency = static_cast<int64_t>(halInfo.maxFrequency),
478 .minSymbolRate = static_cast<int32_t>(halInfo.minSymbolRate),
479 .maxSymbolRate = static_cast<int32_t>(halInfo.maxSymbolRate),
480 .acquireRange = static_cast<int64_t>(halInfo.acquireRange),
481 .exclusiveGroupId = static_cast<int32_t>(halInfo.exclusiveGroupId),
482 };
483 for (int i = 0; i < halInfo.statusCaps.size(); i++) {
484 info.statusCaps.push_back(static_cast<FrontendStatusType>(halInfo.statusCaps[i]));
485 }
486
487 FrontendCapabilities caps;
488 switch (halInfo.type) {
489 case ::android::hardware::tv::tuner::V1_0::FrontendType::ANALOG: {
490 if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::analogCaps ==
491 halInfo.frontendCaps.getDiscriminator()) {
492 FrontendAnalogCapabilities analogCaps{
493 .typeCap = static_cast<int32_t>(halInfo.frontendCaps.analogCaps().typeCap),
494 .sifStandardCap =
495 static_cast<int32_t>(halInfo.frontendCaps.analogCaps().sifStandardCap),
496 };
497 caps.set<FrontendCapabilities::analogCaps>(analogCaps);
498 }
499 break;
500 }
501 case ::android::hardware::tv::tuner::V1_0::FrontendType::ATSC: {
502 if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::atscCaps ==
503 halInfo.frontendCaps.getDiscriminator()) {
504 FrontendAtscCapabilities atscCaps{
505 .modulationCap =
506 static_cast<int32_t>(halInfo.frontendCaps.atscCaps().modulationCap),
507 };
508 caps.set<FrontendCapabilities::atscCaps>(atscCaps);
509 }
510 break;
511 }
512 case ::android::hardware::tv::tuner::V1_0::FrontendType::ATSC3: {
513 if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::atsc3Caps ==
514 halInfo.frontendCaps.getDiscriminator()) {
515 FrontendAtsc3Capabilities atsc3Caps{
516 .bandwidthCap =
517 static_cast<int32_t>(halInfo.frontendCaps.atsc3Caps().bandwidthCap),
518 .modulationCap =
519 static_cast<int32_t>(halInfo.frontendCaps.atsc3Caps().modulationCap),
520 .timeInterleaveModeCap = static_cast<int32_t>(
521 halInfo.frontendCaps.atsc3Caps().timeInterleaveModeCap),
522 .codeRateCap =
523 static_cast<int32_t>(halInfo.frontendCaps.atsc3Caps().codeRateCap),
524 .demodOutputFormatCap = static_cast<int8_t>(
525 halInfo.frontendCaps.atsc3Caps().demodOutputFormatCap),
526 .fecCap = static_cast<int32_t>(halInfo.frontendCaps.atsc3Caps().fecCap),
527 };
528 caps.set<FrontendCapabilities::atsc3Caps>(atsc3Caps);
529 }
530 break;
531 }
532 case ::android::hardware::tv::tuner::V1_0::FrontendType::DVBC: {
533 if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::dvbcCaps ==
534 halInfo.frontendCaps.getDiscriminator()) {
535 FrontendDvbcCapabilities dvbcCaps{
536 .modulationCap =
537 static_cast<int32_t>(halInfo.frontendCaps.dvbcCaps().modulationCap),
538 .fecCap = static_cast<int64_t>(halInfo.frontendCaps.dvbcCaps().fecCap),
539 .annexCap = static_cast<int8_t>(halInfo.frontendCaps.dvbcCaps().annexCap),
540 };
541 caps.set<FrontendCapabilities::dvbcCaps>(dvbcCaps);
542 }
543 break;
544 }
545 case ::android::hardware::tv::tuner::V1_0::FrontendType::DVBS: {
546 if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::dvbsCaps ==
547 halInfo.frontendCaps.getDiscriminator()) {
548 FrontendDvbsCapabilities dvbsCaps{
549 .modulationCap =
550 static_cast<int32_t>(halInfo.frontendCaps.dvbsCaps().modulationCap),
551 .innerfecCap =
552 static_cast<int64_t>(halInfo.frontendCaps.dvbsCaps().innerfecCap),
553 .standard = static_cast<int8_t>(halInfo.frontendCaps.dvbsCaps().standard),
554 };
555 caps.set<FrontendCapabilities::dvbsCaps>(dvbsCaps);
556 }
557 break;
558 }
559 case ::android::hardware::tv::tuner::V1_0::FrontendType::DVBT: {
560 if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::dvbtCaps ==
561 halInfo.frontendCaps.getDiscriminator()) {
562 FrontendDvbtCapabilities dvbtCaps{
563 .transmissionModeCap = static_cast<int32_t>(
564 halInfo.frontendCaps.dvbtCaps().transmissionModeCap),
565 .bandwidthCap =
566 static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().bandwidthCap),
567 .constellationCap =
568 static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().constellationCap),
569 .coderateCap =
570 static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().coderateCap),
571 .hierarchyCap =
572 static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().hierarchyCap),
573 .guardIntervalCap =
574 static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().guardIntervalCap),
575 .isT2Supported = halInfo.frontendCaps.dvbtCaps().isT2Supported,
576 .isMisoSupported = halInfo.frontendCaps.dvbtCaps().isMisoSupported,
577 };
578 caps.set<FrontendCapabilities::dvbtCaps>(dvbtCaps);
579 }
580 break;
581 }
582 case ::android::hardware::tv::tuner::V1_0::FrontendType::ISDBS: {
583 if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::isdbsCaps ==
584 halInfo.frontendCaps.getDiscriminator()) {
585 FrontendIsdbsCapabilities isdbsCaps{
586 .modulationCap =
587 static_cast<int32_t>(halInfo.frontendCaps.isdbsCaps().modulationCap),
588 .coderateCap =
589 static_cast<int32_t>(halInfo.frontendCaps.isdbsCaps().coderateCap),
590 };
591 caps.set<FrontendCapabilities::isdbsCaps>(isdbsCaps);
592 }
593 break;
594 }
595 case ::android::hardware::tv::tuner::V1_0::FrontendType::ISDBS3: {
596 if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::isdbs3Caps ==
597 halInfo.frontendCaps.getDiscriminator()) {
598 FrontendIsdbs3Capabilities isdbs3Caps{
599 .modulationCap =
600 static_cast<int32_t>(halInfo.frontendCaps.isdbs3Caps().modulationCap),
601 .coderateCap =
602 static_cast<int32_t>(halInfo.frontendCaps.isdbs3Caps().coderateCap),
603 };
604 caps.set<FrontendCapabilities::isdbs3Caps>(isdbs3Caps);
605 }
606 break;
607 }
608 case ::android::hardware::tv::tuner::V1_0::FrontendType::ISDBT: {
609 if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::isdbtCaps ==
610 halInfo.frontendCaps.getDiscriminator()) {
611 FrontendIsdbtCapabilities isdbtCaps{
612 .modeCap = static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().modeCap),
613 .bandwidthCap =
614 static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().bandwidthCap),
615 .modulationCap =
616 static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().modulationCap),
617 .coderateCap =
618 static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().coderateCap),
619 .guardIntervalCap =
620 static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().guardIntervalCap),
621 };
622 caps.set<FrontendCapabilities::isdbtCaps>(isdbtCaps);
623 }
624 break;
625 }
626 default: {
627 if (static_cast<HidlFrontendType>(info.type) == HidlFrontendType::DTMB) {
628 FrontendDtmbCapabilities dtmbCaps{
629 .transmissionModeCap = static_cast<int32_t>(halDtmbCaps.transmissionModeCap),
630 .bandwidthCap = static_cast<int32_t>(halDtmbCaps.bandwidthCap),
631 .modulationCap = static_cast<int32_t>(halDtmbCaps.modulationCap),
632 .codeRateCap = static_cast<int32_t>(halDtmbCaps.codeRateCap),
633 .guardIntervalCap = static_cast<int32_t>(halDtmbCaps.guardIntervalCap),
634 .interleaveModeCap = static_cast<int32_t>(halDtmbCaps.interleaveModeCap),
635 };
636 caps.set<FrontendCapabilities::dtmbCaps>(dtmbCaps);
637 }
638 break;
639 }
640 }
641
642 info.frontendCaps = caps;
643 return info;
644}
645
646} // namespace tuner
647} // namespace tv
648} // namespace media
649} // namespace android
650} // namespace aidl