Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b03aa95 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add VTS for Filter TimeDelayHint"

parents c9f9a745 149b0871
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -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) {
+6 −9
Original line number Diff line number Diff line
@@ -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;

+51 −0
Original line number Diff line number Diff line
@@ -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) {