Separate Demux and Filter fixture classes from the Tuner HAL VTS target
test
Test: atest VtsHalTvTunerV1_0TargetTest
Bug: 150953857
Change-Id: I373c3ba56ab80e02c79d24f865a956dae4b44226
diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp
index b4dbda7..448575e 100644
--- a/tv/tuner/1.0/vts/functional/Android.bp
+++ b/tv/tuner/1.0/vts/functional/Android.bp
@@ -20,6 +20,8 @@
srcs: [
"VtsHalTvTunerV1_0TargetTest.cpp",
"FrontendTests.cpp",
+ "DemuxTests.cpp",
+ "FilterTests.cpp",
],
static_libs: [
"android.hardware.tv.tuner@1.0",
diff --git a/tv/tuner/1.0/vts/functional/DemuxTests.cpp b/tv/tuner/1.0/vts/functional/DemuxTests.cpp
new file mode 100644
index 0000000..b1d8a0a
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/DemuxTests.cpp
@@ -0,0 +1,41 @@
+/*
+ * 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 "DemuxTests.h"
+
+AssertionResult DemuxTests::openDemux(sp<IDemux>& demux, uint32_t& demuxId) {
+ Result status;
+ mService->openDemux([&](Result result, uint32_t id, const sp<IDemux>& demuxSp) {
+ mDemux = demuxSp;
+ demux = demuxSp;
+ demuxId = id;
+ status = result;
+ });
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult DemuxTests::setDemuxFrontendDataSource(uint32_t frontendId) {
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ auto status = mDemux->setFrontendDataSource(frontendId);
+ return AssertionResult(status.isOk());
+}
+
+AssertionResult DemuxTests::closeDemux() {
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ auto status = mDemux->close();
+ mDemux = nullptr;
+ return AssertionResult(status.isOk());
+}
\ No newline at end of file
diff --git a/tv/tuner/1.0/vts/functional/DemuxTests.h b/tv/tuner/1.0/vts/functional/DemuxTests.h
new file mode 100644
index 0000000..f405a79
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/DemuxTests.h
@@ -0,0 +1,57 @@
+/*
+ * 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/tv/tuner/1.0/IDemux.h>
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <android/hardware/tv/tuner/1.0/types.h>
+#include <binder/MemoryDealer.h>
+#include <gtest/gtest.h>
+#include <hidl/ServiceManagement.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <map>
+
+using android::sp;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::tv::tuner::V1_0::IDemux;
+using android::hardware::tv::tuner::V1_0::ITuner;
+using android::hardware::tv::tuner::V1_0::Result;
+
+using ::testing::AssertionResult;
+
+class DemuxTests {
+ public:
+ sp<ITuner> mService;
+
+ void setService(sp<ITuner> tuner) { mService = tuner; }
+
+ AssertionResult openDemux(sp<IDemux>& demux, uint32_t& demuxId);
+ AssertionResult setDemuxFrontendDataSource(uint32_t frontendId);
+ AssertionResult closeDemux();
+
+ protected:
+ static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+ static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+ sp<IDemux> mDemux;
+};
\ No newline at end of file
diff --git a/tv/tuner/1.0/vts/functional/FilterTests.cpp b/tv/tuner/1.0/vts/functional/FilterTests.cpp
new file mode 100644
index 0000000..82e955d
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/FilterTests.cpp
@@ -0,0 +1,226 @@
+/*
+ * 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 "FilterTests.h"
+
+void FilterCallback::startFilterEventThread(DemuxFilterEvent event) {
+ struct FilterThreadArgs* threadArgs =
+ (struct FilterThreadArgs*)malloc(sizeof(struct FilterThreadArgs));
+ threadArgs->user = this;
+ threadArgs->event = event;
+
+ pthread_create(&mFilterThread, NULL, __threadLoopFilter, (void*)threadArgs);
+ pthread_setname_np(mFilterThread, "test_playback_input_loop");
+}
+
+void FilterCallback::testFilterDataOutput() {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (mPidFilterOutputCount < 1) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "filter output matching pid does not output within timeout";
+ return;
+ }
+ }
+ mPidFilterOutputCount = 0;
+ ALOGW("[vts] pass and stop");
+}
+
+void FilterCallback::updateFilterMQ(MQDesc& filterMQDescriptor) {
+ mFilterMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
+ EXPECT_TRUE(mFilterMQ);
+ EXPECT_TRUE(EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag) ==
+ android::OK);
+}
+
+void FilterCallback::updateGoldenOutputMap(string goldenOutputFile) {
+ mFilterIdToGoldenOutput = goldenOutputFile;
+}
+
+void* FilterCallback::__threadLoopFilter(void* threadArgs) {
+ FilterCallback* const self =
+ static_cast<FilterCallback*>(((struct FilterThreadArgs*)threadArgs)->user);
+ self->filterThreadLoop(((struct FilterThreadArgs*)threadArgs)->event);
+ return 0;
+}
+
+void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) {
+ android::Mutex::Autolock autoLock(mFilterOutputLock);
+ // Read from mFilterMQ[event.filterId] per event and filter type
+
+ // Assemble to filterOutput[filterId]
+
+ // check if filterOutput[filterId] matches goldenOutput[filterId]
+
+ // If match, remove filterId entry from MQ map
+
+ // end thread
+}
+
+bool FilterCallback::readFilterEventData() {
+ bool result = false;
+ DemuxFilterEvent filterEvent = mFilterEvent;
+ ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId);
+ // todo separate filter handlers
+ for (int i = 0; i < filterEvent.events.size(); i++) {
+ switch (mFilterEventType) {
+ case FilterEventType::SECTION:
+ mDataLength = filterEvent.events[i].section().dataLength;
+ break;
+ case FilterEventType::PES:
+ mDataLength = filterEvent.events[i].pes().dataLength;
+ break;
+ case FilterEventType::MEDIA:
+ return dumpAvData(filterEvent.events[i].media());
+ case FilterEventType::RECORD:
+ break;
+ case FilterEventType::MMTPRECORD:
+ break;
+ case FilterEventType::DOWNLOAD:
+ break;
+ default:
+ break;
+ }
+ // EXPECT_TRUE(mDataLength == goldenDataOutputBuffer.size()) << "buffer size does not
+ // match";
+
+ mDataOutputBuffer.resize(mDataLength);
+ result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength);
+ EXPECT_TRUE(result) << "can't read from Filter MQ";
+
+ /*for (int i = 0; i < mDataLength; i++) {
+ EXPECT_TRUE(goldenDataOutputBuffer[i] == mDataOutputBuffer[i]) << "data does not match";
+ }*/
+ }
+ mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
+ return result;
+}
+
+bool FilterCallback::dumpAvData(DemuxFilterMediaEvent event) {
+ uint32_t length = event.dataLength;
+ uint64_t dataId = event.avDataId;
+ // read data from buffer pointed by a handle
+ hidl_handle handle = event.avMemory;
+
+ int av_fd = handle.getNativeHandle()->data[0];
+ uint8_t* buffer = static_cast<uint8_t*>(
+ mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0 /*offset*/));
+ if (buffer == MAP_FAILED) {
+ ALOGE("[vts] fail to allocate av buffer, errno=%d", errno);
+ return false;
+ }
+ uint8_t output[length + 1];
+ memcpy(output, buffer, length);
+ // print buffer and check with golden output.
+ EXPECT_TRUE(mFilter->releaseAvHandle(handle, dataId) == Result::SUCCESS);
+ return true;
+}
+
+AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type) {
+ Result status;
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+
+ // Create demux callback
+ mFilterCallback = new FilterCallback();
+
+ // Add filter to the local demux
+ mDemux->openFilter(type, FMQ_SIZE_16M, mFilterCallback,
+ [&](Result result, const sp<IFilter>& filter) {
+ mFilter = filter;
+ status = result;
+ });
+
+ if (status == Result::SUCCESS) {
+ mFilterCallback->setFilterEventType(getFilterEventType(type));
+ }
+
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::getNewlyOpenedFilterId(uint32_t& filterId) {
+ Result status;
+ EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+ EXPECT_TRUE(mFilter) << "Test with openFilterInDemux first.";
+ EXPECT_TRUE(mFilterCallback) << "Test with openFilterInDemux first.";
+
+ mFilter->getId([&](Result result, uint32_t filterId) {
+ mFilterId = filterId;
+ status = result;
+ });
+
+ if (status == Result::SUCCESS) {
+ mFilterCallback->setFilterId(mFilterId);
+ mFilterCallback->setFilterInterface(mFilter);
+ mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId);
+ mFilters[mFilterId] = mFilter;
+ mFilterCallbacks[mFilterId] = mFilterCallback;
+ filterId = mFilterId;
+ }
+
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint32_t filterId) {
+ Result status;
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ status = mFilters[filterId]->configure(setting);
+
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::getFilterMQDescriptor(uint32_t filterId) {
+ Result status;
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
+
+ mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) {
+ mFilterMQDescriptor = filterMQDesc;
+ status = result;
+ });
+
+ if (status == Result::SUCCESS) {
+ mFilterCallbacks[filterId]->updateFilterMQ(mFilterMQDescriptor);
+ }
+
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::startFilter(uint32_t filterId) {
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ Result status = mFilters[filterId]->start();
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::stopFilter(uint32_t filterId) {
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ Result status = mFilters[filterId]->stop();
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::closeFilter(uint32_t filterId) {
+ EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+ Result status = mFilters[filterId]->close();
+ if (status == Result::SUCCESS) {
+ for (int i = 0; i < mUsedFilterIds.size(); i++) {
+ if (mUsedFilterIds[i] == filterId) {
+ mUsedFilterIds.erase(mUsedFilterIds.begin() + i);
+ break;
+ }
+ }
+ mFilterCallbacks.erase(filterId);
+ mFilters.erase(filterId);
+ }
+ return AssertionResult(status == Result::SUCCESS);
+}
\ No newline at end of file
diff --git a/tv/tuner/1.0/vts/functional/FilterTests.h b/tv/tuner/1.0/vts/functional/FilterTests.h
new file mode 100644
index 0000000..eab963b
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/FilterTests.h
@@ -0,0 +1,226 @@
+/*
+ * 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/tv/tuner/1.0/IFilter.h>
+#include <android/hardware/tv/tuner/1.0/IFilterCallback.h>
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <android/hardware/tv/tuner/1.0/types.h>
+#include <fmq/MessageQueue.h>
+#include <gtest/gtest.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Status.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#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::tv::tuner::V1_0::DemuxFilterEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
+using android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
+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::DemuxQueueNotifyBits;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
+using android::hardware::tv::tuner::V1_0::IDemux;
+using android::hardware::tv::tuner::V1_0::IFilter;
+using android::hardware::tv::tuner::V1_0::IFilterCallback;
+using android::hardware::tv::tuner::V1_0::ITuner;
+using android::hardware::tv::tuner::V1_0::Result;
+
+using ::testing::AssertionResult;
+
+enum FilterEventType : uint8_t {
+ UNDEFINED,
+ SECTION,
+ MEDIA,
+ PES,
+ RECORD,
+ MMTPRECORD,
+ DOWNLOAD,
+ TEMI,
+};
+
+using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using MQDesc = MQDescriptorSync<uint8_t>;
+
+const uint32_t FMQ_SIZE_1M = 0x100000;
+const uint32_t FMQ_SIZE_16M = 0x1000000;
+
+#define WAIT_TIMEOUT 3000000000
+
+class FilterCallback : public IFilterCallback {
+ public:
+ virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent) 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
+ mFilterEvent = filterEvent;
+ readFilterEventData();
+ mPidFilterOutputCount++;
+ // mFilterIdToMQ.erase(filterEvent.filterId);
+
+ // startFilterEventThread(filterEvent);
+ mMsgCondition.signal();
+ return Void();
+ }
+
+ virtual Return<void> onFilterStatus(const DemuxFilterStatus /*status*/) override {
+ return Void();
+ }
+
+ void setFilterId(uint32_t filterId) { mFilterId = filterId; }
+ void setFilterInterface(sp<IFilter> filter) { mFilter = filter; }
+ void setFilterEventType(FilterEventType type) { mFilterEventType = type; }
+
+ void testFilterDataOutput();
+
+ void startFilterEventThread(DemuxFilterEvent event);
+ static void* __threadLoopFilter(void* threadArgs);
+ void filterThreadLoop(DemuxFilterEvent& event);
+
+ void updateFilterMQ(MQDesc& filterMQDescriptor);
+ void updateGoldenOutputMap(string goldenOutputFile);
+ bool readFilterEventData();
+ bool dumpAvData(DemuxFilterMediaEvent event);
+
+ private:
+ struct FilterThreadArgs {
+ FilterCallback* user;
+ DemuxFilterEvent event;
+ };
+ uint16_t mDataLength = 0;
+ std::vector<uint8_t> mDataOutputBuffer;
+
+ string mFilterIdToGoldenOutput;
+
+ uint32_t mFilterId;
+ sp<IFilter> mFilter;
+ FilterEventType mFilterEventType;
+ std::unique_ptr<FilterMQ> mFilterMQ;
+ EventFlag* mFilterMQEventFlag;
+ DemuxFilterEvent mFilterEvent;
+
+ android::Mutex mMsgLock;
+ android::Mutex mFilterOutputLock;
+ android::Condition mMsgCondition;
+ android::Condition mFilterOutputCondition;
+
+ pthread_t mFilterThread;
+
+ int mPidFilterOutputCount = 0;
+};
+
+class FilterTests {
+ public:
+ void setService(sp<ITuner> tuner) { mService = tuner; }
+ void setDemux(sp<IDemux> demux) { mDemux = demux; }
+
+ std::map<uint32_t, sp<FilterCallback>> getFilterCallbacks() { return mFilterCallbacks; }
+
+ AssertionResult openFilterInDemux(DemuxFilterType type);
+ AssertionResult getNewlyOpenedFilterId(uint32_t& filterId);
+ AssertionResult configFilter(DemuxFilterSettings setting, uint32_t filterId);
+ AssertionResult getFilterMQDescriptor(uint32_t filterId);
+ AssertionResult startFilter(uint32_t filterId);
+ AssertionResult stopFilter(uint32_t filterId);
+ AssertionResult closeFilter(uint32_t filterId);
+
+ FilterEventType getFilterEventType(DemuxFilterType type) {
+ FilterEventType eventType = FilterEventType::UNDEFINED;
+ switch (type.mainType) {
+ case DemuxFilterMainType::TS:
+ switch (type.subType.tsFilterType()) {
+ case DemuxTsFilterType::UNDEFINED:
+ break;
+ case DemuxTsFilterType::SECTION:
+ eventType = FilterEventType::SECTION;
+ break;
+ case DemuxTsFilterType::PES:
+ eventType = FilterEventType::PES;
+ break;
+ case DemuxTsFilterType::TS:
+ break;
+ case DemuxTsFilterType::AUDIO:
+ case DemuxTsFilterType::VIDEO:
+ eventType = FilterEventType::MEDIA;
+ break;
+ case DemuxTsFilterType::PCR:
+ break;
+ case DemuxTsFilterType::RECORD:
+ eventType = FilterEventType::RECORD;
+ break;
+ case DemuxTsFilterType::TEMI:
+ eventType = FilterEventType::TEMI;
+ break;
+ }
+ break;
+ case DemuxFilterMainType::MMTP:
+ /*mmtpSettings*/
+ break;
+ case DemuxFilterMainType::IP:
+ /*ipSettings*/
+ break;
+ case DemuxFilterMainType::TLV:
+ /*tlvSettings*/
+ break;
+ case DemuxFilterMainType::ALP:
+ /*alpSettings*/
+ break;
+ default:
+ break;
+ }
+ return eventType;
+ }
+
+ protected:
+ static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+ static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+ sp<ITuner> mService;
+ sp<IFilter> mFilter;
+ sp<IDemux> mDemux;
+ std::map<uint32_t, sp<IFilter>> mFilters;
+ std::map<uint32_t, sp<FilterCallback>> mFilterCallbacks;
+
+ sp<FilterCallback> mFilterCallback;
+ MQDesc mFilterMQDescriptor;
+ vector<uint32_t> mUsedFilterIds;
+
+ uint32_t mFilterId = -1;
+};
\ No newline at end of file
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
index 5bc3705..fc5071c 100644
--- a/tv/tuner/1.0/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
@@ -307,4 +307,4 @@
ASSERT_TRUE(scanFrontend(frontendConf, scanType));
ASSERT_TRUE(stopScanFrontend());
ASSERT_TRUE(closeFrontend());
-}
\ No newline at end of file
+}
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.h b/tv/tuner/1.0/vts/functional/FrontendTests.h
index 5aa6e15..701be82 100644
--- a/tv/tuner/1.0/vts/functional/FrontendTests.h
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.h
@@ -45,10 +45,7 @@
using android::Mutex;
using android::sp;
using android::hardware::fromHeap;
-using android::hardware::hidl_handle;
-using android::hardware::hidl_string;
using android::hardware::hidl_vec;
-using android::hardware::HidlMemory;
using android::hardware::Return;
using android::hardware::Void;
using android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 59c9479..d836c26 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -17,119 +17,6 @@
#include "VtsHalTvTunerV1_0TargetTest.h"
namespace {
-/******************************** Start FilterCallback **********************************/
-void FilterCallback::startFilterEventThread(DemuxFilterEvent event) {
- struct FilterThreadArgs* threadArgs =
- (struct FilterThreadArgs*)malloc(sizeof(struct FilterThreadArgs));
- threadArgs->user = this;
- threadArgs->event = event;
-
- pthread_create(&mFilterThread, NULL, __threadLoopFilter, (void*)threadArgs);
- pthread_setname_np(mFilterThread, "test_playback_input_loop");
-}
-
-void FilterCallback::testFilterDataOutput() {
- android::Mutex::Autolock autoLock(mMsgLock);
- while (mPidFilterOutputCount < 1) {
- if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
- EXPECT_TRUE(false) << "filter output matching pid does not output within timeout";
- return;
- }
- }
- mPidFilterOutputCount = 0;
- ALOGW("[vts] pass and stop");
-}
-
-void FilterCallback::updateFilterMQ(MQDesc& filterMQDescriptor) {
- mFilterMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
- EXPECT_TRUE(mFilterMQ);
- EXPECT_TRUE(EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag) ==
- android::OK);
-}
-
-void FilterCallback::updateGoldenOutputMap(string goldenOutputFile) {
- mFilterIdToGoldenOutput = goldenOutputFile;
-}
-
-void* FilterCallback::__threadLoopFilter(void* threadArgs) {
- FilterCallback* const self =
- static_cast<FilterCallback*>(((struct FilterThreadArgs*)threadArgs)->user);
- self->filterThreadLoop(((struct FilterThreadArgs*)threadArgs)->event);
- return 0;
-}
-
-void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) {
- android::Mutex::Autolock autoLock(mFilterOutputLock);
- // Read from mFilterMQ[event.filterId] per event and filter type
-
- // Assemble to filterOutput[filterId]
-
- // check if filterOutput[filterId] matches goldenOutput[filterId]
-
- // If match, remove filterId entry from MQ map
-
- // end thread
-}
-
-bool FilterCallback::readFilterEventData() {
- bool result = false;
- DemuxFilterEvent filterEvent = mFilterEvent;
- ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId);
- // todo separate filter handlers
- for (int i = 0; i < filterEvent.events.size(); i++) {
- switch (mFilterEventType) {
- case FilterEventType::SECTION:
- mDataLength = filterEvent.events[i].section().dataLength;
- break;
- case FilterEventType::PES:
- mDataLength = filterEvent.events[i].pes().dataLength;
- break;
- case FilterEventType::MEDIA:
- return dumpAvData(filterEvent.events[i].media());
- case FilterEventType::RECORD:
- break;
- case FilterEventType::MMTPRECORD:
- break;
- case FilterEventType::DOWNLOAD:
- break;
- default:
- break;
- }
- // EXPECT_TRUE(mDataLength == goldenDataOutputBuffer.size()) << "buffer size does not
- // match";
-
- mDataOutputBuffer.resize(mDataLength);
- result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength);
- EXPECT_TRUE(result) << "can't read from Filter MQ";
-
- /*for (int i = 0; i < mDataLength; i++) {
- EXPECT_TRUE(goldenDataOutputBuffer[i] == mDataOutputBuffer[i]) << "data does not match";
- }*/
- }
- mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
- return result;
-}
-
-bool FilterCallback::dumpAvData(DemuxFilterMediaEvent event) {
- uint32_t length = event.dataLength;
- uint64_t dataId = event.avDataId;
- // read data from buffer pointed by a handle
- hidl_handle handle = event.avMemory;
-
- int av_fd = handle.getNativeHandle()->data[0];
- uint8_t* buffer = static_cast<uint8_t*>(
- mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0 /*offset*/));
- if (buffer == MAP_FAILED) {
- ALOGE("[vts] fail to allocate av buffer, errno=%d", errno);
- return false;
- }
- uint8_t output[length + 1];
- memcpy(output, buffer, length);
- // print buffer and check with golden output.
- EXPECT_TRUE(mFilter->releaseAvHandle(handle, dataId) == Result::SUCCESS);
- return true;
-}
-/******************************** End FilterCallback **********************************/
/******************************** Start DvrCallback **********************************/
void DvrCallback::startPlaybackInputThread(PlaybackConf playbackConf,
@@ -303,134 +190,9 @@
}
/********************************** End DvrCallback ************************************/
-/*============================ Start Demux APIs Tests Implementation ============================*/
-AssertionResult TunerHidlTest::openDemux() {
- Result status;
- mService->openDemux([&](Result result, uint32_t demuxId, const sp<IDemux>& demux) {
- mDemux = demux;
- mDemuxId = demuxId;
- status = result;
- });
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::setDemuxFrontendDataSource(uint32_t frontendId) {
- EXPECT_TRUE(mDemux) << "Test with openDemux first.";
- auto status = mDemux->setFrontendDataSource(frontendId);
- return AssertionResult(status.isOk());
-}
-
-AssertionResult TunerHidlTest::closeDemux() {
- EXPECT_TRUE(mDemux) << "Test with openDemux first.";
- auto status = mDemux->close();
- mDemux = nullptr;
- return AssertionResult(status.isOk());
-}
-
-AssertionResult TunerHidlTest::openFilterInDemux(DemuxFilterType type) {
- Result status;
- EXPECT_TRUE(mDemux) << "Test with openDemux first.";
-
- // Create demux callback
- mFilterCallback = new FilterCallback();
-
- // Add filter to the local demux
- mDemux->openFilter(type, FMQ_SIZE_16M, mFilterCallback,
- [&](Result result, const sp<IFilter>& filter) {
- mFilter = filter;
- status = result;
- });
-
- if (status == Result::SUCCESS) {
- mFilterCallback->setFilterEventType(getFilterEventType(type));
- }
-
- return AssertionResult(status == Result::SUCCESS);
-}
-/*============================ End Demux APIs Tests Implementation ============================*/
-
-/*=========================== Start Filter APIs Tests Implementation ===========================*/
-AssertionResult TunerHidlTest::getNewlyOpenedFilterId(uint32_t& filterId) {
- Result status;
- EXPECT_TRUE(mDemux) << "Test with openDemux first.";
- EXPECT_TRUE(mFilter) << "Test with openFilterInDemux first.";
- EXPECT_TRUE(mFilterCallback) << "Test with openFilterInDemux first.";
-
- mFilter->getId([&](Result result, uint32_t filterId) {
- mFilterId = filterId;
- status = result;
- });
-
- if (status == Result::SUCCESS) {
- mFilterCallback->setFilterId(mFilterId);
- mFilterCallback->setFilterInterface(mFilter);
- mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId);
- mFilters[mFilterId] = mFilter;
- mFilterCallbacks[mFilterId] = mFilterCallback;
- filterId = mFilterId;
- }
-
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::configFilter(DemuxFilterSettings setting, uint32_t filterId) {
- Result status;
- EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
- status = mFilters[filterId]->configure(setting);
-
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::getFilterMQDescriptor(uint32_t filterId) {
- Result status;
- EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
- EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
-
- mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) {
- mFilterMQDescriptor = filterMQDesc;
- status = result;
- });
-
- if (status == Result::SUCCESS) {
- mFilterCallbacks[filterId]->updateFilterMQ(mFilterMQDescriptor);
- }
-
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::startFilter(uint32_t filterId) {
- EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
- Result status = mFilters[filterId]->start();
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::stopFilter(uint32_t filterId) {
- EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
- Result status = mFilters[filterId]->stop();
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::closeFilter(uint32_t filterId) {
- EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
- Result status = mFilters[filterId]->close();
- if (status == Result::SUCCESS) {
- for (int i = 0; i < mUsedFilterIds.size(); i++) {
- if (mUsedFilterIds[i] == filterId) {
- mUsedFilterIds.erase(mUsedFilterIds.begin() + i);
- break;
- }
- }
- mFilterCallbacks.erase(filterId);
- mFilters.erase(filterId);
- }
- return AssertionResult(status == Result::SUCCESS);
-}
-/*=========================== End Filter APIs Tests Implementation ===========================*/
-
/*======================== Start Descrambler APIs Tests Implementation ========================*/
AssertionResult TunerHidlTest::createDescrambler() {
Result status;
- EXPECT_TRUE(mDemux) << "Test with openDemux first.";
mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) {
mDescrambler = descrambler;
status = result;
@@ -464,7 +226,6 @@
/*============================ Start Dvr APIs Tests Implementation ============================*/
AssertionResult TunerHidlTest::openDvrInDemux(DvrType type) {
Result status;
- EXPECT_TRUE(mDemux) << "Test with openDemux first.";
// Create dvr callback
mDvrCallback = new DvrCallback();
@@ -485,7 +246,6 @@
AssertionResult TunerHidlTest::getDvrMQDescriptor() {
Result status;
- EXPECT_TRUE(mDemux) << "Test with openDemux first.";
EXPECT_TRUE(mDvr) << "Test with openDvr first.";
mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
@@ -499,12 +259,10 @@
/*========================== Start Data Flow Tests Implementation ==========================*/
AssertionResult TunerHidlTest::broadcastDataFlowTest(vector<string> /*goldenOutputFiles*/) {
- EXPECT_TRUE(mDemux) << "Test with openDemux first.";
- EXPECT_TRUE(mFilterCallback) << "Test with getFilterMQDescriptor first.";
-
// Data Verify Module
std::map<uint32_t, sp<FilterCallback>>::iterator it;
- for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
+ std::map<uint32_t, sp<FilterCallback>> filterCallbacks = mFilterTests.getFilterCallbacks();
+ for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) {
it->second->testFilterDataOutput();
}
return success();
@@ -668,74 +426,26 @@
}
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
- ASSERT_TRUE(openDemux());
- ASSERT_TRUE(setDemuxFrontendDataSource(feId));
- ASSERT_TRUE(openFilterInDemux(filterConf.type));
+ ASSERT_TRUE(mDemuxTests.openDemux(mDemux, mDemuxId));
+ mFilterTests.setDemux(mDemux);
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type));
uint32_t filterId;
- ASSERT_TRUE(getNewlyOpenedFilterId(filterId));
- ASSERT_TRUE(configFilter(filterConf.setting, filterId));
- ASSERT_TRUE(getFilterMQDescriptor(filterId));
- ASSERT_TRUE(startFilter(filterId));
+ ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
+ ASSERT_TRUE(mFilterTests.configFilter(filterConf.setting, filterId));
+ ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(mFilterTests.startFilter(filterId));
// tune test
ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf));
// broadcast data flow test
ASSERT_TRUE(broadcastDataFlowTest(goldenOutputFiles));
ASSERT_TRUE(mFrontendTests.stopTuneFrontend());
- ASSERT_TRUE(stopFilter(filterId));
- ASSERT_TRUE(closeFilter(filterId));
- ASSERT_TRUE(closeDemux());
+ ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+ ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+ ASSERT_TRUE(mDemuxTests.closeDemux());
ASSERT_TRUE(mFrontendTests.closeFrontend());
}
/*================================== End Test Module ==================================*/
-
-/*=============================== Start Helper Functions ===============================*/
-FilterEventType TunerHidlTest::getFilterEventType(DemuxFilterType type) {
- FilterEventType eventType = FilterEventType::UNDEFINED;
- switch (type.mainType) {
- case DemuxFilterMainType::TS:
- switch (type.subType.tsFilterType()) {
- case DemuxTsFilterType::UNDEFINED:
- break;
- case DemuxTsFilterType::SECTION:
- eventType = FilterEventType::SECTION;
- break;
- case DemuxTsFilterType::PES:
- eventType = FilterEventType::PES;
- break;
- case DemuxTsFilterType::TS:
- break;
- case DemuxTsFilterType::AUDIO:
- case DemuxTsFilterType::VIDEO:
- eventType = FilterEventType::MEDIA;
- break;
- case DemuxTsFilterType::PCR:
- break;
- case DemuxTsFilterType::RECORD:
- eventType = FilterEventType::RECORD;
- break;
- case DemuxTsFilterType::TEMI:
- eventType = FilterEventType::TEMI;
- break;
- }
- break;
- case DemuxFilterMainType::MMTP:
- /*mmtpSettings*/
- break;
- case DemuxFilterMainType::IP:
- /*ipSettings*/
- break;
- case DemuxFilterMainType::TLV:
- /*tlvSettings*/
- break;
- case DemuxFilterMainType::ALP:
- /*alpSettings*/
- break;
- default:
- break;
- }
- return eventType;
-}
-/*============================== End Helper Functions ==============================*/
/***************************** End Test Implementation *****************************/
/******************************** Start Test Entry **********************************/
@@ -754,28 +464,39 @@
mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND);
}
-/*============================ Start Demux/Filter Tests ============================*/
-TEST_P(TunerHidlTest, StartFilterInDemux) {
+TEST_P(TunerDemuxHidlTest, openDemux) {
+ description("Open and close a Demux.");
+ uint32_t feId;
+ mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
+ ASSERT_TRUE(feId != INVALID_ID);
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+ ASSERT_TRUE(mDemuxTests.openDemux(mDemux, mDemuxId));
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ ASSERT_TRUE(mDemuxTests.closeDemux());
+}
+
+TEST_P(TunerFilterHidlTest, StartFilterInDemux) {
description("Open and start a filter in Demux.");
uint32_t feId;
mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
ASSERT_TRUE(feId != INVALID_ID);
ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
ASSERT_TRUE(mFrontendTests.setFrontendCallback());
- ASSERT_TRUE(openDemux());
- ASSERT_TRUE(setDemuxFrontendDataSource(feId));
- ASSERT_TRUE(openFilterInDemux(filterArray[TS_VIDEO0].type));
+ ASSERT_TRUE(mDemuxTests.openDemux(mDemux, mDemuxId));
+ mFilterTests.setDemux(mDemux);
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO0].type));
uint32_t filterId;
- ASSERT_TRUE(getNewlyOpenedFilterId(filterId));
- ASSERT_TRUE(configFilter(filterArray[TS_VIDEO0].setting, filterId));
- ASSERT_TRUE(getFilterMQDescriptor(filterId));
- ASSERT_TRUE(startFilter(filterId));
- ASSERT_TRUE(stopFilter(filterId));
- ASSERT_TRUE(closeFilter(filterId));
- ASSERT_TRUE(closeDemux());
+ ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
+ ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO0].setting, filterId));
+ ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+ ASSERT_TRUE(mFilterTests.startFilter(filterId));
+ ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+ ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+ ASSERT_TRUE(mDemuxTests.closeDemux());
ASSERT_TRUE(mFrontendTests.closeFrontend());
}
-/*============================ End Demux/Filter Tests ============================*/
/*============================ Start Descrambler Tests ============================*/
/*
@@ -911,4 +632,14 @@
PerInstance, TunerHidlTest,
testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, TunerDemuxHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, TunerFilterHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
+ android::hardware::PrintInstanceNameToString);
} // namespace
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
index 4d6715e..f177047 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
@@ -14,70 +14,27 @@
* limitations under the License.
*/
-#include <android/hardware/tv/tuner/1.0/IDemux.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/IFilter.h>
-#include <android/hardware/tv/tuner/1.0/IFilterCallback.h>
-#include <android/hardware/tv/tuner/1.0/types.h>
-#include <binder/MemoryDealer.h>
-#include <fmq/MessageQueue.h>
#include <fstream>
#include <iostream>
-#include <map>
+#include "DemuxTests.h"
+#include "FilterTests.h"
#include "FrontendTests.h"
-using android::hardware::EventFlag;
-using android::hardware::kSynchronizedReadWrite;
-using android::hardware::MessageQueue;
-using android::hardware::MQDescriptorSync;
using android::hardware::tv::tuner::V1_0::DataFormat;
-using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
-using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
-using android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent;
-using android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings;
-using android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
-using android::hardware::tv::tuner::V1_0::DemuxFilterRecordSettings;
-using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
-using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
-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::DemuxQueueNotifyBits;
-using android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
-using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
using android::hardware::tv::tuner::V1_0::DvrSettings;
using android::hardware::tv::tuner::V1_0::DvrType;
-using android::hardware::tv::tuner::V1_0::IDemux;
using android::hardware::tv::tuner::V1_0::IDescrambler;
using android::hardware::tv::tuner::V1_0::IDvr;
using android::hardware::tv::tuner::V1_0::IDvrCallback;
-using android::hardware::tv::tuner::V1_0::IFilter;
-using android::hardware::tv::tuner::V1_0::IFilterCallback;
using android::hardware::tv::tuner::V1_0::PlaybackSettings;
using android::hardware::tv::tuner::V1_0::PlaybackStatus;
using android::hardware::tv::tuner::V1_0::RecordSettings;
using android::hardware::tv::tuner::V1_0::RecordStatus;
-using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-using MQDesc = MQDescriptorSync<uint8_t>;
-
-const uint32_t FMQ_SIZE_1M = 0x100000;
-const uint32_t FMQ_SIZE_16M = 0x1000000;
-
-enum FilterEventType : uint8_t {
- UNDEFINED,
- SECTION,
- MEDIA,
- PES,
- RECORD,
- MMTPRECORD,
- DOWNLOAD,
- TEMI,
-};
-
struct PlaybackConf {
string inputDataFile;
PlaybackSettings setting;
@@ -93,68 +50,6 @@
namespace {
-class FilterCallback : public IFilterCallback {
- public:
- virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent) 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
- mFilterEvent = filterEvent;
- readFilterEventData();
- mPidFilterOutputCount++;
- // mFilterIdToMQ.erase(filterEvent.filterId);
-
- // startFilterEventThread(filterEvent);
- mMsgCondition.signal();
- return Void();
- }
-
- virtual Return<void> onFilterStatus(const DemuxFilterStatus /*status*/) override {
- return Void();
- }
-
- void setFilterId(uint32_t filterId) { mFilterId = filterId; }
- void setFilterInterface(sp<IFilter> filter) { mFilter = filter; }
- void setFilterEventType(FilterEventType type) { mFilterEventType = type; }
-
- void testFilterDataOutput();
-
- void startFilterEventThread(DemuxFilterEvent event);
- static void* __threadLoopFilter(void* threadArgs);
- void filterThreadLoop(DemuxFilterEvent& event);
-
- void updateFilterMQ(MQDesc& filterMQDescriptor);
- void updateGoldenOutputMap(string goldenOutputFile);
- bool readFilterEventData();
- bool dumpAvData(DemuxFilterMediaEvent event);
-
- private:
- struct FilterThreadArgs {
- FilterCallback* user;
- DemuxFilterEvent event;
- };
- uint16_t mDataLength = 0;
- std::vector<uint8_t> mDataOutputBuffer;
-
- string mFilterIdToGoldenOutput;
-
- uint32_t mFilterId;
- sp<IFilter> mFilter;
- FilterEventType mFilterEventType;
- std::unique_ptr<FilterMQ> mFilterMQ;
- EventFlag* mFilterMQEventFlag;
- DemuxFilterEvent mFilterEvent;
-
- android::Mutex mMsgLock;
- android::Mutex mFilterOutputLock;
- android::Condition mMsgCondition;
- android::Condition mFilterOutputCondition;
-
- pthread_t mFilterThread;
-
- int mPidFilterOutputCount = 0;
-};
-
class DvrCallback : public IDvrCallback {
public:
virtual Return<void> onRecordStatus(DemuxFilterStatus status) override {
@@ -240,9 +135,6 @@
class TunerFrontendHidlTest : public testing::TestWithParam<std::string> {
public:
- sp<ITuner> mService;
- FrontendTests mFrontendTests;
-
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
ASSERT_NE(mService, nullptr);
@@ -256,12 +148,69 @@
static void description(const std::string& description) {
RecordProperty("description", description);
}
+
+ sp<ITuner> mService;
+ FrontendTests mFrontendTests;
+};
+
+class TunerDemuxHidlTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ mService = ITuner::getService(GetParam());
+ ASSERT_NE(mService, nullptr);
+ initFrontendConfig();
+ initFrontendScanConfig();
+ initFilterConfig();
+
+ mFrontendTests.setService(mService);
+ mDemuxTests.setService(mService);
+ }
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+
+ sp<ITuner> mService;
+ FrontendTests mFrontendTests;
+ DemuxTests mDemuxTests;
+ sp<IDemux> mDemux;
+ uint32_t mDemuxId;
+};
+
+class TunerFilterHidlTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ mService = ITuner::getService(GetParam());
+ ASSERT_NE(mService, nullptr);
+ initFrontendConfig();
+ initFrontendScanConfig();
+ initFilterConfig();
+
+ mFrontendTests.setService(mService);
+ mDemuxTests.setService(mService);
+ mFilterTests.setService(mService);
+ }
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+
+ sp<ITuner> mService;
+ FrontendTests mFrontendTests;
+ DemuxTests mDemuxTests;
+ FilterTests mFilterTests;
+ sp<IDemux> mDemux;
+ uint32_t mDemuxId;
};
class TunerHidlTest : public testing::TestWithParam<std::string> {
public:
sp<ITuner> mService;
FrontendTests mFrontendTests;
+ DemuxTests mDemuxTests;
+ FilterTests mFilterTests;
virtual void SetUp() override {
mService = ITuner::getService(GetParam());
@@ -271,6 +220,8 @@
initFilterConfig();
mFrontendTests.setService(mService);
+ mDemuxTests.setService(mService);
+ mFilterTests.setService(mService);
}
protected:
@@ -279,43 +230,21 @@
}
sp<IDescrambler> mDescrambler;
-
- sp<IDemux> mDemux;
sp<IDvr> mDvr;
- sp<IFilter> mFilter;
- std::map<uint32_t, sp<IFilter>> mFilters;
- std::map<uint32_t, sp<FilterCallback>> mFilterCallbacks;
+ sp<IDemux> mDemux;
+ uint32_t mDemuxId;
- sp<FilterCallback> mFilterCallback;
sp<DvrCallback> mDvrCallback;
- MQDesc mFilterMQDescriptor;
MQDesc mDvrMQDescriptor;
MQDesc mRecordMQDescriptor;
- vector<uint32_t> mUsedFilterIds;
- hidl_vec<FrontendId> mFeIds;
-
- uint32_t mDemuxId;
- uint32_t mFilterId = -1;
pthread_t mPlaybackshread;
bool mPlaybackThreadRunning;
- AssertionResult openDemux();
- AssertionResult setDemuxFrontendDataSource(uint32_t frontendId);
- AssertionResult closeDemux();
-
AssertionResult openDvrInDemux(DvrType type);
AssertionResult configDvr(DvrSettings setting);
AssertionResult getDvrMQDescriptor();
- AssertionResult openFilterInDemux(DemuxFilterType type);
- AssertionResult getNewlyOpenedFilterId(uint32_t& filterId);
- AssertionResult configFilter(DemuxFilterSettings setting, uint32_t filterId);
- AssertionResult getFilterMQDescriptor(uint32_t filterId);
- AssertionResult startFilter(uint32_t filterId);
- AssertionResult stopFilter(uint32_t filterId);
- AssertionResult closeFilter(uint32_t filterId);
-
AssertionResult createDescrambler();
AssertionResult closeDescrambler();
@@ -327,7 +256,5 @@
AssertionResult broadcastDataFlowTest(vector<string> goldenOutputFiles);
void broadcastSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf);
-
- FilterEventType getFilterEventType(DemuxFilterType type);
};
} // namespace
\ No newline at end of file