Merge "Starts default Context Hub HAL in context_hub group" into rvc-dev
diff --git a/audio/6.0/Android.bp b/audio/6.0/Android.bp
index dc6bb98..16abc52 100644
--- a/audio/6.0/Android.bp
+++ b/audio/6.0/Android.bp
@@ -15,6 +15,7 @@
         "IStreamIn.hal",
         "IStreamOut.hal",
         "IStreamOutCallback.hal",
+        "IStreamOutEventCallback.hal",
     ],
     interfaces: [
         "android.hardware.audio.common@6.0",
diff --git a/audio/6.0/IStreamOut.hal b/audio/6.0/IStreamOut.hal
index 13a86ec..9da48fe 100644
--- a/audio/6.0/IStreamOut.hal
+++ b/audio/6.0/IStreamOut.hal
@@ -19,6 +19,7 @@
 import android.hardware.audio.common@6.0;
 import IStream;
 import IStreamOutCallback;
+import IStreamOutEventCallback;
 
 interface IStreamOut extends IStream {
     /**
@@ -168,6 +169,18 @@
     clearCallback() generates (Result retval);
 
     /**
+     * Set the callback interface for notifying about an output stream event.
+     *
+     * Calling this method with a null pointer will result in releasing
+     * the local callback proxy on the server side and thus dereference
+     * the callback implementation on the client side.
+     *
+     * @return retval operation completion status.
+     */
+    setEventCallback(IStreamOutEventCallback callback)
+            generates (Result retval);
+
+    /**
      * Returns whether HAL supports pausing and resuming of streams.
      *
      * @return supportsPause true if pausing is supported.
diff --git a/audio/6.0/IStreamOutEventCallback.hal b/audio/6.0/IStreamOutEventCallback.hal
new file mode 100644
index 0000000..de17d73
--- /dev/null
+++ b/audio/6.0/IStreamOutEventCallback.hal
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.hardware.audio@6.0;
+
+/**
+ * Asynchronous stream out event callback interface. The interface provides
+ * a way for the HAL to notify platform when there are changes, e.g. codec
+ * format change, from the lower layer.
+ */
+interface IStreamOutEventCallback {
+    /**
+     * Codec format changed.
+     *
+     * @param audioMetadata is a buffer containing decoded format changes
+     *     reported by codec. The buffer contains data that can be transformed
+     *     to audio metadata, which is a C++ object based map. See
+     *     `system/media/audio_utils/include/audio_utils/Metadata.h` for
+     *     more details.
+     */
+    oneway onCodecFormatChanged(vec<uint8_t> audioMetadata);
+};
diff --git a/audio/common/6.0/types.hal b/audio/common/6.0/types.hal
index b2806c7..67217ab 100644
--- a/audio/common/6.0/types.hal
+++ b/audio/common/6.0/types.hal
@@ -903,6 +903,25 @@
     SONIFICATION = 4,
 };
 
+/** Encapsulation mode used for sending audio compressed data. */
+@export(name="audio_encapsulation_mode_t", value_prefix="AUDIO_ENCAPSULATION_MODE_")
+enum AudioEncapsulationMode : int32_t {
+    // Do not change these values without updating their counterparts
+    // in frameworks/base/media/java/android/media/AudioTrack.java
+    /**
+     * No encapsulation mode for metadata.
+     */
+    NONE              = 0,
+    /**
+     * Elementary stream payload with metadata
+     */
+    ELEMENTARY_STREAM = 1,
+    /**
+     *  Handle-based payload with metadata
+     */
+    HANDLE            = 2,
+};
+
 /**
  * Additional information about the stream passed to hardware decoders.
  */
@@ -918,6 +937,9 @@
     uint32_t bitWidth;
     uint32_t bufferSize;
     AudioUsage usage;
+    AudioEncapsulationMode encapsulationMode;
+    int32_t contentId;
+    int32_t syncId;
 };
 
 /**
diff --git a/audio/common/all-versions/default/HidlUtils.cpp b/audio/common/all-versions/default/HidlUtils.cpp
index 08002c8..a470c9c 100644
--- a/audio/common/all-versions/default/HidlUtils.cpp
+++ b/audio/common/all-versions/default/HidlUtils.cpp
@@ -28,12 +28,13 @@
 namespace CPP_VERSION {
 namespace implementation {
 
-void HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) {
+status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) {
     config->sampleRateHz = halConfig.sample_rate;
     config->channelMask = EnumBitfield<AudioChannelMask>(halConfig.channel_mask);
     config->format = AudioFormat(halConfig.format);
-    audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo);
+    status_t status = audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo);
     config->frameCount = halConfig.frame_count;
+    return status;
 }
 
 void HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) {
@@ -106,8 +107,8 @@
     return static_cast<audio_usage_t>(usage);
 }
 
-void HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
-                                        AudioOffloadInfo* offload) {
+status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
+                                            AudioOffloadInfo* offload) {
     offload->sampleRateHz = halOffload.sample_rate;
     offload->channelMask = EnumBitfield<AudioChannelMask>(halOffload.channel_mask);
     offload->format = AudioFormat(halOffload.format);
@@ -119,6 +120,26 @@
     offload->bitWidth = halOffload.bit_width;
     offload->bufferSize = halOffload.offload_buffer_size;
     offload->usage = audioUsageFromHal(halOffload.usage);
+#if MAJOR_VERSION >= 6
+    if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) {
+        offload->encapsulationMode =
+                static_cast<AudioEncapsulationMode>(halOffload.encapsulation_mode);
+        offload->contentId = halOffload.content_id;
+        offload->syncId = halOffload.sync_id;
+    } else {
+        offload->encapsulationMode = AudioEncapsulationMode::NONE;
+        offload->contentId = 0;
+        offload->syncId = 0;
+    }
+#else
+    // nonzero values here are not compatible with HAL versions below 6.
+    if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2 &&
+        (halOffload.encapsulation_mode != AUDIO_ENCAPSULATION_MODE_NONE ||
+         halOffload.content_id != 0 || halOffload.sync_id != 0)) {
+        return BAD_VALUE;
+    }
+#endif
+    return OK;
 }
 
 void HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload,
@@ -135,6 +156,14 @@
     halOffload->bit_width = offload.bitWidth;
     halOffload->offload_buffer_size = offload.bufferSize;
     halOffload->usage = audioUsageToHal(offload.usage);
+#if MAJOR_VERSION >= 6
+    halOffload->encapsulation_mode =
+            static_cast<audio_encapsulation_mode_t>(offload.encapsulationMode);
+    halOffload->content_id = offload.contentId;
+    halOffload->sync_id = offload.syncId;
+#else
+    // offload doesn't contain encapsulationMode, contentId, syncId, so this is OK.
+#endif
 }
 
 void HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig,
diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h
index 758a7f4..ef6dee3 100644
--- a/audio/common/all-versions/default/HidlUtils.h
+++ b/audio/common/all-versions/default/HidlUtils.h
@@ -35,8 +35,11 @@
 using namespace ::android::hardware::audio::common::CPP_VERSION;
 
 class HidlUtils {
-   public:
-    static void audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config);
+  public:
+    // A failure here indicates a platform config that is incompatible with
+    // the compiled HIDL interface version.
+    static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config);
+
     static void audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig);
     static void audioGainConfigFromHal(const struct audio_gain_config& halConfig,
                                        AudioGainConfig* config);
@@ -46,8 +49,10 @@
     static void audioGainToHal(const AudioGain& gain, struct audio_gain* halGain);
     static AudioUsage audioUsageFromHal(const audio_usage_t halUsage);
     static audio_usage_t audioUsageToHal(const AudioUsage usage);
-    static void audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
-                                        AudioOffloadInfo* offload);
+    // A failure here indicates a platform offload info that is incompatible with
+    // the compiled HIDL interface version.
+    static status_t audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
+                                            AudioOffloadInfo* offload);
     static void audioOffloadInfoToHal(const AudioOffloadInfo& offload,
                                       audio_offload_info_t* halOffload);
     static void audioPortConfigFromHal(const struct audio_port_config& halConfig,
@@ -58,7 +63,7 @@
                                         const struct audio_port_config* halConfigs,
                                         hidl_vec<AudioPortConfig>* configs);
     static std::unique_ptr<audio_port_config[]> audioPortConfigsToHal(
-        const hidl_vec<AudioPortConfig>& configs);
+            const hidl_vec<AudioPortConfig>& configs);
     static void audioPortFromHal(const struct audio_port& halPort, AudioPort* port);
     static void audioPortToHal(const AudioPort& port, struct audio_port* halPort);
     static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid);
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 47e31c1..6260ba1 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -171,7 +171,8 @@
         streamOut = new StreamOut(this, halStream);
         ++mOpenedStreamsCount;
     }
-    HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+    status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+    ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
     return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
 }
 
@@ -198,7 +199,8 @@
         streamIn = new StreamIn(this, halStream);
         ++mOpenedStreamsCount;
     }
-    HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+    status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
+    ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
     return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
 }
 
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index 7a4d72b..150d641 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -22,6 +22,8 @@
 //#define LOG_NDEBUG 0
 #define ATRACE_TAG ATRACE_TAG_AUDIO
 
+#include <string.h>
+
 #include <memory>
 
 #include <android/log.h>
@@ -612,6 +614,33 @@
     return Result::NOT_SUPPORTED;
 }
 
+Return<Result> StreamOut::setEventCallback(const sp<IStreamOutEventCallback>& callback) {
+    if (mStream->set_event_callback == nullptr) return Result::NOT_SUPPORTED;
+    int result = mStream->set_event_callback(mStream, StreamOut::asyncEventCallback, this);
+    if (result == 0) {
+        mEventCallback = callback;
+    }
+    return Stream::analyzeStatus("set_stream_out_callback", result, {ENOSYS} /*ignore*/);
+}
+
+// static
+int StreamOut::asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie) {
+    StreamOut* self = reinterpret_cast<StreamOut*>(cookie);
+    sp<IStreamOutEventCallback> eventCallback = self->mEventCallback;
+    if (eventCallback.get() == nullptr) return 0;
+    ALOGV("%s event %d", __func__, event);
+    switch (event) {
+        case STREAM_EVENT_CBK_TYPE_CODEC_FORMAT_CHANGED: {
+            hidl_vec<uint8_t> audioMetadata;
+            audioMetadata.setToExternal((uint8_t*)param, strlen((char*)param));
+            eventCallback->onCodecFormatChanged(audioMetadata);
+        } break;
+        default:
+            ALOGW("%s unknown event %d", __func__, event);
+            break;
+    }
+    return 0;
+}
 #endif
 
 }  // namespace implementation
diff --git a/audio/core/all-versions/default/include/core/default/StreamOut.h b/audio/core/all-versions/default/include/core/default/StreamOut.h
index 5db8626..e647da9 100644
--- a/audio/core/all-versions/default/include/core/default/StreamOut.h
+++ b/audio/core/all-versions/default/include/core/default/StreamOut.h
@@ -133,12 +133,19 @@
     static Result getPresentationPositionImpl(audio_stream_out_t* stream, uint64_t* frames,
                                               TimeSpec* timeStamp);
 
-   private:
+#if MAJOR_VERSION >= 6
+    Return<Result> setEventCallback(const sp<IStreamOutEventCallback>& callback) override;
+#endif
+
+  private:
     const sp<Device> mDevice;
     audio_stream_out_t* mStream;
     const sp<Stream> mStreamCommon;
     const sp<StreamMmap<audio_stream_out_t>> mStreamMmap;
-    sp<IStreamOutCallback> mCallback;
+    sp<IStreamOutCallback> mCallback;  // Callback for non-blocking write and drain
+#if MAJOR_VERSION >= 6
+    sp<IStreamOutEventCallback> mEventCallback;
+#endif
     std::unique_ptr<CommandMQ> mCommandMQ;
     std::unique_ptr<DataMQ> mDataMQ;
     std::unique_ptr<StatusMQ> mStatusMQ;
@@ -149,6 +156,10 @@
     virtual ~StreamOut();
 
     static int asyncCallback(stream_callback_event_t event, void* param, void* cookie);
+
+#if MAJOR_VERSION >= 6
+    static int asyncEventCallback(stream_event_callback_type_t event, void* param, void* cookie);
+#endif
 };
 
 }  // namespace implementation
diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
index 9e2a050..b40a329 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -251,3 +251,21 @@
 INSTANTIATE_TEST_CASE_P(PlaybackRateParametersHidl, PlaybackRateParametersHidlTest,
                         ::testing::ValuesIn(getOutputDeviceConfigParameters()),
                         &DeviceConfigParameterToString);
+
+/** Stub implementation of IStreamOutEventCallback **/
+class MockOutEventCallbacks : public IStreamOutEventCallback {
+    Return<void> onCodecFormatChanged(const hidl_vec<uint8_t>& audioMetadata __unused) override {
+        return {};
+    }
+};
+
+TEST_P(OutputStreamTest, SetEventCallback) {
+    doc::test("If supported, set event callback for output stream should never fail");
+    auto res = stream->setEventCallback(new MockOutEventCallbacks);
+    EXPECT_RESULT(okOrNotSupported, res);
+    if (res == Result::OK) {
+        ASSERT_OK(stream->setEventCallback(nullptr));
+    } else {
+        doc::partialTest("The stream does not support event callback");
+    }
+}
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
index cdea8b6..a8e7c0b 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
@@ -14,22 +14,20 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 #include <android-base/strings.h>
 #include <android/hardware/automotive/can/1.0/ICanBus.h>
 #include <android/hardware/automotive/can/1.0/types.h>
 #include <can-vts-utils/can-hal-printers.h>
-#include <can-vts-utils/environment-utils.h>
 #include <gmock/gmock.h>
 #include <hidl-utils/hidl-utils.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 namespace android::hardware::automotive::can::V1_0::vts {
 
 using hardware::hidl_vec;
 
-static utils::SimpleHidlEnvironment<ICanBus>* gEnv = nullptr;
-
 struct CanMessageListener : public can::V1_0::ICanMessageListener {
     virtual Return<void> onReceive(const can::V1_0::CanMessage&) override { return {}; }
 };
@@ -38,7 +36,7 @@
     virtual Return<void> onError(ErrorEvent, bool) override { return {}; }
 };
 
