Support frontend status readiness query.

The caller could use it to check whether frontend status is ready to
read or not.

Bug: 171540820
Test: atest VtsHalTvTunerTargetTest
Change-Id: I65521aacd8afe824342ad0b24f7d89006ceb5851
This commit is contained in:
Hongguang
2022-01-14 13:23:37 -08:00
parent 36f893bfc5
commit 881190f810
11 changed files with 346 additions and 158 deletions

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2022 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.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.tv.tuner;
/* @hide */
@Backing(type="int") @VintfStability
enum FrontendStatusReadiness {
UNDEFINED = 0,
UNAVAILABLE = 1,
UNSTABLE = 2,
STABLE = 3,
UNSUPPORTED = 4,
}

View File

@@ -47,4 +47,5 @@ interface IFrontend {
void unlinkCiCam(in int ciCamId);
String getHardwareInfo();
void removeOutputPid(int pid);
android.hardware.tv.tuner.FrontendStatusReadiness[] getFrontendStatusReadiness(in android.hardware.tv.tuner.FrontendStatusType[] statusTypes);
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2022 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.
*/
package android.hardware.tv.tuner;
/**
* FrontendStatus readiness status.
* @hide
*/
@VintfStability
@Backing(type="int")
enum FrontendStatusReadiness {
/**
* The FrontendStatus readiness status for the given FrontendStatusType is
* undefined.
*/
UNDEFINED,
/**
* The FrontendStatus for the given FrontendStatusType is currently
* unavailable.
*/
UNAVAILABLE,
/**
* The FrontendStatus for the given FrontendStatusType can be read, but its
* unstable.
*/
UNSTABLE,
/**
* The FrontendStatus for the given FrontendStatusType can be ready, and its
* stable.
*/
STABLE,
/**
* The FrontendStatus for the given FrontendStatusType is not supported.
*/
UNSUPPORTED,
}

View File

@@ -19,6 +19,7 @@ package android.hardware.tv.tuner;
import android.hardware.tv.tuner.FrontendScanType;
import android.hardware.tv.tuner.FrontendSettings;
import android.hardware.tv.tuner.FrontendStatus;
import android.hardware.tv.tuner.FrontendStatusReadiness;
import android.hardware.tv.tuner.FrontendStatusType;
import android.hardware.tv.tuner.IFrontendCallback;
@@ -155,4 +156,14 @@ interface IFrontend {
* @return UNAVAILABLE if the frontend doesnt support PID filtering out.
*/
void removeOutputPid(int pid);
/**
* Gets FrontendStatus readiness statuses for given status types.
*
* @param statusTypes an array of status types.
*
* @return an array of current readiness statuses. The ith readiness status in
* the array presents fronted type statusTypes[i]s readiness status.
*/
FrontendStatusReadiness[] getFrontendStatusReadiness(in FrontendStatusType[] statusTypes);
}

View File

@@ -34,6 +34,140 @@ Frontend::Frontend(FrontendType type, int32_t id, std::shared_ptr<Tuner> tuner)
mTuner = tuner;
// Init callback to nullptr
mCallback = nullptr;
switch (mType) {
case FrontendType::ISDBS: {
mFrontendCaps.set<FrontendCapabilities::Tag::isdbsCaps>(FrontendIsdbsCapabilities());
mFrontendStatusCaps = {
FrontendStatusType::DEMOD_LOCK,
FrontendStatusType::SNR,
FrontendStatusType::FEC,
FrontendStatusType::MODULATION,
FrontendStatusType::MODULATIONS,
FrontendStatusType::ROLL_OFF,
FrontendStatusType::STREAM_ID_LIST,
};
break;
}
case FrontendType::ATSC3: {
mFrontendCaps.set<FrontendCapabilities::Tag::atsc3Caps>(FrontendAtsc3Capabilities());
mFrontendStatusCaps = {
FrontendStatusType::BER,
FrontendStatusType::PER,
FrontendStatusType::ATSC3_PLP_INFO,
FrontendStatusType::MODULATIONS,
FrontendStatusType::BERS,
FrontendStatusType::INTERLEAVINGS,
FrontendStatusType::BANDWIDTH,
FrontendStatusType::ATSC3_ALL_PLP_INFO,
};
break;
}
case FrontendType::DVBC: {
mFrontendCaps.set<FrontendCapabilities::Tag::dvbcCaps>(FrontendDvbcCapabilities());
mFrontendStatusCaps = {
FrontendStatusType::PRE_BER, FrontendStatusType::SIGNAL_QUALITY,
FrontendStatusType::MODULATION, FrontendStatusType::SPECTRAL,
FrontendStatusType::MODULATIONS, FrontendStatusType::CODERATES,
FrontendStatusType::INTERLEAVINGS, FrontendStatusType::BANDWIDTH,
};
break;
}
case FrontendType::DVBS: {
mFrontendCaps.set<FrontendCapabilities::Tag::dvbsCaps>(FrontendDvbsCapabilities());
mFrontendStatusCaps = {
FrontendStatusType::SIGNAL_STRENGTH, FrontendStatusType::SYMBOL_RATE,
FrontendStatusType::MODULATION, FrontendStatusType::MODULATIONS,
FrontendStatusType::ROLL_OFF, FrontendStatusType::IS_MISO,
};
break;
}
case FrontendType::DVBT: {
mFrontendCaps.set<FrontendCapabilities::Tag::dvbtCaps>(FrontendDvbtCapabilities());
mFrontendStatusCaps = {
FrontendStatusType::EWBS,
FrontendStatusType::PLP_ID,
FrontendStatusType::HIERARCHY,
FrontendStatusType::MODULATIONS,
FrontendStatusType::BANDWIDTH,
FrontendStatusType::GUARD_INTERVAL,
FrontendStatusType::TRANSMISSION_MODE,
FrontendStatusType::T2_SYSTEM_ID,
FrontendStatusType::DVBT_CELL_IDS,
};
break;
}
case FrontendType::ISDBT: {
FrontendIsdbtCapabilities isdbtCaps{
.modeCap = (int)FrontendIsdbtMode::MODE_1 | (int)FrontendIsdbtMode::MODE_2,
.bandwidthCap = (int)FrontendIsdbtBandwidth::BANDWIDTH_6MHZ,
.modulationCap = (int)FrontendIsdbtModulation::MOD_16QAM,
.coderateCap = (int)FrontendIsdbtCoderate::CODERATE_4_5 |
(int)FrontendIsdbtCoderate::CODERATE_6_7,
.guardIntervalCap = (int)FrontendIsdbtGuardInterval::INTERVAL_1_128,
.timeInterleaveCap = (int)FrontendIsdbtTimeInterleaveMode::AUTO |
(int)FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0,
.isSegmentAuto = true,
.isFullSegment = true,
};
mFrontendCaps.set<FrontendCapabilities::Tag::isdbtCaps>(isdbtCaps);
mFrontendStatusCaps = {
FrontendStatusType::AGC,
FrontendStatusType::LNA,
FrontendStatusType::MODULATION,
FrontendStatusType::MODULATIONS,
FrontendStatusType::BANDWIDTH,
FrontendStatusType::GUARD_INTERVAL,
FrontendStatusType::TRANSMISSION_MODE,
FrontendStatusType::ISDBT_SEGMENTS,
FrontendStatusType::ISDBT_MODE,
FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG,
FrontendStatusType::INTERLEAVINGS,
};
break;
}
case FrontendType::ANALOG: {
mFrontendCaps.set<FrontendCapabilities::Tag::analogCaps>(FrontendAnalogCapabilities());
mFrontendStatusCaps = {
FrontendStatusType::LAYER_ERROR,
FrontendStatusType::MER,
FrontendStatusType::UEC,
FrontendStatusType::TS_DATA_RATES,
};
break;
}
case FrontendType::ATSC: {
mFrontendCaps.set<FrontendCapabilities::Tag::atscCaps>(FrontendAtscCapabilities());
mFrontendStatusCaps = {
FrontendStatusType::FREQ_OFFSET,
FrontendStatusType::RF_LOCK,
FrontendStatusType::MODULATIONS,
FrontendStatusType::IS_LINEAR,
};
break;
}
case FrontendType::ISDBS3: {
mFrontendCaps.set<FrontendCapabilities::Tag::isdbs3Caps>(FrontendIsdbs3Capabilities());
mFrontendStatusCaps = {
FrontendStatusType::DEMOD_LOCK, FrontendStatusType::MODULATION,
FrontendStatusType::MODULATIONS, FrontendStatusType::ROLL_OFF,
FrontendStatusType::IS_SHORT_FRAMES, FrontendStatusType::STREAM_ID_LIST,
};
break;
}
case FrontendType::DTMB: {
mFrontendCaps.set<FrontendCapabilities::Tag::dtmbCaps>(FrontendDtmbCapabilities());
mFrontendStatusCaps = {
FrontendStatusType::MODULATIONS, FrontendStatusType::INTERLEAVINGS,
FrontendStatusType::BANDWIDTH, FrontendStatusType::GUARD_INTERVAL,
FrontendStatusType::TRANSMISSION_MODE,
};
break;
}
default: {
break;
}
}
}
Frontend::~Frontend() {}
@@ -763,6 +897,10 @@ binder_status_t Frontend::dump(int fd, const char** /* args */, uint32_t /* numA
dprintf(fd, " mType: %d\n", mType);
dprintf(fd, " mIsLocked: %d\n", mIsLocked);
dprintf(fd, " mCiCamId: %d\n", mCiCamId);
dprintf(fd, " mFrontendStatusCaps:");
for (int i = 0; i < mFrontendStatusCaps.size(); i++) {
dprintf(fd, " %d\n", mFrontendStatusCaps[i]);
}
return STATUS_OK;
}
@@ -780,6 +918,29 @@ binder_status_t Frontend::dump(int fd, const char** /* args */, uint32_t /* numA
static_cast<int32_t>(Result::UNAVAILABLE));
}
::ndk::ScopedAStatus Frontend::getFrontendStatusReadiness(
const std::vector<FrontendStatusType>& in_statusTypes,
std::vector<FrontendStatusReadiness>* _aidl_return) {
ALOGV("%s", __FUNCTION__);
_aidl_return->resize(in_statusTypes.size());
for (int i = 0; i < in_statusTypes.size(); i++) {
int j = 0;
while (j < mFrontendStatusCaps.size()) {
if (in_statusTypes[i] == mFrontendStatusCaps[j]) {
(*_aidl_return)[i] = FrontendStatusReadiness::STABLE;
break;
}
j++;
}
if (j >= mFrontendStatusCaps.size()) {
(*_aidl_return)[i] = FrontendStatusReadiness::UNSUPPORTED;
}
}
return ::ndk::ScopedAStatus::ok();
}
FrontendType Frontend::getFrontendType() {
return mType;
}
@@ -797,6 +958,21 @@ bool Frontend::isLocked() {
return mIsLocked;
}
void Frontend::getFrontendInfo(FrontendInfo* _aidl_return) {
// assign randomly selected values for testing.
*_aidl_return = {
.type = mType,
.minFrequency = 139000000,
.maxFrequency = 1139000000,
.minSymbolRate = 45,
.maxSymbolRate = 1145,
.acquireRange = 30,
.exclusiveGroupId = 57,
.statusCaps = mFrontendStatusCaps,
.frontendCaps = mFrontendCaps,
};
}
} // namespace tuner
} // namespace tv
} // namespace hardware

View File

@@ -51,6 +51,9 @@ class Frontend : public BnFrontend {
::ndk::ScopedAStatus unlinkCiCam(int32_t in_ciCamId) override;
::ndk::ScopedAStatus getHardwareInfo(std::string* _aidl_return) override;
::ndk::ScopedAStatus removeOutputPid(int32_t in_pid) override;
::ndk::ScopedAStatus getFrontendStatusReadiness(
const std::vector<FrontendStatusType>& in_statusTypes,
std::vector<FrontendStatusReadiness>* _aidl_return) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
@@ -58,6 +61,7 @@ class Frontend : public BnFrontend {
int32_t getFrontendId();
string getSourceFile();
bool isLocked();
void getFrontendInfo(FrontendInfo* _aidl_return);
private:
virtual ~Frontend();
@@ -74,6 +78,8 @@ class Frontend : public BnFrontend {
FrontendSettings mFrontendSettings;
FrontendScanType mFrontendScanType;
std::ifstream mFrontendData;
FrontendCapabilities mFrontendCaps;
vector<FrontendStatusType> mFrontendStatusCaps;
};
} // namespace tuner

View File

@@ -49,154 +49,15 @@ void Tuner::init() {
mFrontends[8] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS3, 8, this->ref<Tuner>());
mFrontends[9] = ndk::SharedRefBase::make<Frontend>(FrontendType::DTMB, 9, this->ref<Tuner>());
vector<FrontendStatusType> statusCaps;
FrontendCapabilities capsIsdbs;
capsIsdbs.set<FrontendCapabilities::Tag::isdbsCaps>(FrontendIsdbsCapabilities());
mFrontendCaps[0] = capsIsdbs;
statusCaps = {
FrontendStatusType::DEMOD_LOCK,
FrontendStatusType::SNR,
FrontendStatusType::FEC,
FrontendStatusType::MODULATION,
FrontendStatusType::MODULATIONS,
FrontendStatusType::ROLL_OFF,
FrontendStatusType::STREAM_ID_LIST,
};
mFrontendStatusCaps[0] = statusCaps;
mMaxUsableFrontends[FrontendType::ISDBS] = 1;
FrontendCapabilities capsAtsc3;
capsAtsc3.set<FrontendCapabilities::Tag::atsc3Caps>(FrontendAtsc3Capabilities());
mFrontendCaps[1] = capsAtsc3;
statusCaps = {
FrontendStatusType::BER,
FrontendStatusType::PER,
FrontendStatusType::ATSC3_PLP_INFO,
FrontendStatusType::MODULATIONS,
FrontendStatusType::BERS,
FrontendStatusType::INTERLEAVINGS,
FrontendStatusType::BANDWIDTH,
FrontendStatusType::ATSC3_ALL_PLP_INFO,
};
mFrontendStatusCaps[1] = statusCaps;
mMaxUsableFrontends[FrontendType::ATSC3] = 1;
FrontendCapabilities capsDvbc;
capsDvbc.set<FrontendCapabilities::Tag::dvbcCaps>(FrontendDvbcCapabilities());
mFrontendCaps[2] = capsDvbc;
statusCaps = {
FrontendStatusType::PRE_BER, FrontendStatusType::SIGNAL_QUALITY,
FrontendStatusType::MODULATION, FrontendStatusType::SPECTRAL,
FrontendStatusType::MODULATIONS, FrontendStatusType::CODERATES,
FrontendStatusType::INTERLEAVINGS, FrontendStatusType::BANDWIDTH,
};
mFrontendStatusCaps[2] = statusCaps;
mMaxUsableFrontends[FrontendType::DVBC] = 1;
FrontendCapabilities capsDvbs;
capsDvbs.set<FrontendCapabilities::Tag::dvbsCaps>(FrontendDvbsCapabilities());
mFrontendCaps[3] = capsDvbs;
statusCaps = {
FrontendStatusType::SIGNAL_STRENGTH, FrontendStatusType::SYMBOL_RATE,
FrontendStatusType::MODULATION, FrontendStatusType::MODULATIONS,
FrontendStatusType::ROLL_OFF, FrontendStatusType::IS_MISO,
};
mFrontendStatusCaps[3] = statusCaps;
mMaxUsableFrontends[FrontendType::DVBS] = 1;
FrontendCapabilities capsDvbt;
capsDvbt.set<FrontendCapabilities::Tag::dvbtCaps>(FrontendDvbtCapabilities());
mFrontendCaps[4] = capsDvbt;
statusCaps = {
FrontendStatusType::EWBS,
FrontendStatusType::PLP_ID,
FrontendStatusType::HIERARCHY,
FrontendStatusType::MODULATIONS,
FrontendStatusType::BANDWIDTH,
FrontendStatusType::GUARD_INTERVAL,
FrontendStatusType::TRANSMISSION_MODE,
FrontendStatusType::T2_SYSTEM_ID,
FrontendStatusType::DVBT_CELL_IDS,
};
mFrontendStatusCaps[4] = statusCaps;
mMaxUsableFrontends[FrontendType::DVBT] = 1;
FrontendCapabilities capsIsdbt;
FrontendIsdbtCapabilities isdbtCaps{
.modeCap = (int)FrontendIsdbtMode::MODE_1 | (int)FrontendIsdbtMode::MODE_2,
.bandwidthCap = (int)FrontendIsdbtBandwidth::BANDWIDTH_6MHZ,
.modulationCap = (int)FrontendIsdbtModulation::MOD_16QAM,
.coderateCap = (int)FrontendIsdbtCoderate::CODERATE_4_5 |
(int)FrontendIsdbtCoderate::CODERATE_6_7,
.guardIntervalCap = (int)FrontendIsdbtGuardInterval::INTERVAL_1_128,
.timeInterleaveCap = (int)FrontendIsdbtTimeInterleaveMode::AUTO |
(int)FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0,
.isSegmentAuto = true,
.isFullSegment = true,
};
capsIsdbt.set<FrontendCapabilities::Tag::isdbtCaps>(isdbtCaps);
mFrontendCaps[5] = capsIsdbt;
statusCaps = {
FrontendStatusType::AGC,
FrontendStatusType::LNA,
FrontendStatusType::MODULATION,
FrontendStatusType::MODULATIONS,
FrontendStatusType::BANDWIDTH,
FrontendStatusType::GUARD_INTERVAL,
FrontendStatusType::TRANSMISSION_MODE,
FrontendStatusType::ISDBT_SEGMENTS,
FrontendStatusType::ISDBT_MODE,
FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG,
FrontendStatusType::INTERLEAVINGS,
};
mFrontendStatusCaps[5] = statusCaps;
mMaxUsableFrontends[FrontendType::ISDBT] = 1;
FrontendCapabilities capsAnalog;
capsAnalog.set<FrontendCapabilities::Tag::analogCaps>(FrontendAnalogCapabilities());
mFrontendCaps[6] = capsAnalog;
statusCaps = {
FrontendStatusType::LAYER_ERROR,
FrontendStatusType::MER,
FrontendStatusType::UEC,
FrontendStatusType::TS_DATA_RATES,
};
mFrontendStatusCaps[6] = statusCaps;
mMaxUsableFrontends[FrontendType::ANALOG] = 1;
FrontendCapabilities capsAtsc;
capsAtsc.set<FrontendCapabilities::Tag::atscCaps>(FrontendAtscCapabilities());
mFrontendCaps[7] = capsAtsc;
statusCaps = {
FrontendStatusType::FREQ_OFFSET,
FrontendStatusType::RF_LOCK,
FrontendStatusType::MODULATIONS,
FrontendStatusType::IS_LINEAR,
};
mFrontendStatusCaps[7] = statusCaps;
mMaxUsableFrontends[FrontendType::ATSC] = 1;
FrontendCapabilities capsIsdbs3;
capsIsdbs3.set<FrontendCapabilities::Tag::isdbs3Caps>(FrontendIsdbs3Capabilities());
mFrontendCaps[8] = capsIsdbs3;
statusCaps = {
FrontendStatusType::DEMOD_LOCK, FrontendStatusType::MODULATION,
FrontendStatusType::MODULATIONS, FrontendStatusType::ROLL_OFF,
FrontendStatusType::IS_SHORT_FRAMES, FrontendStatusType::STREAM_ID_LIST,
};
mFrontendStatusCaps[8] = statusCaps;
mMaxUsableFrontends[FrontendType::ISDBS3] = 1;
FrontendCapabilities capsDtmb;
capsDtmb.set<FrontendCapabilities::Tag::dtmbCaps>(FrontendDtmbCapabilities());
mFrontendCaps[9] = capsDtmb;
statusCaps = {
FrontendStatusType::MODULATIONS, FrontendStatusType::INTERLEAVINGS,
FrontendStatusType::BANDWIDTH, FrontendStatusType::GUARD_INTERVAL,
FrontendStatusType::TRANSMISSION_MODE,
};
mFrontendStatusCaps[9] = statusCaps;
mMaxUsableFrontends[FrontendType::DTMB] = 1;
mLnbs.resize(2);
@@ -267,24 +128,12 @@ Tuner::~Tuner() {}
::ndk::ScopedAStatus Tuner::getFrontendInfo(int32_t in_frontendId, FrontendInfo* _aidl_return) {
ALOGV("%s", __FUNCTION__);
if (in_frontendId >= mFrontendSize) {
if (in_frontendId < 0 || in_frontendId >= mFrontendSize) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_ARGUMENT));
}
// assign randomly selected values for testing.
*_aidl_return = {
.type = mFrontends[in_frontendId]->getFrontendType(),
.minFrequency = 139000000,
.maxFrequency = 1139000000,
.minSymbolRate = 45,
.maxSymbolRate = 1145,
.acquireRange = 30,
.exclusiveGroupId = 57,
.statusCaps = mFrontendStatusCaps[in_frontendId],
.frontendCaps = mFrontendCaps[in_frontendId],
};
mFrontends[in_frontendId]->getFrontendInfo(_aidl_return);
return ::ndk::ScopedAStatus::ok();
}
@@ -360,9 +209,6 @@ binder_status_t Tuner::dump(int fd, const char** args, uint32_t numArgs) {
dprintf(fd, "Frontends:\n");
for (int i = 0; i < mFrontendSize; i++) {
mFrontends[i]->dump(fd, args, numArgs);
for (int j = 0; j < mFrontendStatusCaps[i].size(); j++) {
dprintf(fd, " statusCap: %d\n", mFrontendStatusCaps[i][j]);
}
}
}
{

View File

@@ -75,8 +75,6 @@ class Tuner : public BnTuner {
private:
// Static mFrontends array to maintain local frontends information
map<int32_t, std::shared_ptr<Frontend>> mFrontends;
map<int32_t, FrontendCapabilities> mFrontendCaps;
map<int32_t, vector<FrontendStatusType>> mFrontendStatusCaps;
map<int32_t, int32_t> mFrontendToDemux;
map<int32_t, std::shared_ptr<Demux>> mDemuxes;
// To maintain how many Frontends we have

View File

@@ -581,3 +581,47 @@ void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanT
ASSERT_TRUE(stopScanFrontend());
ASSERT_TRUE(closeFrontend());
}
void FrontendTests::statusReadinessTest(FrontendConfig frontendConf) {
int32_t feId;
vector<FrontendStatusType> allTypes;
vector<FrontendStatusReadiness> readiness;
getFrontendIdByType(frontendConf.type, feId);
ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(openFrontendById(feId));
ASSERT_TRUE(setFrontendCallback());
if (frontendConf.canConnectToCiCam) {
ASSERT_TRUE(linkCiCam(frontendConf.ciCamId));
ASSERT_TRUE(removeOutputPid(frontendConf.removePid));
ASSERT_TRUE(unlinkCiCam(frontendConf.ciCamId));
}
ASSERT_TRUE(getFrontendInfo(feId));
ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
// TODO: find a better way to push all frontend status types
for (int32_t i = 0; i < static_cast<int32_t>(FrontendStatusType::ATSC3_ALL_PLP_INFO); i++) {
allTypes.push_back(static_cast<FrontendStatusType>(i));
}
ndk::ScopedAStatus status = mFrontend->getFrontendStatusReadiness(allTypes, &readiness);
ASSERT_TRUE(status.isOk());
ASSERT_TRUE(readiness.size() == allTypes.size());
for (int32_t i = 0; i < readiness.size(); i++) {
int32_t j = 0;
while (j < mFrontendInfo.statusCaps.size()) {
if (allTypes[i] == mFrontendInfo.statusCaps[j]) {
ASSERT_TRUE(readiness[i] == FrontendStatusReadiness::UNAVAILABLE ||
readiness[i] == FrontendStatusReadiness::UNSTABLE ||
readiness[i] == FrontendStatusReadiness::STABLE);
break;
}
j++;
}
if (j >= mFrontendInfo.statusCaps.size()) {
ASSERT_TRUE(readiness[i] == FrontendStatusReadiness::UNSUPPORTED);
}
}
ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
ASSERT_TRUE(closeFrontend());
}

View File

@@ -102,6 +102,7 @@ class FrontendTests {
void scanTest(FrontendConfig frontend, FrontendScanType type);
void debugInfoTest(FrontendConfig frontendConf);
void maxNumberOfFrontendsTest();
void statusReadinessTest(FrontendConfig frontendConf);
void setDvrTests(DvrTests* dvrTests) { mExternalDvrTests = dvrTests; }
void setDemux(std::shared_ptr<IDemux> demux) { getDvrTests()->setDemux(demux); }

View File

@@ -907,6 +907,14 @@ TEST_P(TunerFrontendAidlTest, maxNumberOfFrontends) {
mFrontendTests.maxNumberOfFrontendsTest();
}
TEST_P(TunerFrontendAidlTest, statusReadinessTest) {
description("Test Max Frontend status readiness");
if (!live.hasFrontendConnection) {
return;
}
mFrontendTests.statusReadinessTest(frontendMap[live.frontendId]);
}
TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowVideoFilterTest) {
description("Test Video Filter functionality in Broadcast use case.");
if (!live.hasFrontendConnection) {