Add VTS for Filter TimeDelayHint
Test: atest VtsHalTvTunerTargetTest Bug: 183057734 Change-Id: I4a97d81c0100ca4114353ed84335fc1593bff800
This commit is contained in:
parent
80bbf093d3
commit
149b087169
3 changed files with 84 additions and 9 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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…
Reference in a new issue