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