712 lines
28 KiB
C++
712 lines
28 KiB
C++
/**
|
|
* Copyright (c) 2021, The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
//#define LOG_NDEBUG 0
|
|
#define LOG_TAG "TunerHidlService"
|
|
|
|
#include "TunerHidlService.h"
|
|
|
|
#include <aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.h>
|
|
#include <aidl/android/hardware/tv/tuner/Result.h>
|
|
#include <android/binder_manager.h>
|
|
#include <binder/IPCThreadState.h>
|
|
#include <binder/PermissionCache.h>
|
|
#include <utils/Log.h>
|
|
|
|
#include "TunerHelper.h"
|
|
#include "TunerHidlDemux.h"
|
|
#include "TunerHidlDescrambler.h"
|
|
#include "TunerHidlFrontend.h"
|
|
#include "TunerHidlLnb.h"
|
|
|
|
using ::aidl::android::hardware::tv::tuner::FrontendAnalogCapabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendAtsc3Capabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendAtscCapabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendCapabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendDtmbCapabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendDvbcCapabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendDvbsCapabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendDvbtCapabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendIsdbs3Capabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendIsdbsCapabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendIsdbtCapabilities;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendIsdbtTimeInterleaveMode;
|
|
using ::aidl::android::hardware::tv::tuner::FrontendType;
|
|
using ::aidl::android::hardware::tv::tuner::Result;
|
|
using ::aidl::android::media::tv::tunerresourcemanager::TunerFrontendInfo;
|
|
using ::android::IPCThreadState;
|
|
using ::android::PermissionCache;
|
|
using ::android::hardware::hidl_vec;
|
|
|
|
using HidlFrontendId = ::android::hardware::tv::tuner::V1_0::FrontendId;
|
|
using HidlLnbId = ::android::hardware::tv::tuner::V1_0::LnbId;
|
|
using HidlFrontendType = ::android::hardware::tv::tuner::V1_1::FrontendType;
|
|
|
|
using namespace std;
|
|
|
|
namespace aidl {
|
|
namespace android {
|
|
namespace media {
|
|
namespace tv {
|
|
namespace tuner {
|
|
|
|
shared_ptr<TunerHidlService> TunerHidlService::sTunerService = nullptr;
|
|
|
|
TunerHidlService::TunerHidlService() {
|
|
if (!TunerHelper::checkTunerFeature()) {
|
|
ALOGD("Device doesn't have tuner hardware.");
|
|
return;
|
|
}
|
|
|
|
updateTunerResources();
|
|
}
|
|
|
|
TunerHidlService::~TunerHidlService() {
|
|
mOpenedFrontends.clear();
|
|
mLnaStatus = -1;
|
|
}
|
|
|
|
binder_status_t TunerHidlService::instantiate() {
|
|
if (HidlITuner::getService() == nullptr) {
|
|
ALOGD("Failed to get ITuner HIDL HAL");
|
|
return STATUS_NAME_NOT_FOUND;
|
|
}
|
|
|
|
sTunerService = ::ndk::SharedRefBase::make<TunerHidlService>();
|
|
return AServiceManager_addService(sTunerService->asBinder().get(), getServiceName());
|
|
}
|
|
|
|
shared_ptr<TunerHidlService> TunerHidlService::getTunerService() {
|
|
return sTunerService;
|
|
}
|
|
|
|
bool TunerHidlService::hasITuner() {
|
|
ALOGV("hasITuner");
|
|
if (mTuner != nullptr) {
|
|
return true;
|
|
}
|
|
|
|
mTuner = HidlITuner::getService();
|
|
if (mTuner == nullptr) {
|
|
ALOGE("Failed to get ITuner service");
|
|
return false;
|
|
}
|
|
mTunerVersion = TUNER_HAL_VERSION_1_0;
|
|
|
|
mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::castFrom(mTuner);
|
|
if (mTuner_1_1 != nullptr) {
|
|
mTunerVersion = TUNER_HAL_VERSION_1_1;
|
|
} else {
|
|
ALOGD("Failed to get ITuner_1_1 service");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool TunerHidlService::hasITuner_1_1() {
|
|
ALOGV("hasITuner_1_1");
|
|
hasITuner();
|
|
return (mTunerVersion == TUNER_HAL_VERSION_1_1);
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::openDemux(int32_t /* in_demuxHandle */,
|
|
shared_ptr<ITunerDemux>* _aidl_return) {
|
|
ALOGV("openDemux");
|
|
if (!hasITuner()) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
HidlResult res;
|
|
uint32_t id;
|
|
sp<IDemux> demuxSp = nullptr;
|
|
mTuner->openDemux([&](HidlResult r, uint32_t demuxId, const sp<IDemux>& demux) {
|
|
demuxSp = demux;
|
|
id = demuxId;
|
|
res = r;
|
|
ALOGD("open demux, id = %d", demuxId);
|
|
});
|
|
if (res == HidlResult::SUCCESS) {
|
|
*_aidl_return = ::ndk::SharedRefBase::make<TunerHidlDemux>(demuxSp, id);
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
ALOGW("open demux failed, res = %d", res);
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::getDemuxCaps(DemuxCapabilities* _aidl_return) {
|
|
ALOGV("getDemuxCaps");
|
|
if (!hasITuner()) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
HidlResult res;
|
|
HidlDemuxCapabilities caps;
|
|
mTuner->getDemuxCaps([&](HidlResult r, const HidlDemuxCapabilities& demuxCaps) {
|
|
caps = demuxCaps;
|
|
res = r;
|
|
});
|
|
if (res == HidlResult::SUCCESS) {
|
|
*_aidl_return = getAidlDemuxCaps(caps);
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
ALOGW("Get demux caps failed, res = %d", res);
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::getFrontendIds(vector<int32_t>* ids) {
|
|
if (!hasITuner()) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
hidl_vec<HidlFrontendId> feIds;
|
|
HidlResult res = getHidlFrontendIds(feIds);
|
|
if (res != HidlResult::SUCCESS) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
|
|
}
|
|
ids->resize(feIds.size());
|
|
copy(feIds.begin(), feIds.end(), ids->begin());
|
|
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::getFrontendInfo(int32_t id, FrontendInfo* _aidl_return) {
|
|
if (!hasITuner()) {
|
|
ALOGE("ITuner service is not init.");
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
HidlFrontendInfo info;
|
|
HidlResult res = getHidlFrontendInfo(id, info);
|
|
if (res != HidlResult::SUCCESS) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
|
|
}
|
|
|
|
HidlFrontendDtmbCapabilities dtmbCaps;
|
|
if (static_cast<HidlFrontendType>(info.type) == HidlFrontendType::DTMB) {
|
|
if (!hasITuner_1_1()) {
|
|
ALOGE("ITuner_1_1 service is not init.");
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
mTuner_1_1->getFrontendDtmbCapabilities(
|
|
id, [&](HidlResult r, const HidlFrontendDtmbCapabilities& caps) {
|
|
dtmbCaps = caps;
|
|
res = r;
|
|
});
|
|
if (res != HidlResult::SUCCESS) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
|
|
}
|
|
}
|
|
|
|
*_aidl_return = getAidlFrontendInfo(info, dtmbCaps);
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::openFrontend(int32_t frontendHandle,
|
|
shared_ptr<ITunerFrontend>* _aidl_return) {
|
|
if (!hasITuner()) {
|
|
ALOGE("ITuner service is not init.");
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
HidlResult status;
|
|
sp<HidlIFrontend> frontend;
|
|
int id = TunerHelper::getResourceIdFromHandle(frontendHandle, FRONTEND);
|
|
mTuner->openFrontendById(id, [&](HidlResult result, const sp<HidlIFrontend>& fe) {
|
|
frontend = fe;
|
|
status = result;
|
|
});
|
|
if (status != HidlResult::SUCCESS) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
|
|
}
|
|
|
|
shared_ptr<TunerHidlFrontend> tunerFrontend =
|
|
::ndk::SharedRefBase::make<TunerHidlFrontend>(frontend, id);
|
|
if (mLnaStatus != -1) {
|
|
tunerFrontend->setLna(mLnaStatus == 1);
|
|
}
|
|
{
|
|
Mutex::Autolock _l(mOpenedFrontendsLock);
|
|
mOpenedFrontends.insert(tunerFrontend);
|
|
}
|
|
*_aidl_return = tunerFrontend;
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
|
|
if (!hasITuner()) {
|
|
ALOGD("get ITuner failed");
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
HidlResult status;
|
|
sp<HidlILnb> lnb;
|
|
int id = TunerHelper::getResourceIdFromHandle(lnbHandle, LNB);
|
|
mTuner->openLnbById(id, [&](HidlResult result, const sp<HidlILnb>& lnbSp) {
|
|
lnb = lnbSp;
|
|
status = result;
|
|
});
|
|
if (status != HidlResult::SUCCESS) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
|
|
}
|
|
|
|
*_aidl_return = ::ndk::SharedRefBase::make<TunerHidlLnb>(lnb, id);
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::openLnbByName(const string& lnbName,
|
|
shared_ptr<ITunerLnb>* _aidl_return) {
|
|
if (!hasITuner()) {
|
|
ALOGE("get ITuner failed");
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
int lnbId;
|
|
HidlResult status;
|
|
sp<HidlILnb> lnb;
|
|
mTuner->openLnbByName(lnbName, [&](HidlResult r, HidlLnbId id, const sp<HidlILnb>& lnbSp) {
|
|
status = r;
|
|
lnb = lnbSp;
|
|
lnbId = static_cast<int32_t>(id);
|
|
});
|
|
if (status != HidlResult::SUCCESS) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
|
|
}
|
|
|
|
*_aidl_return = ::ndk::SharedRefBase::make<TunerHidlLnb>(lnb, lnbId);
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::openDescrambler(
|
|
int32_t /*descramblerHandle*/, shared_ptr<ITunerDescrambler>* _aidl_return) {
|
|
if (!hasITuner()) {
|
|
ALOGD("get ITuner failed");
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
HidlResult status;
|
|
sp<HidlIDescrambler> descrambler;
|
|
//int id = TunerHelper::getResourceIdFromHandle(descramblerHandle, DESCRAMBLER);
|
|
mTuner->openDescrambler([&](HidlResult r, const sp<HidlIDescrambler>& descramblerSp) {
|
|
status = r;
|
|
descrambler = descramblerSp;
|
|
});
|
|
if (status != HidlResult::SUCCESS) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
|
|
}
|
|
|
|
*_aidl_return = ::ndk::SharedRefBase::make<TunerHidlDescrambler>(descrambler);
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::getTunerHalVersion(int* _aidl_return) {
|
|
hasITuner();
|
|
*_aidl_return = mTunerVersion;
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::openSharedFilter(
|
|
const string& in_filterToken, const shared_ptr<ITunerFilterCallback>& in_cb,
|
|
shared_ptr<ITunerFilter>* _aidl_return) {
|
|
if (!hasITuner()) {
|
|
ALOGE("get ITuner failed");
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
if (!PermissionCache::checkCallingPermission(sSharedFilterPermission)) {
|
|
ALOGE("Request requires android.permission.ACCESS_TV_SHARED_FILTER");
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
Mutex::Autolock _l(mSharedFiltersLock);
|
|
if (mSharedFilters.find(in_filterToken) == mSharedFilters.end()) {
|
|
*_aidl_return = nullptr;
|
|
ALOGD("fail to find %s", in_filterToken.c_str());
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::INVALID_STATE));
|
|
}
|
|
|
|
shared_ptr<TunerHidlFilter> filter = mSharedFilters.at(in_filterToken);
|
|
IPCThreadState* ipc = IPCThreadState::self();
|
|
const int pid = ipc->getCallingPid();
|
|
if (!filter->isSharedFilterAllowed(pid)) {
|
|
*_aidl_return = nullptr;
|
|
ALOGD("shared filter %s is opened in the same process", in_filterToken.c_str());
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::INVALID_STATE));
|
|
}
|
|
|
|
filter->attachSharedFilterCallback(in_cb);
|
|
|
|
*_aidl_return = filter;
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::setLna(bool bEnable) {
|
|
if (!hasITuner()) {
|
|
ALOGE("get ITuner failed");
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
mLnaStatus = bEnable ? 1 : 0;
|
|
|
|
{
|
|
Mutex::Autolock _l(mOpenedFrontendsLock);
|
|
for (auto it = mOpenedFrontends.begin(); it != mOpenedFrontends.end(); ++it) {
|
|
(*it)->setLna(mLnaStatus == 1);
|
|
}
|
|
}
|
|
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::setMaxNumberOfFrontends(FrontendType /* in_frontendType */,
|
|
int32_t /* in_maxNumber */) {
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
::ndk::ScopedAStatus TunerHidlService::getMaxNumberOfFrontends(FrontendType /* in_frontendType */,
|
|
int32_t* _aidl_return) {
|
|
*_aidl_return = -1;
|
|
return ::ndk::ScopedAStatus::fromServiceSpecificError(
|
|
static_cast<int32_t>(Result::UNAVAILABLE));
|
|
}
|
|
|
|
string TunerHidlService::addFilterToShared(const shared_ptr<TunerHidlFilter>& sharedFilter) {
|
|
Mutex::Autolock _l(mSharedFiltersLock);
|
|
|
|
// Use sharedFilter address as token.
|
|
string token = to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get()));
|
|
mSharedFilters[token] = sharedFilter;
|
|
|
|
return token;
|
|
}
|
|
|
|
void TunerHidlService::removeSharedFilter(const shared_ptr<TunerHidlFilter>& sharedFilter) {
|
|
Mutex::Autolock _l(mSharedFiltersLock);
|
|
|
|
// Use sharedFilter address as token.
|
|
mSharedFilters.erase(to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get())));
|
|
}
|
|
|
|
void TunerHidlService::removeFrontend(const shared_ptr<TunerHidlFrontend>& frontend) {
|
|
Mutex::Autolock _l(mOpenedFrontendsLock);
|
|
for (auto it = mOpenedFrontends.begin(); it != mOpenedFrontends.end(); ++it) {
|
|
if (it->get() == frontend.get()) {
|
|
mOpenedFrontends.erase(it);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TunerHidlService::updateTunerResources() {
|
|
if (!hasITuner()) {
|
|
ALOGE("Failed to updateTunerResources");
|
|
return;
|
|
}
|
|
|
|
TunerHelper::updateTunerResources(getTRMFrontendInfos(), getTRMLnbHandles());
|
|
}
|
|
|
|
vector<TunerFrontendInfo> TunerHidlService::getTRMFrontendInfos() {
|
|
vector<TunerFrontendInfo> infos;
|
|
hidl_vec<HidlFrontendId> ids;
|
|
HidlResult res = getHidlFrontendIds(ids);
|
|
if (res != HidlResult::SUCCESS) {
|
|
return infos;
|
|
}
|
|
|
|
for (int i = 0; i < ids.size(); i++) {
|
|
HidlFrontendInfo frontendInfo;
|
|
HidlResult res = getHidlFrontendInfo(static_cast<int32_t>(ids[i]), frontendInfo);
|
|
if (res != HidlResult::SUCCESS) {
|
|
continue;
|
|
}
|
|
TunerFrontendInfo tunerFrontendInfo{
|
|
.handle = TunerHelper::getResourceHandleFromId(static_cast<int32_t>(ids[i]),
|
|
FRONTEND),
|
|
.type = static_cast<int32_t>(frontendInfo.type),
|
|
.exclusiveGroupId = static_cast<int32_t>(frontendInfo.exclusiveGroupId),
|
|
};
|
|
infos.push_back(tunerFrontendInfo);
|
|
}
|
|
|
|
return infos;
|
|
}
|
|
|
|
vector<int32_t> TunerHidlService::getTRMLnbHandles() {
|
|
vector<int32_t> lnbHandles;
|
|
if (mTuner != nullptr) {
|
|
HidlResult res;
|
|
vector<HidlLnbId> lnbIds;
|
|
mTuner->getLnbIds([&](HidlResult r, const hidl_vec<HidlLnbId>& ids) {
|
|
lnbIds = ids;
|
|
res = r;
|
|
});
|
|
if (res == HidlResult::SUCCESS && lnbIds.size() > 0) {
|
|
for (int i = 0; i < lnbIds.size(); i++) {
|
|
lnbHandles.push_back(
|
|
TunerHelper::getResourceHandleFromId(static_cast<int32_t>(lnbIds[i]), LNB));
|
|
}
|
|
}
|
|
}
|
|
|
|
return lnbHandles;
|
|
}
|
|
|
|
HidlResult TunerHidlService::getHidlFrontendIds(hidl_vec<HidlFrontendId>& ids) {
|
|
if (mTuner == nullptr) {
|
|
return HidlResult::NOT_INITIALIZED;
|
|
}
|
|
HidlResult res;
|
|
mTuner->getFrontendIds([&](HidlResult r, const hidl_vec<HidlFrontendId>& frontendIds) {
|
|
ids = frontendIds;
|
|
res = r;
|
|
});
|
|
return res;
|
|
}
|
|
|
|
HidlResult TunerHidlService::getHidlFrontendInfo(const int id, HidlFrontendInfo& info) {
|
|
if (mTuner == nullptr) {
|
|
return HidlResult::NOT_INITIALIZED;
|
|
}
|
|
HidlResult res;
|
|
mTuner->getFrontendInfo(id, [&](HidlResult r, const HidlFrontendInfo& feInfo) {
|
|
info = feInfo;
|
|
res = r;
|
|
});
|
|
return res;
|
|
}
|
|
|
|
DemuxCapabilities TunerHidlService::getAidlDemuxCaps(const HidlDemuxCapabilities& caps) {
|
|
DemuxCapabilities aidlCaps{
|
|
.numDemux = static_cast<int32_t>(caps.numDemux),
|
|
.numRecord = static_cast<int32_t>(caps.numRecord),
|
|
.numPlayback = static_cast<int32_t>(caps.numPlayback),
|
|
.numTsFilter = static_cast<int32_t>(caps.numTsFilter),
|
|
.numSectionFilter = static_cast<int32_t>(caps.numSectionFilter),
|
|
.numAudioFilter = static_cast<int32_t>(caps.numAudioFilter),
|
|
.numVideoFilter = static_cast<int32_t>(caps.numVideoFilter),
|
|
.numPesFilter = static_cast<int32_t>(caps.numPesFilter),
|
|
.numPcrFilter = static_cast<int32_t>(caps.numPcrFilter),
|
|
.numBytesInSectionFilter = static_cast<int64_t>(caps.numBytesInSectionFilter),
|
|
.filterCaps = static_cast<int32_t>(caps.filterCaps),
|
|
.bTimeFilter = caps.bTimeFilter,
|
|
};
|
|
aidlCaps.linkCaps.resize(caps.linkCaps.size());
|
|
copy(caps.linkCaps.begin(), caps.linkCaps.end(), aidlCaps.linkCaps.begin());
|
|
return aidlCaps;
|
|
}
|
|
|
|
FrontendInfo TunerHidlService::getAidlFrontendInfo(
|
|
const HidlFrontendInfo& halInfo, const HidlFrontendDtmbCapabilities& halDtmbCaps) {
|
|
FrontendInfo info{
|
|
.type = static_cast<FrontendType>(halInfo.type),
|
|
.minFrequency = static_cast<int64_t>(halInfo.minFrequency),
|
|
.maxFrequency = static_cast<int64_t>(halInfo.maxFrequency),
|
|
.minSymbolRate = static_cast<int32_t>(halInfo.minSymbolRate),
|
|
.maxSymbolRate = static_cast<int32_t>(halInfo.maxSymbolRate),
|
|
.acquireRange = static_cast<int64_t>(halInfo.acquireRange),
|
|
.exclusiveGroupId = static_cast<int32_t>(halInfo.exclusiveGroupId),
|
|
};
|
|
for (int i = 0; i < halInfo.statusCaps.size(); i++) {
|
|
info.statusCaps.push_back(static_cast<FrontendStatusType>(halInfo.statusCaps[i]));
|
|
}
|
|
|
|
FrontendCapabilities caps;
|
|
switch (halInfo.type) {
|
|
case ::android::hardware::tv::tuner::V1_0::FrontendType::ANALOG: {
|
|
if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::analogCaps ==
|
|
halInfo.frontendCaps.getDiscriminator()) {
|
|
FrontendAnalogCapabilities analogCaps{
|
|
.typeCap = static_cast<int32_t>(halInfo.frontendCaps.analogCaps().typeCap),
|
|
.sifStandardCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.analogCaps().sifStandardCap),
|
|
};
|
|
caps.set<FrontendCapabilities::analogCaps>(analogCaps);
|
|
}
|
|
break;
|
|
}
|
|
case ::android::hardware::tv::tuner::V1_0::FrontendType::ATSC: {
|
|
if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::atscCaps ==
|
|
halInfo.frontendCaps.getDiscriminator()) {
|
|
FrontendAtscCapabilities atscCaps{
|
|
.modulationCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.atscCaps().modulationCap),
|
|
};
|
|
caps.set<FrontendCapabilities::atscCaps>(atscCaps);
|
|
}
|
|
break;
|
|
}
|
|
case ::android::hardware::tv::tuner::V1_0::FrontendType::ATSC3: {
|
|
if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::atsc3Caps ==
|
|
halInfo.frontendCaps.getDiscriminator()) {
|
|
FrontendAtsc3Capabilities atsc3Caps{
|
|
.bandwidthCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.atsc3Caps().bandwidthCap),
|
|
.modulationCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.atsc3Caps().modulationCap),
|
|
.timeInterleaveModeCap = static_cast<int32_t>(
|
|
halInfo.frontendCaps.atsc3Caps().timeInterleaveModeCap),
|
|
.codeRateCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.atsc3Caps().codeRateCap),
|
|
.demodOutputFormatCap = static_cast<int8_t>(
|
|
halInfo.frontendCaps.atsc3Caps().demodOutputFormatCap),
|
|
.fecCap = static_cast<int32_t>(halInfo.frontendCaps.atsc3Caps().fecCap),
|
|
};
|
|
caps.set<FrontendCapabilities::atsc3Caps>(atsc3Caps);
|
|
}
|
|
break;
|
|
}
|
|
case ::android::hardware::tv::tuner::V1_0::FrontendType::DVBC: {
|
|
if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::dvbcCaps ==
|
|
halInfo.frontendCaps.getDiscriminator()) {
|
|
FrontendDvbcCapabilities dvbcCaps{
|
|
.modulationCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.dvbcCaps().modulationCap),
|
|
.fecCap = static_cast<int64_t>(halInfo.frontendCaps.dvbcCaps().fecCap),
|
|
.annexCap = static_cast<int8_t>(halInfo.frontendCaps.dvbcCaps().annexCap),
|
|
};
|
|
caps.set<FrontendCapabilities::dvbcCaps>(dvbcCaps);
|
|
}
|
|
break;
|
|
}
|
|
case ::android::hardware::tv::tuner::V1_0::FrontendType::DVBS: {
|
|
if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::dvbsCaps ==
|
|
halInfo.frontendCaps.getDiscriminator()) {
|
|
FrontendDvbsCapabilities dvbsCaps{
|
|
.modulationCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.dvbsCaps().modulationCap),
|
|
.innerfecCap =
|
|
static_cast<int64_t>(halInfo.frontendCaps.dvbsCaps().innerfecCap),
|
|
.standard = static_cast<int8_t>(halInfo.frontendCaps.dvbsCaps().standard),
|
|
};
|
|
caps.set<FrontendCapabilities::dvbsCaps>(dvbsCaps);
|
|
}
|
|
break;
|
|
}
|
|
case ::android::hardware::tv::tuner::V1_0::FrontendType::DVBT: {
|
|
if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::dvbtCaps ==
|
|
halInfo.frontendCaps.getDiscriminator()) {
|
|
FrontendDvbtCapabilities dvbtCaps{
|
|
.transmissionModeCap = static_cast<int32_t>(
|
|
halInfo.frontendCaps.dvbtCaps().transmissionModeCap),
|
|
.bandwidthCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().bandwidthCap),
|
|
.constellationCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().constellationCap),
|
|
.coderateCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().coderateCap),
|
|
.hierarchyCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().hierarchyCap),
|
|
.guardIntervalCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.dvbtCaps().guardIntervalCap),
|
|
.isT2Supported = halInfo.frontendCaps.dvbtCaps().isT2Supported,
|
|
.isMisoSupported = halInfo.frontendCaps.dvbtCaps().isMisoSupported,
|
|
};
|
|
caps.set<FrontendCapabilities::dvbtCaps>(dvbtCaps);
|
|
}
|
|
break;
|
|
}
|
|
case ::android::hardware::tv::tuner::V1_0::FrontendType::ISDBS: {
|
|
if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::isdbsCaps ==
|
|
halInfo.frontendCaps.getDiscriminator()) {
|
|
FrontendIsdbsCapabilities isdbsCaps{
|
|
.modulationCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.isdbsCaps().modulationCap),
|
|
.coderateCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.isdbsCaps().coderateCap),
|
|
};
|
|
caps.set<FrontendCapabilities::isdbsCaps>(isdbsCaps);
|
|
}
|
|
break;
|
|
}
|
|
case ::android::hardware::tv::tuner::V1_0::FrontendType::ISDBS3: {
|
|
if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::isdbs3Caps ==
|
|
halInfo.frontendCaps.getDiscriminator()) {
|
|
FrontendIsdbs3Capabilities isdbs3Caps{
|
|
.modulationCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.isdbs3Caps().modulationCap),
|
|
.coderateCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.isdbs3Caps().coderateCap),
|
|
};
|
|
caps.set<FrontendCapabilities::isdbs3Caps>(isdbs3Caps);
|
|
}
|
|
break;
|
|
}
|
|
case ::android::hardware::tv::tuner::V1_0::FrontendType::ISDBT: {
|
|
if (HidlFrontendInfo::FrontendCapabilities::hidl_discriminator::isdbtCaps ==
|
|
halInfo.frontendCaps.getDiscriminator()) {
|
|
FrontendIsdbtCapabilities isdbtCaps{
|
|
.modeCap = static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().modeCap),
|
|
.bandwidthCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().bandwidthCap),
|
|
.modulationCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().modulationCap),
|
|
.coderateCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().coderateCap),
|
|
.guardIntervalCap =
|
|
static_cast<int32_t>(halInfo.frontendCaps.isdbtCaps().guardIntervalCap),
|
|
.timeInterleaveCap =
|
|
static_cast<int32_t>(FrontendIsdbtTimeInterleaveMode::UNDEFINED),
|
|
.isSegmentAuto = false,
|
|
.isFullSegment = false,
|
|
};
|
|
caps.set<FrontendCapabilities::isdbtCaps>(isdbtCaps);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (static_cast<HidlFrontendType>(info.type) == HidlFrontendType::DTMB) {
|
|
FrontendDtmbCapabilities dtmbCaps{
|
|
.transmissionModeCap = static_cast<int32_t>(halDtmbCaps.transmissionModeCap),
|
|
.bandwidthCap = static_cast<int32_t>(halDtmbCaps.bandwidthCap),
|
|
.modulationCap = static_cast<int32_t>(halDtmbCaps.modulationCap),
|
|
.codeRateCap = static_cast<int32_t>(halDtmbCaps.codeRateCap),
|
|
.guardIntervalCap = static_cast<int32_t>(halDtmbCaps.guardIntervalCap),
|
|
.interleaveModeCap = static_cast<int32_t>(halDtmbCaps.interleaveModeCap),
|
|
};
|
|
caps.set<FrontendCapabilities::dtmbCaps>(dtmbCaps);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
info.frontendCaps = caps;
|
|
return info;
|
|
}
|
|
|
|
} // namespace tuner
|
|
} // namespace tv
|
|
} // namespace media
|
|
} // namespace android
|
|
} // namespace aidl
|