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