-class CanBusHalTest : public ::testing::VtsHalHidlTargetTestBase {
+class CanBusHalTest : public ::testing::TestWithParam<std::string> {
   protected:
     virtual void SetUp() override;
     virtual void TearDown() override;
@@ -51,9 +49,8 @@
 };
 
 void CanBusHalTest::SetUp() {
-    const auto serviceName = gEnv->getServiceName<ICanBus>();
-    mCanBus = getService<ICanBus>(serviceName);
-    ASSERT_TRUE(mCanBus) << "Couldn't open CAN Bus: " << serviceName;
+    mCanBus = ICanBus::getService(GetParam());
+    ASSERT_TRUE(mCanBus) << "Couldn't open CAN Bus: " << GetParam();
 }
 
 void CanBusHalTest::TearDown() {
@@ -75,7 +72,7 @@
     return res;
 }
 
-TEST_F(CanBusHalTest, SendNoPayload) {
+TEST_P(CanBusHalTest, SendNoPayload) {
     CanMessage msg = {};
     msg.id = 0x123;
     ASSERT_NE(mCanBus, nullptr);
@@ -83,7 +80,7 @@
     ASSERT_EQ(Result::OK, result);
 }
 
-TEST_F(CanBusHalTest, Send8B) {
+TEST_P(CanBusHalTest, Send8B) {
     CanMessage msg = {};
     msg.id = 0x234;
     msg.payload = {1, 2, 3, 4, 5, 6, 7, 8};
@@ -92,7 +89,7 @@
     ASSERT_EQ(Result::OK, result);
 }
 
-TEST_F(CanBusHalTest, SendZeroId) {
+TEST_P(CanBusHalTest, SendZeroId) {
     CanMessage msg = {};
     msg.payload = {1, 2, 3};
 
@@ -100,7 +97,7 @@
     ASSERT_EQ(Result::OK, result);
 }
 
-TEST_F(CanBusHalTest, SendTooLong) {
+TEST_P(CanBusHalTest, SendTooLong) {
     CanMessage msg = {};
     msg.id = 0x123;
     msg.payload = hidl_vec<uint8_t>(102400);  // 100kiB
@@ -109,14 +106,14 @@
     ASSERT_EQ(Result::PAYLOAD_TOO_LONG, result);
 }
 
-TEST_F(CanBusHalTest, ListenNoFilter) {
+TEST_P(CanBusHalTest, ListenNoFilter) {
     const auto [result, closeHandle] = listen({}, new CanMessageListener());
     ASSERT_EQ(Result::OK, result);
 
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, ListenSomeFilter) {
+TEST_P(CanBusHalTest, ListenSomeFilter) {
     hidl_vec<CanMessageFilter> filters = {
             {0x123, 0x1FF, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE, false},
             {0x001, 0x00F, FilterFlag::DONT_CARE, FilterFlag::DONT_CARE, true},
@@ -129,12 +126,12 @@
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, ListenNull) {
+TEST_P(CanBusHalTest, ListenNull) {
     const auto [result, closeHandle] = listen({}, nullptr);
     ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
 }
 
-TEST_F(CanBusHalTest, DoubleCloseListener) {
+TEST_P(CanBusHalTest, DoubleCloseListener) {
     const auto [result, closeHandle] = listen({}, new CanMessageListener());
     ASSERT_EQ(Result::OK, result);
 
@@ -142,12 +139,12 @@
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, DontCloseListener) {
+TEST_P(CanBusHalTest, DontCloseListener) {
     const auto [result, closeHandle] = listen({}, new CanMessageListener());
     ASSERT_EQ(Result::OK, result);
 }
 
-TEST_F(CanBusHalTest, DoubleCloseErrorListener) {
+TEST_P(CanBusHalTest, DoubleCloseErrorListener) {
     auto closeHandle = listenForErrors(new CanErrorListener());
     ASSERT_NE(nullptr, closeHandle.get());
 
@@ -155,7 +152,7 @@
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, DoubleCloseNullErrorListener) {
+TEST_P(CanBusHalTest, DoubleCloseNullErrorListener) {
     auto closeHandle = listenForErrors(nullptr);
     ASSERT_NE(nullptr, closeHandle.get());
 
@@ -163,13 +160,11 @@
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, DontCloseErrorListener) {
+TEST_P(CanBusHalTest, DontCloseErrorListener) {
     auto closeHandle = listenForErrors(new CanErrorListener());
     ASSERT_NE(nullptr, closeHandle.get());
 }
 
-}  // namespace android::hardware::automotive::can::V1_0::vts
-
 /**
  * This test requires that you bring up a valid bus first.
  *
@@ -177,19 +172,12 @@
  * mma -j && adb root && adb remount && adb sync
  *
  * Example manual invocation:
- * adb shell /data/nativetest64/VtsHalCanBusV1_0TargetTest/VtsHalCanBusV1_0TargetTest \
- *     --hal_service_instance=android.hardware.automotive.can@1.0::ICanBus/<NAME_OF_VALID_BUS>
+ * adb shell canhalctrl up <NAME_OF_VALID_BUS> socketcan can0 125000
+ * adb shell /data/nativetest64/VtsHalCanBusV1_0TargetTest/VtsHalCanBusV1_0TargetTest\
+ *     --gtest_filter=*_<NAME_OF_VALID_BUS>
  */
-int main(int argc, char** argv) {
-    using android::hardware::automotive::can::V1_0::ICanBus;
-    using android::hardware::automotive::can::V1_0::vts::gEnv;
-    using android::hardware::automotive::can::V1_0::vts::utils::SimpleHidlEnvironment;
-    setenv("TREBLE_TESTING_OVERRIDE", "true", true);
-    android::base::SetDefaultTag("CanBusVts");
-    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
-    gEnv = new SimpleHidlEnvironment<ICanBus>;
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    return RUN_ALL_TESTS();
-}
+INSTANTIATE_TEST_SUITE_P(  //
+        PerInstance, CanBusHalTest, testing::ValuesIn(getAllHalInstanceNames(ICanBus::descriptor)),
+        PrintInstanceNameToString);
+
+}  // namespace android::hardware::automotive::can::V1_0::vts
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
index 68d555d..9039435 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 #include <android-base/strings.h>
 #include <android/hardware/automotive/can/1.0/ICanBus.h>
@@ -23,9 +22,11 @@
 #include <android/hidl/manager/1.2/IServiceManager.h>
 #include <can-vts-utils/bus-enumerator.h>
 #include <can-vts-utils/can-hal-printers.h>
-#include <can-vts-utils/environment-utils.h>
 #include <gmock/gmock.h>
+#include <gtest/gtest.h>
 #include <hidl-utils/hidl-utils.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 #include <utils/Mutex.h>
 #include <utils/SystemClock.h>
 
@@ -39,8 +40,6 @@
 using hardware::hidl_vec;
 using InterfaceType = ICanController::InterfaceType;
 
-static utils::SimpleHidlEnvironment<ICanController>* gEnv = nullptr;
-
 struct CanMessageListener : public can::V1_0::ICanMessageListener {
     DISALLOW_COPY_AND_ASSIGN(CanMessageListener);
 
@@ -133,12 +132,11 @@
     sp<ICanBus> mBus;
 };
 
-class CanBusVirtualHalTest : public ::testing::VtsHalHidlTargetTestBase {
+class CanBusVirtualHalTest : public ::testing::TestWithParam<std::string> {
   protected:
     virtual void SetUp() override;
-
+    virtual void TearDown() override;
     static void SetUpTestCase();
-    static void TearDownTestCase();
 
     Bus makeBus();
 
@@ -147,13 +145,10 @@
 
   private:
     unsigned mLastIface = 0;
-    static sp<ICanController> mCanController;
-    static bool mVirtualSupported;
+    sp<ICanController> mCanController = nullptr;
     static bool mTestCaseInitialized;
 };
 
-sp<ICanController> CanBusVirtualHalTest::mCanController = nullptr;
-bool CanBusVirtualHalTest::mVirtualSupported;
 hidl_vec<hidl_string> CanBusVirtualHalTest::mBusNames;
 bool CanBusVirtualHalTest::mTestCaseInitialized = false;
 
@@ -170,29 +165,27 @@
 }
 
 void CanBusVirtualHalTest::SetUp() {
-    if (!mVirtualSupported) GTEST_SKIP();
     ASSERT_TRUE(mTestCaseInitialized);
-}
 
-void CanBusVirtualHalTest::SetUpTestCase() {
-    const auto serviceName = gEnv->getServiceName<ICanController>();
-    mCanController = getService<ICanController>(serviceName);
-    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << serviceName;
+    mCanController = ICanController::getService(GetParam());
+    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << GetParam();
 
     hidl_vec<InterfaceType> supported;
     mCanController->getSupportedInterfaceTypes(hidl_utils::fill(&supported)).assertOk();
-    mVirtualSupported = supported.contains(InterfaceType::VIRTUAL);
+    if (!supported.contains(InterfaceType::VIRTUAL)) GTEST_SKIP();
+}
 
+void CanBusVirtualHalTest::TearDown() {
+    mCanController.clear();
+}
+
+void CanBusVirtualHalTest::SetUpTestCase() {
     mBusNames = utils::getBusNames();
     ASSERT_NE(0u, mBusNames.size()) << "No ICanBus HALs defined in device manifest";
 
     mTestCaseInitialized = true;
 }
 
-void CanBusVirtualHalTest::TearDownTestCase() {
-    mCanController.clear();
-}
-
 Bus CanBusVirtualHalTest::makeBus() {
     const auto idx = mLastIface++;
     EXPECT_LT(idx, mBusNames.size());
@@ -204,7 +197,7 @@
     return Bus(mCanController, config);
 }
 
-TEST_F(CanBusVirtualHalTest, Send) {
+TEST_P(CanBusVirtualHalTest, Send) {
     auto bus = makeBus();
 
     CanMessage msg = {};
@@ -214,7 +207,7 @@
     bus.send(msg);
 }
 
-TEST_F(CanBusVirtualHalTest, SendAfterClose) {
+TEST_P(CanBusVirtualHalTest, SendAfterClose) {
     auto bus = makeBus();
     auto zombie = bus.get();
     bus.reset();
@@ -223,7 +216,7 @@
     ASSERT_EQ(Result::INTERFACE_DOWN, result);
 }
 
-TEST_F(CanBusVirtualHalTest, SendAndRecv) {
+TEST_P(CanBusVirtualHalTest, SendAndRecv) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
     auto bus1 = makeBus();
     auto bus2 = makeBus();
@@ -243,7 +236,7 @@
     ASSERT_EQ(msg, messages[0]);
 }
 
-TEST_F(CanBusVirtualHalTest, DownOneOfTwo) {
+TEST_P(CanBusVirtualHalTest, DownOneOfTwo) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
 
     auto bus1 = makeBus();
@@ -254,7 +247,7 @@
     bus1.send({});
 }
 
-TEST_F(CanBusVirtualHalTest, FilterPositive) {
+TEST_P(CanBusVirtualHalTest, FilterPositive) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
     auto bus1 = makeBus();
     auto bus2 = makeBus();
@@ -418,7 +411,7 @@
     ASSERT_EQ(expectedPositive, messagesPositive);
 }
 
-TEST_F(CanBusVirtualHalTest, FilterNegative) {
+TEST_P(CanBusVirtualHalTest, FilterNegative) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
     auto bus1 = makeBus();
     auto bus2 = makeBus();
@@ -612,7 +605,7 @@
     ASSERT_EQ(expectedNegative, messagesNegative);
 }
 
-TEST_F(CanBusVirtualHalTest, FilterMixed) {
+TEST_P(CanBusVirtualHalTest, FilterMixed) {
     if (mBusNames.size() < 2u) GTEST_SKIP() << "Not testable with less than two CAN buses.";
     auto bus1 = makeBus();
     auto bus2 = makeBus();
@@ -871,22 +864,13 @@
     ASSERT_EQ(expectedMixed, messagesMixed);
 }
 
-}  // namespace android::hardware::automotive::can::V1_0::vts
-
 /**
  * Example manual invocation:
- * adb shell /data/nativetest64/VtsHalCanBusVirtualV1_0TargetTest/VtsHalCanBusVirtualV1_0TargetTest\
- *     --hal_service_instance=android.hardware.automotive.can@1.0::ICanController/socketcan
+ * adb shell /data/nativetest64/VtsHalCanBusVirtualV1_0TargetTest/VtsHalCanBusVirtualV1_0TargetTest
  */
-int main(int argc, char** argv) {
-    using android::hardware::automotive::can::V1_0::ICanController;
-    using android::hardware::automotive::can::V1_0::vts::gEnv;
-    using android::hardware::automotive::can::V1_0::vts::utils::SimpleHidlEnvironment;
-    android::base::SetDefaultTag("CanBusVirtualVts");
-    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
-    gEnv = new SimpleHidlEnvironment<ICanController>;
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    return RUN_ALL_TESTS();
-}
+INSTANTIATE_TEST_SUITE_P(  //
+        PerInstance, CanBusVirtualHalTest,
+        testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)),
+        PrintInstanceNameToString);
+
+}  // namespace android::hardware::automotive::can::V1_0::vts
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
index 8397215..8ef5758 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanControllerV1_0TargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 #include <android-base/strings.h>
 #include <android/hardware/automotive/can/1.0/ICanBus.h>
@@ -23,9 +22,10 @@
 #include <android/hidl/manager/1.2/IServiceManager.h>
 #include <can-vts-utils/bus-enumerator.h>
 #include <can-vts-utils/can-hal-printers.h>
-#include <can-vts-utils/environment-utils.h>
 #include <gmock/gmock.h>
 #include <hidl-utils/hidl-utils.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 namespace android::hardware::automotive::can::V1_0::vts {
 
@@ -33,9 +33,7 @@
 using InterfaceType = ICanController::InterfaceType;
 using IfId = ICanController::BusConfig::InterfaceId;
 
-static utils::SimpleHidlEnvironment<ICanController>* gEnv = nullptr;
-
-class CanControllerHalTest : public ::testing::VtsHalHidlTargetTestBase {
+class CanControllerHalTest : public ::testing::TestWithParam<std::string> {
   protected:
     virtual void SetUp() override;
     virtual void TearDown() override;
@@ -61,9 +59,8 @@
 void CanControllerHalTest::SetUp() {
     ASSERT_TRUE(mTestCaseInitialized);
 
-    const auto serviceName = gEnv->getServiceName<ICanController>();
-    mCanController = getService<ICanController>(serviceName);
-    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << serviceName;
+    mCanController = ICanController::getService(GetParam());
+    ASSERT_TRUE(mCanController) << "Couldn't open CAN Controller: " << GetParam();
 }
 
 void CanControllerHalTest::TearDown() {
@@ -130,12 +127,12 @@
             << " (should be otherwise)";
 }
 
-TEST_F(CanControllerHalTest, SupportsSomething) {
+TEST_P(CanControllerHalTest, SupportsSomething) {
     const auto supported = getSupportedInterfaceTypes();
     ASSERT_GT(supported.size(), 0u);
 }
 
-TEST_F(CanControllerHalTest, BringUpDown) {
+TEST_P(CanControllerHalTest, BringUpDown) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -148,12 +145,12 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, DownDummy) {
+TEST_P(CanControllerHalTest, DownDummy) {
     const auto result = mCanController->downInterface("imnotup");
     ASSERT_FALSE(result);
 }
 
-TEST_F(CanControllerHalTest, UpTwice) {
+TEST_P(CanControllerHalTest, UpTwice) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -169,7 +166,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, ConfigCompatibility) {
+TEST_P(CanControllerHalTest, ConfigCompatibility) {
     // using random-ish addresses, which may not be valid - we can't test the success case
     // TODO(b/146214370): move interfaceId constructors to a library
     IfId virtualCfg = {};
@@ -231,7 +228,7 @@
     }
 }
 
-TEST_F(CanControllerHalTest, FailEmptyName) {
+TEST_P(CanControllerHalTest, FailEmptyName) {
     const std::string name = "";
 
     assertRegistered(name, false);
@@ -241,7 +238,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, FailBadName) {
+TEST_P(CanControllerHalTest, FailBadName) {
     // 33 characters (name can be at most 32 characters long)
     const std::string name = "ab012345678901234567890123456789c";
 
@@ -252,7 +249,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, FailBadVirtualAddress) {
+TEST_P(CanControllerHalTest, FailBadVirtualAddress) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -262,7 +259,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, FailBadSocketcanAddress) {
+TEST_P(CanControllerHalTest, FailBadSocketcanAddress) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -277,7 +274,7 @@
     assertRegistered(name, false);
 }
 
-TEST_F(CanControllerHalTest, FailBadSlcanAddress) {
+TEST_P(CanControllerHalTest, FailBadSlcanAddress) {
     const std::string name = mBusNames[0];
 
     assertRegistered(name, false);
@@ -292,22 +289,13 @@
     assertRegistered(name, false);
 }
 
-}  // namespace android::hardware::automotive::can::V1_0::vts
-
 /**
  * Example manual invocation:
- * adb shell /data/nativetest64/VtsHalCanControllerV1_0TargetTest/VtsHalCanControllerV1_0TargetTest\
- *     --hal_service_instance=android.hardware.automotive.can@1.0::ICanController/socketcan
+ * adb shell /data/nativetest64/VtsHalCanControllerV1_0TargetTest/VtsHalCanControllerV1_0TargetTest
  */
-int main(int argc, char** argv) {
-    using android::hardware::automotive::can::V1_0::ICanController;
-    using android::hardware::automotive::can::V1_0::vts::gEnv;
-    using android::hardware::automotive::can::V1_0::vts::utils::SimpleHidlEnvironment;
-    android::base::SetDefaultTag("CanControllerVts");
-    android::base::SetMinimumLogSeverity(android::base::VERBOSE);
-    gEnv = new SimpleHidlEnvironment<ICanController>;
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    return RUN_ALL_TESTS();
-}
+INSTANTIATE_TEST_SUITE_P(  //
+        PerInstance, CanControllerHalTest,
+        testing::ValuesIn(getAllHalInstanceNames(ICanController::descriptor)),
+        PrintInstanceNameToString);
+
+}  // namespace android::hardware::automotive::can::V1_0::vts
diff --git a/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h b/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h
deleted file mode 100644
index 3eb9cc1..0000000
--- a/automotive/can/1.0/vts/utils/include/can-vts-utils/environment-utils.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#pragma once
-
-#include <VtsHalHidlTargetTestEnvBase.h>
-
-namespace android::hardware::automotive::can::V1_0::vts::utils {
-
-/**
- * Simple test environment.
- *
- * This is a helper class to instantiate a test environment without boilerplate code for cases where
- * there is no need to pass more parameters than just HIDL service instance name.
- *
- * The class implements registerTestServices() by calling registerTestService() on every HIDL
- * interface provided as parameter to this template.
- *
- * Example usage:
- *     static utils::SimpleHidlEnvironment<IMyService>* gEnv = nullptr;
- *
- *     void CanBusHalTest::SetUp() {
- *         const auto serviceName = gEnv->getServiceName<IMyService>();
- *         (...)
- *     }
- *
- *     int main(int argc, char** argv) {
- *         gEnv = new SimpleHidlEnvironment<IMyService>;
- *         ::testing::AddGlobalTestEnvironment(gEnv);
- *         ::testing::InitGoogleTest(&argc, argv);
- *         gEnv->init(&argc, argv);
- *         return RUN_ALL_TESTS();
- *     }
- *
- * \param T... HIDL interface names to register for a test service
- */
-template <typename... T>
-class SimpleHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-  public:
-    virtual void registerTestServices() override {
-        // Call registerTestService() for every HIDL interface using this template.
-        using expander = int[];
-        (void)expander{0, (registerTestService<T>(), 0)...};
-    }
-};
-
-}  // namespace android::hardware::automotive::can::V1_0::vts::utils
diff --git a/automotive/evs/1.0/vts/functional/Android.bp b/automotive/evs/1.0/vts/functional/Android.bp
index 8988bfd..9f7cd3f 100644
--- a/automotive/evs/1.0/vts/functional/Android.bp
+++ b/automotive/evs/1.0/vts/functional/Android.bp
@@ -28,7 +28,7 @@
         "android.hardware.automotive.evs@1.0",
         "android.hardware.automotive.evs@common-default-lib",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["vts-core"],
     cflags: [
         "-O0",
         "-g",
diff --git a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp
index f7580f0..54862a2 100644
--- a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp
+++ b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp
@@ -17,15 +17,6 @@
 #define LOG_TAG "VtsHalEvsTest"
 
 
-// Note:  We have't got a great way to indicate which target
-// should be tested, so we'll leave the interface served by the
-// default (mock) EVS driver here for easy reference.  All
-// actual EVS drivers should serve on the EvsEnumeratorHw name,
-// however, so the code is checked in that way.
-//const static char kEnumeratorName[]  = "EvsEnumeratorHw-Mock";
-const static char kEnumeratorName[]  = "EvsEnumeratorHw";
-
-
 // These values are called out in the EVS design doc (as of Mar 8, 2017)
 static const int kMaxStreamStartMilliseconds = 500;
 static const int kMinimumFramesPerSecond = 10;
@@ -53,8 +44,9 @@
 #include <android/hardware/automotive/evs/1.0/IEvsCameraStream.h>
 #include <android/hardware/automotive/evs/1.0/IEvsDisplay.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 using namespace ::android::hardware::automotive::evs::V1_0;
 using ::android::hardware::Return;
@@ -64,32 +56,19 @@
 using ::android::hardware::hidl_string;
 using ::android::sp;
 
-// Test environment for Evs HIDL HAL.
-class EvsHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static EvsHidlEnvironment* Instance() {
-        static EvsHidlEnvironment* instance = new EvsHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IEvsEnumerator>(); }
-
-   private:
-    EvsHidlEnvironment() {}
-};
-
 // The main test class for EVS
-class EvsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class EvsHidlTest : public ::testing::TestWithParam<std::string> {
 public:
     virtual void SetUp() override {
         // Make sure we can connect to the enumerator
-        string service_name =
-            EvsHidlEnvironment::Instance()->getServiceName<IEvsEnumerator>(kEnumeratorName);
-        pEnumerator = getService<IEvsEnumerator>(service_name);
+        std::string service_name = GetParam();
+        pEnumerator = IEvsEnumerator::getService(service_name);
+
         ASSERT_NE(pEnumerator.get(), nullptr);
 
-        mIsHwModule = !service_name.compare(kEnumeratorName);
+        // "default" is reserved for EVS manager.
+        constexpr static char kEvsManagerName[] = "default";
+        mIsHwModule = service_name.compare(kEvsManagerName);
     }
 
     virtual void TearDown() override {}
@@ -130,7 +109,7 @@
  * Opens each camera reported by the enumerator and then explicitly closes it via a
  * call to closeCamera.  Then repeats the test to ensure all cameras can be reopened.
  */
-TEST_F(EvsHidlTest, CameraOpenClean) {
+TEST_P(EvsHidlTest, CameraOpenClean) {
     ALOGI("Starting CameraOpenClean test");
 
     // Get the camera list
@@ -162,7 +141,7 @@
  * call.  This ensures that the intended "aggressive open" behavior works.  This is necessary for
  * the system to be tolerant of shutdown/restart race conditions.
  */
-TEST_F(EvsHidlTest, CameraOpenAggressive) {
+TEST_P(EvsHidlTest, CameraOpenAggressive) {
     ALOGI("Starting CameraOpenAggressive test");
 
     // Get the camera list
@@ -216,7 +195,7 @@
  * DisplayOpen:
  * Test both clean shut down and "aggressive open" device stealing behavior.
  */
-TEST_F(EvsHidlTest, DisplayOpen) {
+TEST_P(EvsHidlTest, DisplayOpen) {
     ALOGI("Starting DisplayOpen test");
 
     // Request exclusive access to the EVS display, then let it go
@@ -264,7 +243,7 @@
  * Validate that display states transition as expected and can be queried from either the display
  * object itself or the owning enumerator.
  */
-TEST_F(EvsHidlTest, DisplayStates) {
+TEST_P(EvsHidlTest, DisplayStates) {
     ALOGI("Starting DisplayStates test");
 
     // Ensure the display starts in the expected state
@@ -324,7 +303,7 @@
  * CameraStreamPerformance:
  * Measure and qualify the stream start up time and streaming frame rate of each reported camera
  */
-TEST_F(EvsHidlTest, CameraStreamPerformance) {
+TEST_P(EvsHidlTest, CameraStreamPerformance) {
     ALOGI("Starting CameraStreamPerformance test");
 
     // Get the camera list
@@ -387,7 +366,7 @@
  * Ensure the camera implementation behaves properly when the client holds onto buffers for more
  * than one frame time.  The camera must cleanly skip frames until the client is ready again.
  */
-TEST_F(EvsHidlTest, CameraStreamBuffering) {
+TEST_P(EvsHidlTest, CameraStreamBuffering) {
     ALOGI("Starting CameraStreamBuffering test");
 
     // Arbitrary constant (should be > 1 and less than crazy)
@@ -456,7 +435,7 @@
  * imagery is simply copied to the display buffer and presented on screen.  This is the one test
  * which a human could observe to see the operation of the system on the physical display.
  */
-TEST_F(EvsHidlTest, CameraToDisplayRoundTrip) {
+TEST_P(EvsHidlTest, CameraToDisplayRoundTrip) {
     ALOGI("Starting CameraToDisplayRoundTrip test");
 
     // Get the camera list
@@ -517,7 +496,7 @@
  * Verify that each client can start and stop video streams on the same
  * underlying camera.
  */
-TEST_F(EvsHidlTest, MultiCameraStream) {
+TEST_P(EvsHidlTest, MultiCameraStream) {
     ALOGI("Starting MultiCameraStream test");
 
     if (mIsHwModule) {
@@ -601,11 +580,8 @@
 }
 
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(EvsHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    EvsHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    ALOGI("Test result = %d", status);
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+    PerInstance,
+    EvsHidlTest,
+    testing::ValuesIn(android::hardware::getAllHalInstanceNames(IEvsEnumerator::descriptor)),
+    android::hardware::PrintInstanceNameToString);
diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
index 8580500..cde8048 100644
--- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
+++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
@@ -17,15 +17,6 @@
 #define LOG_TAG "VtsHalEvsTest"
 
 
-// Note:  We have't got a great way to indicate which target
-// should be tested, so we'll leave the interface served by the
-// default (mock) EVS driver here for easy reference.  All
-// actual EVS drivers should serve on the EvsEnumeratorHw name,
-// however, so the code is checked in that way.
-//const static char kEnumeratorName[]  = "EvsEnumeratorHw-Mock";
-const static char kEnumeratorName[]  = "EvsEnumeratorHw";
-
-
 // These values are called out in the EVS design doc (as of Mar 8, 2017)
 static const int kMaxStreamStartMilliseconds = 500;
 static const int kMinimumFramesPerSecond = 10;
@@ -61,10 +52,12 @@
 #include <ui/DisplayConfig.h>
 #include <ui/DisplayState.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 using namespace ::android::hardware::automotive::evs::V1_1;
+using namespace std::chrono_literals;
 
 using ::android::hardware::Return;
 using ::android::hardware::Void;
@@ -97,29 +90,13 @@
 } RawStreamConfig;
 
 
-// Test environment for Evs HIDL HAL.
-class EvsHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static EvsHidlEnvironment* Instance() {
-        static EvsHidlEnvironment* instance = new EvsHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IEvsEnumerator>(); }
-
-   private:
-    EvsHidlEnvironment() {}
-};
-
 // The main test class for EVS
-class EvsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class EvsHidlTest : public ::testing::TestWithParam<std::string> {
 public:
     virtual void SetUp() override {
         // Make sure we can connect to the enumerator
-        string service_name =
-            EvsHidlEnvironment::Instance()->getServiceName<IEvsEnumerator>(kEnumeratorName);
-        pEnumerator = getService<IEvsEnumerator>(service_name);
+        std::string service_name = GetParam();
+        pEnumerator = IEvsEnumerator::getService(service_name);
         ASSERT_NE(pEnumerator.get(), nullptr);
 
         mIsHwModule = pEnumerator->isHardware();
@@ -269,7 +246,7 @@
  * Opens each camera reported by the enumerator and then explicitly closes it via a
  * call to closeCamera.  Then repeats the test to ensure all cameras can be reopened.
  */
-TEST_F(EvsHidlTest, CameraOpenClean) {
+TEST_P(EvsHidlTest, CameraOpenClean) {
     ALOGI("Starting CameraOpenClean test");
 
     // Get the camera list
@@ -338,7 +315,7 @@
  * call.  This ensures that the intended "aggressive open" behavior works.  This is necessary for
  * the system to be tolerant of shutdown/restart race conditions.
  */
-TEST_F(EvsHidlTest, CameraOpenAggressive) {
+TEST_P(EvsHidlTest, CameraOpenAggressive) {
     ALOGI("Starting CameraOpenAggressive test");
 
     // Get the camera list
@@ -415,7 +392,7 @@
  * CameraStreamPerformance:
  * Measure and qualify the stream start up time and streaming frame rate of each reported camera
  */
-TEST_F(EvsHidlTest, CameraStreamPerformance) {
+TEST_P(EvsHidlTest, CameraStreamPerformance) {
     ALOGI("Starting CameraStreamPerformance test");
 
     // Get the camera list
@@ -505,7 +482,7 @@
  * Ensure the camera implementation behaves properly when the client holds onto buffers for more
  * than one frame time.  The camera must cleanly skip frames until the client is ready again.
  */
-TEST_F(EvsHidlTest, CameraStreamBuffering) {
+TEST_P(EvsHidlTest, CameraStreamBuffering) {
     ALOGI("Starting CameraStreamBuffering test");
 
     // Arbitrary constant (should be > 1 and less than crazy)
@@ -590,7 +567,7 @@
  * imagery is simply copied to the display buffer and presented on screen.  This is the one test
  * which a human could observe to see the operation of the system on the physical display.
  */
-TEST_F(EvsHidlTest, CameraToDisplayRoundTrip) {
+TEST_P(EvsHidlTest, CameraToDisplayRoundTrip) {
     ALOGI("Starting CameraToDisplayRoundTrip test");
 
     // Get the camera list
@@ -689,7 +666,7 @@
  * Verify that each client can start and stop video streams on the same
  * underlying camera.
  */
-TEST_F(EvsHidlTest, MultiCameraStream) {
+TEST_P(EvsHidlTest, MultiCameraStream) {
     ALOGI("Starting MultiCameraStream test");
 
     if (mIsHwModule) {
@@ -796,7 +773,7 @@
  * CameraParameter:
  * Verify that a client can adjust a camera parameter.
  */
-TEST_F(EvsHidlTest, CameraParameter) {
+TEST_P(EvsHidlTest, CameraParameter) {
     ALOGI("Starting CameraParameter test");
 
     // Get the camera list
@@ -940,7 +917,7 @@
  * Verify that non-master client gets notified when the master client either
  * terminates or releases a role.
  */
-TEST_F(EvsHidlTest, CameraMasterRelease) {
+TEST_P(EvsHidlTest, CameraMasterRelease) {
     ALOGI("Starting CameraMasterRelease test");
 
     if (mIsHwModule) {
@@ -1121,7 +1098,7 @@
  * Verify that master and non-master clients behave as expected when they try to adjust
  * camera parameters.
  */
-TEST_F(EvsHidlTest, MultiCameraParameter) {
+TEST_P(EvsHidlTest, MultiCameraParameter) {
     ALOGI("Starting MultiCameraParameter test");
 
     if (mIsHwModule) {
@@ -1404,7 +1381,7 @@
 
         std::mutex eventLock;
         auto timer = std::chrono::system_clock::now();
-        unique_lock<std::mutex> lock(eventLock);
+        std::unique_lock<std::mutex> lock(eventLock);
         while (!listening) {
             eventCond.wait_until(lock, timer + 1s);
         }
@@ -1594,7 +1571,7 @@
  * EVS client, which owns the display, is priortized and therefore can take over
  * a master role from other EVS clients without the display.
  */
-TEST_F(EvsHidlTest, HighPriorityCameraClient) {
+TEST_P(EvsHidlTest, HighPriorityCameraClient) {
     ALOGI("Starting HighPriorityCameraClient test");
 
     if (mIsHwModule) {
@@ -1967,7 +1944,7 @@
  * CameraToDisplayRoundTrip test case but this case retrieves available stream
  * configurations from EVS and uses one of them to start a video stream.
  */
-TEST_F(EvsHidlTest, CameraUseStreamConfigToDisplay) {
+TEST_P(EvsHidlTest, CameraUseStreamConfigToDisplay) {
     ALOGI("Starting CameraUseStreamConfigToDisplay test");
 
     // Get the camera list
@@ -2071,7 +2048,7 @@
  * Verify that each client can start and stop video streams on the same
  * underlying camera with same configuration.
  */
-TEST_F(EvsHidlTest, MultiCameraStreamUseConfig) {
+TEST_P(EvsHidlTest, MultiCameraStreamUseConfig) {
     ALOGI("Starting MultiCameraStream test");
 
     if (mIsHwModule) {
@@ -2220,7 +2197,7 @@
  * checking its capability and locating supporting physical camera device
  * identifiers.
  */
-TEST_F(EvsHidlTest, LogicalCameraMetadata) {
+TEST_P(EvsHidlTest, LogicalCameraMetadata) {
     ALOGI("Starting LogicalCameraMetadata test");
 
     // Get the camera list
@@ -2244,7 +2221,7 @@
  * call to closeUltrasonicsArray. Then repeats the test to ensure all ultrasonics arrays
  * can be reopened.
  */
-TEST_F(EvsHidlTest, UltrasonicsArrayOpenClean) {
+TEST_P(EvsHidlTest, UltrasonicsArrayOpenClean) {
     ALOGI("Starting UltrasonicsArrayOpenClean test");
 
     // Get the ultrasonics array list
@@ -2271,7 +2248,7 @@
 
 
 // Starts a stream and verifies all data received is valid.
-TEST_F(EvsHidlTest, UltrasonicsVerifyStreamData) {
+TEST_P(EvsHidlTest, UltrasonicsVerifyStreamData) {
     ALOGI("Starting UltrasonicsVerifyStreamData");
 
     // Get the ultrasonics array list
@@ -2307,7 +2284,7 @@
 
 
 // Sets frames in flight before and after start of stream and verfies success.
-TEST_F(EvsHidlTest, UltrasonicsSetFramesInFlight) {
+TEST_P(EvsHidlTest, UltrasonicsSetFramesInFlight) {
     ALOGI("Starting UltrasonicsSetFramesInFlight");
 
     // Get the ultrasonics array list
@@ -2342,11 +2319,9 @@
 }
 
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(EvsHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    EvsHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    ALOGI("Test result = %d", status);
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+    PerInstance,
+    EvsHidlTest,
+    testing::ValuesIn(android::hardware::getAllHalInstanceNames(IEvsEnumerator::descriptor)),
+    android::hardware::PrintInstanceNameToString);
+
diff --git a/camera/provider/2.6/ICameraProvider.hal b/camera/provider/2.6/ICameraProvider.hal
index 9c46ba0..5651550 100644
--- a/camera/provider/2.6/ICameraProvider.hal
+++ b/camera/provider/2.6/ICameraProvider.hal
@@ -56,11 +56,26 @@
      * s720p - min (max output resolution for the given format, 1280 X 720)
      * s1440p - min (max output resolution for the given format, 1920 X 1440)
      *
+     * If a device has MONOCHROME capability (device's capabilities include
+     * ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) and therefore supports Y8
+     * outputs, stream combinations mentioned above, where YUV is substituted by
+     * Y8 must be also supported.
+     *
      * The camera framework must call this method whenever it gets a
      * cameraDeviceStatusChange callback adding a new camera device or removing
      * a camera device known to it. This is so that the camera framework can get new combinations
      * of camera ids that can stream concurrently, that might have potentially appeared.
      *
+     * For each combination (and their subsets) of camera device ids returned by
+     * getConcurrentStreamingCameraIds(): If only the mandatory combinations can
+     * be supported concurrently by each device, then the resource costs must
+     * sum up to > 100 for the concurrent set, to ensure arbitration between
+     * camera applications work as expected. Only if resources are sufficient
+     * to run a set of cameras at full capability (maximally
+     * resource-consuming framerate and stream size settings available in the
+     * configuration settings exposed through camera metadata), should the sum
+     * of resource costs for the combination be <= 100.
+     *
      * @return status Status code for the operation
      * @return cameraIds a list of camera id combinations that support
      *         concurrent stream configurations with the minimum guarantees
diff --git a/current.txt b/current.txt
index e7face5..42981ad 100644
--- a/current.txt
+++ b/current.txt
@@ -611,9 +611,10 @@
 bca5379d5065e2e08b6ad7308ffc8a71a972fc0698bec678ea32eea786d01cb5 android.hardware.audio@6.0::IPrimaryDevice
 fd1f1b29f26b42e886220f04a08086c00e5ade9d7b53f095438e578ab9d42a93 android.hardware.audio@6.0::IStream
 2df5d5866b37776f25079c0e54b54350a2abe4e025a59c9e02a7d3abe8ca00e8 android.hardware.audio@6.0::IStreamIn
-e6cd2b7c1a86b6ca683c0224ffde3b73aa14f6487de9f46833e539d26d1b3b5c android.hardware.audio@6.0::IStreamOut
+164826a380f4c1700183003f62d7532e367b67381c30ea44f946c0cf00008f85 android.hardware.audio@6.0::IStreamOut
 997fdaad7a9d17ee7e01feb7031a753e2365e72ad30b11d950e9183fabdf3844 android.hardware.audio@6.0::IStreamOutCallback
-167ed5cfb7d91db2e2bf20f1320c1a9004eeb768e26f535e0f7db94a21867d21 android.hardware.audio.common@6.0::types
+e7ca0db9a1098210f327a9b152fa6afe6bf019c41e5264c64829d04d50c0a526 android.hardware.audio@6.0::IStreamOutEventCallback
+bee662c62d997d8065e2bcb5c1e7a9578931f22ce28fd02c219fdb4d0630abf7 android.hardware.audio.common@6.0::types
 817930d58412d662cb45e641c50cb62c727e4a3e3ffe7029a53cad9677b97d58 android.hardware.audio.effect@6.0::types
 525bec6b44f1103869c269a128d51b8dccd73af5340ba863c8886c68357c7faf android.hardware.audio.effect@6.0::IAcousticEchoCancelerEffect
 8d76bbe3719d051a8e9a1dcf9244f37f5b0a491feb249fa48391edf7cb4f3131 android.hardware.audio.effect@6.0::IAutomaticGainControlEffect
@@ -638,7 +639,7 @@
 07d0a252b2d8fa35887908a996ba395cf392968395fc30afab791f46e0c22a52 android.hardware.boot@1.1::IBootControl
 74049a402be913963edfdd80828a53736570e9d8124a1bf18166b6ed46a6b0ab android.hardware.boot@1.1::types
 b8c63679e1a3874b356f3e691aecce1191d38f59063cf2ed2dce8a9d4cabf00e android.hardware.camera.device@3.6::ICameraDevice
-daad72a2f482d8a1f660d0e99ac1b78fedb414a4cfbe3fa56b2cd480e5d6f0cb android.hardware.camera.provider@2.6::ICameraProvider
+99aae72ae75a8ddf63ccffbc585f3a55f4d0847b4adff3d7a0f8bd9e2305bec1 android.hardware.camera.provider@2.6::ICameraProvider
 8f8d9463508ff9cae88eb35c429fd0e2dbca0ca8f5de7fdf836cc0c4370becb6 android.hardware.camera.provider@2.6::ICameraProviderCallback
 a35d5151b48505f06a775b38c0e2e265f80a845d92802324c643565807f81c53 android.hardware.camera.device@3.6::types
 c1aa508d00b66ed5feefea398fd5edf28fa651ac89773adad7dfda4e0a73a952 android.hardware.cas@1.2::ICas
@@ -702,13 +703,9 @@
 77531c8d048f8f8ae532babd0ca86332a865ec9aace1b051226ef2b21123e645 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types
 99f5c26b952271d1246c957e1d0271fa39445ee65cc93aa7c187834f98914a33 android.hardware.radio@1.5::types
-7fefa2cc5b3b3be10b5cff5c5dc195385f491d4bf23ca65f9c6b3c30c8753a33 android.hardware.radio@1.5::IRadio
+b454df853441c12f6e425e8a60dd29fda20f5e6e39b93d1103e4b37495db38aa android.hardware.radio@1.5::IRadio
 e96ae1c3a9c0689002ec2318e9c587f4f607c16a75a3cd38788b77eb91072021 android.hardware.radio@1.5::IRadioIndication
 829d3827eeb5a8f563e80fe627419b3231012fc02bc2e79782ec5e9ad9f799a4 android.hardware.radio@1.5::IRadioResponse
-4c4ce691df02faa28c0729e2a033ec464e1d72699be8bcde4dfb141313dbeba8 android.hardware.radio.config@1.3::types
-a2977755bc5f1ef47f04b7f2400632efda6218e1515dba847da487145cfabc4f android.hardware.radio.config@1.3::IRadioConfig
-742360c775313438b0f82256eac62fb5bbc76a6ae6f388573f3aa142fb2c1eea android.hardware.radio.config@1.3::IRadioConfigIndication
-0006ab8e8b0910cbd3bbb08d5f17d5fac7d65a2bdad5f2334e4851db9d1e6fa8 android.hardware.radio.config@1.3::IRadioConfigResponse
 3ca6616381080bdd6c08141ad12775a94ae868c58b02b1274ae3326f7de724ab android.hardware.sensors@2.1::ISensors
 3d4141c6373cd9ca02fe221a7d12343840de2255d032c38248fe8e35816b58b2 android.hardware.sensors@2.1::ISensorsCallback
 8051cc50fc90ed447f058a8b15d81f35a65f1bd9004b1de4f127edeb89b47978 android.hardware.sensors@2.1::types
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
index 18c4a2e..ce08396 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/PlaneLayoutComponentType.aidl
@@ -41,6 +41,9 @@
     /* Blue */
     B = 1 << 12,
 
+    /* Raw */
+    RAW = 1 << 20,
+
     /* Alpha */
     A = 1 << 30,
 }
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index b6343d3..7a00ed2 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -279,23 +279,48 @@
               mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos));
 }
 
-TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) {
+TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) {
     for (Display display : mComposerCallback->getDisplays()) {
         for (Config config : mComposerClient->getDisplayConfigs(display)) {
             VsyncPeriodNanos expectedVsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4(
                     display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
 
-            mComposerClient->setActiveConfig(display, config);
+            VsyncPeriodChangeTimeline timeline;
+            IComposerClient::VsyncPeriodChangeConstraints constraints;
+
+            constraints.desiredTimeNanos = systemTime();
+            constraints.seamlessRequired = false;
+            EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
+                                           display, config, constraints, &timeline));
+
+            if (timeline.refreshRequired) {
+                sendRefreshFrame(timeline);
+            }
+            waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, 0,
+                                     expectedVsyncPeriodNanos);
+
             VsyncPeriodNanos vsyncPeriodNanos;
             int retryCount = 100;
             do {
                 std::this_thread::sleep_for(10ms);
+                vsyncPeriodNanos = 0;
                 EXPECT_EQ(Error::NONE,
                           mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
                 --retryCount;
             } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
 
             EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+
+            // Make sure that the vsync period stays the same if the active config is not changed.
+            auto timeout = 1ms;
+            for (int i = 0; i < 10; i++) {
+                std::this_thread::sleep_for(timeout);
+                timeout *= 2;
+                vsyncPeriodNanos = 0;
+                EXPECT_EQ(Error::NONE,
+                          mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
+                EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
+            }
         }
     }
 }
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 1416fcc..6cc5e34 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -221,7 +221,7 @@
                     case PlaneLayoutComponentType::Y:
                         ASSERT_EQ(nullptr, outYCbCr->y);
                         ASSERT_EQ(8, planeLayoutComponent.sizeInBits);
-                        ASSERT_EQ(8, planeLayout.sampleIncrementInBits);
+                        ASSERT_EQ(32, planeLayout.sampleIncrementInBits);
                         outYCbCr->y = tmpData;
                         outYCbCr->ystride = planeLayout.strideInBytes;
                         break;
@@ -278,6 +278,8 @@
         }
     }
 
+    bool isEqual(float a, float b) { return abs(a - b) < 0.0001; }
+
     std::unique_ptr<Gralloc> mGralloc;
     IMapper::BufferDescriptorInfo mDummyDescriptorInfo{};
     static const std::set<StandardMetadataType> sRequiredMetadataTypes;
@@ -725,8 +727,10 @@
 
     int fence;
     ASSERT_NO_FATAL_FAILURE(fence = mGralloc->flushLockedBuffer(writeBufferHandle));
-    ASSERT_EQ(0, sync_wait(fence, 3500));
-    close(fence);
+    if (fence >= 0) {
+        ASSERT_EQ(0, sync_wait(fence, 3500));
+        close(fence);
+    }
 
     ASSERT_NO_FATAL_FAILURE(mGralloc->rereadLockedBuffer(readBufferHandle));
 
@@ -1455,17 +1459,17 @@
      *  red             0.680   0.320
      *  white (D65)     0.3127  0.3290
      */
-    std::optional<Smpte2086> smpte2086;
-    smpte2086->primaryRed.x = 0.680;
-    smpte2086->primaryRed.y = 0.320;
-    smpte2086->primaryGreen.x = 0.265;
-    smpte2086->primaryGreen.y = 0.690;
-    smpte2086->primaryBlue.x = 0.150;
-    smpte2086->primaryBlue.y = 0.060;
-    smpte2086->whitePoint.x = 0.3127;
-    smpte2086->whitePoint.y = 0.3290;
-    smpte2086->maxLuminance = 100.0;
-    smpte2086->minLuminance = 0.1;
+    Smpte2086 smpte2086;
+    smpte2086.primaryRed.x = 0.680;
+    smpte2086.primaryRed.y = 0.320;
+    smpte2086.primaryGreen.x = 0.265;
+    smpte2086.primaryGreen.y = 0.690;
+    smpte2086.primaryBlue.x = 0.150;
+    smpte2086.primaryBlue.y = 0.060;
+    smpte2086.whitePoint.x = 0.3127;
+    smpte2086.whitePoint.y = 0.3290;
+    smpte2086.maxLuminance = 100.0;
+    smpte2086.minLuminance = 0.1;
 
     hidl_vec<uint8_t> vec;
     ASSERT_EQ(NO_ERROR, gralloc4::encodeSmpte2086(smpte2086, &vec));
@@ -1475,16 +1479,16 @@
                 std::optional<Smpte2086> realSmpte2086;
                 ASSERT_EQ(NO_ERROR, gralloc4::decodeSmpte2086(vec, &realSmpte2086));
                 ASSERT_TRUE(realSmpte2086.has_value());
-                EXPECT_EQ(smpte2086->primaryRed.x, realSmpte2086->primaryRed.x);
-                EXPECT_EQ(smpte2086->primaryRed.y, realSmpte2086->primaryRed.y);
-                EXPECT_EQ(smpte2086->primaryGreen.x, realSmpte2086->primaryGreen.x);
-                EXPECT_EQ(smpte2086->primaryGreen.y, realSmpte2086->primaryGreen.y);
-                EXPECT_EQ(smpte2086->primaryBlue.x, realSmpte2086->primaryBlue.x);
-                EXPECT_EQ(smpte2086->primaryBlue.y, realSmpte2086->primaryBlue.y);
-                EXPECT_EQ(smpte2086->whitePoint.x, realSmpte2086->whitePoint.x);
-                EXPECT_EQ(smpte2086->whitePoint.y, realSmpte2086->whitePoint.y);
-                EXPECT_EQ(smpte2086->maxLuminance, realSmpte2086->maxLuminance);
-                EXPECT_EQ(smpte2086->minLuminance, realSmpte2086->minLuminance);
+                EXPECT_TRUE(isEqual(smpte2086.primaryRed.x, realSmpte2086->primaryRed.x));
+                EXPECT_TRUE(isEqual(smpte2086.primaryRed.y, realSmpte2086->primaryRed.y));
+                EXPECT_TRUE(isEqual(smpte2086.primaryGreen.x, realSmpte2086->primaryGreen.x));
+                EXPECT_TRUE(isEqual(smpte2086.primaryGreen.y, realSmpte2086->primaryGreen.y));
+                EXPECT_TRUE(isEqual(smpte2086.primaryBlue.x, realSmpte2086->primaryBlue.x));
+                EXPECT_TRUE(isEqual(smpte2086.primaryBlue.y, realSmpte2086->primaryBlue.y));
+                EXPECT_TRUE(isEqual(smpte2086.whitePoint.x, realSmpte2086->whitePoint.x));
+                EXPECT_TRUE(isEqual(smpte2086.whitePoint.y, realSmpte2086->whitePoint.y));
+                EXPECT_TRUE(isEqual(smpte2086.maxLuminance, realSmpte2086->maxLuminance));
+                EXPECT_TRUE(isEqual(smpte2086.minLuminance, realSmpte2086->minLuminance));
             });
 }
 
@@ -1492,9 +1496,9 @@
  * Test IMapper::set(Cta8613)
  */
 TEST_P(GraphicsMapperHidlTest, SetCta861_3) {
-    std::optional<Cta861_3> cta861_3;
-    cta861_3->maxContentLightLevel = 78.0;
-    cta861_3->maxFrameAverageLightLevel = 62.0;
+    Cta861_3 cta861_3;
+    cta861_3.maxContentLightLevel = 78.0;
+    cta861_3.maxFrameAverageLightLevel = 62.0;
 
     hidl_vec<uint8_t> vec;
     ASSERT_EQ(NO_ERROR, gralloc4::encodeCta861_3(cta861_3, &vec));
@@ -1504,9 +1508,10 @@
                 std::optional<Cta861_3> realCta861_3;
                 ASSERT_EQ(NO_ERROR, gralloc4::decodeCta861_3(vec, &realCta861_3));
                 ASSERT_TRUE(realCta861_3.has_value());
-                EXPECT_EQ(cta861_3->maxContentLightLevel, realCta861_3->maxContentLightLevel);
-                EXPECT_EQ(cta861_3->maxFrameAverageLightLevel,
-                          realCta861_3->maxFrameAverageLightLevel);
+                EXPECT_TRUE(
+                        isEqual(cta861_3.maxContentLightLevel, realCta861_3->maxContentLightLevel));
+                EXPECT_TRUE(isEqual(cta861_3.maxFrameAverageLightLevel,
+                                    realCta861_3->maxFrameAverageLightLevel));
             });
 }
 
@@ -1990,7 +1995,7 @@
         const auto& metadataType = description.metadataType;
 
         if (!gralloc4::isStandardMetadataType(metadataType)) {
-            EXPECT_GT(0, description.description.size());
+            EXPECT_GT(description.description.size(), 0);
             continue;
         }
 
@@ -2074,7 +2079,7 @@
     auto info = mDummyDescriptorInfo;
 
     const int pageSize = getpagesize();
-    ASSERT_GE(0, pageSize);
+    ASSERT_GE(pageSize, 0);
     std::vector<uint64_t> requestedReservedSizes{1, 10, 333, static_cast<uint64_t>(pageSize) / 2,
                                                  static_cast<uint64_t>(pageSize)};
 
@@ -2106,7 +2111,7 @@
     auto info = mDummyDescriptorInfo;
 
     const int pageSize = getpagesize();
-    ASSERT_GE(0, pageSize);
+    ASSERT_GE(pageSize, 0);
     std::vector<uint64_t> requestedReservedSizes{static_cast<uint64_t>(pageSize) * 2,
                                                  static_cast<uint64_t>(pageSize) * 10,
                                                  static_cast<uint64_t>(pageSize) * 1000};
@@ -2144,7 +2149,7 @@
     auto info = mDummyDescriptorInfo;
 
     const int pageSize = getpagesize();
-    ASSERT_GE(0, pageSize);
+    ASSERT_GE(pageSize, 0);
     info.reservedSize = pageSize;
 
     ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
diff --git a/health/2.0/default/HealthImplDefault.cpp b/health/2.0/default/HealthImplDefault.cpp
index e3cbefd..08fee9e 100644
--- a/health/2.0/default/HealthImplDefault.cpp
+++ b/health/2.0/default/HealthImplDefault.cpp
@@ -21,18 +21,6 @@
 using android::hardware::health::V2_0::implementation::Health;
 
 static struct healthd_config gHealthdConfig = {
-    .batteryStatusPath = android::String8(android::String8::kEmptyString),
-    .batteryHealthPath = android::String8(android::String8::kEmptyString),
-    .batteryPresentPath = android::String8(android::String8::kEmptyString),
-    .batteryCapacityPath = android::String8(android::String8::kEmptyString),
-    .batteryVoltagePath = android::String8(android::String8::kEmptyString),
-    .batteryTemperaturePath = android::String8(android::String8::kEmptyString),
-    .batteryTechnologyPath = android::String8(android::String8::kEmptyString),
-    .batteryCurrentNowPath = android::String8(android::String8::kEmptyString),
-    .batteryCurrentAvgPath = android::String8(android::String8::kEmptyString),
-    .batteryChargeCounterPath = android::String8(android::String8::kEmptyString),
-    .batteryFullChargePath = android::String8(android::String8::kEmptyString),
-    .batteryCycleCountPath = android::String8(android::String8::kEmptyString),
     .energyCounter = nullptr,
     .boot_min_cap = 0,
     .screen_on = nullptr};
diff --git a/health/utils/libhealthloop/utils.cpp b/health/utils/libhealthloop/utils.cpp
index 053fd19..cd8c7a9 100644
--- a/health/utils/libhealthloop/utils.cpp
+++ b/health/utils/libhealthloop/utils.cpp
@@ -28,21 +28,6 @@
     *healthd_config = {
             .periodic_chores_interval_fast = DEFAULT_PERIODIC_CHORES_INTERVAL_FAST,
             .periodic_chores_interval_slow = DEFAULT_PERIODIC_CHORES_INTERVAL_SLOW,
-            .batteryStatusPath = String8(String8::kEmptyString),
-            .batteryHealthPath = String8(String8::kEmptyString),
-            .batteryPresentPath = String8(String8::kEmptyString),
-            .batteryCapacityPath = String8(String8::kEmptyString),
-            .batteryVoltagePath = String8(String8::kEmptyString),
-            .batteryTemperaturePath = String8(String8::kEmptyString),
-            .batteryTechnologyPath = String8(String8::kEmptyString),
-            .batteryCurrentNowPath = String8(String8::kEmptyString),
-            .batteryCurrentAvgPath = String8(String8::kEmptyString),
-            .batteryChargeCounterPath = String8(String8::kEmptyString),
-            .batteryFullChargePath = String8(String8::kEmptyString),
-            .batteryCycleCountPath = String8(String8::kEmptyString),
-            .batteryCapacityLevelPath = String8(String8::kEmptyString),
-            .batteryChargeTimeToFullNowPath = String8(String8::kEmptyString),
-            .batteryFullChargeDesignCapacityUahPath = String8(String8::kEmptyString),
             .energyCounter = NULL,
             .boot_min_cap = 0,
             .screen_on = NULL,
diff --git a/radio/1.5/IRadio.hal b/radio/1.5/IRadio.hal
index 0b50436..956f9bd 100644
--- a/radio/1.5/IRadio.hal
+++ b/radio/1.5/IRadio.hal
@@ -238,7 +238,8 @@
      * 1) Emergency call is completed; or
      * 2) Another setRadioPower_1_5 is issued with forEmergencyCall being false or
      * preferredForEmergencyCall being false; or
-     * 3) Timeout after a long period of time.
+     * 3) Timeout after 30 seconds if dial or emergencyDial is not called.
+     * Once one of these conditions is reached, the modem should move into normal operation.
      *
      * @param serial Serial number of request.
      * @param powerOn To turn on radio -> on = true, to turn off radio -> on = false.
@@ -324,11 +325,15 @@
     oneway sendCdmaSmsExpectMore(int32_t serial, CdmaSmsMessage sms);
 
     /**
-     * Requests that deactivates one category of the device personalization.
+     * Request that deactivates one category of device personalization. Device personalization
+     * generally binds the device so it can only be used on one carrier or even one carrier subnet
+     * (See TS 22.022). When the user has gained the rights to unbind the device (at the end of a
+     * contract period or other event), the controlKey will be delivered to either the user for
+     * manual entry or to a carrier app on the device for automatic entry.
      *
      * @param serial Serial number of request.
      * @param persoType SIM personalization type.
-     * @param controlKey depersonalization code corresponding to persoType
+     * @param controlKey the unlock code for removing persoType personalization from this device
      *
      * Response function is IRadioResponse.supplySimDepersonalizationResponse()
      */
diff --git a/radio/1.5/vts/functional/Android.bp b/radio/1.5/vts/functional/Android.bp
index 85c4f99..cd30f7d 100644
--- a/radio/1.5/vts/functional/Android.bp
+++ b/radio/1.5/vts/functional/Android.bp
@@ -36,5 +36,5 @@
         "android.hardware.radio.config@1.1",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests"]
+    test_suites: ["general-tests", "vts-core"]
 }
diff --git a/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp b/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
index 5f11d19..31466c5 100644
--- a/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
+++ b/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
@@ -16,11 +16,7 @@
 
 #include <radio_hidl_hal_utils_v1_5.h>
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    RadioHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_5,
+                         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+                                 android::hardware::radio::V1_5::IRadio::descriptor)),
+                         android::hardware::PrintInstanceNameToString);
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 435bd23..003f58e 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -21,7 +21,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() with invalid hysteresisDb
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_invalidHysteresisDb) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_invalidHysteresisDb) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -46,7 +46,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() with empty thresholds
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_EmptyThresholds) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_EmptyThresholds) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -70,7 +70,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for GERAN
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Geran) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Geran) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -95,7 +95,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for UTRAN
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Utran) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Utran) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -120,7 +120,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for EUTRAN
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Eutran_RSRP) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Eutran_RSRP) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -145,7 +145,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for EUTRAN
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Eutran_RSRQ) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Eutran_RSRQ) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -170,7 +170,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for EUTRAN
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Eutran_RSSNR) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Eutran_RSSNR) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -191,7 +191,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for CDMA2000
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Cdma2000) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Cdma2000) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -216,7 +216,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for NGRAN_SSRSRP
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_NGRAN_SSRSRP) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_NGRAN_SSRSRP) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -241,7 +241,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for NGRAN_SSRSRQ
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_NGRAN_SSRSRQ) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_NGRAN_SSRSRQ) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -266,7 +266,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for EUTRAN
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Disable_RSSNR) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_Disable_RSSNR) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -287,7 +287,7 @@
 /*
  * Test IRadio.setSignalStrengthReportingCriteria_1_5() for NGRAN_SSSINR
  */
-TEST_F(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_NGRAN_SSSINR) {
+TEST_P(RadioHidlTest_v1_5, setSignalStrengthReportingCriteria_1_5_NGRAN_SSSINR) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::SignalThresholdInfo signalThresholdInfo;
@@ -312,7 +312,7 @@
 /*
  * Test IRadio.setLinkCapacityReportingCriteria_1_5() invalid hysteresisDlKbps
  */
-TEST_F(RadioHidlTest_v1_5, setLinkCapacityReportingCriteria_1_5_invalidHysteresisDlKbps) {
+TEST_P(RadioHidlTest_v1_5, setLinkCapacityReportingCriteria_1_5_invalidHysteresisDlKbps) {
     serial = GetRandomSerialNumber();
 
     Return<void> res = radio_v1_5->setLinkCapacityReportingCriteria_1_5(
@@ -337,7 +337,7 @@
 /*
  * Test IRadio.setLinkCapacityReportingCriteria_1_5() invalid hysteresisUlKbps
  */
-TEST_F(RadioHidlTest_v1_5, setLinkCapacityReportingCriteria_1_5_invalidHysteresisUlKbps) {
+TEST_P(RadioHidlTest_v1_5, setLinkCapacityReportingCriteria_1_5_invalidHysteresisUlKbps) {
     serial = GetRandomSerialNumber();
 
     Return<void> res = radio_v1_5->setLinkCapacityReportingCriteria_1_5(
@@ -362,7 +362,7 @@
 /*
  * Test IRadio.setLinkCapacityReportingCriteria_1_5() empty params
  */
-TEST_F(RadioHidlTest_v1_5, setLinkCapacityReportingCriteria_1_5_emptyParams) {
+TEST_P(RadioHidlTest_v1_5, setLinkCapacityReportingCriteria_1_5_emptyParams) {
     serial = GetRandomSerialNumber();
 
     Return<void> res = radio_v1_5->setLinkCapacityReportingCriteria_1_5(
@@ -383,7 +383,7 @@
 /*
  * Test IRadio.setLinkCapacityReportingCriteria_1_5() for GERAN
  */
-TEST_F(RadioHidlTest_v1_5, setLinkCapacityReportingCriteria_1_5_Geran) {
+TEST_P(RadioHidlTest_v1_5, setLinkCapacityReportingCriteria_1_5_Geran) {
     serial = GetRandomSerialNumber();
 
     Return<void> res = radio_v1_5->setLinkCapacityReportingCriteria_1_5(
@@ -406,7 +406,7 @@
  * Test IRadio.enableUiccApplications() for the response returned.
  * For SIM ABSENT case.
  */
-TEST_F(RadioHidlTest_v1_5, togglingUiccApplicationsSimAbsent) {
+TEST_P(RadioHidlTest_v1_5, togglingUiccApplicationsSimAbsent) {
     // This test case only test SIM ABSENT case.
     if (cardStatus.base.base.cardState != CardState::ABSENT) return;
 
@@ -433,7 +433,7 @@
  * Test IRadio.enableUiccApplications() for the response returned.
  * For SIM PRESENT case.
  */
-TEST_F(RadioHidlTest_v1_5, togglingUiccApplicationsSimPresent) {
+TEST_P(RadioHidlTest_v1_5, togglingUiccApplicationsSimPresent) {
     // This test case only test SIM ABSENT case.
     if (cardStatus.base.base.cardState != CardState::PRESENT) return;
 
@@ -479,7 +479,7 @@
 /*
  * Test IRadio.areUiccApplicationsEnabled() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, areUiccApplicationsEnabled) {
+TEST_P(RadioHidlTest_v1_5, areUiccApplicationsEnabled) {
     // Disable Uicc applications.
     serial = GetRandomSerialNumber();
     radio_v1_5->areUiccApplicationsEnabled(serial);
@@ -499,7 +499,7 @@
 /*
  * Test IRadio.setSystemSelectionChannels_1_5() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, setSystemSelectionChannels_1_5) {
+TEST_P(RadioHidlTest_v1_5, setSystemSelectionChannels_1_5) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -537,7 +537,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -578,7 +578,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() with invalid specifier.
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidArgument) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidArgument) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
@@ -605,7 +605,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() with invalid interval (lower boundary).
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval1) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval1) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -644,7 +644,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() with invalid interval (upper boundary).
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval2) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidInterval2) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -683,7 +683,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() with invalid max search time (lower boundary).
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime1) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime1) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -722,7 +722,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() with invalid max search time (upper boundary).
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime2) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidMaxSearchTime2) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -761,7 +761,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() with invalid periodicity (lower boundary).
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity1) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity1) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -800,7 +800,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() with invalid periodicity (upper boundary).
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity2) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan_InvalidPeriodicity2) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -839,7 +839,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() with valid periodicity
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan_GoodRequest1) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan_GoodRequest1) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -878,7 +878,7 @@
 /*
  * Test IRadio.startNetworkScan_1_5() with valid periodicity and plmns
  */
-TEST_F(RadioHidlTest_v1_5, startNetworkScan_GoodRequest2) {
+TEST_P(RadioHidlTest_v1_5, startNetworkScan_GoodRequest2) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::RadioAccessSpecifier::Bands rasBands;
@@ -918,7 +918,7 @@
 /*
  * Test IRadio.setupDataCall_1_5() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, setupDataCall_1_5) {
+TEST_P(RadioHidlTest_v1_5, setupDataCall_1_5) {
     serial = GetRandomSerialNumber();
 
     ::android::hardware::radio::V1_5::AccessNetwork accessNetwork =
@@ -975,7 +975,7 @@
 /*
  * Test IRadio.setInitialAttachApn_1_5() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, setInitialAttachApn_1_5) {
+TEST_P(RadioHidlTest_v1_5, setInitialAttachApn_1_5) {
     serial = GetRandomSerialNumber();
 
     // Create a dataProfileInfo
@@ -1018,7 +1018,7 @@
 /*
  * Test IRadio.setDataProfile_1_5() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, setDataProfile_1_5) {
+TEST_P(RadioHidlTest_v1_5, setDataProfile_1_5) {
     serial = GetRandomSerialNumber();
 
     // Create a dataProfileInfo
@@ -1065,7 +1065,7 @@
 /*
  * Test IRadio.setRadioPower_1_5() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, setRadioPower_1_5_emergencyCall_cancelled) {
+TEST_P(RadioHidlTest_v1_5, setRadioPower_1_5_emergencyCall_cancelled) {
     // Set radio power to off.
     serial = GetRandomSerialNumber();
     radio_v1_5->setRadioPower_1_5(serial, false, false, false);
@@ -1096,7 +1096,7 @@
 /*
  * Test IRadio.setNetworkSelectionModeManual_1_5() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, setNetworkSelectionModeManual_1_5) {
+TEST_P(RadioHidlTest_v1_5, setNetworkSelectionModeManual_1_5) {
     serial = GetRandomSerialNumber();
 
     // can't camp on nonexistent MCCMNC, so we expect this to fail.
@@ -1122,7 +1122,7 @@
 /*
  * Test IRadio.sendCdmaSmsExpectMore() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, sendCdmaSmsExpectMore) {
+TEST_P(RadioHidlTest_v1_5, sendCdmaSmsExpectMore) {
     serial = GetRandomSerialNumber();
 
     // Create a CdmaSmsAddress
@@ -1166,7 +1166,7 @@
 /*
  * Test IRadio.getBarringInfo() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_5, getBarringInfo) {
+TEST_P(RadioHidlTest_v1_5, getBarringInfo) {
     serial = GetRandomSerialNumber();
 
     Return<void> res = radio_v1_5->getBarringInfo(serial);
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_test.cpp b/radio/1.5/vts/functional/radio_hidl_hal_test.cpp
index a5d236d..ca6bbeb 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_test.cpp
@@ -17,19 +17,7 @@
 #include <radio_hidl_hal_utils_v1_5.h>
 
 void RadioHidlTest_v1_5::SetUp() {
-    radio_v1_5 = ::testing::VtsHalHidlTargetTestBase::getService<
-            ::android::hardware::radio::V1_5::IRadio>(
-            RadioHidlEnvironment::Instance()
-                    ->getServiceName<::android::hardware::radio::V1_5::IRadio>(
-                            hidl_string(RADIO_SERVICE_NAME)));
-    if (radio_v1_5 == NULL) {
-        sleep(60);
-        radio_v1_5 = ::testing::VtsHalHidlTargetTestBase::getService<
-                ::android::hardware::radio::V1_5::IRadio>(
-                RadioHidlEnvironment::Instance()
-                        ->getServiceName<::android::hardware::radio::V1_5::IRadio>(
-                                hidl_string(RADIO_SERVICE_NAME)));
-    }
+    radio_v1_5 = android::hardware::radio::V1_5::IRadio::getService(GetParam());
     ASSERT_NE(nullptr, radio_v1_5.get());
 
     radioRsp_v1_5 = new (std::nothrow) RadioResponse_v1_5(*this);
@@ -48,10 +36,8 @@
     EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
 
     sp<::android::hardware::radio::config::V1_1::IRadioConfig> radioConfig =
-            ::testing::VtsHalHidlTargetTestBase::getService<
-                    ::android::hardware::radio::config::V1_1::IRadioConfig>();
-
-    /* Enforce Vts tesing with RadioConfig is existed. */
+            ::android::hardware::radio::config::V1_1::IRadioConfig::getService();
+    /* Enforce Vts testing with RadioConfig is existed. */
     ASSERT_NE(nullptr, radioConfig.get());
 
     /* Enforce Vts Testing with Sim Status Present only. */
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
index a7c1cdc..6488609 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
+++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
@@ -14,10 +14,14 @@
  * limitations under the License.
  */
 
+#pragma once
+
 #include <android-base/logging.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <utils/Log.h>
 #include <chrono>
 #include <condition_variable>
 #include <mutex>
@@ -799,24 +803,8 @@
             /*barringInfos*/);
 };
 
-// Test environment for Radio HIDL HAL.
-class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-  public:
-    // get the test environment singleton
-    static RadioHidlEnvironment* Instance() {
-        static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
-        return instance;
-    }
-    virtual void registerTestServices() override {
-        registerTestService<::android::hardware::radio::V1_5::IRadio>();
-    }
-
-  private:
-    RadioHidlEnvironment() {}
-};
-
 // The main test class for Radio HIDL.
-class RadioHidlTest_v1_5 : public ::testing::VtsHalHidlTargetTestBase {
+class RadioHidlTest_v1_5 : public ::testing::TestWithParam<std::string> {
   protected:
     std::mutex mtx_;
     std::condition_variable cv_;
diff --git a/tv/tuner/1.0/default/Frontend.cpp b/tv/tuner/1.0/default/Frontend.cpp
index dd2f8a6..7e206a7 100644
--- a/tv/tuner/1.0/default/Frontend.cpp
+++ b/tv/tuner/1.0/default/Frontend.cpp
@@ -81,6 +81,10 @@
 Return<Result> Frontend::scan(const FrontendSettings& /* settings */, FrontendScanType /* type */) {
     ALOGV("%s", __FUNCTION__);
 
+    FrontendScanMessage msg;
+    msg.isLocked(true);
+    mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
+
     return Result::SUCCESS;
 }
 
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 820c58c..f693e7c 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -44,6 +44,8 @@
 #include <iostream>
 #include <map>
 
+#include "VtsHalTvTunerV1_0TestConfigurations.h"
+
 #define WAIT_TIMEOUT 3000000000
 #define WAIT_TIMEOUT_data_ready 3000000000 * 4
 
@@ -84,9 +86,11 @@
 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;
@@ -103,6 +107,8 @@
 using android::hardware::tv::tuner::V1_0::RecordStatus;
 using android::hardware::tv::tuner::V1_0::Result;
 
+using ::testing::AssertionResult;
+
 namespace {
 
 using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
@@ -150,11 +156,7 @@
 // const uint16_t FMQ_SIZE_4K = 0x1000;
 const uint32_t FMQ_SIZE_1M = 0x100000;
 const uint32_t FMQ_SIZE_16M = 0x1000000;
-
-struct FilterConf {
-    DemuxFilterType type;
-    DemuxFilterSettings setting;
-};
+const uint8_t FRONTEND_EVENT_CALLBACK_WAIT_COUNT = 4;
 
 enum FilterEventType : uint8_t {
     UNDEFINED,
@@ -172,6 +174,7 @@
     PlaybackSettings setting;
 };
 
+/******************************** Start FrontendCallback **********************************/
 class FrontendCallback : public IFrontendCallback {
   public:
     virtual Return<void> onEvent(FrontendEventType frontendEventType) override {
@@ -182,28 +185,38 @@
         return Void();
     }
 
-    virtual Return<void> onScanMessage(FrontendScanMessageType /* type */,
-                                       const FrontendScanMessage& /* message */) override {
+    virtual Return<void> onScanMessage(FrontendScanMessageType type,
+                                       const FrontendScanMessage& message) override {
         android::Mutex::Autolock autoLock(mMsgLock);
+        ALOGD("[vts] scan message. Type: %d", mScanMessageType);
         mScanMessageReceived = true;
+        mScanMessageType = type;
+        mScanLockMessageReceived =
+                mScanLockMessageReceived | (type == FrontendScanMessageType::LOCKED);
+        mScanMessage = message;
         mMsgCondition.signal();
         return Void();
     };
 
-    void testOnEvent(sp<IFrontend>& frontend, FrontendSettings settings);
-    void testOnDiseqcMessage(sp<IFrontend>& frontend, FrontendSettings settings);
+    void tuneTestOnEventReceive(sp<IFrontend>& frontend, FrontendSettings settings);
+    void tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings);
+    void scanTestOnMessageLock(sp<IFrontend>& frontend, FrontendSettings settings,
+                               FrontendScanType type);
 
   private:
     bool mEventReceived = false;
-    bool mDiseqcMessageReceived = false;
     bool mScanMessageReceived = false;
+    bool mScanLockMessageReceived = false;
     FrontendEventType mEventType;
+    FrontendScanMessageType mScanMessageType;
+    FrontendScanMessage mScanMessage;
     hidl_vec<uint8_t> mEventMessage;
     android::Mutex mMsgLock;
     android::Condition mMsgCondition;
+    uint8_t mOnEvenRetry = 0;
 };
 
-void FrontendCallback::testOnEvent(sp<IFrontend>& frontend, FrontendSettings settings) {
+void FrontendCallback::tuneTestOnEventReceive(sp<IFrontend>& frontend, FrontendSettings settings) {
     Result result = frontend->tune(settings);
 
     EXPECT_TRUE(result == Result::SUCCESS);
@@ -215,29 +228,77 @@
             return;
         }
     }
+    mEventReceived = false;
 }
 
-void FrontendCallback::testOnDiseqcMessage(sp<IFrontend>& frontend, FrontendSettings settings) {
+void FrontendCallback::tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings) {
     Result result = frontend->tune(settings);
 
     EXPECT_TRUE(result == Result::SUCCESS);
 
     android::Mutex::Autolock autoLock(mMsgLock);
-    while (!mDiseqcMessageReceived) {
+wait:
+    while (!mEventReceived) {
         if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
-            EXPECT_TRUE(false) << "diseqc message not received within timeout";
+            EXPECT_TRUE(false) << "event not received within timeout";
             return;
         }
     }
+    if (mEventType != FrontendEventType::LOCKED) {
+        ALOGD("[vts] frontend callback event received. Type: %d", mEventType);
+        mEventReceived = false;
+        if (mOnEvenRetry++ < FRONTEND_EVENT_CALLBACK_WAIT_COUNT) {
+            goto wait;
+        }
+    }
+    EXPECT_TRUE(mEventType == FrontendEventType::LOCKED) << "LOCK event not received";
+    mEventReceived = false;
+    mOnEvenRetry = 0;
 }
 
+void FrontendCallback::scanTestOnMessageLock(sp<IFrontend>& frontend, FrontendSettings settings,
+                                             FrontendScanType type) {
+    Result result = frontend->scan(settings, type);
+    EXPECT_TRUE(result == Result::SUCCESS);
+    android::Mutex::Autolock autoLock(mMsgLock);
+    int messagesCount = 0;
+
+wait:
+    int count = 0;
+    while (!mScanMessageReceived) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            ALOGD("[vts] waiting for scan message callback...");
+            if (count++ > 10) {
+                EXPECT_TRUE(false) << "WAITING TOO LONG!!";
+                return;
+            }
+        }
+    }
+
+    if (mScanMessageType != FrontendScanMessageType::END) {
+        ALOGD("[vts] frontend scan message received. Type: %d", mScanMessageType);
+        mScanMessageReceived = false;
+        if (messagesCount++ > 3) {
+            EXPECT_TRUE(false) << "WAITING ON TOO MANY MSGS!!";
+            return;
+        }
+        goto wait;
+    }
+
+    EXPECT_TRUE(mScanLockMessageReceived) << "scan lock message not received before scan ended";
+    mScanMessageReceived = false;
+    mScanLockMessageReceived = false;
+}
+/******************************** 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
-        mFilterIdToEvent = filterEvent;
+        mFilterEvent = filterEvent;
         readFilterEventData();
         mPidFilterOutputCount++;
         // mFilterIdToMQ.erase(filterEvent.filterId);
@@ -276,9 +337,9 @@
 
     uint32_t mFilterId;
     FilterEventType mFilterEventType;
-    std::unique_ptr<FilterMQ> mFilterIdToMQ;
-    EventFlag* mFilterIdToMQEventFlag;
-    DemuxFilterEvent mFilterIdToEvent;
+    std::unique_ptr<FilterMQ> mFilterMQ;
+    EventFlag* mFilterMQEventFlag;
+    DemuxFilterEvent mFilterEvent;
 
     android::Mutex mMsgLock;
     android::Mutex mFilterOutputLock;
@@ -313,10 +374,10 @@
 }
 
 void FilterCallback::updateFilterMQ(MQDesc& filterMQDescriptor) {
-    mFilterIdToMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
-    EXPECT_TRUE(mFilterIdToMQ);
-    EXPECT_TRUE(EventFlag::createEventFlag(mFilterIdToMQ->getEventFlagWord(),
-                                           &mFilterIdToMQEventFlag) == android::OK);
+    mFilterMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
+    EXPECT_TRUE(mFilterMQ);
+    EXPECT_TRUE(EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag) ==
+                android::OK);
 }
 
 void FilterCallback::updateGoldenOutputMap(string goldenOutputFile) {
@@ -332,7 +393,7 @@
 
 void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) {
     android::Mutex::Autolock autoLock(mFilterOutputLock);
-    // Read from mFilterIdToMQ[event.filterId] per event and filter type
+    // Read from mFilterMQ[event.filterId] per event and filter type
 
     // Assemble to filterOutput[filterId]
 
@@ -345,7 +406,7 @@
 
 bool FilterCallback::readFilterEventData() {
     bool result = false;
-    DemuxFilterEvent filterEvent = mFilterIdToEvent;
+    DemuxFilterEvent filterEvent = mFilterEvent;
     ALOGW("[vts] reading from filter FMQ %d", mFilterId);
     // todo separate filter handlers
     for (int i = 0; i < filterEvent.events.size(); i++) {
@@ -357,6 +418,7 @@
                 mDataLength = filterEvent.events[i].pes().dataLength;
                 break;
             case FilterEventType::MEDIA:
+                mDataLength = filterEvent.events[i].media().dataLength;
                 break;
             case FilterEventType::RECORD:
                 break;
@@ -371,17 +433,19 @@
         // match";
 
         mDataOutputBuffer.resize(mDataLength);
-        result = mFilterIdToMQ->read(mDataOutputBuffer.data(), mDataLength);
+        result = mFilterMQ->read(mDataOutputBuffer.data(), mDataLength);
         EXPECT_TRUE(result) << "can't read from Filter MQ";
 
         /*for (int i = 0; i < mDataLength; i++) {
             EXPECT_TRUE(goldenDataOutputBuffer[i] == mDataOutputBuffer[i]) << "data does not match";
         }*/
     }
-    mFilterIdToMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
+    mFilterMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
     return result;
 }
+/******************************** End FilterCallback **********************************/
 
+/******************************** Start DvrCallback **********************************/
 class DvrCallback : public IDvrCallback {
   public:
     virtual Return<void> onRecordStatus(DemuxFilterStatus status) override {
@@ -445,11 +509,10 @@
     uint16_t mDataLength = 0;
     std::vector<uint8_t> mDataOutputBuffer;
 
-    std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterIdToMQ;
+    std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterMQ;
     std::unique_ptr<FilterMQ> mPlaybackMQ;
     std::unique_ptr<FilterMQ> mRecordMQ;
-    std::map<uint32_t, EventFlag*> mFilterIdToMQEventFlag;
-    std::map<uint32_t, DemuxFilterEvent> mFilterIdToEvent;
+    std::map<uint32_t, EventFlag*> mFilterMQEventFlag;
 
     android::Mutex mMsgLock;
     android::Mutex mPlaybackThreadLock;
@@ -635,22 +698,32 @@
     mRecordThreadRunning = false;
     android::Mutex::Autolock autoLock(mRecordThreadLock);
 }
+/********************************** 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;
@@ -661,274 +734,165 @@
     sp<FilterCallback> mFilterCallback;
     sp<DvrCallback> mDvrCallback;
     MQDesc mFilterMQDescriptor;
-    MQDesc mPlaybackMQDescriptor;
+    MQDesc mDvrMQDescriptor;
     MQDesc mRecordMQDescriptor;
     vector<uint32_t> mUsedFilterIds;
+    hidl_vec<FrontendId> mFeIds;
 
     uint32_t mDemuxId;
-    uint32_t mFilterId;
+    uint32_t mFilterId = -1;
 
     pthread_t mPlaybackshread;
     bool mPlaybackThreadRunning;
 
-    ::testing::AssertionResult createFrontend(int32_t frontendId);
-    ::testing::AssertionResult tuneFrontend(int32_t frontendId);
-    ::testing::AssertionResult stopTuneFrontend(int32_t frontendId);
-    ::testing::AssertionResult closeFrontend(int32_t frontendId);
-    ::testing::AssertionResult createDemux();
-    ::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId,
-                                                       FrontendSettings settings);
-    ::testing::AssertionResult getPlaybackMQDescriptor();
-    ::testing::AssertionResult addPlaybackToDemux(PlaybackSettings setting);
-    ::testing::AssertionResult getRecordMQDescriptor();
-    ::testing::AssertionResult addRecordToDemux(RecordSettings setting);
-    ::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting);
-    ::testing::AssertionResult getFilterMQDescriptor();
-    ::testing::AssertionResult closeDemux();
-    ::testing::AssertionResult createDescrambler();
-    ::testing::AssertionResult closeDescrambler();
+    AssertionResult getFrontendIds();
+    AssertionResult getFrontendInfo(uint32_t frontendId);
+    AssertionResult openFrontend(uint32_t frontendId);
+    AssertionResult setFrontendCallback();
+    AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
+    AssertionResult stopScanFrontend();
+    AssertionResult tuneFrontend(FrontendConfig config);
+    AssertionResult stopTuneFrontend();
+    AssertionResult closeFrontend();
 
-    ::testing::AssertionResult playbackDataFlowTest(vector<FilterConf> filterConf,
-                                                    PlaybackConf playbackConf,
-                                                    vector<string> goldenOutputFiles);
-    ::testing::AssertionResult recordDataFlowTest(vector<FilterConf> filterConf,
-                                                  RecordSettings recordSetting,
-                                                  vector<string> goldenOutputFiles);
-    ::testing::AssertionResult broadcastDataFlowTest(vector<FilterConf> filterConf,
-                                                     vector<string> goldenOutputFiles);
+    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);
+
+    FilterEventType getFilterEventType(DemuxFilterType type);
 };
 
-::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) {
+/*========================== 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::openFrontend(uint32_t frontendId) {
+    Result status;
     mService->openFrontendById(frontendId, [&](Result result, const sp<IFrontend>& frontend) {
         mFrontend = frontend;
         status = result;
     });
-    if (status != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
+    return AssertionResult(status == Result::SUCCESS);
+}
 
+AssertionResult TunerHidlTest::setFrontendCallback() {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontend first.";
     mFrontendCallback = new FrontendCallback();
     auto callbackStatus = mFrontend->setCallback(mFrontendCallback);
-
-    return ::testing::AssertionResult(callbackStatus.isOk());
+    return AssertionResult(callbackStatus.isOk());
 }
 
-::testing::AssertionResult TunerHidlTest::tuneFrontend(int32_t frontendId) {
-    if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
+AssertionResult TunerHidlTest::scanFrontend(FrontendConfig config, FrontendScanType type) {
+    EXPECT_TRUE(mFrontendCallback)
+            << "test with openFrontend/setFrontendCallback/getFrontendInfo first.";
 
-    // Frontend Settings for testing
-    FrontendSettings frontendSettings;
-    FrontendAtscSettings frontendAtscSettings{
-            .frequency = 0,
-            .modulation = FrontendAtscModulation::UNDEFINED,
-    };
-    frontendSettings.atsc(frontendAtscSettings);
-    mFrontendCallback->testOnEvent(mFrontend, frontendSettings);
+    EXPECT_TRUE(mFrontendInfo.type == config.type)
+            << "FrontendConfig does not match the frontend info of the given id.";
 
-    FrontendDvbtSettings frontendDvbtSettings{
-            .frequency = 0,
-    };
-    frontendSettings.dvbt(frontendDvbtSettings);
-    mFrontendCallback->testOnEvent(mFrontend, frontendSettings);
-
-    return ::testing::AssertionResult(true);
+    mFrontendCallback->scanTestOnMessageLock(mFrontend, config.settings, type);
+    return AssertionResult(true);
 }
 
-::testing::AssertionResult TunerHidlTest::stopTuneFrontend(int32_t frontendId) {
+AssertionResult TunerHidlTest::stopScanFrontend() {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontend first.";
     Result status;
-    if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
+    status = mFrontend->stopScan();
+    return AssertionResult(status == Result::SUCCESS);
+}
 
+AssertionResult TunerHidlTest::tuneFrontend(FrontendConfig config) {
+    EXPECT_TRUE(mFrontendCallback)
+            << "test with openFrontend/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 openFrontend first.";
+    Result status;
     status = mFrontend->stopTune();
-    return ::testing::AssertionResult(status == Result::SUCCESS);
+    return AssertionResult(status == Result::SUCCESS);
 }
 
-::testing::AssertionResult TunerHidlTest::closeFrontend(int32_t frontendId) {
+AssertionResult TunerHidlTest::closeFrontend() {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontend first.";
     Result status;
-    if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
     status = mFrontend->close();
     mFrontend = nullptr;
-    return ::testing::AssertionResult(status == Result::SUCCESS);
+    mFrontendCallback = nullptr;
+    return AssertionResult(status == Result::SUCCESS);
 }
+/*=========================== End Frontend APIs Tests Implementation ===========================*/
 
-::testing::AssertionResult TunerHidlTest::createDemux() {
+/*============================ Start Demux APIs Tests Implementation ============================*/
+AssertionResult TunerHidlTest::openDemux() {
     Result status;
-
     mService->openDemux([&](Result result, uint32_t demuxId, const sp<IDemux>& demux) {
         mDemux = demux;
         mDemuxId = demuxId;
         status = result;
     });
-    return ::testing::AssertionResult(status == Result::SUCCESS);
+    return AssertionResult(status == Result::SUCCESS);
 }
 
-::testing::AssertionResult TunerHidlTest::createDemuxWithFrontend(int32_t frontendId,
-                                                                  FrontendSettings settings) {
-    Result status;
-
-    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    if (!mFrontend && createFrontend(frontendId) == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    mFrontendCallback->testOnEvent(mFrontend, settings);
-
-    status = mDemux->setFrontendDataSource(frontendId);
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
+AssertionResult TunerHidlTest::setDemuxFrontendDataSource(uint32_t frontendId) {
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mFrontend) << "Test with openFrontend first.";
+    auto status = mDemux->setFrontendDataSource(frontendId);
+    return AssertionResult(status.isOk());
 }
 
-::testing::AssertionResult TunerHidlTest::closeDemux() {
-    Result status;
-    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    status = mDemux->close();
+AssertionResult TunerHidlTest::closeDemux() {
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    auto status = mDemux->close();
     mDemux = nullptr;
-    return ::testing::AssertionResult(status == Result::SUCCESS);
+    return AssertionResult(status.isOk());
 }
 
-::testing::AssertionResult TunerHidlTest::createDescrambler() {
+AssertionResult TunerHidlTest::openFilterInDemux(DemuxFilterType type) {
     Result status;
-
-    mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) {
-        mDescrambler = descrambler;
-        status = result;
-    });
-    if (status != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
-
-    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    status = mDescrambler->setDemuxSource(mDemuxId);
-    if (status != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
-
-    // Test if demux source can be set more than once.
-    status = mDescrambler->setDemuxSource(mDemuxId);
-    return ::testing::AssertionResult(status == Result::INVALID_STATE);
-}
-
-::testing::AssertionResult TunerHidlTest::closeDescrambler() {
-    Result status;
-    if (!mDescrambler && createDescrambler() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    status = mDescrambler->close();
-    mDescrambler = nullptr;
-    return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::addPlaybackToDemux(PlaybackSettings setting) {
-    Result status;
-
-    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    // Create dvr callback
-    mDvrCallback = new DvrCallback();
-
-    // Add playback input to the local demux
-    mDemux->openDvr(DvrType::PLAYBACK, FMQ_SIZE_1M, mDvrCallback,
-                    [&](Result result, const sp<IDvr>& dvr) {
-                        mDvr = dvr;
-                        status = result;
-                    });
-
-    if (status != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
-
-    DvrSettings dvrSetting;
-    dvrSetting.playback(setting);
-    status = mDvr->configure(dvrSetting);
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::getPlaybackMQDescriptor() {
-    Result status;
-
-    if ((!mDemux && createDemux() == ::testing::AssertionFailure()) || !mDvr) {
-        return ::testing::AssertionFailure();
-    }
-
-    mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
-        mPlaybackMQDescriptor = dvrMQDesc;
-        status = result;
-    });
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::addRecordToDemux(RecordSettings setting) {
-    Result status;
-
-    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-
-    // Create dvr callback
-    mDvrCallback = new DvrCallback();
-
-    // Add playback input to the local demux
-    mDemux->openDvr(DvrType::RECORD, FMQ_SIZE_1M, mDvrCallback,
-                    [&](Result result, const sp<IDvr>& dvr) {
-                        mDvr = dvr;
-                        status = result;
-                    });
-
-    if (status != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
-
-    DvrSettings dvrSetting;
-    dvrSetting.record(setting);
-    status = mDvr->configure(dvrSetting);
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::getRecordMQDescriptor() {
-    Result status;
-
-    if ((!mDemux && createDemux() == ::testing::AssertionFailure()) || !mDvr) {
-        return ::testing::AssertionFailure();
-    }
-
-    mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
-        mRecordMQDescriptor = dvrMQDesc;
-        status = result;
-    });
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::addFilterToDemux(DemuxFilterType type,
-                                                           DemuxFilterSettings setting) {
-    Result status;
-
-    if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
 
     // Create demux callback
     mFilterCallback = new FilterCallback();
@@ -940,21 +904,322 @@
                            status = result;
                        });
 
-    if (status != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
+    if (status == Result::SUCCESS) {
+        mFilterCallback->setFilterEventType(getFilterEventType(type));
     }
 
+    return AssertionResult(status == Result::SUCCESS);
+}
+/*============================ End Demux APIs Tests Implementation ============================*/
+
+/*=========================== Start Filter APIs Tests Implementation ===========================*/
+AssertionResult TunerHidlTest::getNewlyOpenedFilterId(uint32_t& filterId) {
+    Result status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mFilter) << "Test with openFilterInDemux first.";
+    EXPECT_TRUE(mFilterCallback) << "Test with openFilterInDemux first.";
+
     mFilter->getId([&](Result result, uint32_t filterId) {
         mFilterId = filterId;
         status = result;
     });
 
-    if (status != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
+    if (status == Result::SUCCESS) {
+        mFilterCallback->setFilterId(mFilterId);
+        mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId);
+        mFilters[mFilterId] = mFilter;
+        mFilterCallbacks[mFilterId] = mFilterCallback;
+        filterId = mFilterId;
     }
 
-    mFilterCallback->setFilterId(mFilterId);
+    return AssertionResult(status == Result::SUCCESS || status == Result::UNAVAILABLE);
+}
 
+AssertionResult TunerHidlTest::configFilter(DemuxFilterSettings setting, uint32_t filterId) {
+    Result status;
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    status = mFilters[filterId]->configure(setting);
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::getFilterMQDescriptor(uint32_t filterId) {
+    Result status;
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
+
+    mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) {
+        mFilterMQDescriptor = filterMQDesc;
+        status = result;
+    });
+
+    if (status == Result::SUCCESS) {
+        mFilterCallbacks[filterId]->updateFilterMQ(mFilterMQDescriptor);
+    }
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::startFilter(uint32_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    Result status = mFilters[filterId]->start();
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::stopFilter(uint32_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    Result status = mFilters[filterId]->stop();
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::closeFilter(uint32_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    Result status = mFilters[filterId]->close();
+    if (status == Result::SUCCESS) {
+        for (int i = 0; i < mUsedFilterIds.size(); i++) {
+            if (mUsedFilterIds[i] == filterId) {
+                mUsedFilterIds.erase(mUsedFilterIds.begin() + i);
+                break;
+            }
+        }
+        mFilterCallbacks.erase(filterId);
+        mFilters.erase(filterId);
+    }
+    return AssertionResult(status == Result::SUCCESS);
+}
+/*=========================== End Filter APIs Tests Implementation ===========================*/
+
+/*======================== Start Descrambler APIs Tests Implementation ========================*/
+AssertionResult TunerHidlTest::createDescrambler() {
+    Result status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) {
+        mDescrambler = descrambler;
+        status = result;
+    });
+    if (status != Result::SUCCESS) {
+        return failure();
+    }
+
+    status = mDescrambler->setDemuxSource(mDemuxId);
+    if (status != Result::SUCCESS) {
+        return failure();
+    }
+
+    // Test if demux source can be set more than once.
+    status = mDescrambler->setDemuxSource(mDemuxId);
+    return AssertionResult(status == Result::INVALID_STATE);
+}
+
+AssertionResult TunerHidlTest::closeDescrambler() {
+    Result status;
+    if (!mDescrambler && createDescrambler() == failure()) {
+        return failure();
+    }
+
+    status = mDescrambler->close();
+    mDescrambler = nullptr;
+    return AssertionResult(status == Result::SUCCESS);
+}
+/*========================= End Descrambler APIs Tests Implementation =========================*/
+
+/*============================ Start Dvr APIs Tests Implementation ============================*/
+AssertionResult TunerHidlTest::openDvrInDemux(DvrType type) {
+    Result status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+
+    // Create dvr callback
+    mDvrCallback = new DvrCallback();
+
+    mDemux->openDvr(type, FMQ_SIZE_1M, mDvrCallback, [&](Result result, const sp<IDvr>& dvr) {
+        mDvr = dvr;
+        status = result;
+    });
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::configDvr(DvrSettings setting) {
+    Result status = mDvr->configure(setting);
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult TunerHidlTest::getDvrMQDescriptor() {
+    Result status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvr) << "Test with openDvr first.";
+
+    mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
+        mDvrMQDescriptor = dvrMQDesc;
+        status = result;
+    });
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+/*============================ End Dvr APIs Tests Implementation ============================*/
+
+/*========================== 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.";
+
+    // Data Verify Module
+    std::map<uint32_t, sp<FilterCallback>>::iterator it;
+    for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
+        it->second->testFilterDataOutput();
+    }
+    return success();
+}
+
+/*
+ * TODO: re-enable the tests after finalizing the test refactoring.
+ */
+/*AssertionResult TunerHidlTest::playbackDataFlowTest(
+        vector<FilterConf> filterConf, PlaybackConf playbackConf,
+        vector<string> \/\*goldenOutputFiles\*\/) {
+    Result status;
+    int filterIdsSize;
+    // Filter Configuration Module
+    for (int i = 0; i < filterConf.size(); i++) {
+        if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
+                    failure() ||
+            // TODO use a map to save the FMQs/EvenFlags and pass to callback
+            getFilterMQDescriptor() == failure()) {
+            return failure();
+        }
+        filterIdsSize = mUsedFilterIds.size();
+        mUsedFilterIds.resize(filterIdsSize + 1);
+        mUsedFilterIds[filterIdsSize] = mFilterId;
+        mFilters[mFilterId] = mFilter;
+        mFilterCallbacks[mFilterId] = mFilterCallback;
+        mFilterCallback->updateFilterMQ(mFilterMQDescriptor);
+        // mDemuxCallback->updateGoldenOutputMap(goldenOutputFiles[i]);
+        status = mFilter->start();
+        if (status != Result::SUCCESS) {
+            return failure();
+        }
+    }
+
+    // Playback Input Module
+    PlaybackSettings playbackSetting = playbackConf.setting;
+    if (addPlaybackToDemux(playbackSetting) == failure() ||
+        getPlaybackMQDescriptor() == failure()) {
+        return failure();
+    }
+    for (int i = 0; i <= filterIdsSize; i++) {
+        if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
+            return failure();
+        }
+    }
+    mDvrCallback->startPlaybackInputThread(playbackConf, mPlaybackMQDescriptor);
+    status = mDvr->start();
+    if (status != Result::SUCCESS) {
+        return failure();
+    }
+
+    // Data Verify Module
+    std::map<uint32_t, sp<FilterCallback>>::iterator it;
+    for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
+        it->second->testFilterDataOutput();
+    }
+    mDvrCallback->stopPlaybackThread();
+
+    // Clean Up Module
+    for (int i = 0; i <= filterIdsSize; i++) {
+        if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
+            return failure();
+        }
+    }
+    if (mDvr->stop() != Result::SUCCESS) {
+        return failure();
+    }
+    mUsedFilterIds.clear();
+    mFilterCallbacks.clear();
+    mFilters.clear();
+    return closeDemux();
+}
+
+AssertionResult TunerHidlTest::recordDataFlowTest(vector<FilterConf> filterConf,
+                                                  RecordSettings recordSetting,
+                                                  vector<string> goldenOutputFiles) {
+    Result status;
+    hidl_vec<FrontendId> feIds;
+
+    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
+        status = result;
+        feIds = frontendIds;
+    });
+
+    if (feIds.size() == 0) {
+        ALOGW("[   WARN   ] Frontend isn't available");
+        return failure();
+    }
+
+    FrontendDvbtSettings dvbt{
+            .frequency = 1000,
+    };
+    FrontendSettings settings;
+    settings.dvbt(dvbt);
+
+    int filterIdsSize;
+    // Filter Configuration Module
+    for (int i = 0; i < filterConf.size(); i++) {
+        if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
+                    failure() ||
+            // TODO use a map to save the FMQs/EvenFlags and pass to callback
+            getFilterMQDescriptor() == failure()) {
+            return failure();
+        }
+        filterIdsSize = mUsedFilterIds.size();
+        mUsedFilterIds.resize(filterIdsSize + 1);
+        mUsedFilterIds[filterIdsSize] = mFilterId;
+        mFilters[mFilterId] = mFilter;
+    }
+
+    // Record Config Module
+    if (addRecordToDemux(recordSetting) == failure() ||
+        getRecordMQDescriptor() == failure()) {
+        return failure();
+    }
+    for (int i = 0; i <= filterIdsSize; i++) {
+        if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
+            return failure();
+        }
+    }
+
+    mDvrCallback->startRecordOutputThread(recordSetting, mRecordMQDescriptor);
+    status = mDvr->start();
+    if (status != Result::SUCCESS) {
+        return failure();
+    }
+
+    if (setDemuxFrontendDataSource(feIds[0]) != success()) {
+        return failure();
+    }
+
+    // Data Verify Module
+    mDvrCallback->testRecordOutput();
+
+    // Clean Up Module
+    for (int i = 0; i <= filterIdsSize; i++) {
+        if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
+            return failure();
+        }
+    }
+    if (mFrontend->stopTune() != Result::SUCCESS) {
+        return failure();
+    }
+    mUsedFilterIds.clear();
+    mFilterCallbacks.clear();
+    mFilters.clear();
+    return closeDemux();
+}*/
+/*========================= End Data Flow Tests Implementation =========================*/
+
+/*=============================== Start Helper Functions ===============================*/
+FilterEventType TunerHidlTest::getFilterEventType(DemuxFilterType type) {
     FilterEventType eventType = FilterEventType::UNDEFINED;
     switch (type.mainType) {
         case DemuxFilterMainType::TS:
@@ -998,358 +1263,151 @@
         default:
             break;
     }
-    mFilterCallback->setFilterEventType(eventType);
+    return eventType;
+}
+/*============================== End Helper Functions ==============================*/
+/***************************** End Test Implementation *****************************/
 
-    // Configure the filter
-    status = mFilter->configure(setting);
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
+/******************************** Start Test Entry **********************************/
+/*============================== Start Frontend Tests ==============================*/
+TEST_P(TunerHidlTest, getFrontendIds) {
+    description("Get Frontend ids and verify frontends exist");
+    ASSERT_TRUE(getFrontendIds());
+    ASSERT_TRUE(mFeIds.size() > 0);
 }
 
-::testing::AssertionResult TunerHidlTest::getFilterMQDescriptor() {
-    Result status;
+TEST_P(TunerHidlTest, openFrontend) {
+    description("Open all the existing Frontends and close them");
+    ASSERT_TRUE(getFrontendIds());
+    ASSERT_TRUE(mFeIds.size() > 0);
 
-    if (!mDemux || !mFilter) {
-        return ::testing::AssertionFailure();
-    }
-
-    mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) {
-        mFilterMQDescriptor = filterMQDesc;
-        status = result;
-    });
-
-    return ::testing::AssertionResult(status == Result::SUCCESS);
-}
-
-::testing::AssertionResult TunerHidlTest::playbackDataFlowTest(
-        vector<FilterConf> filterConf, PlaybackConf playbackConf,
-        vector<string> /*goldenOutputFiles*/) {
-    Result status;
-    int filterIdsSize;
-    // Filter Configuration Module
-    for (int i = 0; i < filterConf.size(); i++) {
-        if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
-                    ::testing::AssertionFailure() ||
-            // TODO use a map to save the FMQs/EvenFlags and pass to callback
-            getFilterMQDescriptor() == ::testing::AssertionFailure()) {
-            return ::testing::AssertionFailure();
-        }
-        filterIdsSize = mUsedFilterIds.size();
-        mUsedFilterIds.resize(filterIdsSize + 1);
-        mUsedFilterIds[filterIdsSize] = mFilterId;
-        mFilters[mFilterId] = mFilter;
-        mFilterCallbacks[mFilterId] = mFilterCallback;
-        mFilterCallback->updateFilterMQ(mFilterMQDescriptor);
-        // mDemuxCallback->updateGoldenOutputMap(goldenOutputFiles[i]);
-        status = mFilter->start();
-        if (status != Result::SUCCESS) {
-            return ::testing::AssertionFailure();
-        }
-    }
-
-    // Playback Input Module
-    PlaybackSettings playbackSetting = playbackConf.setting;
-    if (addPlaybackToDemux(playbackSetting) == ::testing::AssertionFailure() ||
-        getPlaybackMQDescriptor() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-    for (int i = 0; i <= filterIdsSize; i++) {
-        if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
-            return ::testing::AssertionFailure();
-        }
-    }
-    mDvrCallback->startPlaybackInputThread(playbackConf, mPlaybackMQDescriptor);
-    status = mDvr->start();
-    if (status != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
-
-    // Data Verify Module
-    std::map<uint32_t, sp<FilterCallback>>::iterator it;
-    for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
-        it->second->testFilterDataOutput();
-    }
-    mDvrCallback->stopPlaybackThread();
-
-    // Clean Up Module
-    for (int i = 0; i <= filterIdsSize; i++) {
-        if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
-            return ::testing::AssertionFailure();
-        }
-    }
-    if (mDvr->stop() != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
-    mUsedFilterIds.clear();
-    mFilterCallbacks.clear();
-    mFilters.clear();
-    return closeDemux();
-}
-
-::testing::AssertionResult TunerHidlTest::broadcastDataFlowTest(
-        vector<FilterConf> filterConf, vector<string> /*goldenOutputFiles*/) {
-    Result status;
-    hidl_vec<FrontendId> feIds;
-
-    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
-        status = result;
-        feIds = frontendIds;
-    });
-
-    if (feIds.size() == 0) {
-        ALOGW("[   WARN   ] Frontend isn't available");
-        return ::testing::AssertionFailure();
-    }
-
-    FrontendDvbtSettings dvbt{
-            .frequency = 1000,
-    };
-    FrontendSettings settings;
-    settings.dvbt(dvbt);
-
-    if (createDemuxWithFrontend(feIds[0], settings) != ::testing::AssertionSuccess()) {
-        return ::testing::AssertionFailure();
-    }
-
-    int filterIdsSize;
-    // Filter Configuration Module
-    for (int i = 0; i < filterConf.size(); i++) {
-        if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
-                    ::testing::AssertionFailure() ||
-            // TODO use a map to save the FMQs/EvenFlags and pass to callback
-            getFilterMQDescriptor() == ::testing::AssertionFailure()) {
-            return ::testing::AssertionFailure();
-        }
-        filterIdsSize = mUsedFilterIds.size();
-        mUsedFilterIds.resize(filterIdsSize + 1);
-        mUsedFilterIds[filterIdsSize] = mFilterId;
-        mFilters[mFilterId] = mFilter;
-        mFilterCallbacks[mFilterId] = mFilterCallback;
-        mFilterCallback->updateFilterMQ(mFilterMQDescriptor);
-        status = mFilter->start();
-        if (status != Result::SUCCESS) {
-            return ::testing::AssertionFailure();
-        }
-    }
-
-    // Data Verify Module
-    std::map<uint32_t, sp<FilterCallback>>::iterator it;
-    for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
-        it->second->testFilterDataOutput();
-    }
-
-    // Clean Up Module
-    for (int i = 0; i <= filterIdsSize; i++) {
-        if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
-            return ::testing::AssertionFailure();
-        }
-    }
-    if (mFrontend->stopTune() != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
-    mUsedFilterIds.clear();
-    mFilterCallbacks.clear();
-    mFilters.clear();
-    return closeDemux();
-}
-
-::testing::AssertionResult TunerHidlTest::recordDataFlowTest(vector<FilterConf> filterConf,
-                                                             RecordSettings recordSetting,
-                                                             vector<string> /*goldenOutputFiles*/) {
-    Result status;
-    hidl_vec<FrontendId> feIds;
-
-    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
-        status = result;
-        feIds = frontendIds;
-    });
-
-    if (feIds.size() == 0) {
-        ALOGW("[   WARN   ] Frontend isn't available");
-        return ::testing::AssertionFailure();
-    }
-
-    FrontendDvbtSettings dvbt{
-            .frequency = 1000,
-    };
-    FrontendSettings settings;
-    settings.dvbt(dvbt);
-
-    int filterIdsSize;
-    // Filter Configuration Module
-    for (int i = 0; i < filterConf.size(); i++) {
-        if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
-                    ::testing::AssertionFailure() ||
-            // TODO use a map to save the FMQs/EvenFlags and pass to callback
-            getFilterMQDescriptor() == ::testing::AssertionFailure()) {
-            return ::testing::AssertionFailure();
-        }
-        filterIdsSize = mUsedFilterIds.size();
-        mUsedFilterIds.resize(filterIdsSize + 1);
-        mUsedFilterIds[filterIdsSize] = mFilterId;
-        mFilters[mFilterId] = mFilter;
-    }
-
-    // Record Config Module
-    if (addRecordToDemux(recordSetting) == ::testing::AssertionFailure() ||
-        getRecordMQDescriptor() == ::testing::AssertionFailure()) {
-        return ::testing::AssertionFailure();
-    }
-    for (int i = 0; i <= filterIdsSize; i++) {
-        if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
-            return ::testing::AssertionFailure();
-        }
-    }
-
-    mDvrCallback->startRecordOutputThread(recordSetting, mRecordMQDescriptor);
-    status = mDvr->start();
-    if (status != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
-
-    if (createDemuxWithFrontend(feIds[0], settings) != ::testing::AssertionSuccess()) {
-        return ::testing::AssertionFailure();
-    }
-
-    // Data Verify Module
-    mDvrCallback->testRecordOutput();
-
-    // Clean Up Module
-    for (int i = 0; i <= filterIdsSize; i++) {
-        if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
-            return ::testing::AssertionFailure();
-        }
-    }
-    if (mFrontend->stopTune() != Result::SUCCESS) {
-        return ::testing::AssertionFailure();
-    }
-    mUsedFilterIds.clear();
-    mFilterCallbacks.clear();
-    mFilters.clear();
-    return closeDemux();
-}
-
-/*
- * API STATUS TESTS
- */
-TEST_P(TunerHidlTest, CreateFrontend) {
-    Result status;
-    hidl_vec<FrontendId> feIds;
-
-    description("Create Frontends");
-    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
-        status = result;
-        feIds = frontendIds;
-    });
-
-    if (feIds.size() == 0) {
-        ALOGW("[   WARN   ] Frontend isn't available");
-        return;
-    }
-
-    for (size_t i = 0; i < feIds.size(); i++) {
-        ASSERT_TRUE(createFrontend(feIds[i]));
+    for (size_t i = 0; i < mFeIds.size(); i++) {
+        ASSERT_TRUE(openFrontend(mFeIds[i]));
+        ASSERT_TRUE(closeFrontend());
     }
 }
 
 TEST_P(TunerHidlTest, TuneFrontend) {
-    Result status;
-    hidl_vec<FrontendId> feIds;
-
-    description("Tune Frontends and check callback onEvent");
-    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
-        status = result;
-        feIds = frontendIds;
-    });
-
-    if (feIds.size() == 0) {
-        ALOGW("[   WARN   ] Frontend isn't available");
-        return;
-    }
-
-    for (size_t i = 0; i < feIds.size(); i++) {
-        ASSERT_TRUE(tuneFrontend(feIds[i]));
+    description("Tune one Frontend with specific setting and check Lock event");
+    ASSERT_TRUE(getFrontendIds());
+    ASSERT_TRUE(mFeIds.size() > 0);
+    ALOGW("[vts] expected Frontend type is %d", frontendArray[0].type);
+    for (size_t i = 0; i < mFeIds.size(); i++) {
+        ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+        ALOGW("[vts] Frontend type is %d", mFrontendInfo.type);
+        if (mFrontendInfo.type != frontendArray[0].type) {
+            continue;
+        }
+        ASSERT_TRUE(openFrontend(mFeIds[i]));
+        ASSERT_TRUE(setFrontendCallback());
+        ASSERT_TRUE(stopTuneFrontend());
+        ASSERT_TRUE(tuneFrontend(frontendArray[0]));
+        ASSERT_TRUE(stopTuneFrontend());
+        ASSERT_TRUE(closeFrontend());
+        break;
     }
 }
 
-TEST_P(TunerHidlTest, StopTuneFrontend) {
-    Result status;
-    hidl_vec<FrontendId> feIds;
+TEST_P(TunerHidlTest, AutoScanFrontend) {
+    description("Run an auto frontend scan with specific setting and check lock scanMessage");
+    ASSERT_TRUE(getFrontendIds());
+    ASSERT_TRUE(mFeIds.size() > 0);
 
-    description("stopTune Frontends");
-    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
-        status = result;
-        feIds = frontendIds;
-    });
-
-    if (feIds.size() == 0) {
-        ALOGW("[   WARN   ] Frontend isn't available");
-        return;
+    for (size_t i = 0; i < mFeIds.size(); i++) {
+        ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+        if (mFrontendInfo.type != frontendArray[0].type) {
+            continue;
+        }
+        ASSERT_TRUE(openFrontend(mFeIds[i]));
+        ASSERT_TRUE(setFrontendCallback());
+        ASSERT_TRUE(stopScanFrontend());
+        ASSERT_TRUE(scanFrontend(frontendScanArray[0], FrontendScanType::SCAN_AUTO));
+        ASSERT_TRUE(stopScanFrontend());
+        ASSERT_TRUE(closeFrontend());
+        break;
     }
+}
+/*=============================== End Frontend Tests ===============================*/
 
-    for (size_t i = 0; i < feIds.size(); i++) {
-        ASSERT_TRUE(stopTuneFrontend(feIds[i]));
+/*============================ Start Demux/Filter Tests ============================*/
+TEST_P(TunerHidlTest, OpenDemuxWithFrontendDataSource) {
+    description("Open Demux with a Frontend as its data source.");
+    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 != frontendArray[0].type) {
+            continue;
+        }
+        ASSERT_TRUE(openFrontend(mFeIds[i]));
+        ASSERT_TRUE(setFrontendCallback());
+        ASSERT_TRUE(openDemux());
+        ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i]));
+        ASSERT_TRUE(closeDemux());
+        ASSERT_TRUE(closeFrontend());
+        break;
     }
 }
 
-TEST_P(TunerHidlTest, CloseFrontend) {
-    Result status;
-    hidl_vec<FrontendId> feIds;
+TEST_P(TunerHidlTest, OpenFilterInDemux) {
+    description("Open a filter in Demux.");
+    ASSERT_TRUE(getFrontendIds());
+    ASSERT_TRUE(mFeIds.size() > 0);
 
-    description("Close Frontends");
-    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
-        status = result;
-        feIds = frontendIds;
-    });
-
-    if (feIds.size() == 0) {
-        ALOGW("[   WARN   ] Frontend isn't available");
-        return;
-    }
-
-    for (size_t i = 0; i < feIds.size(); i++) {
-        ASSERT_TRUE(closeFrontend(feIds[i]));
+    for (size_t i = 0; i < mFeIds.size(); i++) {
+        ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+        if (mFrontendInfo.type != frontendArray[0].type) {
+            continue;
+        }
+        ASSERT_TRUE(openFrontend(mFeIds[i]));
+        ASSERT_TRUE(setFrontendCallback());
+        ASSERT_TRUE(openDemux());
+        ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i]));
+        ASSERT_TRUE(openFilterInDemux(filterArray[0].type));
+        uint32_t filterId;
+        ASSERT_TRUE(getNewlyOpenedFilterId(filterId));
+        ASSERT_TRUE(closeFilter(filterId));
+        ASSERT_TRUE(closeDemux());
+        ASSERT_TRUE(closeFrontend());
+        break;
     }
 }
 
-TEST_P(TunerHidlTest, CreateDemuxWithFrontend) {
-    Result status;
-    hidl_vec<FrontendId> feIds;
+TEST_P(TunerHidlTest, StartFilterInDemux) {
+    description("Open and start a filter in Demux.");
+    ASSERT_TRUE(getFrontendIds());
+    ASSERT_TRUE(mFeIds.size() > 0);
 
-    description("Create Demux with Frontend");
-    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
-        status = result;
-        feIds = frontendIds;
-    });
-
-    if (feIds.size() == 0) {
-        ALOGW("[   WARN   ] Frontend isn't available");
-        return;
-    }
-
-    FrontendDvbtSettings dvbt{
-        .frequency = 1000,
-    };
-    FrontendSettings settings;
-    settings.dvbt(dvbt);
-
-    for (size_t i = 0; i < feIds.size(); i++) {
-        ASSERT_TRUE(createDemuxWithFrontend(feIds[i], settings));
-        mFrontend->stopTune();
+    for (size_t i = 0; i < mFeIds.size(); i++) {
+        ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+        if (mFrontendInfo.type != frontendArray[0].type) {
+            continue;
+        }
+        ASSERT_TRUE(openFrontend(mFeIds[i]));
+        ASSERT_TRUE(setFrontendCallback());
+        ASSERT_TRUE(openDemux());
+        ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i]));
+        ASSERT_TRUE(openFilterInDemux(filterArray[0].type));
+        uint32_t filterId;
+        ASSERT_TRUE(getNewlyOpenedFilterId(filterId));
+        ASSERT_TRUE(configFilter(filterArray[0].setting, filterId));
+        ASSERT_TRUE(getFilterMQDescriptor(filterId));
+        ASSERT_TRUE(startFilter(filterId));
+        ASSERT_TRUE(stopFilter(filterId));
+        ASSERT_TRUE(closeFilter(filterId));
+        ASSERT_TRUE(closeDemux());
+        ASSERT_TRUE(closeFrontend());
+        break;
     }
 }
+/*============================ End Demux/Filter Tests ============================*/
 
-TEST_P(TunerHidlTest, CreateDemux) {
-    description("Create Demux");
-    ASSERT_TRUE(createDemux());
-}
-
-TEST_P(TunerHidlTest, CloseDemux) {
-    description("Close Demux");
-    ASSERT_TRUE(closeDemux());
-}
-
-TEST_P(TunerHidlTest, CreateDescrambler) {
+/*============================ Start Descrambler Tests ============================*/
+/*
+ * TODO: re-enable the tests after finalizing the test refactoring.
+ */
+/*TEST_P(TunerHidlTest, CreateDescrambler) {
     description("Create Descrambler");
     ASSERT_TRUE(createDescrambler());
 }
@@ -1357,11 +1415,44 @@
 TEST_P(TunerHidlTest, CloseDescrambler) {
     description("Close Descrambler");
     ASSERT_TRUE(closeDescrambler());
+}*/
+/*============================== End Descrambler Tests ==============================*/
+
+/*============================== Start Data Flow Tests ==============================*/
+TEST_P(TunerHidlTest, BroadcastDataFlowWithAudioFilterTest) {
+    description("Open Demux with a Frontend as its data source.");
+    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 != frontendArray[0].type) {
+            continue;
+        }
+        ASSERT_TRUE(openFrontend(mFeIds[i]));
+        ASSERT_TRUE(setFrontendCallback());
+        ASSERT_TRUE(openDemux());
+        ASSERT_TRUE(setDemuxFrontendDataSource(mFeIds[i]));
+        ASSERT_TRUE(openFilterInDemux(filterArray[0].type));
+        uint32_t filterId;
+        ASSERT_TRUE(getNewlyOpenedFilterId(filterId));
+        ASSERT_TRUE(configFilter(filterArray[0].setting, filterId));
+        ASSERT_TRUE(getFilterMQDescriptor(filterId));
+        ASSERT_TRUE(startFilter(filterId));
+        // tune test
+        ASSERT_TRUE(tuneFrontend(frontendArray[0]));
+        // broadcast data flow test
+        ASSERT_TRUE(broadcastDataFlowTest(goldenOutputFiles));
+        ASSERT_TRUE(stopTuneFrontend());
+        ASSERT_TRUE(stopFilter(filterId));
+        ASSERT_TRUE(closeFilter(filterId));
+        ASSERT_TRUE(closeDemux());
+        ASSERT_TRUE(closeFrontend());
+        break;
+    }
 }
 
 /*
- * DATA FLOW TESTS
- *
  * TODO: re-enable the tests after finalizing the testing stream.
  */
 /*TEST_P(TunerHidlTest, PlaybackDataFlowWithSectionFilterTest) {
@@ -1407,36 +1498,6 @@
     ASSERT_TRUE(playbackDataFlowTest(filterConf, playbackConf, goldenOutputFiles));
 }
 
-TEST_P(TunerHidlTest, BroadcastDataFlowWithPesFilterTest) {
-    description("Feed ts data from frontend and test with PES filter");
-
-    // todo modulize the filter conf parser
-    vector<FilterConf> filterConf;
-    filterConf.resize(1);
-
-    DemuxFilterSettings filterSetting;
-    DemuxTsFilterSettings tsFilterSetting{
-            .tpid = 119,
-    };
-    DemuxFilterPesDataSettings pesFilterSetting;
-    tsFilterSetting.filterSettings.pesData(pesFilterSetting);
-    filterSetting.ts(tsFilterSetting);
-
-    DemuxFilterType type{
-            .mainType = DemuxFilterMainType::TS,
-    };
-    type.subType.tsFilterType(DemuxTsFilterType::PES);
-    FilterConf pesFilterConf{
-            .type = type,
-            .setting = filterSetting,
-    };
-    filterConf[0] = pesFilterConf;
-
-    vector<string> goldenOutputFiles;
-
-    ASSERT_TRUE(broadcastDataFlowTest(filterConf, goldenOutputFiles));
-}
-
 TEST_P(TunerHidlTest, RecordDataFlowWithTsRecordFilterTest) {
     description("Feed ts data from frontend to recording and test with ts record filter");
 
@@ -1474,7 +1535,8 @@
 
     ASSERT_TRUE(recordDataFlowTest(filterConf, recordSetting, goldenOutputFiles));
 }*/
-
+/*============================== End Data Flow Tests ==============================*/
+/******************************** End Test Entry **********************************/
 }  // namespace
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
new file mode 100644
index 0000000..55ca857
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
@@ -0,0 +1,137 @@
+/*
+ * 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-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 <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <fstream>
+#include <iostream>
+#include <map>
+
+using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
+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::DemuxTpid;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtBandwidth;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtCoderate;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtConstellation;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtGuardInterval;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtHierarchy;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtStandard;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtTransmissionMode;
+using android::hardware::tv::tuner::V1_0::FrontendSettings;
+using android::hardware::tv::tuner::V1_0::FrontendType;
+
+namespace {
+
+#define frontend_transponders_count 1
+#define channels_count 1
+#define frontend_scan_count 1
+#define filter_count 2
+
+struct FilterConfig {
+    DemuxFilterType type;
+    DemuxFilterSettings setting;
+};
+
+struct FrontendConfig {
+    FrontendType type;
+    FrontendSettings settings;
+};
+
+struct ChannelConfig {
+    int32_t frontendId;
+    int32_t channelId;
+    std::string channelName;
+    DemuxTpid videoPid;
+    DemuxTpid audioPid;
+};
+
+static FrontendConfig frontendArray[frontend_transponders_count];
+static FrontendConfig frontendScanArray[channels_count];
+static ChannelConfig channelArray[frontend_scan_count];
+static FilterConfig filterArray[filter_count];
+static vector<string> goldenOutputFiles;
+
+/** Configuration array for the frontend tune test */
+inline void initFrontendConfig() {
+    FrontendDvbtSettings dvbtSettings{
+            .frequency = 578000,
+            .transmissionMode = FrontendDvbtTransmissionMode::AUTO,
+            .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ,
+            .constellation = FrontendDvbtConstellation::AUTO,
+            .hierarchy = FrontendDvbtHierarchy::AUTO,
+            .hpCoderate = FrontendDvbtCoderate::AUTO,
+            .lpCoderate = FrontendDvbtCoderate::AUTO,
+            .guardInterval = FrontendDvbtGuardInterval::AUTO,
+            .isHighPriority = true,
+            .standard = FrontendDvbtStandard::T,
+    };
+    frontendArray[0].type = FrontendType::DVBT, frontendArray[0].settings.dvbt(dvbtSettings);
+};
+
+/** Configuration array for the frontend scan test */
+inline void initFrontendScanConfig() {
+    frontendScanArray[0].type = FrontendType::DVBT, frontendScanArray[0].settings.dvbt({
+                                                            .frequency = 577000,
+                                                    });
+};
+
+/** Configuration array for the filter test */
+inline void initFilterConfig() {
+    // TS Video filter setting
+    filterArray[0].type.mainType = DemuxFilterMainType::TS;
+    filterArray[0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
+    filterArray[0].setting.ts().tpid = 49;
+    filterArray[0].setting.ts().filterSettings.av({.isPassthrough = false});
+    // TS PES filter setting
+    filterArray[1].type.mainType = DemuxFilterMainType::TS;
+    filterArray[1].type.subType.tsFilterType(DemuxTsFilterType::PES);
+    filterArray[1].setting.ts().tpid = 256;
+    filterArray[1].setting.ts().filterSettings.pesData({
+            .isRaw = true,
+            .streamId = 0xbd,
+    });
+};
+
+}  // namespace
\ No newline at end of file