Add VTS for Filter TimeDelayHint

Test: atest VtsHalTvTunerTargetTest
Bug: 183057734
Change-Id: I4a97d81c0100ca4114353ed84335fc1593bff800
This commit is contained in:
Patrick Rohr 2021-11-20 00:39:37 +01:00
parent 80bbf093d3
commit 149b087169
3 changed files with 84 additions and 9 deletions

View file

@ -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) {

View file

@ -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>
@ -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();
@ -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;

View file

@ -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) {