• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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