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