1 /**
2 * Copyright (c) 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 "TunerService"
18
19 #include <android/binder_manager.h>
20 #include <android/content/pm/IPackageManagerNative.h>
21 #include <binder/IServiceManager.h>
22 #include <utils/Log.h>
23 #include "TunerService.h"
24 #include "TunerFrontend.h"
25 #include "TunerLnb.h"
26 #include "TunerDemux.h"
27 #include "TunerDescrambler.h"
28
29 using ::aidl::android::media::tv::tuner::TunerFrontendAnalogCapabilities;
30 using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3Capabilities;
31 using ::aidl::android::media::tv::tuner::TunerFrontendAtscCapabilities;
32 using ::aidl::android::media::tv::tuner::TunerFrontendCableCapabilities;
33 using ::aidl::android::media::tv::tuner::TunerFrontendCapabilities;
34 using ::aidl::android::media::tv::tuner::TunerFrontendDvbsCapabilities;
35 using ::aidl::android::media::tv::tuner::TunerFrontendDvbtCapabilities;
36 using ::aidl::android::media::tv::tuner::TunerFrontendIsdbs3Capabilities;
37 using ::aidl::android::media::tv::tuner::TunerFrontendIsdbsCapabilities;
38 using ::aidl::android::media::tv::tuner::TunerFrontendIsdbtCapabilities;
39 using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings;
40 using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
41 using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
42 using ::android::hardware::tv::tuner::V1_0::DemuxFilterType;
43 using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
44 using ::android::hardware::tv::tuner::V1_0::FrontendId;
45 using ::android::hardware::tv::tuner::V1_0::FrontendType;
46 using ::android::hardware::tv::tuner::V1_0::IFrontend;
47 using ::android::hardware::tv::tuner::V1_0::ILnb;
48 using ::android::hardware::tv::tuner::V1_0::LnbId;
49 using ::android::hardware::tv::tuner::V1_0::Result;
50 using ::android::hardware::tv::tuner::V1_1::FrontendDtmbCapabilities;
51
52 namespace android {
53
TunerService()54 TunerService::TunerService() {
55 sp<IServiceManager> serviceMgr = defaultServiceManager();
56 sp<content::pm::IPackageManagerNative> packageMgr;
57 if (serviceMgr.get() == nullptr) {
58 ALOGE("%s: Cannot find service manager", __func__);
59 return;
60 } else {
61 sp<IBinder> binder = serviceMgr->waitForService(String16("package_native"));
62 packageMgr = interface_cast<content::pm::IPackageManagerNative>(binder);
63 }
64
65 bool hasFeature = false;
66 if (packageMgr != nullptr) {
67 binder::Status status = packageMgr->hasSystemFeature(FEATURE_TUNER, 0, &hasFeature);
68 if (!status.isOk()) {
69 ALOGE("%s: hasSystemFeature failed: %s",
70 __func__, status.exceptionMessage().c_str());
71 return;
72 }
73 if (!hasFeature) {
74 ALOGD("Current device does not support tuner feaure.");
75 return;
76 }
77 } else {
78 ALOGD("%s: Cannot find package manager.", __func__);
79 return;
80 }
81
82 ::ndk::SpAIBinder binder(AServiceManager_waitForService("tv_tuner_resource_mgr"));
83 mTunerResourceManager = ITunerResourceManager::fromBinder(binder);
84 updateTunerResources();
85 }
86
~TunerService()87 TunerService::~TunerService() {}
88
instantiate()89 binder_status_t TunerService::instantiate() {
90 shared_ptr<TunerService> service =
91 ::ndk::SharedRefBase::make<TunerService>();
92 return AServiceManager_addService(service->asBinder().get(), getServiceName());
93 }
94
hasITuner()95 bool TunerService::hasITuner() {
96 ALOGD("hasITuner");
97 if (mTuner != nullptr) {
98 return true;
99 }
100 mTuner = ITuner::getService();
101 if (mTuner == nullptr) {
102 ALOGE("Failed to get ITuner service");
103 return false;
104 }
105 mTunerVersion = TUNER_HAL_VERSION_1_0;
106 mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::castFrom(mTuner);
107 if (mTuner_1_1 != nullptr) {
108 mTunerVersion = TUNER_HAL_VERSION_1_1;
109 } else {
110 ALOGE("Failed to get ITuner_1_1 service");
111 }
112 return true;
113 }
114
hasITuner_1_1()115 bool TunerService::hasITuner_1_1() {
116 ALOGD("hasITuner_1_1");
117 hasITuner();
118 return (mTunerVersion == TUNER_HAL_VERSION_1_1);
119 }
120
openDemux(int,std::shared_ptr<ITunerDemux> * _aidl_return)121 Status TunerService::openDemux(
122 int /* demuxHandle */, std::shared_ptr<ITunerDemux>* _aidl_return) {
123 ALOGD("openDemux");
124 if (!hasITuner()) {
125 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::NOT_INITIALIZED));
126 }
127 Result res;
128 uint32_t id;
129 sp<IDemux> demuxSp = nullptr;
130 shared_ptr<ITunerDemux> tunerDemux = nullptr;
131 mTuner->openDemux([&](Result 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 == Result::SUCCESS) {
138 tunerDemux = ::ndk::SharedRefBase::make<TunerDemux>(demuxSp, id);
139 *_aidl_return = tunerDemux->ref<ITunerDemux>();
140 return Status::ok();
141 }
142
143 ALOGW("open demux failed, res = %d", res);
144 return Status::fromServiceSpecificError(static_cast<int32_t>(res));
145 }
146
getDemuxCaps(TunerDemuxCapabilities * _aidl_return)147 Status TunerService::getDemuxCaps(TunerDemuxCapabilities* _aidl_return) {
148 ALOGD("getDemuxCaps");
149 if (!hasITuner()) {
150 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::NOT_INITIALIZED));
151 }
152 Result res;
153 DemuxCapabilities caps;
154 mTuner->getDemuxCaps([&](Result r, const DemuxCapabilities& demuxCaps) {
155 caps = demuxCaps;
156 res = r;
157 });
158 if (res == Result::SUCCESS) {
159 *_aidl_return = getAidlDemuxCaps(caps);
160 return Status::ok();
161 }
162
163 ALOGW("Get demux caps failed, res = %d", res);
164 return Status::fromServiceSpecificError(static_cast<int32_t>(res));
165 }
166
getFrontendIds(vector<int32_t> * ids)167 Status TunerService::getFrontendIds(vector<int32_t>* ids) {
168 if (!hasITuner()) {
169 return Status::fromServiceSpecificError(
170 static_cast<int32_t>(Result::NOT_INITIALIZED));
171 }
172 hidl_vec<FrontendId> feIds;
173 Result res = getHidlFrontendIds(feIds);
174 if (res != Result::SUCCESS) {
175 return Status::fromServiceSpecificError(static_cast<int32_t>(res));
176 }
177 ids->resize(feIds.size());
178 copy(feIds.begin(), feIds.end(), ids->begin());
179
180 return Status::ok();
181 }
182
getFrontendInfo(int32_t id,TunerFrontendInfo * _aidl_return)183 Status TunerService::getFrontendInfo(int32_t id, TunerFrontendInfo* _aidl_return) {
184 if (!hasITuner()) {
185 ALOGE("ITuner service is not init.");
186 return ::ndk::ScopedAStatus::fromServiceSpecificError(
187 static_cast<int32_t>(Result::UNAVAILABLE));
188 }
189
190 FrontendInfo info;
191 Result res = getHidlFrontendInfo(id, info);
192 if (res != Result::SUCCESS) {
193 return Status::fromServiceSpecificError(static_cast<int32_t>(res));
194 }
195
196 TunerFrontendInfo tunerInfo = convertToAidlFrontendInfo(info);
197 *_aidl_return = tunerInfo;
198 return Status::ok();
199 }
200
getFrontendDtmbCapabilities(int32_t id,TunerFrontendDtmbCapabilities * _aidl_return)201 Status TunerService::getFrontendDtmbCapabilities(
202 int32_t id, TunerFrontendDtmbCapabilities* _aidl_return) {
203 if (!hasITuner_1_1()) {
204 ALOGE("ITuner_1_1 service is not init.");
205 return ::ndk::ScopedAStatus::fromServiceSpecificError(
206 static_cast<int32_t>(Result::UNAVAILABLE));
207 }
208
209 Result res;
210 FrontendDtmbCapabilities dtmbCaps;
211 mTuner_1_1->getFrontendDtmbCapabilities(id,
212 [&](Result r, const FrontendDtmbCapabilities& caps) {
213 dtmbCaps = caps;
214 res = r;
215 });
216 if (res != Result::SUCCESS) {
217 return Status::fromServiceSpecificError(static_cast<int32_t>(res));
218 }
219
220 TunerFrontendDtmbCapabilities aidlDtmbCaps{
221 .transmissionModeCap = (int)dtmbCaps.transmissionModeCap,
222 .bandwidthCap = (int)dtmbCaps.bandwidthCap,
223 .modulationCap = (int)dtmbCaps.modulationCap,
224 .codeRateCap = (int)dtmbCaps.codeRateCap,
225 .guardIntervalCap = (int)dtmbCaps.guardIntervalCap,
226 .interleaveModeCap = (int)dtmbCaps.interleaveModeCap,
227 };
228
229 *_aidl_return = aidlDtmbCaps;
230 return Status::ok();
231 }
232
openFrontend(int32_t frontendHandle,shared_ptr<ITunerFrontend> * _aidl_return)233 Status TunerService::openFrontend(
234 int32_t frontendHandle, shared_ptr<ITunerFrontend>* _aidl_return) {
235 if (!hasITuner()) {
236 ALOGE("ITuner service is not init.");
237 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
238 }
239
240 Result status;
241 sp<IFrontend> frontend;
242 int id = getResourceIdFromHandle(frontendHandle, FRONTEND);
243 mTuner->openFrontendById(id, [&](Result result, const sp<IFrontend>& fe) {
244 frontend = fe;
245 status = result;
246 });
247 if (status != Result::SUCCESS) {
248 return Status::fromServiceSpecificError(static_cast<int32_t>(status));
249 }
250 *_aidl_return = ::ndk::SharedRefBase::make<TunerFrontend>(frontend, id);
251 return Status::ok();
252 }
253
openLnb(int lnbHandle,shared_ptr<ITunerLnb> * _aidl_return)254 Status TunerService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
255 if (!hasITuner()) {
256 ALOGD("get ITuner failed");
257 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
258 }
259
260 Result status;
261 sp<ILnb> lnb;
262 int id = getResourceIdFromHandle(lnbHandle, LNB);
263 mTuner->openLnbById(id, [&](Result result, const sp<ILnb>& lnbSp){
264 lnb = lnbSp;
265 status = result;
266 });
267 if (status != Result::SUCCESS) {
268 return Status::fromServiceSpecificError(static_cast<int32_t>(status));
269 }
270
271 *_aidl_return = ::ndk::SharedRefBase::make<TunerLnb>(lnb, id);
272 return Status::ok();
273 }
274
openLnbByName(const string & lnbName,shared_ptr<ITunerLnb> * _aidl_return)275 Status TunerService::openLnbByName(const string& lnbName, shared_ptr<ITunerLnb>* _aidl_return) {
276 if (!hasITuner()) {
277 ALOGE("get ITuner failed");
278 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
279 }
280
281 int lnbId;
282 Result status;
283 sp<ILnb> lnb;
284 mTuner->openLnbByName(lnbName, [&](Result r, LnbId id, const sp<ILnb>& lnbSp) {
285 status = r;
286 lnb = lnbSp;
287 lnbId = (int)id;
288 });
289 if (status != Result::SUCCESS) {
290 return Status::fromServiceSpecificError(static_cast<int32_t>(status));
291 }
292
293 *_aidl_return = ::ndk::SharedRefBase::make<TunerLnb>(lnb, lnbId);
294 return Status::ok();
295 }
296
openDescrambler(int32_t,std::shared_ptr<ITunerDescrambler> * _aidl_return)297 Status TunerService::openDescrambler(int32_t /*descramblerHandle*/,
298 std::shared_ptr<ITunerDescrambler>* _aidl_return) {
299 if (!hasITuner()) {
300 ALOGD("get ITuner failed");
301 return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
302 }
303
304 Result status;
305 sp<IDescrambler> descrambler;
306 //int id = getResourceIdFromHandle(descramblerHandle, DESCRAMBLER);
307 mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
308 status = r;
309 descrambler = descramblerSp;
310 });
311 if (status != Result::SUCCESS) {
312 return Status::fromServiceSpecificError(static_cast<int32_t>(status));
313 }
314
315 *_aidl_return = ::ndk::SharedRefBase::make<TunerDescrambler>(descrambler);
316 return Status::ok();
317 }
318
updateTunerResources()319 void TunerService::updateTunerResources() {
320 if (!hasITuner() || mTunerResourceManager == NULL) {
321 ALOGE("Failed to updateTunerResources");
322 return;
323 }
324
325 updateFrontendResources();
326 updateLnbResources();
327 // TODO: update Demux, Descrambler.
328 }
329
getTunerHalVersion(int * _aidl_return)330 Status TunerService::getTunerHalVersion(int* _aidl_return) {
331 hasITuner();
332 *_aidl_return = mTunerVersion;
333 return Status::ok();
334 }
335
updateFrontendResources()336 void TunerService::updateFrontendResources() {
337 hidl_vec<FrontendId> ids;
338 Result res = getHidlFrontendIds(ids);
339 if (res != Result::SUCCESS) {
340 return;
341 }
342 vector<TunerFrontendInfo> infos;
343 for (int i = 0; i < ids.size(); i++) {
344 FrontendInfo frontendInfo;
345 Result res = getHidlFrontendInfo((int)ids[i], frontendInfo);
346 if (res != Result::SUCCESS) {
347 continue;
348 }
349 TunerFrontendInfo tunerFrontendInfo{
350 .handle = getResourceHandleFromId((int)ids[i], FRONTEND),
351 .type = static_cast<int>(frontendInfo.type),
352 .exclusiveGroupId = static_cast<int>(frontendInfo.exclusiveGroupId),
353 };
354 infos.push_back(tunerFrontendInfo);
355 }
356 mTunerResourceManager->setFrontendInfoList(infos);
357 }
358
updateLnbResources()359 void TunerService::updateLnbResources() {
360 vector<int> handles = getLnbHandles();
361 if (handles.size() == 0) {
362 return;
363 }
364 mTunerResourceManager->setLnbInfoList(handles);
365 }
366
getLnbHandles()367 vector<int> TunerService::getLnbHandles() {
368 vector<int> lnbHandles;
369 if (mTuner != NULL) {
370 Result res;
371 vector<LnbId> lnbIds;
372 mTuner->getLnbIds([&](Result r, const hardware::hidl_vec<LnbId>& ids) {
373 lnbIds = ids;
374 res = r;
375 });
376 if (res != Result::SUCCESS || lnbIds.size() == 0) {
377 } else {
378 for (int i = 0; i < lnbIds.size(); i++) {
379 lnbHandles.push_back(getResourceHandleFromId((int)lnbIds[i], LNB));
380 }
381 }
382 }
383
384 return lnbHandles;
385 }
386
getHidlFrontendIds(hidl_vec<FrontendId> & ids)387 Result TunerService::getHidlFrontendIds(hidl_vec<FrontendId>& ids) {
388 if (mTuner == NULL) {
389 return Result::NOT_INITIALIZED;
390 }
391 Result res;
392 mTuner->getFrontendIds([&](Result r, const hidl_vec<FrontendId>& frontendIds) {
393 ids = frontendIds;
394 res = r;
395 });
396 return res;
397 }
398
getHidlFrontendInfo(int id,FrontendInfo & info)399 Result TunerService::getHidlFrontendInfo(int id, FrontendInfo& info) {
400 if (mTuner == NULL) {
401 return Result::NOT_INITIALIZED;
402 }
403 Result res;
404 mTuner->getFrontendInfo(id, [&](Result r, const FrontendInfo& feInfo) {
405 info = feInfo;
406 res = r;
407 });
408 return res;
409 }
410
getAidlDemuxCaps(DemuxCapabilities caps)411 TunerDemuxCapabilities TunerService::getAidlDemuxCaps(DemuxCapabilities caps) {
412 TunerDemuxCapabilities aidlCaps{
413 .numDemux = (int)caps.numDemux,
414 .numRecord = (int)caps.numRecord,
415 .numPlayback = (int)caps.numPlayback,
416 .numTsFilter = (int)caps.numTsFilter,
417 .numSectionFilter = (int)caps.numSectionFilter,
418 .numAudioFilter = (int)caps.numAudioFilter,
419 .numVideoFilter = (int)caps.numVideoFilter,
420 .numPesFilter = (int)caps.numPesFilter,
421 .numPcrFilter = (int)caps.numPcrFilter,
422 .numBytesInSectionFilter = (int)caps.numBytesInSectionFilter,
423 .filterCaps = (int)caps.filterCaps,
424 .bTimeFilter = caps.bTimeFilter,
425 };
426 aidlCaps.linkCaps.resize(caps.linkCaps.size());
427 copy(caps.linkCaps.begin(), caps.linkCaps.end(), aidlCaps.linkCaps.begin());
428 return aidlCaps;
429 }
430
convertToAidlFrontendInfo(FrontendInfo halInfo)431 TunerFrontendInfo TunerService::convertToAidlFrontendInfo(FrontendInfo halInfo) {
432 TunerFrontendInfo info{
433 .type = (int)halInfo.type,
434 .minFrequency = (int)halInfo.minFrequency,
435 .maxFrequency = (int)halInfo.maxFrequency,
436 .minSymbolRate = (int)halInfo.minSymbolRate,
437 .maxSymbolRate = (int)halInfo.maxSymbolRate,
438 .acquireRange = (int)halInfo.acquireRange,
439 .exclusiveGroupId = (int)halInfo.exclusiveGroupId,
440 };
441 for (int i = 0; i < halInfo.statusCaps.size(); i++) {
442 info.statusCaps.push_back((int)halInfo.statusCaps[i]);
443 }
444
445 TunerFrontendCapabilities caps;
446 switch (halInfo.type) {
447 case FrontendType::ANALOG: {
448 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::analogCaps
449 == halInfo.frontendCaps.getDiscriminator()) {
450 TunerFrontendAnalogCapabilities analogCaps{
451 .typeCap = (int)halInfo.frontendCaps.analogCaps().typeCap,
452 .sifStandardCap = (int)halInfo.frontendCaps.analogCaps().sifStandardCap,
453 };
454 caps.set<TunerFrontendCapabilities::analogCaps>(analogCaps);
455 }
456 break;
457 }
458 case FrontendType::ATSC: {
459 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::atscCaps
460 == halInfo.frontendCaps.getDiscriminator()) {
461 TunerFrontendAtscCapabilities atscCaps{
462 .modulationCap = (int)halInfo.frontendCaps.atscCaps().modulationCap,
463 };
464 caps.set<TunerFrontendCapabilities::atscCaps>(atscCaps);
465 }
466 break;
467 }
468 case FrontendType::ATSC3: {
469 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::atsc3Caps
470 == halInfo.frontendCaps.getDiscriminator()) {
471 TunerFrontendAtsc3Capabilities atsc3Caps{
472 .bandwidthCap = (int)halInfo.frontendCaps.atsc3Caps().bandwidthCap,
473 .modulationCap = (int)halInfo.frontendCaps.atsc3Caps().modulationCap,
474 .timeInterleaveModeCap =
475 (int)halInfo.frontendCaps.atsc3Caps().timeInterleaveModeCap,
476 .codeRateCap = (int)halInfo.frontendCaps.atsc3Caps().codeRateCap,
477 .demodOutputFormatCap
478 = (int)halInfo.frontendCaps.atsc3Caps().demodOutputFormatCap,
479 .fecCap = (int)halInfo.frontendCaps.atsc3Caps().fecCap,
480 };
481 caps.set<TunerFrontendCapabilities::atsc3Caps>(atsc3Caps);
482 }
483 break;
484 }
485 case FrontendType::DVBC: {
486 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::dvbcCaps
487 == halInfo.frontendCaps.getDiscriminator()) {
488 TunerFrontendCableCapabilities cableCaps{
489 .modulationCap = (int)halInfo.frontendCaps.dvbcCaps().modulationCap,
490 .codeRateCap = (int64_t)halInfo.frontendCaps.dvbcCaps().fecCap,
491 .annexCap = (int)halInfo.frontendCaps.dvbcCaps().annexCap,
492 };
493 caps.set<TunerFrontendCapabilities::cableCaps>(cableCaps);
494 }
495 break;
496 }
497 case FrontendType::DVBS: {
498 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::dvbsCaps
499 == halInfo.frontendCaps.getDiscriminator()) {
500 TunerFrontendDvbsCapabilities dvbsCaps{
501 .modulationCap = (int)halInfo.frontendCaps.dvbsCaps().modulationCap,
502 .codeRateCap = (long)halInfo.frontendCaps.dvbsCaps().innerfecCap,
503 .standard = (int)halInfo.frontendCaps.dvbsCaps().standard,
504 };
505 caps.set<TunerFrontendCapabilities::dvbsCaps>(dvbsCaps);
506 }
507 break;
508 }
509 case FrontendType::DVBT: {
510 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::dvbtCaps
511 == halInfo.frontendCaps.getDiscriminator()) {
512 TunerFrontendDvbtCapabilities dvbtCaps{
513 .transmissionModeCap = (int)halInfo.frontendCaps.dvbtCaps().transmissionModeCap,
514 .bandwidthCap = (int)halInfo.frontendCaps.dvbtCaps().bandwidthCap,
515 .constellationCap = (int)halInfo.frontendCaps.dvbtCaps().constellationCap,
516 .codeRateCap = (int)halInfo.frontendCaps.dvbtCaps().coderateCap,
517 .hierarchyCap = (int)halInfo.frontendCaps.dvbtCaps().hierarchyCap,
518 .guardIntervalCap = (int)halInfo.frontendCaps.dvbtCaps().guardIntervalCap,
519 .isT2Supported = (bool)halInfo.frontendCaps.dvbtCaps().isT2Supported,
520 .isMisoSupported = (bool)halInfo.frontendCaps.dvbtCaps().isMisoSupported,
521 };
522 caps.set<TunerFrontendCapabilities::dvbtCaps>(dvbtCaps);
523 }
524 break;
525 }
526 case FrontendType::ISDBS: {
527 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::isdbsCaps
528 == halInfo.frontendCaps.getDiscriminator()) {
529 TunerFrontendIsdbsCapabilities isdbsCaps{
530 .modulationCap = (int)halInfo.frontendCaps.isdbsCaps().modulationCap,
531 .codeRateCap = (int)halInfo.frontendCaps.isdbsCaps().coderateCap,
532 };
533 caps.set<TunerFrontendCapabilities::isdbsCaps>(isdbsCaps);
534 }
535 break;
536 }
537 case FrontendType::ISDBS3: {
538 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::isdbs3Caps
539 == halInfo.frontendCaps.getDiscriminator()) {
540 TunerFrontendIsdbs3Capabilities isdbs3Caps{
541 .modulationCap = (int)halInfo.frontendCaps.isdbs3Caps().modulationCap,
542 .codeRateCap = (int)halInfo.frontendCaps.isdbs3Caps().coderateCap,
543 };
544 caps.set<TunerFrontendCapabilities::isdbs3Caps>(isdbs3Caps);
545 }
546 break;
547 }
548 case FrontendType::ISDBT: {
549 if (FrontendInfo::FrontendCapabilities::hidl_discriminator::isdbtCaps
550 == halInfo.frontendCaps.getDiscriminator()) {
551 TunerFrontendIsdbtCapabilities isdbtCaps{
552 .modeCap = (int)halInfo.frontendCaps.isdbtCaps().modeCap,
553 .bandwidthCap = (int)halInfo.frontendCaps.isdbtCaps().bandwidthCap,
554 .modulationCap = (int)halInfo.frontendCaps.isdbtCaps().modulationCap,
555 .codeRateCap = (int)halInfo.frontendCaps.isdbtCaps().coderateCap,
556 .guardIntervalCap = (int)halInfo.frontendCaps.isdbtCaps().guardIntervalCap,
557 };
558 caps.set<TunerFrontendCapabilities::isdbtCaps>(isdbtCaps);
559 }
560 break;
561 }
562 default:
563 break;
564 }
565
566 info.caps = caps;
567 return info;
568 }
569 } // namespace android
570