Make VtsHalTvTunerV1_0FrontendTest an independent test.
Note that this refactoring extracts two header files for
VtsHalTvTunerV1_0FrontendTest and VtsHalTvTunerV1_0TargetTest.
Test: atest VtsHalTvTunerV1_0FrontendTest/VtsHalTvTunerV1_0TargetTest
Bug: 150953857
Change-Id: Ie5f0dc4a9180ecc779004cb451a45ae54a6ea47c
diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp
index 641e16a..b4dbda7 100644
--- a/tv/tuner/1.0/vts/functional/Android.bp
+++ b/tv/tuner/1.0/vts/functional/Android.bp
@@ -17,7 +17,10 @@
cc_test {
name: "VtsHalTvTunerV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
- srcs: ["VtsHalTvTunerV1_0TargetTest.cpp"],
+ srcs: [
+ "VtsHalTvTunerV1_0TargetTest.cpp",
+ "FrontendTests.cpp",
+ ],
static_libs: [
"android.hardware.tv.tuner@1.0",
"android.hidl.allocator@1.0",
diff --git a/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
new file mode 100644
index 0000000..5bc3705
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
@@ -0,0 +1,310 @@
+/*
+ * 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 "FrontendTests.h"
+
+Return<void> FrontendCallback::onEvent(FrontendEventType frontendEventType) {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ ALOGD("[vts] frontend event received. Type: %d", frontendEventType);
+ mEventReceived = true;
+ mMsgCondition.signal();
+ switch (frontendEventType) {
+ case FrontendEventType::LOCKED:
+ mLockMsgReceived = true;
+ mLockMsgCondition.signal();
+ return Void();
+ default:
+ // do nothing
+ return Void();
+ }
+}
+
+Return<void> FrontendCallback::onScanMessage(FrontendScanMessageType type,
+ const FrontendScanMessage& message) {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (!mScanMsgProcessed) {
+ mMsgCondition.wait(mMsgLock);
+ }
+ ALOGD("[vts] frontend scan message. Type: %d", type);
+ mScanMessageReceived = true;
+ mScanMsgProcessed = false;
+ mScanMessageType = type;
+ mScanMessage = message;
+ mMsgCondition.signal();
+ return Void();
+}
+
+void FrontendCallback::tuneTestOnEventReceive(sp<IFrontend>& frontend, FrontendSettings settings) {
+ Result result = frontend->tune(settings);
+ EXPECT_TRUE(result == Result::SUCCESS);
+
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (!mEventReceived) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "Event not received within timeout";
+ mLockMsgReceived = false;
+ return;
+ }
+ }
+ mEventReceived = false;
+}
+
+void FrontendCallback::tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings) {
+ Result result = frontend->tune(settings);
+ EXPECT_TRUE(result == Result::SUCCESS);
+
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (!mLockMsgReceived) {
+ if (-ETIMEDOUT == mLockMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "Event LOCKED not received within timeout";
+ mLockMsgReceived = false;
+ return;
+ }
+ }
+ mLockMsgReceived = false;
+}
+
+void FrontendCallback::scanTest(sp<IFrontend>& frontend, FrontendConfig config,
+ FrontendScanType type) {
+ uint32_t targetFrequency = getTargetFrequency(config.settings, config.type);
+ if (type == FrontendScanType::SCAN_BLIND) {
+ // reset the frequency in the scan configuration to test blind scan. The settings param of
+ // passed in means the real input config on the transponder connected to the DUT.
+ // We want the blind the test to start from lower frequency than this to check the blind
+ // scan implementation.
+ resetBlindScanStartingFrequency(config, targetFrequency - 100);
+ }
+
+ Result result = frontend->scan(config.settings, type);
+ EXPECT_TRUE(result == Result::SUCCESS);
+
+ bool scanMsgLockedReceived = false;
+ bool targetFrequencyReceived = false;
+
+ android::Mutex::Autolock autoLock(mMsgLock);
+wait:
+ while (!mScanMessageReceived) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "Scan message not received within timeout";
+ mScanMessageReceived = false;
+ mScanMsgProcessed = true;
+ return;
+ }
+ }
+
+ if (mScanMessageType != FrontendScanMessageType::END) {
+ if (mScanMessageType == FrontendScanMessageType::LOCKED) {
+ scanMsgLockedReceived = true;
+ Result result = frontend->scan(config.settings, type);
+ EXPECT_TRUE(result == Result::SUCCESS);
+ }
+
+ if (mScanMessageType == FrontendScanMessageType::FREQUENCY) {
+ targetFrequencyReceived = mScanMessage.frequencies().size() > 0 &&
+ mScanMessage.frequencies()[0] == targetFrequency;
+ }
+
+ if (mScanMessageType == FrontendScanMessageType::PROGRESS_PERCENT) {
+ ALOGD("[vts] Scan in progress...[%d%%]", mScanMessage.progressPercent());
+ }
+
+ mScanMessageReceived = false;
+ mScanMsgProcessed = true;
+ mMsgCondition.signal();
+ goto wait;
+ }
+
+ EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
+ EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
+ mScanMessageReceived = false;
+ mScanMsgProcessed = true;
+}
+
+uint32_t FrontendCallback::getTargetFrequency(FrontendSettings settings, FrontendType type) {
+ switch (type) {
+ case FrontendType::ANALOG:
+ return settings.analog().frequency;
+ case FrontendType::ATSC:
+ return settings.atsc().frequency;
+ case FrontendType::ATSC3:
+ return settings.atsc3().frequency;
+ case FrontendType::DVBC:
+ return settings.dvbc().frequency;
+ case FrontendType::DVBS:
+ return settings.dvbs().frequency;
+ case FrontendType::DVBT:
+ return settings.dvbt().frequency;
+ case FrontendType::ISDBS:
+ return settings.isdbs().frequency;
+ case FrontendType::ISDBS3:
+ return settings.isdbs3().frequency;
+ case FrontendType::ISDBT:
+ return settings.isdbt().frequency;
+ default:
+ return 0;
+ }
+}
+
+void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig& config,
+ uint32_t resetingFreq) {
+ switch (config.type) {
+ case FrontendType::ANALOG:
+ config.settings.analog().frequency = resetingFreq;
+ break;
+ case FrontendType::ATSC:
+ config.settings.atsc().frequency = resetingFreq;
+ break;
+ case FrontendType::ATSC3:
+ config.settings.atsc3().frequency = resetingFreq;
+ break;
+ case FrontendType::DVBC:
+ config.settings.dvbc().frequency = resetingFreq;
+ break;
+ case FrontendType::DVBS:
+ config.settings.dvbs().frequency = resetingFreq;
+ break;
+ case FrontendType::DVBT:
+ config.settings.dvbt().frequency = resetingFreq;
+ break;
+ case FrontendType::ISDBS:
+ config.settings.isdbs().frequency = resetingFreq;
+ break;
+ case FrontendType::ISDBS3:
+ config.settings.isdbs3().frequency = resetingFreq;
+ break;
+ case FrontendType::ISDBT:
+ config.settings.isdbt().frequency = resetingFreq;
+ break;
+ default:
+ // do nothing
+ return;
+ }
+}
+
+AssertionResult FrontendTests::getFrontendIds() {
+ Result status;
+ mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
+ status = result;
+ mFeIds = frontendIds;
+ });
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FrontendTests::getFrontendInfo(uint32_t frontendId) {
+ Result status;
+ mService->getFrontendInfo(frontendId, [&](Result result, const FrontendInfo& frontendInfo) {
+ mFrontendInfo = frontendInfo;
+ status = result;
+ });
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FrontendTests::openFrontendById(uint32_t frontendId) {
+ Result status;
+ mService->openFrontendById(frontendId, [&](Result result, const sp<IFrontend>& frontend) {
+ mFrontend = frontend;
+ status = result;
+ });
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FrontendTests::setFrontendCallback() {
+ EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+ mFrontendCallback = new FrontendCallback();
+ auto callbackStatus = mFrontend->setCallback(mFrontendCallback);
+ return AssertionResult(callbackStatus.isOk());
+}
+
+AssertionResult FrontendTests::scanFrontend(FrontendConfig config, FrontendScanType type) {
+ EXPECT_TRUE(mFrontendCallback)
+ << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
+
+ EXPECT_TRUE(mFrontendInfo.type == config.type)
+ << "FrontendConfig does not match the frontend info of the given id.";
+
+ mFrontendCallback->scanTest(mFrontend, config, type);
+ return AssertionResult(true);
+}
+
+AssertionResult FrontendTests::stopScanFrontend() {
+ EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+ Result status;
+ status = mFrontend->stopScan();
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FrontendTests::tuneFrontend(FrontendConfig config) {
+ EXPECT_TRUE(mFrontendCallback)
+ << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
+
+ EXPECT_TRUE(mFrontendInfo.type == config.type)
+ << "FrontendConfig does not match the frontend info of the given id.";
+
+ mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
+ return AssertionResult(true);
+}
+
+AssertionResult FrontendTests::stopTuneFrontend() {
+ EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+ Result status;
+ status = mFrontend->stopTune();
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FrontendTests::closeFrontend() {
+ EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+ Result status;
+ status = mFrontend->close();
+ mFrontend = nullptr;
+ mFrontendCallback = nullptr;
+ return AssertionResult(status == Result::SUCCESS);
+}
+
+void FrontendTests::getFrontendIdByType(FrontendType feType, uint32_t& feId) {
+ ASSERT_TRUE(getFrontendIds());
+ ASSERT_TRUE(mFeIds.size() > 0);
+ for (size_t i = 0; i < mFeIds.size(); i++) {
+ ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+ if (mFrontendInfo.type != feType) {
+ continue;
+ }
+ feId = mFeIds[i];
+ return;
+ }
+ feId = INVALID_ID;
+}
+
+void FrontendTests::tuneTest(FrontendConfig frontendConf) {
+ uint32_t feId;
+ getFrontendIdByType(frontendConf.type, feId);
+ ASSERT_TRUE(feId != INVALID_ID);
+ ASSERT_TRUE(openFrontendById(feId));
+ ASSERT_TRUE(setFrontendCallback());
+ ASSERT_TRUE(tuneFrontend(frontendConf));
+ ASSERT_TRUE(stopTuneFrontend());
+ ASSERT_TRUE(closeFrontend());
+}
+
+void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanType) {
+ uint32_t feId;
+ getFrontendIdByType(frontendConf.type, feId);
+ ASSERT_TRUE(feId != INVALID_ID);
+ ASSERT_TRUE(openFrontendById(feId));
+ ASSERT_TRUE(setFrontendCallback());
+ 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
new file mode 100644
index 0000000..5aa6e15
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.h
@@ -0,0 +1,127 @@
+/*
+ * 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/IFrontend.h>
+#include <android/hardware/tv/tuner/1.0/IFrontendCallback.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/GtestPrinter.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/ServiceManagement.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <map>
+
+#include "VtsHalTvTunerV1_0TestConfigurations.h"
+
+#define WAIT_TIMEOUT 3000000000
+#define INVALID_ID -1
+
+using android::Condition;
+using android::IMemory;
+using android::IMemoryHeap;
+using android::MemoryDealer;
+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;
+using android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
+using android::hardware::tv::tuner::V1_0::FrontendEventType;
+using android::hardware::tv::tuner::V1_0::FrontendId;
+using android::hardware::tv::tuner::V1_0::FrontendInfo;
+using android::hardware::tv::tuner::V1_0::FrontendInnerFec;
+using android::hardware::tv::tuner::V1_0::FrontendScanMessage;
+using android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
+using android::hardware::tv::tuner::V1_0::FrontendScanType;
+using android::hardware::tv::tuner::V1_0::FrontendSettings;
+using android::hardware::tv::tuner::V1_0::IFrontend;
+using android::hardware::tv::tuner::V1_0::IFrontendCallback;
+using android::hardware::tv::tuner::V1_0::ITuner;
+using android::hardware::tv::tuner::V1_0::Result;
+
+using ::testing::AssertionResult;
+
+#define INVALID_ID -1
+#define WAIT_TIMEOUT 3000000000
+
+class FrontendCallback : public IFrontendCallback {
+ public:
+ virtual Return<void> onEvent(FrontendEventType frontendEventType) override;
+ virtual Return<void> onScanMessage(FrontendScanMessageType type,
+ const FrontendScanMessage& message) override;
+
+ void tuneTestOnEventReceive(sp<IFrontend>& frontend, FrontendSettings settings);
+ void tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings);
+ void scanTest(sp<IFrontend>& frontend, FrontendConfig config, FrontendScanType type);
+
+ // Helper methods
+ uint32_t getTargetFrequency(FrontendSettings settings, FrontendType type);
+ void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq);
+
+ private:
+ bool mEventReceived = false;
+ bool mScanMessageReceived = false;
+ bool mLockMsgReceived = false;
+ bool mScanMsgProcessed = true;
+ FrontendScanMessageType mScanMessageType;
+ FrontendScanMessage mScanMessage;
+ hidl_vec<uint8_t> mEventMessage;
+ android::Mutex mMsgLock;
+ android::Condition mMsgCondition;
+ android::Condition mLockMsgCondition;
+};
+
+class FrontendTests {
+ public:
+ sp<ITuner> mService;
+
+ void setService(sp<ITuner> tuner) { mService = tuner; }
+
+ AssertionResult getFrontendIds();
+ AssertionResult getFrontendInfo(uint32_t frontendId);
+ AssertionResult openFrontendById(uint32_t frontendId);
+ AssertionResult setFrontendCallback();
+ AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
+ AssertionResult stopScanFrontend();
+ AssertionResult tuneFrontend(FrontendConfig config);
+ AssertionResult stopTuneFrontend();
+ AssertionResult closeFrontend();
+
+ void getFrontendIdByType(FrontendType feType, uint32_t& feId);
+ void tuneTest(FrontendConfig frontendConf);
+ void scanTest(FrontendConfig frontend, FrontendScanType type);
+
+ protected:
+ sp<IFrontend> mFrontend;
+ FrontendInfo mFrontendInfo;
+ sp<FrontendCallback> mFrontendCallback;
+ hidl_vec<FrontendId> mFeIds;
+};
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 5e98367..59c9479 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -14,433 +14,10 @@
* limitations under the License.
*/
-#define LOG_TAG "Tuner_hidl_hal_test"
-
-#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/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/IFrontend.h>
-#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
-#include <android/hardware/tv/tuner/1.0/ITuner.h>
-#include <android/hardware/tv/tuner/1.0/types.h>
-#include <binder/MemoryDealer.h>
-#include <fmq/MessageQueue.h>
-#include <gtest/gtest.h>
-#include <hidl/GtestPrinter.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hidl/ServiceManagement.h>
-#include <hidl/Status.h>
-#include <hidlmemory/FrameworkUtils.h>
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
-#include <fstream>
-#include <iostream>
-#include <map>
-
-#include "VtsHalTvTunerV1_0TestConfigurations.h"
-
-#define WAIT_TIMEOUT 3000000000
-#define INVALID_ID -1
-
-using android::Condition;
-using android::IMemory;
-using android::IMemoryHeap;
-using android::MemoryDealer;
-using android::Mutex;
-using android::sp;
-using android::hardware::EventFlag;
-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::kSynchronizedReadWrite;
-using android::hardware::MessageQueue;
-using android::hardware::MQDescriptorSync;
-using android::hardware::Return;
-using android::hardware::Void;
-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::FrontendAtscModulation;
-using android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
-using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
-using android::hardware::tv::tuner::V1_0::FrontendEventType;
-using android::hardware::tv::tuner::V1_0::FrontendId;
-using android::hardware::tv::tuner::V1_0::FrontendInfo;
-using android::hardware::tv::tuner::V1_0::FrontendInnerFec;
-using android::hardware::tv::tuner::V1_0::FrontendScanMessage;
-using android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
-using android::hardware::tv::tuner::V1_0::FrontendScanType;
-using android::hardware::tv::tuner::V1_0::FrontendSettings;
-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::IFrontend;
-using android::hardware::tv::tuner::V1_0::IFrontendCallback;
-using android::hardware::tv::tuner::V1_0::ITuner;
-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 android::hardware::tv::tuner::V1_0::Result;
-
-using ::testing::AssertionResult;
+#include "VtsHalTvTunerV1_0TargetTest.h"
namespace {
-
-using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-using MQDesc = MQDescriptorSync<uint8_t>;
-
-const std::vector<uint8_t> goldenDataOutputBuffer{
- 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
- 0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
- 0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
- 0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
- 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
- 0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
- 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
- 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
- 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
- 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x2d, 0x20,
- 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d,
- 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
- 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x3d,
- 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68, 0x65,
- 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
- 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e,
- 0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20,
- 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72,
- 0x6f, 0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
- 0x73, 0x3d, 0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71,
- 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31,
- 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d,
- 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66,
- 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d,
- 0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68,
- 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x64, 0x5f,
- 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20,
- 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69, 0x6e, 0x74, 0x65,
- 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72, 0x61, 0x79,
- 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
- 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
- 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68,
- 0x74, 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
- 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20,
- 0x73, 0x63, 0x65, 0x6e, 0x65,
-};
-
-// const uint16_t FMQ_SIZE_4K = 0x1000;
-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;
-};
-
-/******************************** Start FrontendCallback **********************************/
-class FrontendCallback : public IFrontendCallback {
- public:
- virtual Return<void> onEvent(FrontendEventType frontendEventType) override {
- android::Mutex::Autolock autoLock(mMsgLock);
- ALOGD("[vts] frontend event received. Type: %d", frontendEventType);
- mEventReceived = true;
- mMsgCondition.signal();
- switch (frontendEventType) {
- case FrontendEventType::LOCKED:
- mLockMsgReceived = true;
- mLockMsgCondition.signal();
- return Void();
- default:
- // do nothing
- return Void();
- }
- }
-
- virtual Return<void> onScanMessage(FrontendScanMessageType type,
- const FrontendScanMessage& message) override {
- android::Mutex::Autolock autoLock(mMsgLock);
- while (!mScanMsgProcessed) {
- mMsgCondition.wait(mMsgLock);
- }
- ALOGD("[vts] frontend scan message. Type: %d", type);
- mScanMessageReceived = true;
- mScanMsgProcessed = false;
- mScanMessageType = type;
- mScanMessage = message;
- mMsgCondition.signal();
- return Void();
- }
-
- void tuneTestOnEventReceive(sp<IFrontend>& frontend, FrontendSettings settings);
- void tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings);
- void scanTest(sp<IFrontend>& frontend, FrontendConfig config, FrontendScanType type);
-
- // Helper methods
- uint32_t getTargetFrequency(FrontendSettings settings, FrontendType type);
- void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq);
-
- private:
- bool mEventReceived = false;
- bool mScanMessageReceived = false;
- bool mLockMsgReceived = false;
- bool mScanMsgProcessed = true;
- FrontendScanMessageType mScanMessageType;
- FrontendScanMessage mScanMessage;
- hidl_vec<uint8_t> mEventMessage;
- android::Mutex mMsgLock;
- android::Condition mMsgCondition;
- android::Condition mLockMsgCondition;
-};
-
-void FrontendCallback::tuneTestOnEventReceive(sp<IFrontend>& frontend, FrontendSettings settings) {
- Result result = frontend->tune(settings);
- EXPECT_TRUE(result == Result::SUCCESS);
-
- android::Mutex::Autolock autoLock(mMsgLock);
- while (!mEventReceived) {
- if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
- EXPECT_TRUE(false) << "Event not received within timeout";
- mLockMsgReceived = false;
- return;
- }
- }
- mEventReceived = false;
-}
-
-void FrontendCallback::tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings) {
- Result result = frontend->tune(settings);
- EXPECT_TRUE(result == Result::SUCCESS);
-
- android::Mutex::Autolock autoLock(mMsgLock);
- while (!mLockMsgReceived) {
- if (-ETIMEDOUT == mLockMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
- EXPECT_TRUE(false) << "Event LOCKED not received within timeout";
- mLockMsgReceived = false;
- return;
- }
- }
- mLockMsgReceived = false;
-}
-
-void FrontendCallback::scanTest(sp<IFrontend>& frontend, FrontendConfig config,
- FrontendScanType type) {
- uint32_t targetFrequency = getTargetFrequency(config.settings, config.type);
- if (type == FrontendScanType::SCAN_BLIND) {
- // reset the frequency in the scan configuration to test blind scan. The settings param of
- // passed in means the real input config on the transponder connected to the DUT.
- // We want the blind the test to start from lower frequency than this to check the blind
- // scan implementation.
- resetBlindScanStartingFrequency(config, targetFrequency - 100);
- }
-
- Result result = frontend->scan(config.settings, type);
- EXPECT_TRUE(result == Result::SUCCESS);
-
- bool scanMsgLockedReceived = false;
- bool targetFrequencyReceived = false;
-
- android::Mutex::Autolock autoLock(mMsgLock);
-wait:
- while (!mScanMessageReceived) {
- if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
- EXPECT_TRUE(false) << "Scan message not received within timeout";
- mScanMessageReceived = false;
- mScanMsgProcessed = true;
- return;
- }
- }
-
- if (mScanMessageType != FrontendScanMessageType::END) {
- if (mScanMessageType == FrontendScanMessageType::LOCKED) {
- scanMsgLockedReceived = true;
- Result result = frontend->scan(config.settings, type);
- EXPECT_TRUE(result == Result::SUCCESS);
- }
-
- if (mScanMessageType == FrontendScanMessageType::FREQUENCY) {
- targetFrequencyReceived = mScanMessage.frequencies().size() > 0 &&
- mScanMessage.frequencies()[0] == targetFrequency;
- }
-
- if (mScanMessageType == FrontendScanMessageType::PROGRESS_PERCENT) {
- ALOGD("[vts] Scan in progress...[%d%%]", mScanMessage.progressPercent());
- }
-
- mScanMessageReceived = false;
- mScanMsgProcessed = true;
- mMsgCondition.signal();
- goto wait;
- }
-
- EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
- EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
- mScanMessageReceived = false;
- mScanMsgProcessed = true;
-}
-
-uint32_t FrontendCallback::getTargetFrequency(FrontendSettings settings, FrontendType type) {
- switch (type) {
- case FrontendType::ANALOG:
- return settings.analog().frequency;
- case FrontendType::ATSC:
- return settings.atsc().frequency;
- case FrontendType::ATSC3:
- return settings.atsc3().frequency;
- case FrontendType::DVBC:
- return settings.dvbc().frequency;
- case FrontendType::DVBS:
- return settings.dvbs().frequency;
- case FrontendType::DVBT:
- return settings.dvbt().frequency;
- case FrontendType::ISDBS:
- return settings.isdbs().frequency;
- case FrontendType::ISDBS3:
- return settings.isdbs3().frequency;
- case FrontendType::ISDBT:
- return settings.isdbt().frequency;
- default:
- return 0;
- }
-}
-
-void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig& config,
- uint32_t resetingFreq) {
- switch (config.type) {
- case FrontendType::ANALOG:
- config.settings.analog().frequency = resetingFreq;
- break;
- case FrontendType::ATSC:
- config.settings.atsc().frequency = resetingFreq;
- break;
- case FrontendType::ATSC3:
- config.settings.atsc3().frequency = resetingFreq;
- break;
- case FrontendType::DVBC:
- config.settings.dvbc().frequency = resetingFreq;
- break;
- case FrontendType::DVBS:
- config.settings.dvbs().frequency = resetingFreq;
- break;
- case FrontendType::DVBT:
- config.settings.dvbt().frequency = resetingFreq;
- break;
- case FrontendType::ISDBS:
- config.settings.isdbs().frequency = resetingFreq;
- break;
- case FrontendType::ISDBS3:
- config.settings.isdbs3().frequency = resetingFreq;
- break;
- case FrontendType::ISDBT:
- config.settings.isdbt().frequency = resetingFreq;
- break;
- default:
- // do nothing
- return;
- }
-}
-/******************************** End FrontendCallback **********************************/
-
/******************************** Start FilterCallback **********************************/
-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;
-};
-
void FilterCallback::startFilterEventThread(DemuxFilterEvent event) {
struct FilterThreadArgs* threadArgs =
(struct FilterThreadArgs*)malloc(sizeof(struct FilterThreadArgs));
@@ -555,89 +132,6 @@
/******************************** End FilterCallback **********************************/
/******************************** Start DvrCallback **********************************/
-class DvrCallback : public IDvrCallback {
- public:
- virtual Return<void> onRecordStatus(DemuxFilterStatus status) override {
- ALOGW("[vts] record status %hhu", status);
- switch (status) {
- case DemuxFilterStatus::DATA_READY:
- break;
- case DemuxFilterStatus::LOW_WATER:
- break;
- case DemuxFilterStatus::HIGH_WATER:
- case DemuxFilterStatus::OVERFLOW:
- ALOGW("[vts] record overflow. Flushing");
- break;
- }
- return Void();
- }
-
- virtual Return<void> onPlaybackStatus(PlaybackStatus status) override {
- // android::Mutex::Autolock autoLock(mMsgLock);
- ALOGW("[vts] playback status %d", status);
- switch (status) {
- case PlaybackStatus::SPACE_EMPTY:
- case PlaybackStatus::SPACE_ALMOST_EMPTY:
- ALOGW("[vts] keep playback inputing %d", status);
- mKeepWritingPlaybackFMQ = true;
- break;
- case PlaybackStatus::SPACE_ALMOST_FULL:
- case PlaybackStatus::SPACE_FULL:
- ALOGW("[vts] stop playback inputing %d", status);
- mKeepWritingPlaybackFMQ = false;
- break;
- }
- return Void();
- }
-
- void testFilterDataOutput();
- void stopPlaybackThread();
- void testRecordOutput();
- void stopRecordThread();
-
- void startPlaybackInputThread(PlaybackConf playbackConf, MQDesc& playbackMQDescriptor);
- void startRecordOutputThread(RecordSettings recordSetting, MQDesc& recordMQDescriptor);
- static void* __threadLoopPlayback(void* threadArgs);
- static void* __threadLoopRecord(void* threadArgs);
- void playbackThreadLoop(PlaybackConf* playbackConf, bool* keepWritingPlaybackFMQ);
- void recordThreadLoop(RecordSettings* recordSetting, bool* keepWritingPlaybackFMQ);
-
- bool readRecordFMQ();
-
- private:
- struct PlaybackThreadArgs {
- DvrCallback* user;
- PlaybackConf* playbackConf;
- bool* keepWritingPlaybackFMQ;
- };
- struct RecordThreadArgs {
- DvrCallback* user;
- RecordSettings* recordSetting;
- bool* keepReadingRecordFMQ;
- };
- uint16_t mDataLength = 0;
- std::vector<uint8_t> mDataOutputBuffer;
-
- std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterMQ;
- std::unique_ptr<FilterMQ> mPlaybackMQ;
- std::unique_ptr<FilterMQ> mRecordMQ;
- std::map<uint32_t, EventFlag*> mFilterMQEventFlag;
-
- android::Mutex mMsgLock;
- android::Mutex mPlaybackThreadLock;
- android::Mutex mRecordThreadLock;
- android::Condition mMsgCondition;
-
- bool mKeepWritingPlaybackFMQ = true;
- bool mKeepReadingRecordFMQ = true;
- bool mPlaybackThreadRunning;
- bool mRecordThreadRunning;
- pthread_t mPlaybackThread;
- pthread_t mRecordThread;
-
- int mPidFilterOutputCount = 0;
-};
-
void DvrCallback::startPlaybackInputThread(PlaybackConf playbackConf,
MQDesc& playbackMQDescriptor) {
mPlaybackMQ = std::make_unique<FilterMQ>(playbackMQDescriptor, true /* resetPointers */);
@@ -809,176 +303,6 @@
}
/********************************** End DvrCallback ************************************/
-/***************************** Start Test Implementation ******************************/
-class TunerHidlTest : public testing::TestWithParam<std::string> {
- public:
- virtual void SetUp() override {
- mService = ITuner::getService(GetParam());
- ASSERT_NE(mService, nullptr);
- initFrontendConfig();
- initFrontendScanConfig();
- initFilterConfig();
- }
-
- sp<ITuner> mService;
-
- protected:
- static AssertionResult failure() { return ::testing::AssertionFailure(); }
-
- static AssertionResult success() { return ::testing::AssertionSuccess(); }
-
- static void description(const std::string& description) {
- RecordProperty("description", description);
- }
-
- sp<IFrontend> mFrontend;
- FrontendInfo mFrontendInfo;
- sp<FrontendCallback> mFrontendCallback;
- 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<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 getFrontendIds();
- AssertionResult getFrontendInfo(uint32_t frontendId);
- AssertionResult openFrontendById(uint32_t frontendId);
- AssertionResult setFrontendCallback();
- AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
- AssertionResult stopScanFrontend();
- AssertionResult tuneFrontend(FrontendConfig config);
- AssertionResult stopTuneFrontend();
- AssertionResult closeFrontend();
-
- 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();
-
- AssertionResult playbackDataFlowTest(vector<FilterConfig> filterConf, PlaybackConf playbackConf,
- vector<string> goldenOutputFiles);
- AssertionResult recordDataFlowTest(vector<FilterConfig> filterConf,
- RecordSettings recordSetting,
- vector<string> goldenOutputFiles);
- AssertionResult broadcastDataFlowTest(vector<string> goldenOutputFiles);
-
- void broadcastSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf);
- void getFrontendIdByType(FrontendType feType, uint32_t& feId);
- void scanTest(FrontendConfig frontend, FrontendScanType type);
-
- FilterEventType getFilterEventType(DemuxFilterType type);
-};
-
-/*========================== Start Frontend APIs Tests Implementation ==========================*/
-AssertionResult TunerHidlTest::getFrontendIds() {
- Result status;
- mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
- status = result;
- mFeIds = frontendIds;
- });
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::getFrontendInfo(uint32_t frontendId) {
- Result status;
- mService->getFrontendInfo(frontendId, [&](Result result, const FrontendInfo& frontendInfo) {
- mFrontendInfo = frontendInfo;
- status = result;
- });
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::openFrontendById(uint32_t frontendId) {
- Result status;
- mService->openFrontendById(frontendId, [&](Result result, const sp<IFrontend>& frontend) {
- mFrontend = frontend;
- status = result;
- });
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::setFrontendCallback() {
- EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
- mFrontendCallback = new FrontendCallback();
- auto callbackStatus = mFrontend->setCallback(mFrontendCallback);
- return AssertionResult(callbackStatus.isOk());
-}
-
-AssertionResult TunerHidlTest::scanFrontend(FrontendConfig config, FrontendScanType type) {
- EXPECT_TRUE(mFrontendCallback)
- << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
-
- EXPECT_TRUE(mFrontendInfo.type == config.type)
- << "FrontendConfig does not match the frontend info of the given id.";
-
- mFrontendCallback->scanTest(mFrontend, config, type);
- return AssertionResult(true);
-}
-
-AssertionResult TunerHidlTest::stopScanFrontend() {
- EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
- Result status;
- status = mFrontend->stopScan();
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::tuneFrontend(FrontendConfig config) {
- EXPECT_TRUE(mFrontendCallback)
- << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
-
- EXPECT_TRUE(mFrontendInfo.type == config.type)
- << "FrontendConfig does not match the frontend info of the given id.";
-
- mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
- return AssertionResult(true);
-}
-
-AssertionResult TunerHidlTest::stopTuneFrontend() {
- EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
- Result status;
- status = mFrontend->stopTune();
- return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult TunerHidlTest::closeFrontend() {
- EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
- Result status;
- status = mFrontend->close();
- mFrontend = nullptr;
- mFrontendCallback = nullptr;
- return AssertionResult(status == Result::SUCCESS);
-}
-/*=========================== End Frontend APIs Tests Implementation ===========================*/
-
/*============================ Start Demux APIs Tests Implementation ============================*/
AssertionResult TunerHidlTest::openDemux() {
Result status;
@@ -992,7 +316,6 @@
AssertionResult TunerHidlTest::setDemuxFrontendDataSource(uint32_t frontendId) {
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
- EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
auto status = mDemux->setFrontendDataSource(frontendId);
return AssertionResult(status.isOk());
}
@@ -1176,7 +499,6 @@
/*========================== Start Data Flow Tests Implementation ==========================*/
AssertionResult TunerHidlTest::broadcastDataFlowTest(vector<string> /*goldenOutputFiles*/) {
- EXPECT_TRUE(mFrontend) << "Test with openFilterInDemux first.";
EXPECT_TRUE(mDemux) << "Test with openDemux first.";
EXPECT_TRUE(mFilterCallback) << "Test with getFilterMQDescriptor first.";
@@ -1334,32 +656,18 @@
/*========================= End Data Flow Tests Implementation =========================*/
/*================================= Start Test Module =================================*/
-void TunerHidlTest::getFrontendIdByType(FrontendType feType, uint32_t& feId) {
- ASSERT_TRUE(getFrontendIds());
- ASSERT_TRUE(mFeIds.size() > 0);
- for (size_t i = 0; i < mFeIds.size(); i++) {
- ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
- if (mFrontendInfo.type != feType) {
- continue;
- }
- feId = mFeIds[i];
- return;
- }
- feId = INVALID_ID;
-}
-
void TunerHidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
FrontendConfig frontendConf) {
uint32_t feId;
- getFrontendIdByType(frontendConf.type, feId);
+ mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
if (feId == INVALID_ID) {
// TODO broadcast test on Cuttlefish needs licensed ts input,
// these tests are runnable on vendor device with real frontend module
// or with manual ts installing and use DVBT frontend.
return;
}
- ASSERT_TRUE(openFrontendById(feId));
- ASSERT_TRUE(setFrontendCallback());
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
ASSERT_TRUE(openDemux());
ASSERT_TRUE(setDemuxFrontendDataSource(feId));
ASSERT_TRUE(openFilterInDemux(filterConf.type));
@@ -1369,25 +677,14 @@
ASSERT_TRUE(getFilterMQDescriptor(filterId));
ASSERT_TRUE(startFilter(filterId));
// tune test
- ASSERT_TRUE(tuneFrontend(frontendConf));
+ ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf));
// broadcast data flow test
ASSERT_TRUE(broadcastDataFlowTest(goldenOutputFiles));
- ASSERT_TRUE(stopTuneFrontend());
+ ASSERT_TRUE(mFrontendTests.stopTuneFrontend());
ASSERT_TRUE(stopFilter(filterId));
ASSERT_TRUE(closeFilter(filterId));
ASSERT_TRUE(closeDemux());
- ASSERT_TRUE(closeFrontend());
-}
-
-void TunerHidlTest::scanTest(FrontendConfig frontendConf, FrontendScanType scanType) {
- uint32_t feId;
- getFrontendIdByType(frontendConf.type, feId);
- ASSERT_TRUE(feId != INVALID_ID);
- ASSERT_TRUE(openFrontendById(feId));
- ASSERT_TRUE(setFrontendCallback());
- ASSERT_TRUE(scanFrontend(frontendConf, scanType));
- ASSERT_TRUE(stopScanFrontend());
- ASSERT_TRUE(closeFrontend());
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
}
/*================================== End Test Module ==================================*/
@@ -1442,38 +739,29 @@
/***************************** End Test Implementation *****************************/
/******************************** Start Test Entry **********************************/
-/*============================== Start Frontend Tests ==============================*/
-TEST_P(TunerHidlTest, TuneFrontend) {
+TEST_P(TunerFrontendHidlTest, TuneFrontend) {
description("Tune one Frontend with specific setting and check Lock event");
- uint32_t feId;
- getFrontendIdByType(frontendArray[DVBT].type, feId);
- ASSERT_TRUE(feId != INVALID_ID);
- ASSERT_TRUE(openFrontendById(feId));
- ASSERT_TRUE(setFrontendCallback());
- ASSERT_TRUE(tuneFrontend(frontendArray[DVBT]));
- ASSERT_TRUE(stopTuneFrontend());
- ASSERT_TRUE(closeFrontend());
+ mFrontendTests.tuneTest(frontendArray[DVBT]);
}
-TEST_P(TunerHidlTest, AutoScanFrontend) {
+TEST_P(TunerFrontendHidlTest, AutoScanFrontend) {
description("Run an auto frontend scan with specific setting and check lock scanMessage");
- scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_AUTO);
+ mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_AUTO);
}
-TEST_P(TunerHidlTest, BlindScanFrontend) {
+TEST_P(TunerFrontendHidlTest, BlindScanFrontend) {
description("Run an blind frontend scan with specific setting and check lock scanMessage");
- scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND);
+ mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND);
}
-/*=============================== End Frontend Tests ===============================*/
/*============================ Start Demux/Filter Tests ============================*/
TEST_P(TunerHidlTest, StartFilterInDemux) {
description("Open and start a filter in Demux.");
uint32_t feId;
- getFrontendIdByType(frontendArray[DVBT].type, feId);
+ mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
ASSERT_TRUE(feId != INVALID_ID);
- ASSERT_TRUE(openFrontendById(feId));
- ASSERT_TRUE(setFrontendCallback());
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
ASSERT_TRUE(openDemux());
ASSERT_TRUE(setDemuxFrontendDataSource(feId));
ASSERT_TRUE(openFilterInDemux(filterArray[TS_VIDEO0].type));
@@ -1485,7 +773,7 @@
ASSERT_TRUE(stopFilter(filterId));
ASSERT_TRUE(closeFilter(filterId));
ASSERT_TRUE(closeDemux());
- ASSERT_TRUE(closeFrontend());
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
}
/*============================ End Demux/Filter Tests ============================*/
@@ -1614,9 +902,13 @@
}*/
/*============================== End Data Flow Tests ==============================*/
/******************************** End Test Entry **********************************/
-} // namespace
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, TunerFrontendHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
+ android::hardware::PrintInstanceNameToString);
INSTANTIATE_TEST_SUITE_P(
PerInstance, TunerHidlTest,
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
new file mode 100644
index 0000000..4d6715e
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
@@ -0,0 +1,333 @@
+/*
+ * 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 <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 "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;
+};
+
+static AssertionResult failure() {
+ return ::testing::AssertionFailure();
+}
+
+static AssertionResult success() {
+ return ::testing::AssertionSuccess();
+}
+
+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 {
+ ALOGW("[vts] record status %hhu", status);
+ switch (status) {
+ case DemuxFilterStatus::DATA_READY:
+ break;
+ case DemuxFilterStatus::LOW_WATER:
+ break;
+ case DemuxFilterStatus::HIGH_WATER:
+ case DemuxFilterStatus::OVERFLOW:
+ ALOGW("[vts] record overflow. Flushing");
+ break;
+ }
+ return Void();
+ }
+
+ virtual Return<void> onPlaybackStatus(PlaybackStatus status) override {
+ // android::Mutex::Autolock autoLock(mMsgLock);
+ ALOGW("[vts] playback status %d", status);
+ switch (status) {
+ case PlaybackStatus::SPACE_EMPTY:
+ case PlaybackStatus::SPACE_ALMOST_EMPTY:
+ ALOGW("[vts] keep playback inputing %d", status);
+ mKeepWritingPlaybackFMQ = true;
+ break;
+ case PlaybackStatus::SPACE_ALMOST_FULL:
+ case PlaybackStatus::SPACE_FULL:
+ ALOGW("[vts] stop playback inputing %d", status);
+ mKeepWritingPlaybackFMQ = false;
+ break;
+ }
+ return Void();
+ }
+
+ void testFilterDataOutput();
+ void stopPlaybackThread();
+ void testRecordOutput();
+ void stopRecordThread();
+
+ void startPlaybackInputThread(PlaybackConf playbackConf, MQDesc& playbackMQDescriptor);
+ void startRecordOutputThread(RecordSettings recordSetting, MQDesc& recordMQDescriptor);
+ static void* __threadLoopPlayback(void* threadArgs);
+ static void* __threadLoopRecord(void* threadArgs);
+ void playbackThreadLoop(PlaybackConf* playbackConf, bool* keepWritingPlaybackFMQ);
+ void recordThreadLoop(RecordSettings* recordSetting, bool* keepWritingPlaybackFMQ);
+
+ bool readRecordFMQ();
+
+ private:
+ struct PlaybackThreadArgs {
+ DvrCallback* user;
+ PlaybackConf* playbackConf;
+ bool* keepWritingPlaybackFMQ;
+ };
+ struct RecordThreadArgs {
+ DvrCallback* user;
+ RecordSettings* recordSetting;
+ bool* keepReadingRecordFMQ;
+ };
+ uint16_t mDataLength = 0;
+ std::vector<uint8_t> mDataOutputBuffer;
+
+ std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterMQ;
+ std::unique_ptr<FilterMQ> mPlaybackMQ;
+ std::unique_ptr<FilterMQ> mRecordMQ;
+ std::map<uint32_t, EventFlag*> mFilterMQEventFlag;
+
+ android::Mutex mMsgLock;
+ android::Mutex mPlaybackThreadLock;
+ android::Mutex mRecordThreadLock;
+ android::Condition mMsgCondition;
+
+ bool mKeepWritingPlaybackFMQ = true;
+ bool mKeepReadingRecordFMQ = true;
+ bool mPlaybackThreadRunning;
+ bool mRecordThreadRunning;
+ pthread_t mPlaybackThread;
+ pthread_t mRecordThread;
+
+ int mPidFilterOutputCount = 0;
+};
+
+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);
+ initFrontendConfig();
+ initFrontendScanConfig();
+
+ mFrontendTests.setService(mService);
+ }
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+};
+
+class TunerHidlTest : public testing::TestWithParam<std::string> {
+ public:
+ sp<ITuner> mService;
+ FrontendTests mFrontendTests;
+
+ virtual void SetUp() override {
+ mService = ITuner::getService(GetParam());
+ ASSERT_NE(mService, nullptr);
+ initFrontendConfig();
+ initFrontendScanConfig();
+ initFilterConfig();
+
+ mFrontendTests.setService(mService);
+ }
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+
+ 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<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();
+
+ AssertionResult playbackDataFlowTest(vector<FilterConfig> filterConf, PlaybackConf playbackConf,
+ vector<string> goldenOutputFiles);
+ AssertionResult recordDataFlowTest(vector<FilterConfig> filterConf,
+ RecordSettings recordSetting,
+ vector<string> goldenOutputFiles);
+ AssertionResult broadcastDataFlowTest(vector<string> goldenOutputFiles);
+
+ void broadcastSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf);
+
+ FilterEventType getFilterEventType(DemuxFilterType type);
+};
+} // namespace
\ No newline at end of file