Loading tv/tuner/aidl/vts/functional/FilterTests.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,33 @@ using ::aidl::android::hardware::common::NativeHandle; ::ndk::ScopedAStatus FilterCallback::onFilterEvent(const vector<DemuxFilterEvent>& events) { android::Mutex::Autolock autoLock(mMsgLock); // Temprarily we treat the first coming back filter data on the matching pid a success // once all of the MQ are cleared, means we got all the expected output readFilterEventsData(events); mPidFilterOutputCount++; mMsgCondition.signal(); // HACK: we need to cast the const away as DemuxFilterEvent contains a ScopedFileDescriptor // that cannot be copied. for (auto&& e : const_cast<std::vector<DemuxFilterEvent>&>(events)) { auto it = mFilterEventPromises.find(e.getTag()); if (it != mFilterEventPromises.cend()) { it->second.set_value(std::move(e)); mFilterEventPromises.erase(it); } } return ::ndk::ScopedAStatus::ok(); } std::future<DemuxFilterEvent> FilterCallback::getNextFilterEventWithTag(DemuxFilterEvent::Tag tag) { // Note: this currently only supports one future per DemuxFilterEvent::Tag. mFilterEventPromises[tag] = std::promise<DemuxFilterEvent>(); return mFilterEventPromises[tag].get_future(); } void FilterCallback::testFilterDataOutput() { android::Mutex::Autolock autoLock(mMsgLock); while (mPidFilterOutputCount < 1) { Loading tv/tuner/aidl/vts/functional/FilterTests.h +6 −9 Original line number Diff line number Diff line Loading @@ -24,7 +24,9 @@ #include <log/log.h> #include <utils/Condition.h> #include <utils/Mutex.h> #include <future> #include <map> #include <unordered_map> #include <fmq/AidlMessageQueue.h> Loading Loading @@ -58,15 +60,9 @@ using MQDesc = MQDescriptor<int8_t, SynchronizedReadWrite>; class FilterCallback : public BnFilterCallback { public: virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override { android::Mutex::Autolock autoLock(mMsgLock); // Temprarily we treat the first coming back filter data on the matching pid a success // once all of the MQ are cleared, means we got all the expected output readFilterEventsData(events); mPidFilterOutputCount++; mMsgCondition.signal(); return ::ndk::ScopedAStatus::ok(); } virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override; std::future<DemuxFilterEvent> getNextFilterEventWithTag(DemuxFilterEvent::Tag tag); virtual ::ndk::ScopedAStatus onFilterStatus(const DemuxFilterStatus /*status*/) override { return ::ndk::ScopedAStatus::ok(); Loading @@ -89,6 +85,7 @@ class FilterCallback : public BnFilterCallback { int32_t mFilterId; std::shared_ptr<IFilter> mFilter; std::unordered_map<DemuxFilterEvent::Tag, std::promise<DemuxFilterEvent>> mFilterEventPromises; native_handle_t* mAvSharedHandle = nullptr; uint64_t mAvSharedMemSize = -1; Loading tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -640,6 +640,57 @@ TEST_P(TunerFilterAidlTest, testTimeFilter) { testTimeFilter(timeFilterMap[timeFilter.timeFilterId]); } // TODO: move boilerplate into text fixture TEST_P(TunerFilterAidlTest, FilterTimeDelayHintTest) { description("Test filter delay hint."); int32_t feId; int32_t demuxId; std::shared_ptr<IDemux> demux; int64_t filterId; mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); const auto& filterConf = filterMap[live.ipFilterId]; ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); auto filter = mFilterTests.getFilterById(filterId); auto delayValue = std::chrono::milliseconds(5000); FilterDelayHint delayHint; delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS; delayHint.hintValue = delayValue.count(); auto status = filter->setDelayHint(delayHint); ASSERT_TRUE(status.isOk()); auto startTime = std::chrono::steady_clock::now(); ASSERT_TRUE(mFilterTests.startFilter(filterId)); auto cb = mFilterTests.getFilterCallbacks().at(filterId); auto future = cb->getNextFilterEventWithTag(DemuxFilterEvent::Tag::ipPayload); // block and wait for callback to be received. ASSERT_EQ(future.wait_for(std::chrono::seconds(10)), std::future_status::ready); auto duration = std::chrono::steady_clock::now() - startTime; ASSERT_GE(duration, delayValue); // cleanup ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) { description("Feed ts data from playback and configure Ts section filter to get output"); if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) { Loading Loading
tv/tuner/aidl/vts/functional/FilterTests.cpp +27 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,33 @@ using ::aidl::android::hardware::common::NativeHandle; ::ndk::ScopedAStatus FilterCallback::onFilterEvent(const vector<DemuxFilterEvent>& events) { android::Mutex::Autolock autoLock(mMsgLock); // Temprarily we treat the first coming back filter data on the matching pid a success // once all of the MQ are cleared, means we got all the expected output readFilterEventsData(events); mPidFilterOutputCount++; mMsgCondition.signal(); // HACK: we need to cast the const away as DemuxFilterEvent contains a ScopedFileDescriptor // that cannot be copied. for (auto&& e : const_cast<std::vector<DemuxFilterEvent>&>(events)) { auto it = mFilterEventPromises.find(e.getTag()); if (it != mFilterEventPromises.cend()) { it->second.set_value(std::move(e)); mFilterEventPromises.erase(it); } } return ::ndk::ScopedAStatus::ok(); } std::future<DemuxFilterEvent> FilterCallback::getNextFilterEventWithTag(DemuxFilterEvent::Tag tag) { // Note: this currently only supports one future per DemuxFilterEvent::Tag. mFilterEventPromises[tag] = std::promise<DemuxFilterEvent>(); return mFilterEventPromises[tag].get_future(); } void FilterCallback::testFilterDataOutput() { android::Mutex::Autolock autoLock(mMsgLock); while (mPidFilterOutputCount < 1) { Loading
tv/tuner/aidl/vts/functional/FilterTests.h +6 −9 Original line number Diff line number Diff line Loading @@ -24,7 +24,9 @@ #include <log/log.h> #include <utils/Condition.h> #include <utils/Mutex.h> #include <future> #include <map> #include <unordered_map> #include <fmq/AidlMessageQueue.h> Loading Loading @@ -58,15 +60,9 @@ using MQDesc = MQDescriptor<int8_t, SynchronizedReadWrite>; class FilterCallback : public BnFilterCallback { public: virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override { android::Mutex::Autolock autoLock(mMsgLock); // Temprarily we treat the first coming back filter data on the matching pid a success // once all of the MQ are cleared, means we got all the expected output readFilterEventsData(events); mPidFilterOutputCount++; mMsgCondition.signal(); return ::ndk::ScopedAStatus::ok(); } virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override; std::future<DemuxFilterEvent> getNextFilterEventWithTag(DemuxFilterEvent::Tag tag); virtual ::ndk::ScopedAStatus onFilterStatus(const DemuxFilterStatus /*status*/) override { return ::ndk::ScopedAStatus::ok(); Loading @@ -89,6 +85,7 @@ class FilterCallback : public BnFilterCallback { int32_t mFilterId; std::shared_ptr<IFilter> mFilter; std::unordered_map<DemuxFilterEvent::Tag, std::promise<DemuxFilterEvent>> mFilterEventPromises; native_handle_t* mAvSharedHandle = nullptr; uint64_t mAvSharedMemSize = -1; Loading
tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp +51 −0 Original line number Diff line number Diff line Loading @@ -640,6 +640,57 @@ TEST_P(TunerFilterAidlTest, testTimeFilter) { testTimeFilter(timeFilterMap[timeFilter.timeFilterId]); } // TODO: move boilerplate into text fixture TEST_P(TunerFilterAidlTest, FilterTimeDelayHintTest) { description("Test filter delay hint."); int32_t feId; int32_t demuxId; std::shared_ptr<IDemux> demux; int64_t filterId; mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId); ASSERT_TRUE(feId != INVALID_ID); ASSERT_TRUE(mFrontendTests.openFrontendById(feId)); ASSERT_TRUE(mFrontendTests.setFrontendCallback()); ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId)); ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId)); mFilterTests.setDemux(demux); const auto& filterConf = filterMap[live.ipFilterId]; ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize)); ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId)); ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId)); ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId)); auto filter = mFilterTests.getFilterById(filterId); auto delayValue = std::chrono::milliseconds(5000); FilterDelayHint delayHint; delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS; delayHint.hintValue = delayValue.count(); auto status = filter->setDelayHint(delayHint); ASSERT_TRUE(status.isOk()); auto startTime = std::chrono::steady_clock::now(); ASSERT_TRUE(mFilterTests.startFilter(filterId)); auto cb = mFilterTests.getFilterCallbacks().at(filterId); auto future = cb->getNextFilterEventWithTag(DemuxFilterEvent::Tag::ipPayload); // block and wait for callback to be received. ASSERT_EQ(future.wait_for(std::chrono::seconds(10)), std::future_status::ready); auto duration = std::chrono::steady_clock::now() - startTime; ASSERT_GE(duration, delayValue); // cleanup ASSERT_TRUE(mFilterTests.stopFilter(filterId)); ASSERT_TRUE(mFilterTests.closeFilter(filterId)); ASSERT_TRUE(mDemuxTests.closeDemux()); ASSERT_TRUE(mFrontendTests.closeFrontend()); } TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) { description("Feed ts data from playback and configure Ts section filter to get output"); if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) { Loading