Loading tv/tuner/1.0/vts/functional/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -23,8 +23,12 @@ cc_test { "DemuxTests.cpp", "FilterTests.cpp", "DvrTests.cpp", "DescramblerTests.cpp", ], static_libs: [ "android.hardware.cas@1.0", "android.hardware.cas@1.1", "android.hardware.cas@1.2", "android.hardware.tv.tuner@1.0", "android.hidl.allocator@1.0", "android.hidl.memory@1.0", Loading tv/tuner/1.0/vts/functional/DescramblerTests.cpp 0 → 100644 +195 −0 Original line number Diff line number Diff line /* * Copyright 2020 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. */ #include "DescramblerTests.h" AssertionResult DescramblerTests::createCasPlugin(int32_t caSystemId) { auto status = mMediaCasService->isSystemIdSupported(caSystemId); if (!status.isOk() || !status) { ALOGW("[vts] Failed to check isSystemIdSupported."); return failure(); } mCasListener = new MediaCasListener(); auto pluginStatus = mMediaCasService->createPluginExt(caSystemId, mCasListener); if (!pluginStatus.isOk()) { ALOGW("[vts] Failed to createPluginExt."); return failure(); } mCas = ICas::castFrom(pluginStatus); if (mCas == nullptr) { ALOGW("[vts] Failed to get ICas."); return failure(); } return success(); } AssertionResult DescramblerTests::openCasSession(TunerKeyToken& sessionId, vector<uint8_t> hidlPvtData) { Status sessionStatus; SessionIntent intent = SessionIntent::LIVE; ScramblingMode mode = ScramblingMode::RESERVED; auto returnVoid = mCas->openSession_1_2(intent, mode, [&](Status status, const hidl_vec<uint8_t>& id) { sessionStatus = status; sessionId = id; }); if (!returnVoid.isOk() || (sessionStatus != Status::OK)) { ALOGW("[vts] Failed to open cas session."); mCas->closeSession(sessionId); return failure(); } auto status = mCas->setSessionPrivateData(sessionId, hidlPvtData); if (status != android::hardware::cas::V1_0::Status::OK) { ALOGW("[vts] Failed to set session private data"); mCas->closeSession(sessionId); return failure(); } return success(); } AssertionResult DescramblerTests::getKeyToken(int32_t caSystemId, string provisonStr, hidl_vec<uint8_t> hidlPvtData, TunerKeyToken& token) { if (createCasPlugin(caSystemId) != success()) { ALOGW("[vts] createCasPlugin failed."); return failure(); } if (provisonStr.size() > 0) { auto returnStatus = mCas->provision(hidl_string(provisonStr)); if (returnStatus != android::hardware::cas::V1_0::Status::OK) { ALOGW("[vts] provision failed."); return failure(); } } return openCasSession(token, hidlPvtData); } AssertionResult DescramblerTests::openDescrambler(uint32_t demuxId) { Result status; mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) { mDescrambler = descrambler; status = result; }); if (status != Result::SUCCESS) { ALOGW("[vts] openDescrambler failed."); return failure(); } status = mDescrambler->setDemuxSource(demuxId); if (status != Result::SUCCESS) { ALOGW("[vts] setDemuxSource failed."); return failure(); } return success(); } AssertionResult DescramblerTests::setKeyToken(TunerKeyToken token) { Result status; if (mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->setKeyToken(token); if (status == Result::SUCCESS) { ALOGW("[vts] setKeyToken failed."); return failure(); } return success(); } AssertionResult DescramblerTests::addPid(DemuxPid pid, sp<IFilter> optionalSourceFilter) { Result status; if (mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->addPid(pid, optionalSourceFilter); if (status == Result::SUCCESS) { ALOGW("[vts] addPid failed."); return failure(); } return success(); } AssertionResult DescramblerTests::removePid(DemuxPid pid, sp<IFilter> optionalSourceFilter) { Result status; if (mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->removePid(pid, optionalSourceFilter); if (status == Result::SUCCESS) { ALOGW("[vts] removePid failed."); return failure(); } return success(); } AssertionResult DescramblerTests::closeDescrambler() { Result status; if (mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->close(); mDescrambler = nullptr; if (status == Result::SUCCESS) { ALOGW("[vts] close Descrambler failed."); return failure(); } return success(); } AssertionResult DescramblerTests::getDemuxPidFromFilterSettings(DemuxFilterType type, DemuxFilterSettings settings, DemuxPid& pid) { switch (type.mainType) { case DemuxFilterMainType::TS: if (type.subType.tsFilterType() == DemuxTsFilterType::AUDIO || type.subType.tsFilterType() == DemuxTsFilterType::VIDEO) { pid.tPid(settings.ts().tpid); } else { ALOGW("[vts] Not a media ts filter!"); return failure(); } break; case DemuxFilterMainType::MMTP: if (type.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO || type.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) { pid.mmtpPid(settings.mmtp().mmtpPid); } else { ALOGW("[vts] Not a media mmtp filter!"); return failure(); } break; default: ALOGW("[vts] Not a media filter!"); return failure(); } return success(); } tv/tuner/1.0/vts/functional/DescramblerTests.h 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright 2020 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. */ #include <VtsHalHidlTargetTestBase.h> #include <VtsHalHidlTargetTestEnvBase.h> #include <android-base/logging.h> #include <android/hardware/cas/1.0/types.h> #include <android/hardware/cas/1.2/ICas.h> #include <android/hardware/cas/1.2/ICasListener.h> #include <android/hardware/cas/1.2/IMediaCasService.h> #include <android/hardware/cas/1.2/types.h> #include <android/hardware/tv/tuner/1.0/IDescrambler.h> #include <android/hardware/tv/tuner/1.0/IDvr.h> #include <android/hardware/tv/tuner/1.0/IDvrCallback.h> #include <android/hardware/tv/tuner/1.0/ITuner.h> #include <android/hardware/tv/tuner/1.0/types.h> #include <fmq/MessageQueue.h> #include <hidl/Status.h> #include <utils/Condition.h> #include <utils/Mutex.h> #include <fstream> #include <iostream> #include <map> using android::Condition; using android::Mutex; using android::sp; using android::hardware::EventFlag; using android::hardware::hidl_handle; using android::hardware::hidl_string; using android::hardware::hidl_vec; using android::hardware::kSynchronizedReadWrite; using android::hardware::MessageQueue; using android::hardware::MQDescriptorSync; using android::hardware::Return; using android::hardware::Void; using android::hardware::cas::V1_2::ICas; using android::hardware::cas::V1_2::ICasListener; using android::hardware::cas::V1_2::IMediaCasService; using android::hardware::cas::V1_2::ScramblingMode; using android::hardware::cas::V1_2::SessionIntent; using android::hardware::cas::V1_2::Status; using android::hardware::cas::V1_2::StatusEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; using android::hardware::tv::tuner::V1_0::DemuxFilterType; using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; using android::hardware::tv::tuner::V1_0::DemuxPid; using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; using android::hardware::tv::tuner::V1_0::IDescrambler; using android::hardware::tv::tuner::V1_0::IFilter; using android::hardware::tv::tuner::V1_0::ITuner; using android::hardware::tv::tuner::V1_0::Result; using android::hardware::tv::tuner::V1_0::TunerKeyToken; using ::testing::AssertionResult; class MediaCasListener : public ICasListener { public: virtual Return<void> onEvent(int32_t /*event*/, int32_t /*arg*/, const hidl_vec<uint8_t>& /*data*/) override { return Void(); } virtual Return<void> onSessionEvent(const hidl_vec<uint8_t>& /*sessionId*/, int32_t /*event*/, int32_t /*arg*/, const hidl_vec<uint8_t>& /*data*/) override { return Void(); } virtual Return<void> onStatusUpdate(StatusEvent /*event*/, int32_t /*arg*/) override { return Void(); } }; class DescramblerTests { public: void setService(sp<ITuner> tuner) { mService = tuner; } void setCasService(sp<IMediaCasService> casService) { mMediaCasService = casService; } AssertionResult setKeyToken(TunerKeyToken token); AssertionResult openDescrambler(uint32_t demuxId); AssertionResult addPid(DemuxPid pid, sp<IFilter> optionalSourceFilter); AssertionResult removePid(DemuxPid pid, sp<IFilter> optionalSourceFilter); AssertionResult closeDescrambler(); AssertionResult getKeyToken(int32_t caSystemId, string provisonStr, hidl_vec<uint8_t> hidlPvtData, TunerKeyToken& token); AssertionResult getDemuxPidFromFilterSettings(DemuxFilterType type, DemuxFilterSettings settings, DemuxPid& pid); protected: static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult success() { return ::testing::AssertionSuccess(); } sp<ITuner> mService; sp<ICas> mCas; sp<IMediaCasService> mMediaCasService; sp<MediaCasListener> mCasListener; sp<IDescrambler> mDescrambler; private: AssertionResult openCasSession(TunerKeyToken& sessionId, vector<uint8_t> hidlPvtData); AssertionResult createCasPlugin(int32_t caSystemId); }; tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +84 −49 Original line number Diff line number Diff line Loading @@ -18,53 +18,17 @@ namespace { AssertionResult TunerHidlTest::createDescrambler(uint32_t demuxId) { Result status; mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) { mDescrambler = descrambler; status = result; }); if (status != Result::SUCCESS) { return failure(); } status = mDescrambler->setDemuxSource(demuxId); if (status != Result::SUCCESS) { return failure(); } // Test if demux source can be set more than once. status = mDescrambler->setDemuxSource(demuxId); return AssertionResult(status == Result::INVALID_STATE); } AssertionResult TunerHidlTest::closeDescrambler() { Result status; EXPECT_TRUE(mDescrambler); status = mDescrambler->close(); mDescrambler = nullptr; return AssertionResult(status == Result::SUCCESS); } AssertionResult TunerBroadcastHidlTest::filterDataOutputTest(vector<string> /*goldenOutputFiles*/) { // Data Verify Module std::map<uint32_t, sp<FilterCallback>>::iterator it; std::map<uint32_t, sp<FilterCallback>> filterCallbacks = mFilterTests.getFilterCallbacks(); for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) { it->second->testFilterDataOutput(); } return success(); return filterDataOutputTestBase(mFilterTests); } AssertionResult TunerPlaybackHidlTest::filterDataOutputTest(vector<string> /*goldenOutputFiles*/) { // Data Verify Module std::map<uint32_t, sp<FilterCallback>>::iterator it; std::map<uint32_t, sp<FilterCallback>> filterCallbacks = mFilterTests.getFilterCallbacks(); for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) { it->second->testFilterDataOutput(); return filterDataOutputTestBase(mFilterTests); } return success(); AssertionResult TunerDescramblerHidlTest::filterDataOutputTest( vector<string> /*goldenOutputFiles*/) { return filterDataOutputTestBase(mFilterTests); } void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, Loading Loading @@ -233,6 +197,69 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC ASSERT_TRUE(mFrontendTests.closeFrontend()); } void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs, FrontendConfig frontendConf, DescramblerConfig descConfig) { uint32_t feId; uint32_t demuxId; sp<IDemux> demux; set<uint32_t> filterIds; uint32_t filterId; set<struct FilterConfig>::iterator config; set<uint32_t>::iterator id; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); if (feId == INVALID_ID) { // TODO broadcast test on Cuttlefish needs licensed ts input, // these tests are runnable on vendor device with real frontend module // or with manual ts installing and use DVBT frontend. return; } ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter((*config).settings, filterId)); filterIds.insert(filterId); } mDescramblerTests.openDescrambler(demuxId); TunerKeyToken token; ASSERT_TRUE(mDescramblerTests.getKeyToken(descConfig.casSystemId, descConfig.provisionStr, descConfig.hidlPvtData, token)); mDescramblerTests.setKeyToken(token); vector<DemuxPid> pids; DemuxPid pid; for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { ASSERT_TRUE(mDescramblerTests.getDemuxPidFromFilterSettings((*config).type, (*config).settings, pid)); pids.push_back(pid); mDescramblerTests.addPid(pid, nullptr); } for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.startFilter(*id)); } // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf)); ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); ASSERT_TRUE(mFrontendTests.stopTuneFrontend()); for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.stopFilter(*id)); } for (auto pid : pids) { mDescramblerTests.removePid(pid, nullptr); } mDescramblerTests.closeDescrambler(); for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.closeFilter(*id)); } ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } TEST_P(TunerFrontendHidlTest, TuneFrontend) { description("Tune one Frontend with specific setting and check Lock event"); mFrontendTests.tuneTest(frontendArray[DVBT]); Loading Loading @@ -341,7 +368,7 @@ TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]); } TEST_P(TunerHidlTest, CreateDescrambler) { TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { description("Create Descrambler"); uint32_t feId; uint32_t demuxId; Loading @@ -352,13 +379,21 @@ TEST_P(TunerHidlTest, CreateDescrambler) { ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); ASSERT_TRUE(createDescrambler(demuxId)); ASSERT_TRUE(closeDescrambler()); mDescramblerTests.openDescrambler(demuxId); mDescramblerTests.closeDescrambler(); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } INSTANTIATE_TEST_SUITE_P( TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { description("Test ts audio filter in scrambled broadcast use case"); set<FilterConfig> filterConfs; filterConfs.insert(filterArray[TS_AUDIO0]); filterConfs.insert(filterArray[TS_VIDEO1]); scrambledBroadcastTest(filterConfs, frontendArray[DVBT], descramblerArray[DESC_0]); } /*INSTANTIATE_TEST_SUITE_P( PerInstance, TunerFrontendHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); Loading Loading @@ -386,10 +421,10 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( PerInstance, TunerRecordHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); android::hardware::PrintInstanceNameToString);*/ INSTANTIATE_TEST_SUITE_P( PerInstance, TunerHidlTest, PerInstance, TunerDescramblerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); } // namespace tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +24 −12 Original line number Diff line number Diff line Loading @@ -14,19 +14,14 @@ * limitations under the License. */ #include <android/hardware/tv/tuner/1.0/IDescrambler.h> #include "DemuxTests.h" #include "DescramblerTests.h" #include "DvrTests.h" #include "FrontendTests.h" using android::hardware::tv::tuner::V1_0::DataFormat; using android::hardware::tv::tuner::V1_0::IDescrambler; static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult success() { return ::testing::AssertionSuccess(); } Loading @@ -38,6 +33,17 @@ void initConfiguration() { initFrontendScanConfig(); initFilterConfig(); initDvrConfig(); initDescramblerConfig(); } AssertionResult filterDataOutputTestBase(FilterTests tests) { // Data Verify Module std::map<uint32_t, sp<FilterCallback>>::iterator it; std::map<uint32_t, sp<FilterCallback>> filterCallbacks = tests.getFilterCallbacks(); for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) { it->second->testFilterDataOutput(); } return success(); } class TunerFrontendHidlTest : public testing::TestWithParam<std::string> { Loading Loading @@ -193,15 +199,19 @@ class TunerRecordHidlTest : public testing::TestWithParam<std::string> { DvrTests mDvrTests; }; class TunerHidlTest : public testing::TestWithParam<std::string> { class TunerDescramblerHidlTest : public testing::TestWithParam<std::string> { public: virtual void SetUp() override { mService = ITuner::getService(GetParam()); mCasService = IMediaCasService::getService(); ASSERT_NE(mService, nullptr); ASSERT_NE(mCasService, nullptr); initConfiguration(); mFrontendTests.setService(mService); mDemuxTests.setService(mService); mDescramblerTests.setService(mService); mDescramblerTests.setCasService(mCasService); } protected: Loading @@ -209,13 +219,15 @@ class TunerHidlTest : public testing::TestWithParam<std::string> { RecordProperty("description", description); } void scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs, FrontendConfig frontendConf, DescramblerConfig descConfig); AssertionResult filterDataOutputTest(vector<string> /*goldenOutputFiles*/); sp<ITuner> mService; sp<IMediaCasService> mCasService; FrontendTests mFrontendTests; DemuxTests mDemuxTests; sp<IDescrambler> mDescrambler; AssertionResult createDescrambler(uint32_t demuxId); AssertionResult closeDescrambler(); FilterTests mFilterTests; DescramblerTests mDescramblerTests; }; } // namespace Loading
tv/tuner/1.0/vts/functional/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -23,8 +23,12 @@ cc_test { "DemuxTests.cpp", "FilterTests.cpp", "DvrTests.cpp", "DescramblerTests.cpp", ], static_libs: [ "android.hardware.cas@1.0", "android.hardware.cas@1.1", "android.hardware.cas@1.2", "android.hardware.tv.tuner@1.0", "android.hidl.allocator@1.0", "android.hidl.memory@1.0", Loading
tv/tuner/1.0/vts/functional/DescramblerTests.cpp 0 → 100644 +195 −0 Original line number Diff line number Diff line /* * Copyright 2020 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. */ #include "DescramblerTests.h" AssertionResult DescramblerTests::createCasPlugin(int32_t caSystemId) { auto status = mMediaCasService->isSystemIdSupported(caSystemId); if (!status.isOk() || !status) { ALOGW("[vts] Failed to check isSystemIdSupported."); return failure(); } mCasListener = new MediaCasListener(); auto pluginStatus = mMediaCasService->createPluginExt(caSystemId, mCasListener); if (!pluginStatus.isOk()) { ALOGW("[vts] Failed to createPluginExt."); return failure(); } mCas = ICas::castFrom(pluginStatus); if (mCas == nullptr) { ALOGW("[vts] Failed to get ICas."); return failure(); } return success(); } AssertionResult DescramblerTests::openCasSession(TunerKeyToken& sessionId, vector<uint8_t> hidlPvtData) { Status sessionStatus; SessionIntent intent = SessionIntent::LIVE; ScramblingMode mode = ScramblingMode::RESERVED; auto returnVoid = mCas->openSession_1_2(intent, mode, [&](Status status, const hidl_vec<uint8_t>& id) { sessionStatus = status; sessionId = id; }); if (!returnVoid.isOk() || (sessionStatus != Status::OK)) { ALOGW("[vts] Failed to open cas session."); mCas->closeSession(sessionId); return failure(); } auto status = mCas->setSessionPrivateData(sessionId, hidlPvtData); if (status != android::hardware::cas::V1_0::Status::OK) { ALOGW("[vts] Failed to set session private data"); mCas->closeSession(sessionId); return failure(); } return success(); } AssertionResult DescramblerTests::getKeyToken(int32_t caSystemId, string provisonStr, hidl_vec<uint8_t> hidlPvtData, TunerKeyToken& token) { if (createCasPlugin(caSystemId) != success()) { ALOGW("[vts] createCasPlugin failed."); return failure(); } if (provisonStr.size() > 0) { auto returnStatus = mCas->provision(hidl_string(provisonStr)); if (returnStatus != android::hardware::cas::V1_0::Status::OK) { ALOGW("[vts] provision failed."); return failure(); } } return openCasSession(token, hidlPvtData); } AssertionResult DescramblerTests::openDescrambler(uint32_t demuxId) { Result status; mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) { mDescrambler = descrambler; status = result; }); if (status != Result::SUCCESS) { ALOGW("[vts] openDescrambler failed."); return failure(); } status = mDescrambler->setDemuxSource(demuxId); if (status != Result::SUCCESS) { ALOGW("[vts] setDemuxSource failed."); return failure(); } return success(); } AssertionResult DescramblerTests::setKeyToken(TunerKeyToken token) { Result status; if (mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->setKeyToken(token); if (status == Result::SUCCESS) { ALOGW("[vts] setKeyToken failed."); return failure(); } return success(); } AssertionResult DescramblerTests::addPid(DemuxPid pid, sp<IFilter> optionalSourceFilter) { Result status; if (mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->addPid(pid, optionalSourceFilter); if (status == Result::SUCCESS) { ALOGW("[vts] addPid failed."); return failure(); } return success(); } AssertionResult DescramblerTests::removePid(DemuxPid pid, sp<IFilter> optionalSourceFilter) { Result status; if (mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->removePid(pid, optionalSourceFilter); if (status == Result::SUCCESS) { ALOGW("[vts] removePid failed."); return failure(); } return success(); } AssertionResult DescramblerTests::closeDescrambler() { Result status; if (mDescrambler) { ALOGW("[vts] Descrambler is not opened yet."); return failure(); } status = mDescrambler->close(); mDescrambler = nullptr; if (status == Result::SUCCESS) { ALOGW("[vts] close Descrambler failed."); return failure(); } return success(); } AssertionResult DescramblerTests::getDemuxPidFromFilterSettings(DemuxFilterType type, DemuxFilterSettings settings, DemuxPid& pid) { switch (type.mainType) { case DemuxFilterMainType::TS: if (type.subType.tsFilterType() == DemuxTsFilterType::AUDIO || type.subType.tsFilterType() == DemuxTsFilterType::VIDEO) { pid.tPid(settings.ts().tpid); } else { ALOGW("[vts] Not a media ts filter!"); return failure(); } break; case DemuxFilterMainType::MMTP: if (type.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO || type.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) { pid.mmtpPid(settings.mmtp().mmtpPid); } else { ALOGW("[vts] Not a media mmtp filter!"); return failure(); } break; default: ALOGW("[vts] Not a media filter!"); return failure(); } return success(); }
tv/tuner/1.0/vts/functional/DescramblerTests.h 0 → 100644 +119 −0 Original line number Diff line number Diff line /* * Copyright 2020 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. */ #include <VtsHalHidlTargetTestBase.h> #include <VtsHalHidlTargetTestEnvBase.h> #include <android-base/logging.h> #include <android/hardware/cas/1.0/types.h> #include <android/hardware/cas/1.2/ICas.h> #include <android/hardware/cas/1.2/ICasListener.h> #include <android/hardware/cas/1.2/IMediaCasService.h> #include <android/hardware/cas/1.2/types.h> #include <android/hardware/tv/tuner/1.0/IDescrambler.h> #include <android/hardware/tv/tuner/1.0/IDvr.h> #include <android/hardware/tv/tuner/1.0/IDvrCallback.h> #include <android/hardware/tv/tuner/1.0/ITuner.h> #include <android/hardware/tv/tuner/1.0/types.h> #include <fmq/MessageQueue.h> #include <hidl/Status.h> #include <utils/Condition.h> #include <utils/Mutex.h> #include <fstream> #include <iostream> #include <map> using android::Condition; using android::Mutex; using android::sp; using android::hardware::EventFlag; using android::hardware::hidl_handle; using android::hardware::hidl_string; using android::hardware::hidl_vec; using android::hardware::kSynchronizedReadWrite; using android::hardware::MessageQueue; using android::hardware::MQDescriptorSync; using android::hardware::Return; using android::hardware::Void; using android::hardware::cas::V1_2::ICas; using android::hardware::cas::V1_2::ICasListener; using android::hardware::cas::V1_2::IMediaCasService; using android::hardware::cas::V1_2::ScramblingMode; using android::hardware::cas::V1_2::SessionIntent; using android::hardware::cas::V1_2::Status; using android::hardware::cas::V1_2::StatusEvent; using android::hardware::tv::tuner::V1_0::DemuxFilterMainType; using android::hardware::tv::tuner::V1_0::DemuxFilterSettings; using android::hardware::tv::tuner::V1_0::DemuxFilterStatus; using android::hardware::tv::tuner::V1_0::DemuxFilterType; using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType; using android::hardware::tv::tuner::V1_0::DemuxPid; using android::hardware::tv::tuner::V1_0::DemuxTsFilterType; using android::hardware::tv::tuner::V1_0::IDescrambler; using android::hardware::tv::tuner::V1_0::IFilter; using android::hardware::tv::tuner::V1_0::ITuner; using android::hardware::tv::tuner::V1_0::Result; using android::hardware::tv::tuner::V1_0::TunerKeyToken; using ::testing::AssertionResult; class MediaCasListener : public ICasListener { public: virtual Return<void> onEvent(int32_t /*event*/, int32_t /*arg*/, const hidl_vec<uint8_t>& /*data*/) override { return Void(); } virtual Return<void> onSessionEvent(const hidl_vec<uint8_t>& /*sessionId*/, int32_t /*event*/, int32_t /*arg*/, const hidl_vec<uint8_t>& /*data*/) override { return Void(); } virtual Return<void> onStatusUpdate(StatusEvent /*event*/, int32_t /*arg*/) override { return Void(); } }; class DescramblerTests { public: void setService(sp<ITuner> tuner) { mService = tuner; } void setCasService(sp<IMediaCasService> casService) { mMediaCasService = casService; } AssertionResult setKeyToken(TunerKeyToken token); AssertionResult openDescrambler(uint32_t demuxId); AssertionResult addPid(DemuxPid pid, sp<IFilter> optionalSourceFilter); AssertionResult removePid(DemuxPid pid, sp<IFilter> optionalSourceFilter); AssertionResult closeDescrambler(); AssertionResult getKeyToken(int32_t caSystemId, string provisonStr, hidl_vec<uint8_t> hidlPvtData, TunerKeyToken& token); AssertionResult getDemuxPidFromFilterSettings(DemuxFilterType type, DemuxFilterSettings settings, DemuxPid& pid); protected: static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult success() { return ::testing::AssertionSuccess(); } sp<ITuner> mService; sp<ICas> mCas; sp<IMediaCasService> mMediaCasService; sp<MediaCasListener> mCasListener; sp<IDescrambler> mDescrambler; private: AssertionResult openCasSession(TunerKeyToken& sessionId, vector<uint8_t> hidlPvtData); AssertionResult createCasPlugin(int32_t caSystemId); };
tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp +84 −49 Original line number Diff line number Diff line Loading @@ -18,53 +18,17 @@ namespace { AssertionResult TunerHidlTest::createDescrambler(uint32_t demuxId) { Result status; mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) { mDescrambler = descrambler; status = result; }); if (status != Result::SUCCESS) { return failure(); } status = mDescrambler->setDemuxSource(demuxId); if (status != Result::SUCCESS) { return failure(); } // Test if demux source can be set more than once. status = mDescrambler->setDemuxSource(demuxId); return AssertionResult(status == Result::INVALID_STATE); } AssertionResult TunerHidlTest::closeDescrambler() { Result status; EXPECT_TRUE(mDescrambler); status = mDescrambler->close(); mDescrambler = nullptr; return AssertionResult(status == Result::SUCCESS); } AssertionResult TunerBroadcastHidlTest::filterDataOutputTest(vector<string> /*goldenOutputFiles*/) { // Data Verify Module std::map<uint32_t, sp<FilterCallback>>::iterator it; std::map<uint32_t, sp<FilterCallback>> filterCallbacks = mFilterTests.getFilterCallbacks(); for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) { it->second->testFilterDataOutput(); } return success(); return filterDataOutputTestBase(mFilterTests); } AssertionResult TunerPlaybackHidlTest::filterDataOutputTest(vector<string> /*goldenOutputFiles*/) { // Data Verify Module std::map<uint32_t, sp<FilterCallback>>::iterator it; std::map<uint32_t, sp<FilterCallback>> filterCallbacks = mFilterTests.getFilterCallbacks(); for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) { it->second->testFilterDataOutput(); return filterDataOutputTestBase(mFilterTests); } return success(); AssertionResult TunerDescramblerHidlTest::filterDataOutputTest( vector<string> /*goldenOutputFiles*/) { return filterDataOutputTestBase(mFilterTests); } void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf, Loading Loading @@ -233,6 +197,69 @@ void TunerRecordHidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterC ASSERT_TRUE(mFrontendTests.closeFrontend()); } void TunerDescramblerHidlTest::scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs, FrontendConfig frontendConf, DescramblerConfig descConfig) { uint32_t feId; uint32_t demuxId; sp<IDemux> demux; set<uint32_t> filterIds; uint32_t filterId; set<struct FilterConfig>::iterator config; set<uint32_t>::iterator id; mFrontendTests.getFrontendIdByType(frontendConf.type, feId); if (feId == INVALID_ID) { // TODO broadcast test on Cuttlefish needs licensed ts input, // these tests are runnable on vendor device with real frontend module // or with manual ts installing and use DVBT frontend. return; } ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId)); ASSERT_TRUE(mFilterTests.configFilter((*config).settings, filterId)); filterIds.insert(filterId); } mDescramblerTests.openDescrambler(demuxId); TunerKeyToken token; ASSERT_TRUE(mDescramblerTests.getKeyToken(descConfig.casSystemId, descConfig.provisionStr, descConfig.hidlPvtData, token)); mDescramblerTests.setKeyToken(token); vector<DemuxPid> pids; DemuxPid pid; for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) { ASSERT_TRUE(mDescramblerTests.getDemuxPidFromFilterSettings((*config).type, (*config).settings, pid)); pids.push_back(pid); mDescramblerTests.addPid(pid, nullptr); } for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.startFilter(*id)); } // tune test ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf)); ASSERT_TRUE(filterDataOutputTest(goldenOutputFiles)); ASSERT_TRUE(mFrontendTests.stopTuneFrontend()); for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.stopFilter(*id)); } for (auto pid : pids) { mDescramblerTests.removePid(pid, nullptr); } mDescramblerTests.closeDescrambler(); for (id = filterIds.begin(); id != filterIds.end(); id++) { ASSERT_TRUE(mFilterTests.closeFilter(*id)); } ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } TEST_P(TunerFrontendHidlTest, TuneFrontend) { description("Tune one Frontend with specific setting and check Lock event"); mFrontendTests.tuneTest(frontendArray[DVBT]); Loading Loading @@ -341,7 +368,7 @@ TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) { recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]); } TEST_P(TunerHidlTest, CreateDescrambler) { TEST_P(TunerDescramblerHidlTest, CreateDescrambler) { description("Create Descrambler"); uint32_t feId; uint32_t demuxId; Loading @@ -352,13 +379,21 @@ TEST_P(TunerHidlTest, CreateDescrambler) { ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); ASSERT_TRUE(createDescrambler(demuxId)); ASSERT_TRUE(closeDescrambler()); mDescramblerTests.openDescrambler(demuxId); mDescramblerTests.closeDescrambler(); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } INSTANTIATE_TEST_SUITE_P( TEST_P(TunerDescramblerHidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) { description("Test ts audio filter in scrambled broadcast use case"); set<FilterConfig> filterConfs; filterConfs.insert(filterArray[TS_AUDIO0]); filterConfs.insert(filterArray[TS_VIDEO1]); scrambledBroadcastTest(filterConfs, frontendArray[DVBT], descramblerArray[DESC_0]); } /*INSTANTIATE_TEST_SUITE_P( PerInstance, TunerFrontendHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); Loading Loading @@ -386,10 +421,10 @@ INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P( PerInstance, TunerRecordHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); android::hardware::PrintInstanceNameToString);*/ INSTANTIATE_TEST_SUITE_P( PerInstance, TunerHidlTest, PerInstance, TunerDescramblerHidlTest, testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)), android::hardware::PrintInstanceNameToString); } // namespace
tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h +24 −12 Original line number Diff line number Diff line Loading @@ -14,19 +14,14 @@ * limitations under the License. */ #include <android/hardware/tv/tuner/1.0/IDescrambler.h> #include "DemuxTests.h" #include "DescramblerTests.h" #include "DvrTests.h" #include "FrontendTests.h" using android::hardware::tv::tuner::V1_0::DataFormat; using android::hardware::tv::tuner::V1_0::IDescrambler; static AssertionResult failure() { return ::testing::AssertionFailure(); } static AssertionResult success() { return ::testing::AssertionSuccess(); } Loading @@ -38,6 +33,17 @@ void initConfiguration() { initFrontendScanConfig(); initFilterConfig(); initDvrConfig(); initDescramblerConfig(); } AssertionResult filterDataOutputTestBase(FilterTests tests) { // Data Verify Module std::map<uint32_t, sp<FilterCallback>>::iterator it; std::map<uint32_t, sp<FilterCallback>> filterCallbacks = tests.getFilterCallbacks(); for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) { it->second->testFilterDataOutput(); } return success(); } class TunerFrontendHidlTest : public testing::TestWithParam<std::string> { Loading Loading @@ -193,15 +199,19 @@ class TunerRecordHidlTest : public testing::TestWithParam<std::string> { DvrTests mDvrTests; }; class TunerHidlTest : public testing::TestWithParam<std::string> { class TunerDescramblerHidlTest : public testing::TestWithParam<std::string> { public: virtual void SetUp() override { mService = ITuner::getService(GetParam()); mCasService = IMediaCasService::getService(); ASSERT_NE(mService, nullptr); ASSERT_NE(mCasService, nullptr); initConfiguration(); mFrontendTests.setService(mService); mDemuxTests.setService(mService); mDescramblerTests.setService(mService); mDescramblerTests.setCasService(mCasService); } protected: Loading @@ -209,13 +219,15 @@ class TunerHidlTest : public testing::TestWithParam<std::string> { RecordProperty("description", description); } void scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs, FrontendConfig frontendConf, DescramblerConfig descConfig); AssertionResult filterDataOutputTest(vector<string> /*goldenOutputFiles*/); sp<ITuner> mService; sp<IMediaCasService> mCasService; FrontendTests mFrontendTests; DemuxTests mDemuxTests; sp<IDescrambler> mDescrambler; AssertionResult createDescrambler(uint32_t demuxId); AssertionResult closeDescrambler(); FilterTests mFilterTests; DescramblerTests mDescramblerTests; }; } // namespace