Merge "Ringbuffer stops logging after wifi toggle"
diff --git a/automotive/can/1.0/default/libnetdevice/printer.cpp b/automotive/can/1.0/default/libnetdevice/printer.cpp
index f6c9c60..179d501 100644
--- a/automotive/can/1.0/default/libnetdevice/printer.cpp
+++ b/automotive/can/1.0/default/libnetdevice/printer.cpp
@@ -65,14 +65,13 @@
     const auto rawData = data.getRaw();
     const auto dataLen = rawData.len();
     ss << std::hex;
-    if (dataLen > 16) ss << std::endl << " 0000 ";
     int i = 0;
     for (const auto byte : rawData) {
-        if (i++ > 0) ss << ' ';
-        ss << std::setw(2) << unsigned(byte);
-        if (i % 16 == 0) {
+        if (i % 16 == 0 && dataLen > 16) {
             ss << std::endl << ' ' << std::dec << std::setw(4) << i << std::hex;
         }
+        if (i++ > 0 || dataLen > 16) ss << ' ';
+        ss << std::setw(2) << unsigned(byte);
     }
     ss << std::dec;
     if (dataLen > 16) ss << std::endl;
diff --git a/bluetooth/a2dp/1.0/vts/functional/VtsHalBluetoothA2dpV1_0TargetTest.cpp b/bluetooth/a2dp/1.0/vts/functional/VtsHalBluetoothA2dpV1_0TargetTest.cpp
index 44b138a..f7fdf31 100644
--- a/bluetooth/a2dp/1.0/vts/functional/VtsHalBluetoothA2dpV1_0TargetTest.cpp
+++ b/bluetooth/a2dp/1.0/vts/functional/VtsHalBluetoothA2dpV1_0TargetTest.cpp
@@ -107,4 +107,6 @@
     PerInstance, BluetoothA2dpHidlTest,
     testing::ValuesIn(android::hardware::getAllHalInstanceNames(
         IBluetoothAudioOffload::descriptor)),
-    android::hardware::PrintInstanceNameToString);
\ No newline at end of file
+    android::hardware::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothA2dpHidlTest);
diff --git a/bluetooth/audio/2.0/default/session/BluetoothAudioSession.cpp b/bluetooth/audio/2.0/default/session/BluetoothAudioSession.cpp
index d60e732..50119bf 100644
--- a/bluetooth/audio/2.0/default/session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/2.0/default/session/BluetoothAudioSession.cpp
@@ -90,14 +90,16 @@
 // bluetooth_audio outputs
 void BluetoothAudioSession::OnSessionEnded() {
   std::lock_guard<std::recursive_mutex> guard(mutex_);
-  if (IsSessionReady()) {
-    ReportSessionStatus();
-  }
+  bool toggled = IsSessionReady();
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
   audio_config_ = (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH
                        ? kInvalidOffloadAudioConfiguration
                        : kInvalidSoftwareAudioConfiguration);
   stack_iface_ = nullptr;
   UpdateDataPath(nullptr);
+  if (toggled) {
+    ReportSessionStatus();
+  }
 }
 
 // invoking the registered session_changed_cb_
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 382b282..9463924 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -372,7 +372,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.radio</name>
-        <version>1.5</version>
+        <version>1.6</version>
         <interface>
             <name>IRadio</name>
             <instance>slot1</instance>
@@ -482,7 +482,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.tv.tuner</name>
-        <version>1.0</version>
+        <version>1.0-1</version>
         <interface>
             <name>ITuner</name>
             <instance>default</instance>
diff --git a/drm/1.0/default/Android.bp b/drm/1.0/default/Android.bp
index ed6bcde..93b3278 100644
--- a/drm/1.0/default/Android.bp
+++ b/drm/1.0/default/Android.bp
@@ -1,3 +1,17 @@
+// Copyright (C) 2016-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.
+
 cc_library_static {
     name: "android.hardware.drm@1.0-helper",
     vendor_available: true,
@@ -21,3 +35,111 @@
     ],
     export_include_dirs : ["include"]
 }
+
+soong_config_module_type {
+    name: "android_hardware_drm_1_0_multilib",
+    module_type: "cc_defaults",
+    config_namespace: "ANDROID",
+    bool_variables: ["TARGET_ENABLE_MEDIADRM_64"],
+    properties: ["compile_multilib"],
+}
+
+android_hardware_drm_1_0_multilib {
+    name: "android.hardware.drm@1.0-multilib-lib",
+    compile_multilib: "32",
+    soong_config_variables: {
+        TARGET_ENABLE_MEDIADRM_64: {
+            compile_multilib: "both",
+        }
+    }
+}
+
+android_hardware_drm_1_0_multilib {
+    name: "android.hardware.drm@1.0-multilib-exe",
+    compile_multilib: "32",
+    soong_config_variables: {
+        TARGET_ENABLE_MEDIADRM_64: {
+            compile_multilib: "first",
+        }
+    }
+}
+
+cc_defaults {
+    name: "android.hardware.drm@1.0-service-defaults",
+    proprietary: true,
+    relative_install_path: "hw",
+    include_dirs: ["hardware/interfaces/drm"],
+    header_libs: ["media_plugin_headers"],
+    static_libs: ["android.hardware.drm@1.0-helper"],
+
+    shared_libs: [
+        "android.hardware.drm@1.0",
+        "android.hidl.memory@1.0",
+        "libhidlbase",
+        "libhardware",
+        "liblog",
+        "libutils",
+        "libbinder",
+    ],
+}
+
+//############ Build legacy drm service ############
+
+cc_binary {
+    name: "android.hardware.drm@1.0-service",
+    defaults: [
+        "android.hardware.drm@1.0-multilib-exe",
+        "android.hardware.drm@1.0-service-defaults"
+    ],
+    init_rc: ["android.hardware.drm@1.0-service.rc"],
+    srcs: ["service.cpp"],
+}
+
+//############ Build legacy drm lazy service ############
+
+cc_binary {
+    name: "android.hardware.drm@1.0-service-lazy",
+    defaults: [
+        "android.hardware.drm@1.0-multilib-exe",
+        "android.hardware.drm@1.0-service-defaults"
+    ],
+    overrides: ["android.hardware.drm@1.0-service"],
+    init_rc: ["android.hardware.drm@1.0-service-lazy.rc"],
+    srcs: ["serviceLazy.cpp"],
+}
+
+//############ Build legacy drm impl library ############
+
+cc_library_shared {
+    name: "android.hardware.drm@1.0-impl",
+    defaults: ["android.hardware.drm@1.0-multilib-lib"],
+    proprietary: true,
+    relative_install_path: "hw",
+
+    include_dirs: [
+        "frameworks/native/include",
+        "frameworks/av/include",
+    ],
+
+    shared_libs: [
+        "android.hardware.drm@1.0",
+        "android.hidl.memory@1.0",
+        "libcutils",
+        "libhidlbase",
+        "libhidlmemory",
+        "liblog",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+
+    static_libs: ["android.hardware.drm@1.0-helper"],
+
+    srcs: [
+        "DrmFactory.cpp",
+        "DrmPlugin.cpp",
+        "CryptoFactory.cpp",
+        "CryptoPlugin.cpp",
+        "LegacyPluginPath.cpp",
+        "TypeConvert.cpp",
+    ],
+}
diff --git a/drm/1.0/default/Android.mk b/drm/1.0/default/Android.mk
deleted file mode 100644
index 9016dc3..0000000
--- a/drm/1.0/default/Android.mk
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# Copyright (C) 2016 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.
-
-
-############# Build legacy drm service ############
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-include $(LOCAL_PATH)/common_default_service.mk
-LOCAL_MODULE := android.hardware.drm@1.0-service
-LOCAL_INIT_RC := android.hardware.drm@1.0-service.rc
-LOCAL_SRC_FILES := service.cpp
-
-include $(BUILD_EXECUTABLE)
-
-############# Build legacy drm lazy service ############
-
-include $(CLEAR_VARS)
-
-include $(LOCAL_PATH)/common_default_service.mk
-LOCAL_MODULE := android.hardware.drm@1.0-service-lazy
-LOCAL_OVERRIDES_MODULES := android.hardware.drm@1.0-service
-LOCAL_INIT_RC := android.hardware.drm@1.0-service-lazy.rc
-LOCAL_SRC_FILES := serviceLazy.cpp
-
-include $(BUILD_EXECUTABLE)
-
-############# Build legacy drm impl library ############
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.drm@1.0-impl
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
-    DrmFactory.cpp \
-    DrmPlugin.cpp \
-    CryptoFactory.cpp \
-    CryptoPlugin.cpp \
-    LegacyPluginPath.cpp \
-    TypeConvert.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-    android.hardware.drm@1.0 \
-    android.hidl.memory@1.0 \
-    libcutils \
-    libhidlbase \
-    libhidlmemory \
-    liblog \
-    libstagefright_foundation \
-    libutils \
-
-LOCAL_STATIC_LIBRARIES := \
-    android.hardware.drm@1.0-helper \
-
-LOCAL_C_INCLUDES := \
-    frameworks/native/include \
-    frameworks/av/include
-
-# TODO: Some legacy DRM plugins only support 32-bit. They need to be migrated to
-# 64-bit. (b/18948909) Once all of a device's legacy DRM plugins support 64-bit,
-# that device can turn on TARGET_ENABLE_MEDIADRM_64 to build this impl as
-# 64-bit.
-ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
-LOCAL_32_BIT_ONLY := true
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/drm/1.0/default/common_default_service.mk b/drm/1.0/default/common_default_service.mk
deleted file mode 100644
index 1b5a975..0000000
--- a/drm/1.0/default/common_default_service.mk
+++ /dev/null
@@ -1,44 +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.
-
-include $(CLEAR_VARS)
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-
-LOCAL_SHARED_LIBRARIES := \
-  android.hardware.drm@1.0 \
-  android.hidl.memory@1.0 \
-  libhidlbase \
-  libhardware \
-  liblog \
-  libutils \
-  libbinder \
-
-LOCAL_STATIC_LIBRARIES := \
-  android.hardware.drm@1.0-helper \
-
-LOCAL_C_INCLUDES := \
-  hardware/interfaces/drm
-
-LOCAL_HEADER_LIBRARIES := \
-  media_plugin_headers
-
-# TODO(b/18948909) Some legacy DRM plugins only support 32-bit. They need to be
-# migrated to 64-bit. Once all of a device's legacy DRM plugins support 64-bit,
-# that device can turn on TARGET_ENABLE_MEDIADRM_64 to build this service as
-# 64-bit.
-ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
-LOCAL_32_BIT_ONLY := true
-endif
diff --git a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
index 33feb5e..a3d2956 100644
--- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
@@ -247,8 +247,10 @@
     ALOGD("Observed %d GnssSvStatus, while awaiting one location (%d received)",
           sv_info_list_cbq_size, location_called_count);
 
-    hidl_vec<IGnssCallback_2_1::GnssSvInfo> last_sv_info_list;
-    ASSERT_TRUE(gnss_cb_->sv_info_list_cbq_.retrieve(last_sv_info_list, 1));
+    // Get the last sv_info_list
+    std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
+    gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size, 1);
+    hidl_vec<IGnssCallback_2_1::GnssSvInfo> last_sv_info_list = sv_info_vec_list.back();
 
     bool nonZeroCn0Found = false;
     for (auto sv_info : last_sv_info_list) {
@@ -673,4 +675,4 @@
             iMeasurementCorrections->setCorrections_1_1(Utils::getMockMeasurementCorrections_1_1());
     ASSERT_TRUE(result.isOk());
     EXPECT_TRUE(result);
-}
\ No newline at end of file
+}
diff --git a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp
index 495de0f..728a523 100644
--- a/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -212,9 +212,11 @@
     EXPECT_EQ(ErrorCode::UNIMPLEMENTED,
               convert(AttestKey(
                       AuthorizationSetBuilder()
+                              .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
                               .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
                               .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")),
                       &cert_chain)));
+    CheckedDeleteKey();
 }
 
 TEST_P(DeviceUniqueAttestationTest, Rsa) {
diff --git a/radio/1.6/Android.bp b/radio/1.6/Android.bp
new file mode 100644
index 0000000..b363f57
--- /dev/null
+++ b/radio/1.6/Android.bp
@@ -0,0 +1,22 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.radio@1.6",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+        "IRadio.hal",
+        "IRadioIndication.hal",
+        "IRadioResponse.hal",
+    ],
+    interfaces: [
+        "android.hardware.radio@1.0",
+        "android.hardware.radio@1.1",
+        "android.hardware.radio@1.2",
+        "android.hardware.radio@1.3",
+        "android.hardware.radio@1.4",
+        "android.hardware.radio@1.5",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+}
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
new file mode 100644
index 0000000..a084b92
--- /dev/null
+++ b/radio/1.6/IRadio.hal
@@ -0,0 +1,30 @@
+/*
+ * 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.radio@1.6;
+
+import @1.5::IRadio;
+
+/**
+ * This interface is used by telephony and telecom to talk to cellular radio.
+ * All the functions have minimum one parameter:
+ * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
+ * duration of a method call. If clients provide colliding serials (including passing the same
+ * serial to different methods), multiple responses (one for each method call) must still be served.
+ * setResponseFunctions must work with @1.6:IRadioResponse and @1.6::IRadioIndication.
+ */
+interface IRadio extends @1.5::IRadio {
+};
diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal
new file mode 100644
index 0000000..9951dd9
--- /dev/null
+++ b/radio/1.6/IRadioIndication.hal
@@ -0,0 +1,25 @@
+/*
+ * 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.radio@1.6;
+
+import @1.5::IRadioIndication;
+
+/**
+ * Interface declaring unsolicited radio indications.
+ */
+interface IRadioIndication extends @1.5::IRadioIndication {
+};
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
new file mode 100644
index 0000000..a67aa3f
--- /dev/null
+++ b/radio/1.6/IRadioResponse.hal
@@ -0,0 +1,25 @@
+/*
+ * 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.radio@1.6;
+
+import @1.5::IRadioResponse;
+
+/**
+ * Interface declaring response functions to solicited radio requests.
+ */
+interface IRadioResponse extends @1.5::IRadioResponse {
+};
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
new file mode 100644
index 0000000..3395619
--- /dev/null
+++ b/radio/1.6/types.hal
@@ -0,0 +1,17 @@
+/*
+ * 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.radio@1.6;
diff --git a/radio/1.6/vts/OWNERS b/radio/1.6/vts/OWNERS
new file mode 100644
index 0000000..3629a6c
--- /dev/null
+++ b/radio/1.6/vts/OWNERS
@@ -0,0 +1,10 @@
+# Telephony team
+refuhoo@google.com
+amitmahajan@google.com
+jackyu@google.com
+fionaxu@google.com
+# more to add
+
+# VTS team
+yuexima@google.com
+dshi@google.com
\ No newline at end of file
diff --git a/radio/1.6/vts/functional/Android.bp b/radio/1.6/vts/functional/Android.bp
new file mode 100644
index 0000000..a6cfc6f
--- /dev/null
+++ b/radio/1.6/vts/functional/Android.bp
@@ -0,0 +1,41 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalRadioV1_6TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "radio_hidl_hal_api.cpp",
+        "radio_hidl_hal_test.cpp",
+        "radio_response.cpp",
+        "radio_indication.cpp",
+        "VtsHalRadioV1_6TargetTest.cpp",
+    ],
+    static_libs: [
+        "RadioVtsTestUtilBase",
+        "android.hardware.radio@1.6",
+        "android.hardware.radio@1.5",
+        "android.hardware.radio@1.4",
+        "android.hardware.radio@1.3",
+        "android.hardware.radio@1.2",
+        "android.hardware.radio@1.1",
+        "android.hardware.radio@1.0",
+        "android.hardware.radio.config@1.0",
+        "android.hardware.radio.config@1.1",
+    ],
+    header_libs: ["radio.util.header@1.0"],
+    test_suites: ["general-tests", "vts"]
+}
diff --git a/radio/1.6/vts/functional/VtsHalRadioV1_6TargetTest.cpp b/radio/1.6/vts/functional/VtsHalRadioV1_6TargetTest.cpp
new file mode 100644
index 0000000..12cefd6
--- /dev/null
+++ b/radio/1.6/vts/functional/VtsHalRadioV1_6TargetTest.cpp
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_6.h>
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioHidlTest_v1_6,
+                         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+                                 android::hardware::radio::V1_6::IRadio::descriptor)),
+                         android::hardware::PrintInstanceNameToString);
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
new file mode 100644
index 0000000..8ed56ed
--- /dev/null
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_6.h>
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
new file mode 100644
index 0000000..e9a4542
--- /dev/null
+++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_6.h>
+
+void RadioHidlTest_v1_6::SetUp() {
+    radio_v1_6 = android::hardware::radio::V1_6::IRadio::getService(GetParam());
+    ASSERT_NE(nullptr, radio_v1_6.get());
+
+    radioRsp_v1_6 = new (std::nothrow) RadioResponse_v1_6(*this);
+    ASSERT_NE(nullptr, radioRsp_v1_6.get());
+
+    count_ = 0;
+
+    radioInd_v1_6 = new (std::nothrow) RadioIndication_v1_6(*this);
+    ASSERT_NE(nullptr, radioInd_v1_6.get());
+
+    radio_v1_6->setResponseFunctions(radioRsp_v1_6, radioInd_v1_6);
+
+    getDataCallList();
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_v1_6->rspInfo.error);
+
+    sp<::android::hardware::radio::config::V1_1::IRadioConfig> radioConfig =
+            ::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. */
+    EXPECT_EQ(CardState::PRESENT, cardStatus.base.base.base.cardState);
+}
+
+/*
+ * Notify that the response message is received.
+ */
+void RadioHidlTest_v1_6::notify(int receivedSerial) {
+    std::unique_lock<std::mutex> lock(mtx_);
+    if (serial == receivedSerial) {
+        count_++;
+        cv_.notify_one();
+    }
+}
+
+/*
+ * Wait till the response message is notified or till TIMEOUT_PERIOD.
+ */
+std::cv_status RadioHidlTest_v1_6::wait() {
+    std::unique_lock<std::mutex> lock(mtx_);
+
+    std::cv_status status = std::cv_status::no_timeout;
+    auto now = std::chrono::system_clock::now();
+    while (count_ == 0) {
+        status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+        if (status == std::cv_status::timeout) {
+            return status;
+        }
+    }
+    count_--;
+    return status;
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
new file mode 100644
index 0000000..66846ea
--- /dev/null
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -0,0 +1,856 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android-base/logging.h>
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <utils/Log.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+#include <android/hardware/radio/config/1.1/IRadioConfig.h>
+
+#include <android/hardware/radio/1.6/IRadio.h>
+#include <android/hardware/radio/1.6/IRadioIndication.h>
+#include <android/hardware/radio/1.6/IRadioResponse.h>
+#include <android/hardware/radio/1.6/types.h>
+
+#include "vts_test_util.h"
+
+using namespace ::android::hardware::radio::V1_6;
+using namespace ::android::hardware::radio::V1_5;
+using namespace ::android::hardware::radio::V1_4;
+using namespace ::android::hardware::radio::V1_3;
+using namespace ::android::hardware::radio::V1_2;
+using namespace ::android::hardware::radio::V1_1;
+using namespace ::android::hardware::radio::V1_0;
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+#define TIMEOUT_PERIOD 75
+#define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
+#define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+
+#define RADIO_SERVICE_NAME "slot1"
+
+class RadioHidlTest_v1_6;
+extern ::android::hardware::radio::V1_5::CardStatus cardStatus;
+
+/* Callback class for radio response v1_5 */
+class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioResponse {
+  protected:
+    RadioHidlTest_v1_6& parent_v1_6;
+
+  public:
+    hidl_vec<RadioBandMode> radioBandModes;
+
+    RadioResponseInfo rspInfo;
+
+    // Call
+    hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
+
+    // Modem
+    bool isModemEnabled;
+    bool enableModemResponseToggle;
+
+    ::android::hardware::hidl_bitfield<::android::hardware::radio::V1_4::RadioAccessFamily>
+            networkTypeBitmapResponse;
+
+    // Data
+    ::android::hardware::radio::V1_4::DataRegStateResult dataRegResp;
+
+    // SimLock status
+    ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierRestrictionsResp;
+    ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicyResp;
+
+    // Whether toggling uicc applications operation is supported.
+    bool canToggleUiccApplicationsEnablement;
+
+    // Whether Uicc applications are enabled or not.
+    bool areUiccApplicationsEnabled;
+
+    // Barring Info Response
+    ::android::hardware::radio::V1_5::CellIdentity barringCellIdentity;
+    ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo> barringInfos;
+
+    RadioResponse_v1_6(RadioHidlTest_v1_6& parent_v1_6);
+    virtual ~RadioResponse_v1_6() = default;
+
+    Return<void> getIccCardStatusResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_0::CardStatus& cardStatus);
+
+    Return<void> supplyIccPinForAppResponse(const RadioResponseInfo& info,
+                                            int32_t remainingRetries);
+
+    Return<void> supplyIccPukForAppResponse(const RadioResponseInfo& info,
+                                            int32_t remainingRetries);
+
+    Return<void> supplyIccPin2ForAppResponse(const RadioResponseInfo& info,
+                                             int32_t remainingRetries);
+
+    Return<void> supplyIccPuk2ForAppResponse(const RadioResponseInfo& info,
+                                             int32_t remainingRetries);
+
+    Return<void> changeIccPinForAppResponse(const RadioResponseInfo& info,
+                                            int32_t remainingRetries);
+
+    Return<void> changeIccPin2ForAppResponse(const RadioResponseInfo& info,
+                                             int32_t remainingRetries);
+
+    Return<void> supplyNetworkDepersonalizationResponse(const RadioResponseInfo& info,
+                                                        int32_t remainingRetries);
+
+    Return<void> getCurrentCallsResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::Call>& calls);
+
+    Return<void> dialResponse(const RadioResponseInfo& info);
+
+    Return<void> getIMSIForAppResponse(const RadioResponseInfo& info,
+                                       const ::android::hardware::hidl_string& imsi);
+
+    Return<void> hangupConnectionResponse(const RadioResponseInfo& info);
+
+    Return<void> hangupWaitingOrBackgroundResponse(const RadioResponseInfo& info);
+
+    Return<void> hangupForegroundResumeBackgroundResponse(const RadioResponseInfo& info);
+
+    Return<void> switchWaitingOrHoldingAndActiveResponse(const RadioResponseInfo& info);
+
+    Return<void> conferenceResponse(const RadioResponseInfo& info);
+
+    Return<void> rejectCallResponse(const RadioResponseInfo& info);
+
+    Return<void> getLastCallFailCauseResponse(const RadioResponseInfo& info,
+                                              const LastCallFailCauseInfo& failCauseInfo);
+
+    Return<void> getSignalStrengthResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_0::SignalStrength& sigStrength);
+
+    Return<void> getVoiceRegistrationStateResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_0::VoiceRegStateResult& voiceRegResponse);
+
+    Return<void> getDataRegistrationStateResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_0::DataRegStateResult& dataRegResponse);
+
+    Return<void> getOperatorResponse(const RadioResponseInfo& info,
+                                     const ::android::hardware::hidl_string& longName,
+                                     const ::android::hardware::hidl_string& shortName,
+                                     const ::android::hardware::hidl_string& numeric);
+
+    Return<void> setRadioPowerResponse(const RadioResponseInfo& info);
+
+    Return<void> sendDtmfResponse(const RadioResponseInfo& info);
+
+    Return<void> sendSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+
+    Return<void> sendSMSExpectMoreResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+
+    Return<void> setupDataCallResponse(
+            const RadioResponseInfo& info,
+            const android::hardware::radio::V1_0::SetupDataCallResult& dcResponse);
+
+    Return<void> iccIOForAppResponse(const RadioResponseInfo& info, const IccIoResult& iccIo);
+
+    Return<void> sendUssdResponse(const RadioResponseInfo& info);
+
+    Return<void> cancelPendingUssdResponse(const RadioResponseInfo& info);
+
+    Return<void> getClirResponse(const RadioResponseInfo& info, int32_t n, int32_t m);
+
+    Return<void> setClirResponse(const RadioResponseInfo& info);
+
+    Return<void> getCallForwardStatusResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<CallForwardInfo>& call_forwardInfos);
+
+    Return<void> setCallForwardResponse(const RadioResponseInfo& info);
+
+    Return<void> getCallWaitingResponse(const RadioResponseInfo& info, bool enable,
+                                        int32_t serviceClass);
+
+    Return<void> setCallWaitingResponse(const RadioResponseInfo& info);
+
+    Return<void> acknowledgeLastIncomingGsmSmsResponse(const RadioResponseInfo& info);
+
+    Return<void> acceptCallResponse(const RadioResponseInfo& info);
+
+    Return<void> deactivateDataCallResponse(const RadioResponseInfo& info);
+
+    Return<void> getFacilityLockForAppResponse(const RadioResponseInfo& info, int32_t response);
+
+    Return<void> setFacilityLockForAppResponse(const RadioResponseInfo& info, int32_t retry);
+
+    Return<void> setBarringPasswordResponse(const RadioResponseInfo& info);
+
+    Return<void> getNetworkSelectionModeResponse(const RadioResponseInfo& info, bool manual);
+
+    Return<void> setNetworkSelectionModeAutomaticResponse(const RadioResponseInfo& info);
+
+    Return<void> setNetworkSelectionModeManualResponse(const RadioResponseInfo& info);
+
+    Return<void> getAvailableNetworksResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<OperatorInfo>& networkInfos);
+
+    Return<void> startDtmfResponse(const RadioResponseInfo& info);
+
+    Return<void> stopDtmfResponse(const RadioResponseInfo& info);
+
+    Return<void> getBasebandVersionResponse(const RadioResponseInfo& info,
+                                            const ::android::hardware::hidl_string& version);
+
+    Return<void> separateConnectionResponse(const RadioResponseInfo& info);
+
+    Return<void> setMuteResponse(const RadioResponseInfo& info);
+
+    Return<void> getMuteResponse(const RadioResponseInfo& info, bool enable);
+
+    Return<void> getClipResponse(const RadioResponseInfo& info, ClipStatus status);
+
+    Return<void> getDataCallListResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<
+                    android::hardware::radio::V1_0::SetupDataCallResult>& dcResponse);
+
+    Return<void> sendOemRilRequestRawResponse(const RadioResponseInfo& info,
+                                              const ::android::hardware::hidl_vec<uint8_t>& data);
+
+    Return<void> sendOemRilRequestStringsResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& data);
+
+    Return<void> setSuppServiceNotificationsResponse(const RadioResponseInfo& info);
+
+    Return<void> writeSmsToSimResponse(const RadioResponseInfo& info, int32_t index);
+
+    Return<void> deleteSmsOnSimResponse(const RadioResponseInfo& info);
+
+    Return<void> setBandModeResponse(const RadioResponseInfo& info);
+
+    Return<void> getAvailableBandModesResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<RadioBandMode>& bandModes);
+
+    Return<void> sendEnvelopeResponse(const RadioResponseInfo& info,
+                                      const ::android::hardware::hidl_string& commandResponse);
+
+    Return<void> sendTerminalResponseToSimResponse(const RadioResponseInfo& info);
+
+    Return<void> handleStkCallSetupRequestFromSimResponse(const RadioResponseInfo& info);
+
+    Return<void> explicitCallTransferResponse(const RadioResponseInfo& info);
+
+    Return<void> setPreferredNetworkTypeResponse(const RadioResponseInfo& info);
+
+    Return<void> getPreferredNetworkTypeResponse(const RadioResponseInfo& info,
+                                                 PreferredNetworkType nwType);
+
+    Return<void> getNeighboringCidsResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<NeighboringCell>& cells);
+
+    Return<void> setLocationUpdatesResponse(const RadioResponseInfo& info);
+
+    Return<void> setCdmaSubscriptionSourceResponse(const RadioResponseInfo& info);
+
+    Return<void> setCdmaRoamingPreferenceResponse(const RadioResponseInfo& info);
+
+    Return<void> getCdmaRoamingPreferenceResponse(const RadioResponseInfo& info,
+                                                  CdmaRoamingType type);
+
+    Return<void> setTTYModeResponse(const RadioResponseInfo& info);
+
+    Return<void> getTTYModeResponse(const RadioResponseInfo& info, TtyMode mode);
+
+    Return<void> setPreferredVoicePrivacyResponse(const RadioResponseInfo& info);
+
+    Return<void> getPreferredVoicePrivacyResponse(const RadioResponseInfo& info, bool enable);
+
+    Return<void> sendCDMAFeatureCodeResponse(const RadioResponseInfo& info);
+
+    Return<void> sendBurstDtmfResponse(const RadioResponseInfo& info);
+
+    Return<void> sendCdmaSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+
+    Return<void> acknowledgeLastIncomingCdmaSmsResponse(const RadioResponseInfo& info);
+
+    Return<void> getGsmBroadcastConfigResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo>& configs);
+
+    Return<void> setGsmBroadcastConfigResponse(const RadioResponseInfo& info);
+
+    Return<void> setGsmBroadcastActivationResponse(const RadioResponseInfo& info);
+
+    Return<void> getCdmaBroadcastConfigResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo>& configs);
+
+    Return<void> setCdmaBroadcastConfigResponse(const RadioResponseInfo& info);
+
+    Return<void> setCdmaBroadcastActivationResponse(const RadioResponseInfo& info);
+
+    Return<void> getCDMASubscriptionResponse(const RadioResponseInfo& info,
+                                             const ::android::hardware::hidl_string& mdn,
+                                             const ::android::hardware::hidl_string& hSid,
+                                             const ::android::hardware::hidl_string& hNid,
+                                             const ::android::hardware::hidl_string& min,
+                                             const ::android::hardware::hidl_string& prl);
+
+    Return<void> writeSmsToRuimResponse(const RadioResponseInfo& info, uint32_t index);
+
+    Return<void> deleteSmsOnRuimResponse(const RadioResponseInfo& info);
+
+    Return<void> getDeviceIdentityResponse(const RadioResponseInfo& info,
+                                           const ::android::hardware::hidl_string& imei,
+                                           const ::android::hardware::hidl_string& imeisv,
+                                           const ::android::hardware::hidl_string& esn,
+                                           const ::android::hardware::hidl_string& meid);
+
+    Return<void> exitEmergencyCallbackModeResponse(const RadioResponseInfo& info);
+
+    Return<void> getSmscAddressResponse(const RadioResponseInfo& info,
+                                        const ::android::hardware::hidl_string& smsc);
+
+    Return<void> setSmscAddressResponse(const RadioResponseInfo& info);
+
+    Return<void> reportSmsMemoryStatusResponse(const RadioResponseInfo& info);
+
+    Return<void> reportStkServiceIsRunningResponse(const RadioResponseInfo& info);
+
+    Return<void> getCdmaSubscriptionSourceResponse(const RadioResponseInfo& info,
+                                                   CdmaSubscriptionSource source);
+
+    Return<void> requestIsimAuthenticationResponse(
+            const RadioResponseInfo& info, const ::android::hardware::hidl_string& response);
+
+    Return<void> acknowledgeIncomingGsmSmsWithPduResponse(const RadioResponseInfo& info);
+
+    Return<void> sendEnvelopeWithStatusResponse(const RadioResponseInfo& info,
+                                                const IccIoResult& iccIo);
+
+    Return<void> getVoiceRadioTechnologyResponse(
+            const RadioResponseInfo& info, ::android::hardware::radio::V1_0::RadioTechnology rat);
+
+    Return<void> getCellInfoListResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::CellInfo>&
+                    cellInfo);
+
+    Return<void> setCellInfoListRateResponse(const RadioResponseInfo& info);
+
+    Return<void> setInitialAttachApnResponse(const RadioResponseInfo& info);
+
+    Return<void> getImsRegistrationStateResponse(const RadioResponseInfo& info, bool isRegistered,
+                                                 RadioTechnologyFamily ratFamily);
+
+    Return<void> sendImsSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+
+    Return<void> iccTransmitApduBasicChannelResponse(const RadioResponseInfo& info,
+                                                     const IccIoResult& result);
+
+    Return<void> iccOpenLogicalChannelResponse(
+            const RadioResponseInfo& info, int32_t channelId,
+            const ::android::hardware::hidl_vec<int8_t>& selectResponse);
+
+    Return<void> iccCloseLogicalChannelResponse(const RadioResponseInfo& info);
+
+    Return<void> iccTransmitApduLogicalChannelResponse(const RadioResponseInfo& info,
+                                                       const IccIoResult& result);
+
+    Return<void> nvReadItemResponse(const RadioResponseInfo& info,
+                                    const ::android::hardware::hidl_string& result);
+
+    Return<void> nvWriteItemResponse(const RadioResponseInfo& info);
+
+    Return<void> nvWriteCdmaPrlResponse(const RadioResponseInfo& info);
+
+    Return<void> nvResetConfigResponse(const RadioResponseInfo& info);
+
+    Return<void> setUiccSubscriptionResponse(const RadioResponseInfo& info);
+
+    Return<void> setDataAllowedResponse(const RadioResponseInfo& info);
+
+    Return<void> getHardwareConfigResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<HardwareConfig>& config);
+
+    Return<void> requestIccSimAuthenticationResponse(const RadioResponseInfo& info,
+                                                     const IccIoResult& result);
+
+    Return<void> setDataProfileResponse(const RadioResponseInfo& info);
+
+    Return<void> requestShutdownResponse(const RadioResponseInfo& info);
+
+    Return<void> getRadioCapabilityResponse(
+            const RadioResponseInfo& info,
+            const android::hardware::radio::V1_0::RadioCapability& rc);
+
+    Return<void> setRadioCapabilityResponse(
+            const RadioResponseInfo& info,
+            const android::hardware::radio::V1_0::RadioCapability& rc);
+
+    Return<void> startLceServiceResponse(const RadioResponseInfo& info,
+                                         const LceStatusInfo& statusInfo);
+
+    Return<void> stopLceServiceResponse(const RadioResponseInfo& info,
+                                        const LceStatusInfo& statusInfo);
+
+    Return<void> pullLceDataResponse(const RadioResponseInfo& info, const LceDataInfo& lceInfo);
+
+    Return<void> getModemActivityInfoResponse(const RadioResponseInfo& info,
+                                              const ActivityStatsInfo& activityInfo);
+
+    Return<void> setAllowedCarriersResponse(const RadioResponseInfo& info, int32_t numAllowed);
+
+    Return<void> getAllowedCarriersResponse(const RadioResponseInfo& info, bool allAllowed,
+                                            const CarrierRestrictions& carriers);
+
+    Return<void> sendDeviceStateResponse(const RadioResponseInfo& info);
+
+    Return<void> setIndicationFilterResponse(const RadioResponseInfo& info);
+
+    Return<void> setSimCardPowerResponse(const RadioResponseInfo& info);
+
+    Return<void> acknowledgeRequest(int32_t serial);
+
+    /* 1.1 Api */
+    Return<void> setCarrierInfoForImsiEncryptionResponse(const RadioResponseInfo& info);
+
+    Return<void> setSimCardPowerResponse_1_1(const RadioResponseInfo& info);
+
+    Return<void> startNetworkScanResponse(const RadioResponseInfo& info);
+
+    Return<void> stopNetworkScanResponse(const RadioResponseInfo& info);
+
+    Return<void> startKeepaliveResponse(const RadioResponseInfo& info,
+                                        const KeepaliveStatus& status);
+
+    Return<void> stopKeepaliveResponse(const RadioResponseInfo& info);
+
+    /* 1.2 Api */
+    Return<void> setSignalStrengthReportingCriteriaResponse(const RadioResponseInfo& info);
+
+    Return<void> setLinkCapacityReportingCriteriaResponse(const RadioResponseInfo& info);
+
+    Return<void> getIccCardStatusResponse_1_2(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_2::CardStatus& card_status);
+
+    Return<void> getCurrentCallsResponse_1_2(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls);
+
+    Return<void> getSignalStrengthResponse_1_2(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_2::SignalStrength& sig_strength);
+
+    Return<void> getSignalStrengthResponse_1_4(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_4::SignalStrength& sig_strength);
+
+    Return<void> getCellInfoListResponse_1_2(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::CellInfo>&
+                    cellInfo);
+
+    Return<void> getVoiceRegistrationStateResponse_1_2(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse);
+
+    Return<void> getDataRegistrationStateResponse_1_2(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_2::DataRegStateResult& dataRegResponse);
+
+    /* 1.3 Api */
+    Return<void> setSystemSelectionChannelsResponse(const RadioResponseInfo& info);
+
+    Return<void> enableModemResponse(const RadioResponseInfo& info);
+
+    Return<void> getModemStackStatusResponse(const RadioResponseInfo& info, const bool enabled);
+
+    /* 1.4 Api */
+    Return<void> emergencyDialResponse(const RadioResponseInfo& info);
+
+    Return<void> startNetworkScanResponse_1_4(const RadioResponseInfo& info);
+
+    Return<void> getCellInfoListResponse_1_4(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::CellInfo>&
+                    cellInfo);
+
+    Return<void> getDataRegistrationStateResponse_1_4(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_4::DataRegStateResult& dataRegResponse);
+
+    Return<void> getIccCardStatusResponse_1_4(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_4::CardStatus& card_status);
+
+    Return<void> getPreferredNetworkTypeBitmapResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_bitfield<
+                    ::android::hardware::radio::V1_4::RadioAccessFamily>
+                    networkTypeBitmap);
+
+    Return<void> setPreferredNetworkTypeBitmapResponse(const RadioResponseInfo& info);
+
+    Return<void> getDataCallListResponse_1_4(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<
+                    ::android::hardware::radio::V1_4::SetupDataCallResult>& dcResponse);
+
+    Return<void> setupDataCallResponse_1_4(
+            const RadioResponseInfo& info,
+            const android::hardware::radio::V1_4::SetupDataCallResult& dcResponse);
+
+    Return<void> setAllowedCarriersResponse_1_4(const RadioResponseInfo& info);
+
+    Return<void> getAllowedCarriersResponse_1_4(const RadioResponseInfo& info,
+                                                const CarrierRestrictionsWithPriority& carriers,
+                                                SimLockMultiSimPolicy multiSimPolicy);
+
+    /* 1.5 Api */
+    Return<void> setSignalStrengthReportingCriteriaResponse_1_5(const RadioResponseInfo& info);
+
+    Return<void> setLinkCapacityReportingCriteriaResponse_1_5(const RadioResponseInfo& info);
+
+    Return<void> enableUiccApplicationsResponse(const RadioResponseInfo& info);
+
+    Return<void> areUiccApplicationsEnabledResponse(const RadioResponseInfo& info, bool enabled);
+
+    Return<void> canToggleUiccApplicationsEnablementResponse(const RadioResponseInfo& info,
+                                                             bool canToggle);
+
+    Return<void> setSystemSelectionChannelsResponse_1_5(const RadioResponseInfo& info);
+
+    Return<void> startNetworkScanResponse_1_5(const RadioResponseInfo& info);
+
+    Return<void> setupDataCallResponse_1_5(
+            const RadioResponseInfo& info,
+            const android::hardware::radio::V1_5::SetupDataCallResult& dcResponse);
+
+    Return<void> getDataCallListResponse_1_5(
+            const RadioResponseInfo& info,
+            const hidl_vec<::android::hardware::radio::V1_5::SetupDataCallResult>& dcResponse);
+
+    Return<void> setInitialAttachApnResponse_1_5(const RadioResponseInfo& info);
+
+    Return<void> setDataProfileResponse_1_5(const RadioResponseInfo& info);
+
+    Return<void> setRadioPowerResponse_1_5(const RadioResponseInfo& info);
+
+    Return<void> setIndicationFilterResponse_1_5(const RadioResponseInfo& info);
+
+    Return<void> getBarringInfoResponse(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_5::CellIdentity& cellIdentity,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo>&
+                    barringInfos);
+
+    Return<void> getVoiceRegistrationStateResponse_1_5(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_5::RegStateResult& regResponse);
+
+    Return<void> getDataRegistrationStateResponse_1_5(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_5::RegStateResult& regResponse);
+
+    Return<void> getCellInfoListResponse_1_5(
+            const RadioResponseInfo& info,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::CellInfo>&
+                    cellInfo);
+
+    Return<void> setNetworkSelectionModeManualResponse_1_5(const RadioResponseInfo& info);
+
+    Return<void> sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info,
+                                               const SendSmsResult& sms);
+
+    Return<void> supplySimDepersonalizationResponse(
+            const RadioResponseInfo& info,
+            ::android::hardware::radio::V1_5::PersoSubstate persoType, int32_t remainingRetries);
+
+    Return<void> getIccCardStatusResponse_1_5(
+            const RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_5::CardStatus& card_status);
+
+    /* 1.6 Api */
+};
+
+/* Callback class for radio indication */
+class RadioIndication_v1_6 : public ::android::hardware::radio::V1_6::IRadioIndication {
+  protected:
+    RadioHidlTest_v1_6& parent_v1_6;
+
+  public:
+    RadioIndication_v1_6(RadioHidlTest_v1_6& parent_v1_6);
+    virtual ~RadioIndication_v1_6() = default;
+
+    /* 1.6 Api */
+
+    /* 1.5 Api */
+    Return<void> uiccApplicationsEnablementChanged(RadioIndicationType type, bool enabled);
+
+    Return<void> networkScanResult_1_5(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_5::NetworkScanResult& result);
+
+    Return<void> cellInfoList_1_5(
+            RadioIndicationType type,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::CellInfo>&
+                    records);
+
+    Return<void> dataCallListChanged_1_5(
+            RadioIndicationType type,
+            const hidl_vec<::android::hardware::radio::V1_5::SetupDataCallResult>& dcList);
+
+    /* 1.4 Api */
+    Return<void> currentEmergencyNumberList(
+            RadioIndicationType type,
+            const ::android::hardware::hidl_vec<EmergencyNumber>& emergencyNumberList);
+
+    Return<void> cellInfoList_1_4(
+            RadioIndicationType type,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::CellInfo>&
+                    records);
+
+    Return<void> networkScanResult_1_4(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_4::NetworkScanResult& result);
+
+    Return<void> currentPhysicalChannelConfigs_1_4(
+            RadioIndicationType type,
+            const ::android::hardware::hidl_vec<
+                    ::android::hardware::radio::V1_4::PhysicalChannelConfig>& configs);
+
+    Return<void> dataCallListChanged_1_4(
+            RadioIndicationType type,
+            const ::android::hardware::hidl_vec<
+                    android::hardware::radio::V1_4::SetupDataCallResult>& dcList);
+
+    /* 1.2 Api */
+    Return<void> networkScanResult_1_2(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_2::NetworkScanResult& result);
+
+    Return<void> cellInfoList_1_2(
+            RadioIndicationType type,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::CellInfo>&
+                    records);
+
+    Return<void> currentLinkCapacityEstimate(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_2::LinkCapacityEstimate& lce);
+
+    Return<void> currentPhysicalChannelConfigs(
+            RadioIndicationType type,
+            const ::android::hardware::hidl_vec<
+                    ::android::hardware::radio::V1_2::PhysicalChannelConfig>& configs);
+
+    Return<void> currentSignalStrength_1_2(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_2::SignalStrength& signalStrength);
+
+    Return<void> currentSignalStrength_1_4(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_4::SignalStrength& signalStrength);
+
+    /* 1.1 Api */
+    Return<void> carrierInfoForImsiEncryption(RadioIndicationType info);
+
+    Return<void> networkScanResult(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_1::NetworkScanResult& result);
+
+    Return<void> keepaliveStatus(RadioIndicationType type, const KeepaliveStatus& status);
+
+    /* 1.0 Api */
+    Return<void> radioStateChanged(RadioIndicationType type, RadioState radioState);
+
+    Return<void> callStateChanged(RadioIndicationType type);
+
+    Return<void> networkStateChanged(RadioIndicationType type);
+
+    Return<void> newSms(RadioIndicationType type,
+                        const ::android::hardware::hidl_vec<uint8_t>& pdu);
+
+    Return<void> newSmsStatusReport(RadioIndicationType type,
+                                    const ::android::hardware::hidl_vec<uint8_t>& pdu);
+
+    Return<void> newSmsOnSim(RadioIndicationType type, int32_t recordNumber);
+
+    Return<void> onUssd(RadioIndicationType type, UssdModeType modeType,
+                        const ::android::hardware::hidl_string& msg);
+
+    Return<void> nitzTimeReceived(RadioIndicationType type,
+                                  const ::android::hardware::hidl_string& nitzTime,
+                                  uint64_t receivedTime);
+
+    Return<void> currentSignalStrength(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_0::SignalStrength& signalStrength);
+
+    Return<void> dataCallListChanged(
+            RadioIndicationType type,
+            const ::android::hardware::hidl_vec<
+                    android::hardware::radio::V1_0::SetupDataCallResult>& dcList);
+
+    Return<void> suppSvcNotify(RadioIndicationType type, const SuppSvcNotification& suppSvc);
+
+    Return<void> stkSessionEnd(RadioIndicationType type);
+
+    Return<void> stkProactiveCommand(RadioIndicationType type,
+                                     const ::android::hardware::hidl_string& cmd);
+
+    Return<void> stkEventNotify(RadioIndicationType type,
+                                const ::android::hardware::hidl_string& cmd);
+
+    Return<void> stkCallSetup(RadioIndicationType type, int64_t timeout);
+
+    Return<void> simSmsStorageFull(RadioIndicationType type);
+
+    Return<void> simRefresh(RadioIndicationType type, const SimRefreshResult& refreshResult);
+
+    Return<void> callRing(RadioIndicationType type, bool isGsm, const CdmaSignalInfoRecord& record);
+
+    Return<void> simStatusChanged(RadioIndicationType type);
+
+    Return<void> cdmaNewSms(RadioIndicationType type, const CdmaSmsMessage& msg);
+
+    Return<void> newBroadcastSms(RadioIndicationType type,
+                                 const ::android::hardware::hidl_vec<uint8_t>& data);
+
+    Return<void> cdmaRuimSmsStorageFull(RadioIndicationType type);
+
+    Return<void> restrictedStateChanged(RadioIndicationType type, PhoneRestrictedState state);
+
+    Return<void> enterEmergencyCallbackMode(RadioIndicationType type);
+
+    Return<void> cdmaCallWaiting(RadioIndicationType type,
+                                 const CdmaCallWaiting& callWaitingRecord);
+
+    Return<void> cdmaOtaProvisionStatus(RadioIndicationType type, CdmaOtaProvisionStatus status);
+
+    Return<void> cdmaInfoRec(RadioIndicationType type, const CdmaInformationRecords& records);
+
+    Return<void> indicateRingbackTone(RadioIndicationType type, bool start);
+
+    Return<void> resendIncallMute(RadioIndicationType type);
+
+    Return<void> cdmaSubscriptionSourceChanged(RadioIndicationType type,
+                                               CdmaSubscriptionSource cdmaSource);
+
+    Return<void> cdmaPrlChanged(RadioIndicationType type, int32_t version);
+
+    Return<void> exitEmergencyCallbackMode(RadioIndicationType type);
+
+    Return<void> rilConnected(RadioIndicationType type);
+
+    Return<void> voiceRadioTechChanged(RadioIndicationType type,
+                                       ::android::hardware::radio::V1_0::RadioTechnology rat);
+
+    Return<void> cellInfoList(
+            RadioIndicationType type,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::CellInfo>&
+                    records);
+
+    Return<void> imsNetworkStateChanged(RadioIndicationType type);
+
+    Return<void> subscriptionStatusChanged(RadioIndicationType type, bool activate);
+
+    Return<void> srvccStateNotify(RadioIndicationType type, SrvccState state);
+
+    Return<void> hardwareConfigChanged(
+            RadioIndicationType type, const ::android::hardware::hidl_vec<HardwareConfig>& configs);
+
+    Return<void> radioCapabilityIndication(
+            RadioIndicationType type, const android::hardware::radio::V1_0::RadioCapability& rc);
+
+    Return<void> onSupplementaryServiceIndication(RadioIndicationType type,
+                                                  const StkCcUnsolSsResult& ss);
+
+    Return<void> stkCallControlAlphaNotify(RadioIndicationType type,
+                                           const ::android::hardware::hidl_string& alpha);
+
+    Return<void> lceData(RadioIndicationType type, const LceDataInfo& lce);
+
+    Return<void> pcoData(RadioIndicationType type, const PcoDataInfo& pco);
+
+    Return<void> modemReset(RadioIndicationType type,
+                            const ::android::hardware::hidl_string& reason);
+
+    Return<void> registrationFailed(
+            RadioIndicationType type,
+            const ::android::hardware::radio::V1_5::CellIdentity& cellIdentity,
+            const ::android::hardware::hidl_string& chosenPlmn,
+            ::android::hardware::hidl_bitfield<::android::hardware::radio::V1_5::Domain> domain,
+            int32_t causeCode, int32_t additionalCauseCode);
+
+    Return<void> barringInfoChanged(
+            RadioIndicationType /*type*/,
+            const ::android::hardware::radio::V1_5::CellIdentity& /*cellIdentity*/,
+            const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo>&
+            /*barringInfos*/);
+};
+
+// The main test class for Radio HIDL.
+class RadioHidlTest_v1_6 : public ::testing::TestWithParam<std::string> {
+  protected:
+    std::mutex mtx_;
+    std::condition_variable cv_;
+    int count_;
+
+    /* Serial number for radio request */
+    int serial;
+
+    /* Clear Potential Established Calls */
+    void clearPotentialEstablishedCalls();
+
+    /* Get current data call list */
+    void getDataCallList();
+
+  public:
+    virtual void SetUp() override;
+
+    /* Used as a mechanism to inform the test about data/event callback */
+    void notify(int receivedSerial);
+
+    /* Test code calls this function to wait for response */
+    std::cv_status wait();
+
+    /* radio service handle */
+    sp<::android::hardware::radio::V1_6::IRadio> radio_v1_6;
+
+    /* radio response handle */
+    sp<RadioResponse_v1_6> radioRsp_v1_6;
+
+    /* radio indication handle */
+    sp<RadioIndication_v1_6> radioInd_v1_6;
+};
diff --git a/radio/1.6/vts/functional/radio_indication.cpp b/radio/1.6/vts/functional/radio_indication.cpp
new file mode 100644
index 0000000..857ea3c
--- /dev/null
+++ b/radio/1.6/vts/functional/radio_indication.cpp
@@ -0,0 +1,372 @@
+/*
+ * 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_6.h>
+
+RadioIndication_v1_6::RadioIndication_v1_6(RadioHidlTest_v1_6& parent) : parent_v1_6(parent) {}
+
+/* 1.6 Apis */
+
+/* 1.5 Apis */
+Return<void> RadioIndication_v1_6::uiccApplicationsEnablementChanged(RadioIndicationType /*type*/,
+                                                                     bool /*enabled*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::registrationFailed(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_5::CellIdentity& /*cellIdentity*/,
+        const hidl_string& /*chosenPlmn*/,
+        ::android::hardware::hidl_bitfield<::android::hardware::radio::V1_5::Domain> /*domain*/,
+        int32_t /*causeCode*/, int32_t /*additionalCauseCode*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::barringInfoChanged(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_5::CellIdentity& /*cellIdentity*/,
+        const hidl_vec<::android::hardware::radio::V1_5::BarringInfo>& /*barringInfos*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::networkScanResult_1_5(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_5::NetworkScanResult& /*result*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cellInfoList_1_5(
+        RadioIndicationType /*type*/,
+        const hidl_vec<::android::hardware::radio::V1_5::CellInfo>& /*records*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::dataCallListChanged_1_5(
+        RadioIndicationType /*type*/,
+        const hidl_vec<android::hardware::radio::V1_5::SetupDataCallResult>& /*dcList*/) {
+    return Void();
+}
+
+/* 1.4 Apis */
+Return<void> RadioIndication_v1_6::currentPhysicalChannelConfigs_1_4(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::hidl_vec<
+                ::android::hardware::radio::V1_4::PhysicalChannelConfig>& /*configs*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::networkScanResult_1_4(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_4::NetworkScanResult& /*result*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cellInfoList_1_4(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::hidl_vec<
+                ::android::hardware::radio::V1_4::CellInfo>& /*records*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::currentEmergencyNumberList(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::hidl_vec<EmergencyNumber>& /*emergencyNumberList*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::dataCallListChanged_1_4(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::hidl_vec<android::hardware::radio::V1_4::SetupDataCallResult>&
+        /*dcList*/) {
+    return Void();
+}
+
+/* 1.2 Apis */
+Return<void> RadioIndication_v1_6::networkScanResult_1_2(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_2::NetworkScanResult& /*result*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cellInfoList_1_2(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::hidl_vec<
+                ::android::hardware::radio::V1_2::CellInfo>& /*records*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::currentLinkCapacityEstimate(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_2::LinkCapacityEstimate& /*lce*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::currentPhysicalChannelConfigs(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::hidl_vec<
+                ::android::hardware::radio::V1_2::PhysicalChannelConfig>& /*configs*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::currentSignalStrength_1_2(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_2::SignalStrength& /*signalStrength*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::currentSignalStrength_1_4(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_4::SignalStrength& /*signalStrength*/) {
+    return Void();
+}
+
+/* 1.1 Apis */
+Return<void> RadioIndication_v1_6::carrierInfoForImsiEncryption(RadioIndicationType /*info*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::networkScanResult(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_1::NetworkScanResult& /*result*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::keepaliveStatus(RadioIndicationType /*type*/,
+                                                   const KeepaliveStatus& /*status*/) {
+    return Void();
+}
+
+/* 1.0 Apis */
+Return<void> RadioIndication_v1_6::radioStateChanged(RadioIndicationType /*type*/,
+                                                     RadioState /*radioState*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::callStateChanged(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::networkStateChanged(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::newSms(RadioIndicationType /*type*/,
+                                          const ::android::hardware::hidl_vec<uint8_t>& /*pdu*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::newSmsStatusReport(
+        RadioIndicationType /*type*/, const ::android::hardware::hidl_vec<uint8_t>& /*pdu*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::newSmsOnSim(RadioIndicationType /*type*/,
+                                               int32_t /*recordNumber*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::onUssd(RadioIndicationType /*type*/, UssdModeType /*modeType*/,
+                                          const ::android::hardware::hidl_string& /*msg*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::nitzTimeReceived(
+        RadioIndicationType /*type*/, const ::android::hardware::hidl_string& /*nitzTime*/,
+        uint64_t /*receivedTime*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::currentSignalStrength(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::radio::V1_0::SignalStrength& /*signalStrength*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::dataCallListChanged(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::hidl_vec<android::hardware::radio::V1_0::SetupDataCallResult>&
+        /*dcList*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::suppSvcNotify(RadioIndicationType /*type*/,
+                                                 const SuppSvcNotification& /*suppSvc*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::stkSessionEnd(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::stkProactiveCommand(
+        RadioIndicationType /*type*/, const ::android::hardware::hidl_string& /*cmd*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::stkEventNotify(RadioIndicationType /*type*/,
+                                                  const ::android::hardware::hidl_string& /*cmd*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::stkCallSetup(RadioIndicationType /*type*/, int64_t /*timeout*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::simSmsStorageFull(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::simRefresh(RadioIndicationType /*type*/,
+                                              const SimRefreshResult& /*refreshResult*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::callRing(RadioIndicationType /*type*/, bool /*isGsm*/,
+                                            const CdmaSignalInfoRecord& /*record*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::simStatusChanged(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cdmaNewSms(RadioIndicationType /*type*/,
+                                              const CdmaSmsMessage& /*msg*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::newBroadcastSms(
+        RadioIndicationType /*type*/, const ::android::hardware::hidl_vec<uint8_t>& /*data*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cdmaRuimSmsStorageFull(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::restrictedStateChanged(RadioIndicationType /*type*/,
+                                                          PhoneRestrictedState /*state*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::enterEmergencyCallbackMode(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cdmaCallWaiting(RadioIndicationType /*type*/,
+                                                   const CdmaCallWaiting& /*callWaitingRecord*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cdmaOtaProvisionStatus(RadioIndicationType /*type*/,
+                                                          CdmaOtaProvisionStatus /*status*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cdmaInfoRec(RadioIndicationType /*type*/,
+                                               const CdmaInformationRecords& /*records*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::indicateRingbackTone(RadioIndicationType /*type*/,
+                                                        bool /*start*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::resendIncallMute(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cdmaSubscriptionSourceChanged(
+        RadioIndicationType /*type*/, CdmaSubscriptionSource /*cdmaSource*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cdmaPrlChanged(RadioIndicationType /*type*/,
+                                                  int32_t /*version*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::exitEmergencyCallbackMode(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::rilConnected(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::voiceRadioTechChanged(
+        RadioIndicationType /*type*/, ::android::hardware::radio::V1_0::RadioTechnology /*rat*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::cellInfoList(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::hidl_vec<
+                ::android::hardware::radio::V1_0::CellInfo>& /*records*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::imsNetworkStateChanged(RadioIndicationType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::subscriptionStatusChanged(RadioIndicationType /*type*/,
+                                                             bool /*activate*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::srvccStateNotify(RadioIndicationType /*type*/,
+                                                    SrvccState /*state*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::hardwareConfigChanged(
+        RadioIndicationType /*type*/,
+        const ::android::hardware::hidl_vec<HardwareConfig>& /*configs*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::radioCapabilityIndication(
+        RadioIndicationType /*type*/,
+        const android::hardware::radio::V1_0::RadioCapability& /*rc*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::onSupplementaryServiceIndication(
+        RadioIndicationType /*type*/, const StkCcUnsolSsResult& /*ss*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::stkCallControlAlphaNotify(
+        RadioIndicationType /*type*/, const ::android::hardware::hidl_string& /*alpha*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::lceData(RadioIndicationType /*type*/,
+                                           const LceDataInfo& /*lce*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::pcoData(RadioIndicationType /*type*/,
+                                           const PcoDataInfo& /*pco*/) {
+    return Void();
+}
+
+Return<void> RadioIndication_v1_6::modemReset(RadioIndicationType /*type*/,
+                                              const ::android::hardware::hidl_string& /*reason*/) {
+    return Void();
+}
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
new file mode 100644
index 0000000..44e61b9
--- /dev/null
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -0,0 +1,1044 @@
+/*
+ * 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_6.h>
+
+::android::hardware::radio::V1_5::CardStatus cardStatus;
+
+RadioResponse_v1_6::RadioResponse_v1_6(RadioHidlTest_v1_6& parent) : parent_v1_6(parent) {}
+
+/* 1.0 Apis */
+Return<void> RadioResponse_v1_6::getIccCardStatusResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::radio::V1_0::CardStatus& /*card_status*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::supplyIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+                                                            int32_t /*remainingRetries*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::supplyIccPukForAppResponse(const RadioResponseInfo& /*info*/,
+                                                            int32_t /*remainingRetries*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::supplyIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+                                                             int32_t /*remainingRetries*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::supplyIccPuk2ForAppResponse(const RadioResponseInfo& /*info*/,
+                                                             int32_t /*remainingRetries*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::changeIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+                                                            int32_t /*remainingRetries*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::changeIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+                                                             int32_t /*remainingRetries*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::supplyNetworkDepersonalizationResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCurrentCallsResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::Call>& /*calls*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::dialResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getIMSIForAppResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imsi*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::hangupConnectionResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::hangupWaitingOrBackgroundResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::hangupForegroundResumeBackgroundResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::switchWaitingOrHoldingAndActiveResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::conferenceResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::rejectCallResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getLastCallFailCauseResponse(
+        const RadioResponseInfo& /*info*/, const LastCallFailCauseInfo& /*failCauseInfo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getSignalStrengthResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::radio::V1_0::SignalStrength& /*sig_strength*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::radio::V1_0::VoiceRegStateResult& /*voiceRegResponse*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::radio::V1_0::DataRegStateResult& /*dataRegResponse*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getOperatorResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*longName*/,
+        const ::android::hardware::hidl_string& /*shortName*/,
+        const ::android::hardware::hidl_string& /*numeric*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setRadioPowerResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendSmsResponse(const RadioResponseInfo& /*info*/,
+                                                 const SendSmsResult& /*sms*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendSMSExpectMoreResponse(const RadioResponseInfo& /*info*/,
+                                                           const SendSmsResult& /*sms*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setupDataCallResponse(
+        const RadioResponseInfo& /*info*/,
+        const android::hardware::radio::V1_0::SetupDataCallResult& /*dcResponse*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::iccIOForAppResponse(const RadioResponseInfo& /*info*/,
+                                                     const IccIoResult& /*iccIo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendUssdResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::cancelPendingUssdResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getClirResponse(const RadioResponseInfo& /*info*/, int32_t /*n*/,
+                                                 int32_t /*m*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setClirResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCallForwardStatusResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec<CallForwardInfo>&
+        /*callForwardInfos*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setCallForwardResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCallWaitingResponse(const RadioResponseInfo& /*info*/,
+                                                        bool /*enable*/, int32_t /*serviceClass*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setCallWaitingResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::acknowledgeLastIncomingGsmSmsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::acceptCallResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::deactivateDataCallResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
+                                                               int32_t /*response*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
+                                                               int32_t /*retry*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setBarringPasswordResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getNetworkSelectionModeResponse(const RadioResponseInfo& /*info*/,
+                                                                 bool /*manual*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setNetworkSelectionModeAutomaticResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setNetworkSelectionModeManualResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getAvailableNetworksResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<OperatorInfo>& /*networkInfos*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::startDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::stopDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getBasebandVersionResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*version*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::separateConnectionResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setMuteResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getMuteResponse(const RadioResponseInfo& /*info*/,
+                                                 bool /*enable*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getClipResponse(const RadioResponseInfo& /*info*/,
+                                                 ClipStatus /*status*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getDataCallListResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<android::hardware::radio::V1_0::SetupDataCallResult>&
+        /*dcResponse*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendOemRilRequestRawResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec<uint8_t>& /*data*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendOemRilRequestStringsResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& /*data*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setSuppServiceNotificationsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::writeSmsToSimResponse(const RadioResponseInfo& /*info*/,
+                                                       int32_t /*index*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::deleteSmsOnSimResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setBandModeResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getAvailableBandModesResponse(
+        const RadioResponseInfo& info,
+        const ::android::hardware::hidl_vec<RadioBandMode>& bandModes) {
+    rspInfo = info;
+    radioBandModes = bandModes;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendEnvelopeResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_string& /*commandResponse*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendTerminalResponseToSimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::handleStkCallSetupRequestFromSimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::explicitCallTransferResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setPreferredNetworkTypeResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getPreferredNetworkTypeResponse(const RadioResponseInfo& /*info*/,
+                                                                 PreferredNetworkType /*nw_type*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getNeighboringCidsResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<NeighboringCell>& /*cells*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setLocationUpdatesResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setCdmaSubscriptionSourceResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setCdmaRoamingPreferenceResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCdmaRoamingPreferenceResponse(const RadioResponseInfo& /*info*/,
+                                                                  CdmaRoamingType /*type*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setTTYModeResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getTTYModeResponse(const RadioResponseInfo& /*info*/,
+                                                    TtyMode /*mode*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setPreferredVoicePrivacyResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getPreferredVoicePrivacyResponse(const RadioResponseInfo& /*info*/,
+                                                                  bool /*enable*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendCDMAFeatureCodeResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendBurstDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendCdmaSmsResponse(const RadioResponseInfo& /*info*/,
+                                                     const SendSmsResult& /*sms*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::acknowledgeLastIncomingCdmaSmsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getGsmBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setGsmBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setGsmBroadcastActivationResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCdmaBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setCdmaBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setCdmaBroadcastActivationResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCDMASubscriptionResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*mdn*/,
+        const ::android::hardware::hidl_string& /*hSid*/,
+        const ::android::hardware::hidl_string& /*hNid*/,
+        const ::android::hardware::hidl_string& /*min*/,
+        const ::android::hardware::hidl_string& /*prl*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::writeSmsToRuimResponse(const RadioResponseInfo& /*info*/,
+                                                        uint32_t /*index*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::deleteSmsOnRuimResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getDeviceIdentityResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imei*/,
+        const ::android::hardware::hidl_string& /*imeisv*/,
+        const ::android::hardware::hidl_string& /*esn*/,
+        const ::android::hardware::hidl_string& /*meid*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::exitEmergencyCallbackModeResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getSmscAddressResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*smsc*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setSmscAddressResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::reportSmsMemoryStatusResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::reportStkServiceIsRunningResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCdmaSubscriptionSourceResponse(
+        const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::requestIsimAuthenticationResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*response*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::acknowledgeIncomingGsmSmsWithPduResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendEnvelopeWithStatusResponse(const RadioResponseInfo& /*info*/,
+                                                                const IccIoResult& /*iccIo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getVoiceRadioTechnologyResponse(
+        const RadioResponseInfo& /*info*/,
+        ::android::hardware::radio::V1_0::RadioTechnology /*rat*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCellInfoListResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<
+                ::android::hardware::radio::V1_0::CellInfo>& /*cellInfo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setCellInfoListRateResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setInitialAttachApnResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getImsRegistrationStateResponse(
+        const RadioResponseInfo& /*info*/, bool /*isRegistered*/,
+        RadioTechnologyFamily /*ratFamily*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendImsSmsResponse(const RadioResponseInfo& /*info*/,
+                                                    const SendSmsResult& /*sms*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::iccTransmitApduBasicChannelResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::iccOpenLogicalChannelResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*channelId*/,
+        const ::android::hardware::hidl_vec<int8_t>& /*selectResponse*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::iccCloseLogicalChannelResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::iccTransmitApduLogicalChannelResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::nvReadItemResponse(
+        const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*result*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::nvWriteItemResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::nvResetConfigResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setUiccSubscriptionResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setDataAllowedResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getHardwareConfigResponse(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<HardwareConfig>& /*config*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::requestIccSimAuthenticationResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setDataProfileResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::requestShutdownResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getRadioCapabilityResponse(
+        const RadioResponseInfo& /*info*/,
+        const android::hardware::radio::V1_0::RadioCapability& /*rc*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setRadioCapabilityResponse(
+        const RadioResponseInfo& /*info*/,
+        const android::hardware::radio::V1_0::RadioCapability& /*rc*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::startLceServiceResponse(const RadioResponseInfo& /*info*/,
+                                                         const LceStatusInfo& /*statusInfo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::stopLceServiceResponse(const RadioResponseInfo& /*info*/,
+                                                        const LceStatusInfo& /*statusInfo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::pullLceDataResponse(const RadioResponseInfo& /*info*/,
+                                                     const LceDataInfo& /*lceInfo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getModemActivityInfoResponse(
+        const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setAllowedCarriersResponse(const RadioResponseInfo& /*info*/,
+                                                            int32_t /*numAllowed*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getAllowedCarriersResponse(
+        const RadioResponseInfo& /*info*/, bool /*allAllowed*/,
+        const CarrierRestrictions& /*carriers*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendDeviceStateResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setIndicationFilterResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setSimCardPowerResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::acknowledgeRequest(int32_t /*serial*/) {
+    return Void();
+}
+
+/* 1.1 Apis */
+Return<void> RadioResponse_v1_6::setCarrierInfoForImsiEncryptionResponse(
+        const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setSimCardPowerResponse_1_1(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::startNetworkScanResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::stopNetworkScanResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
+                                                        const KeepaliveStatus& /*status*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+    return Void();
+}
+
+/* 1.2 Apis */
+Return<void> RadioResponse_v1_6::setSignalStrengthReportingCriteriaResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setLinkCapacityReportingCriteriaResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getIccCardStatusResponse_1_2(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::radio::V1_2::CardStatus& /*card_status*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCurrentCallsResponse_1_2(
+        const RadioResponseInfo& info,
+        const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls) {
+    rspInfo = info;
+    currentCalls = calls;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getSignalStrengthResponse_1_2(
+        const RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_2::SignalStrength& /*sig_strength*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getSignalStrengthResponse_1_4(
+        const RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_4::SignalStrength& /*sig_strength*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_2(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<
+                ::android::hardware::radio::V1_2::CellInfo>& /*cellInfo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_2(
+        const RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse_1_2(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::radio::V1_2::DataRegStateResult& /*dataRegResponse*/) {
+    return Void();
+}
+
+/* 1.3 Apis */
+Return<void> RadioResponse_v1_6::setSystemSelectionChannelsResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::enableModemResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getModemStackStatusResponse(const RadioResponseInfo& info,
+                                                             const bool enabled) {
+    rspInfo = info;
+    isModemEnabled = enabled;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+/* 1.4 Apis */
+Return<void> RadioResponse_v1_6::emergencyDialResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::startNetworkScanResponse_1_4(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse_1_4(
+        const RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_4::DataRegStateResult& dataRegResponse) {
+    rspInfo = info;
+    dataRegResp = dataRegResponse;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_4(
+        const RadioResponseInfo& info,
+        const ::android::hardware::hidl_vec<
+                ::android::hardware::radio::V1_4::CellInfo>& /*cellInfo*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getIccCardStatusResponse_1_4(
+        const RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_4::CardStatus& /*card_status*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getPreferredNetworkTypeBitmapResponse(
+        const RadioResponseInfo& info, const ::android::hardware::hidl_bitfield<
+                                               ::android::hardware::radio::V1_4::RadioAccessFamily>
+                                               networkTypeBitmap) {
+    rspInfo = info;
+    networkTypeBitmapResponse = networkTypeBitmap;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setPreferredNetworkTypeBitmapResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getDataCallListResponse_1_4(
+        const RadioResponseInfo& info,
+        const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::SetupDataCallResult>&
+        /*dcResponse*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setupDataCallResponse_1_4(
+        const RadioResponseInfo& info,
+        const android::hardware::radio::V1_4::SetupDataCallResult& /*dcResponse*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setAllowedCarriersResponse_1_4(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getAllowedCarriersResponse_1_4(
+        const RadioResponseInfo& info, const CarrierRestrictionsWithPriority& carriers,
+        SimLockMultiSimPolicy multiSimPolicy) {
+    rspInfo = info;
+    carrierRestrictionsResp = carriers;
+    multiSimPolicyResp = multiSimPolicy;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+/* 1.5 Apis */
+Return<void> RadioResponse_v1_6::setSignalStrengthReportingCriteriaResponse_1_5(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setLinkCapacityReportingCriteriaResponse_1_5(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::enableUiccApplicationsResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::areUiccApplicationsEnabledResponse(const RadioResponseInfo& info,
+                                                                    bool enabled) {
+    rspInfo = info;
+    areUiccApplicationsEnabled = enabled;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::canToggleUiccApplicationsEnablementResponse(
+        const RadioResponseInfo& info, bool canToggle) {
+    rspInfo = info;
+    canToggleUiccApplicationsEnablement = canToggle;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setSystemSelectionChannelsResponse_1_5(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::startNetworkScanResponse_1_5(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setupDataCallResponse_1_5(
+        const RadioResponseInfo& info,
+        const android::hardware::radio::V1_5::SetupDataCallResult& /* dcResponse */) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getDataCallListResponse_1_5(
+        const RadioResponseInfo& info,
+        const hidl_vec<::android::hardware::radio::V1_5::SetupDataCallResult>& /* dcResponse */) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setInitialAttachApnResponse_1_5(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setDataProfileResponse_1_5(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setRadioPowerResponse_1_5(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setIndicationFilterResponse_1_5(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getBarringInfoResponse(
+        const RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_5::CellIdentity& cellIdentity,
+        const ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo>&
+                barringInfos) {
+    this->barringCellIdentity = cellIdentity;
+    this->barringInfos = barringInfos;
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getVoiceRegistrationStateResponse_1_5(
+        const RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getDataRegistrationStateResponse_1_5(
+        const RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getCellInfoListResponse_1_5(
+        const RadioResponseInfo& /*info*/,
+        const ::android::hardware::hidl_vec<
+                ::android::hardware::radio::V1_5::CellInfo>& /*cellInfo*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::setNetworkSelectionModeManualResponse_1_5(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info,
+                                                               const SendSmsResult& /*sms*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::supplySimDepersonalizationResponse(
+        const RadioResponseInfo& /*info*/,
+        ::android::hardware::radio::V1_5::PersoSubstate /*persoType*/,
+        int32_t /*remainingRetries*/) {
+    return Void();
+}
+
+Return<void> RadioResponse_v1_6::getIccCardStatusResponse_1_5(
+        const RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_5::CardStatus& card_status) {
+    rspInfo = info;
+    cardStatus = card_status;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
+
+/* 1.6 Apis */
+
diff --git a/secure_element/1.0/vts/functional/AndroidTest.xml b/secure_element/1.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..4724f23
--- /dev/null
+++ b/secure_element/1.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalSecureElementV1_0TargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SECURE_ELEMENT_SIM_CARD" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalSecureElementV1_0TargetTest->/data/local/tmp/VtsHalSecureElementV1_0TargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalSecureElementV1_0TargetTest" />
+    </test>
+</configuration>
diff --git a/secure_element/1.1/vts/functional/AndroidTest.xml b/secure_element/1.1/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..3d7b715
--- /dev/null
+++ b/secure_element/1.1/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalSecureElementV1_1TargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SECURE_ELEMENT_SIM_CARD" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalSecureElementV1_1TargetTest->/data/local/tmp/VtsHalSecureElementV1_1TargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalSecureElementV1_1TargetTest" />
+    </test>
+</configuration>
diff --git a/secure_element/1.2/vts/functional/AndroidTest.xml b/secure_element/1.2/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..0bd8061
--- /dev/null
+++ b/secure_element/1.2/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalSecureElementV1_2TargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+    <option name="config-descriptor:metadata" key="token" value="SECURE_ELEMENT_SIM_CARD" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="VtsHalSecureElementV1_2TargetTest->/data/local/tmp/VtsHalSecureElementV1_2TargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalSecureElementV1_2TargetTest" />
+    </test>
+</configuration>
diff --git a/tv/input/1.0/vts/functional/VtsHalTvInputV1_0TargetTest.cpp b/tv/input/1.0/vts/functional/VtsHalTvInputV1_0TargetTest.cpp
index 8092d5e..59c70eb 100644
--- a/tv/input/1.0/vts/functional/VtsHalTvInputV1_0TargetTest.cpp
+++ b/tv/input/1.0/vts/functional/VtsHalTvInputV1_0TargetTest.cpp
@@ -337,6 +337,3 @@
         PerInstance, TvInputHidlTest,
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITvInput::descriptor)),
         android::hardware::PrintInstanceNameToString);
-
-// TODO remove from the allow list once the cf tv target is enabled for testing
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TvInputHidlTest);
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 4521824..078f5df 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -628,14 +628,4 @@
         PerInstance, TunerDescramblerHidlTest,
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
         android::hardware::PrintInstanceNameToString);
-
-// TODO remove from the allow list once the cf tv target is enabled for testing
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFrontendHidlTest);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerLnbHidlTest);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxHidlTest);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerBroadcastHidlTest);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerPlaybackHidlTest);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerRecordHidlTest);
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDescramblerHidlTest);
 }  // namespace
diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp
new file mode 100644
index 0000000..476915e
--- /dev/null
+++ b/tv/tuner/1.1/Android.bp
@@ -0,0 +1,17 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.tv.tuner@1.1",
+    root: "android.hardware",
+    srcs: [
+        "IFilter.hal",
+        "ITuner.hal",
+        "IDemux.hal",
+    ],
+    interfaces: [
+        "android.hidl.base@1.0",
+        "android.hidl.safe_union@1.0",
+        "android.hardware.tv.tuner@1.0",
+    ],
+    gen_java: false,
+}
diff --git a/tv/tuner/1.1/IDemux.hal b/tv/tuner/1.1/IDemux.hal
new file mode 100644
index 0000000..81cd001
--- /dev/null
+++ b/tv/tuner/1.1/IDemux.hal
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner@1.1;
+
+import @1.0::IDemux;
+import @1.0::Result;
+import @1.0::IFilter;
+
+/**
+ * Demultiplexer(Demux) takes a single multiplexed input and splits it into
+ * one or more output.
+ */
+interface IDemux extends @1.0::IDemux {
+    /**
+     * Get a 64-bit hardware sync ID for audio and video.
+     *
+     * It is used by the client to get the hardware sync ID for audio and video.
+     *
+     * @param filter the filter instance.
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         INVALID_ARGUMENT if failed for a wrong filter ID.
+     *         UNKNOWN_ERROR if failed for other reasons.
+     * @return avSyncHwId the id of hardware A/V sync.
+     */
+    getAvSyncHwId64Bit(IFilter filter) generates (Result result, uint64_t avSyncHwId);
+};
\ No newline at end of file
diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal
new file mode 100644
index 0000000..6c4d8a5
--- /dev/null
+++ b/tv/tuner/1.1/IFilter.hal
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+package android.hardware.tv.tuner@1.1;
+
+import @1.0::IFilter;
+import @1.0::Result;
+
+/**
+ * The Filter is used to filter wanted data according to the filter's
+ * configuration.
+ *
+ * To access the v1.1 IFilter APIs, the implementation can cast the IFilter
+ * interface returned from the @1.0::IDemux openFilter into a v1.1 IFiler
+ * using V1_1::IFilter::castFrom(V1_0::IFilter).
+ */
+interface IFilter extends @1.0::IFilter {
+    /**
+     * Get the 64-bit filter Id. This id is 32-bit in Tuner HAL 1.0.
+     *
+     * It is used by the client to ask the hardware resource id for the filter.
+     *
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         INVALID_STATE if failed for wrong state.
+     *         UNKNOWN_ERROR if failed for other reasons.
+     * @return filterId the hardware resource Id for the filter.
+     */
+    getId64Bit() generates (Result result, uint64_t filterId);
+};
diff --git a/tv/tuner/1.1/ITuner.hal b/tv/tuner/1.1/ITuner.hal
new file mode 100644
index 0000000..915fb85
--- /dev/null
+++ b/tv/tuner/1.1/ITuner.hal
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package android.hardware.tv.tuner@1.1;
+
+import @1.0::ITuner;
+import @1.0::Result;
+
+/**
+ * Top level interface to manage Frontend, Demux and Decrambler hardware
+ * resources which are needed for Android TV.
+ */
+interface ITuner extends @1.0::ITuner {};
diff --git a/tv/tuner/1.1/TEST_MAPPING b/tv/tuner/1.1/TEST_MAPPING
new file mode 100644
index 0000000..7c91b8f
--- /dev/null
+++ b/tv/tuner/1.1/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalTvTunerV1_1TargetTest"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tv/tuner/1.1/default/Android.bp b/tv/tuner/1.1/default/Android.bp
new file mode 100644
index 0000000..7e45864
--- /dev/null
+++ b/tv/tuner/1.1/default/Android.bp
@@ -0,0 +1,52 @@
+cc_defaults {
+    name: "tuner_service_defaults@1.1",
+    defaults: ["hidl_defaults"],
+    vendor: true,
+    relative_install_path: "hw",
+    srcs: [
+        "Filter.cpp",
+        "Frontend.cpp",
+        "Descrambler.cpp",
+        "Demux.cpp",
+        "Dvr.cpp",
+        "TimeFilter.cpp",
+        "Tuner.cpp",
+        "Lnb.cpp",
+        "service.cpp",
+    ],
+
+    compile_multilib: "first",
+
+    shared_libs: [
+        "android.hardware.tv.tuner@1.0",
+        "android.hardware.tv.tuner@1.1",
+        "android.hidl.memory@1.0",
+        "libcutils",
+        "libfmq",
+        "libhidlbase",
+        "libhidlmemory",
+        "libion",
+        "liblog",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+    header_libs: [
+        "media_plugin_headers",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.tv.tuner@1.1-service",
+    vintf_fragments: ["android.hardware.tv.tuner@1.1-service.xml"],
+    defaults: ["tuner_service_defaults@1.1"],
+    init_rc: ["android.hardware.tv.tuner@1.1-service.rc"],
+}
+
+cc_binary {
+    name: "android.hardware.tv.tuner@1.1-service-lazy",
+    vintf_fragments: ["android.hardware.tv.tuner@1.1-service-lazy.xml"],
+    overrides: ["android.hardware.tv.tuner@1.1-service"],
+    defaults: ["tuner_service_defaults@1.1"],
+    init_rc: ["android.hardware.tv.tuner@1.1-service-lazy.rc"],
+    cflags: ["-DLAZY_SERVICE"],
+}
diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp
new file mode 100644
index 0000000..f501d74
--- /dev/null
+++ b/tv/tuner/1.1/default/Demux.cpp
@@ -0,0 +1,445 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.tv.tuner@1.1-Demux"
+
+#include "Demux.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+#define WAIT_TIMEOUT 3000000000
+Demux::Demux(uint32_t demuxId, sp<Tuner> tuner) {
+    mDemuxId = demuxId;
+    mTunerService = tuner;
+}
+
+Demux::~Demux() {}
+
+Return<void> Demux::getAvSyncHwId64Bit(const sp<IFilter>& filter, getAvSyncHwId64Bit_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    uint64_t avSyncHwId = -1;
+    uint64_t id;
+    Result status;
+
+    sp<V1_1::IFilter> filter_v1_1 = V1_1::IFilter::castFrom(filter);
+    if (filter_v1_1 != NULL) {
+        filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) {
+            id = filterId;
+            status = result;
+        });
+    } else {
+        filter->getId([&](Result result, uint32_t filterId) {
+            id = filterId;
+            status = result;
+        });
+    }
+
+    if (status != Result::SUCCESS) {
+        ALOGE("[Demux] Can't get 64-bit filter Id.");
+        _hidl_cb(Result::INVALID_STATE, avSyncHwId);
+        return Void();
+    }
+
+    if (!mFilters[id]->isMediaFilter()) {
+        ALOGE("[Demux] Given filter is not a media filter.");
+        _hidl_cb(Result::INVALID_ARGUMENT, avSyncHwId);
+        return Void();
+    }
+
+    if (!mPcrFilterIds.empty()) {
+        // Return the lowest pcr filter id in the default implementation as the av sync id
+        _hidl_cb(Result::SUCCESS, *mPcrFilterIds.begin());
+        return Void();
+    }
+
+    ALOGE("[Demux] No PCR filter opened.");
+    _hidl_cb(Result::INVALID_STATE, avSyncHwId);
+    return Void();
+}
+
+Return<Result> Demux::setFrontendDataSource(uint32_t frontendId) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mTunerService == nullptr) {
+        return Result::NOT_INITIALIZED;
+    }
+
+    mFrontend = mTunerService->getFrontendById(frontendId);
+
+    if (mFrontend == nullptr) {
+        return Result::INVALID_STATE;
+    }
+
+    mTunerService->setFrontendAsDemuxSource(frontendId, mDemuxId);
+
+    return Result::SUCCESS;
+}
+
+Return<void> Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize,
+                               const sp<IFilterCallback>& cb, openFilter_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    uint64_t filterId;
+    filterId = ++mLastUsedFilterId;
+
+    if (cb == nullptr) {
+        ALOGW("[Demux] callback can't be null");
+        _hidl_cb(Result::INVALID_ARGUMENT, new Filter());
+        return Void();
+    }
+
+    sp<Filter> filter = new Filter(type, filterId, bufferSize, cb, this);
+
+    if (!filter->createFilterMQ()) {
+        _hidl_cb(Result::UNKNOWN_ERROR, filter);
+        return Void();
+    }
+
+    mFilters[filterId] = filter;
+    if (filter->isPcrFilter()) {
+        mPcrFilterIds.insert(filterId);
+    }
+    bool result = true;
+    if (!filter->isRecordFilter()) {
+        // Only save non-record filters for now. Record filters are saved when the
+        // IDvr.attacheFilter is called.
+        mPlaybackFilterIds.insert(filterId);
+        if (mDvrPlayback != nullptr) {
+            result = mDvrPlayback->addPlaybackFilter(filterId, filter);
+        }
+    }
+
+    _hidl_cb(result ? Result::SUCCESS : Result::INVALID_ARGUMENT, filter);
+    return Void();
+}
+
+Return<void> Demux::openTimeFilter(openTimeFilter_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    mTimeFilter = new TimeFilter(this);
+
+    _hidl_cb(Result::SUCCESS, mTimeFilter);
+    return Void();
+}
+
+Return<void> Demux::getAvSyncHwId(const sp<IFilter>& filter, getAvSyncHwId_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    uint32_t avSyncHwId = -1;
+    uint64_t id;
+    Result status;
+
+    sp<V1_1::IFilter> filter_v1_1 = V1_1::IFilter::castFrom(filter);
+    if (filter_v1_1 != NULL) {
+        filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) {
+            id = filterId;
+            status = result;
+        });
+    } else {
+        filter->getId([&](Result result, uint32_t filterId) {
+            id = filterId;
+            status = result;
+        });
+    }
+
+    if (status != Result::SUCCESS) {
+        ALOGE("[Demux] Can't get filter Id.");
+        _hidl_cb(Result::INVALID_STATE, avSyncHwId);
+        return Void();
+    }
+
+    if (!mFilters[id]->isMediaFilter()) {
+        ALOGE("[Demux] Given filter is not a media filter.");
+        _hidl_cb(Result::INVALID_ARGUMENT, avSyncHwId);
+        return Void();
+    }
+
+    if (!mPcrFilterIds.empty()) {
+        // Return the lowest pcr filter id in the default implementation as the av sync id
+        _hidl_cb(Result::SUCCESS, *mPcrFilterIds.begin());
+        return Void();
+    }
+
+    ALOGE("[Demux] No PCR filter opened.");
+    _hidl_cb(Result::INVALID_STATE, avSyncHwId);
+    return Void();
+}
+
+Return<void> Demux::getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    uint64_t avSyncTime = -1;
+    if (mPcrFilterIds.empty()) {
+        _hidl_cb(Result::INVALID_STATE, avSyncTime);
+        return Void();
+    }
+    if (avSyncHwId != *mPcrFilterIds.begin()) {
+        _hidl_cb(Result::INVALID_ARGUMENT, avSyncTime);
+        return Void();
+    }
+
+    _hidl_cb(Result::SUCCESS, avSyncTime);
+    return Void();
+}
+
+Return<Result> Demux::close() {
+    ALOGV("%s", __FUNCTION__);
+
+    set<uint64_t>::iterator it;
+    for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
+        mDvrPlayback->removePlaybackFilter(*it);
+    }
+    mPlaybackFilterIds.clear();
+    mRecordFilterIds.clear();
+    mFilters.clear();
+    mLastUsedFilterId = -1;
+    mTunerService->removeDemux(mDemuxId);
+
+    return Result::SUCCESS;
+}
+
+Return<void> Demux::openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
+                            openDvr_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (cb == nullptr) {
+        ALOGW("[Demux] DVR callback can't be null");
+        _hidl_cb(Result::INVALID_ARGUMENT, new Dvr());
+        return Void();
+    }
+
+    set<uint64_t>::iterator it;
+    switch (type) {
+        case DvrType::PLAYBACK:
+            mDvrPlayback = new Dvr(type, bufferSize, cb, this);
+            if (!mDvrPlayback->createDvrMQ()) {
+                _hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback);
+                return Void();
+            }
+
+            for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
+                if (!mDvrPlayback->addPlaybackFilter(*it, mFilters[*it])) {
+                    ALOGE("[Demux] Can't get filter info for DVR playback");
+                    _hidl_cb(Result::UNKNOWN_ERROR, mDvrPlayback);
+                    return Void();
+                }
+            }
+
+            _hidl_cb(Result::SUCCESS, mDvrPlayback);
+            return Void();
+        case DvrType::RECORD:
+            mDvrRecord = new Dvr(type, bufferSize, cb, this);
+            if (!mDvrRecord->createDvrMQ()) {
+                _hidl_cb(Result::UNKNOWN_ERROR, mDvrRecord);
+                return Void();
+            }
+
+            _hidl_cb(Result::SUCCESS, mDvrRecord);
+            return Void();
+        default:
+            _hidl_cb(Result::INVALID_ARGUMENT, nullptr);
+            return Void();
+    }
+}
+
+Return<Result> Demux::connectCiCam(uint32_t ciCamId) {
+    ALOGV("%s", __FUNCTION__);
+
+    mCiCamId = ciCamId;
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Demux::disconnectCiCam() {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Result Demux::removeFilter(uint64_t filterId) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mDvrPlayback != nullptr) {
+        mDvrPlayback->removePlaybackFilter(filterId);
+    }
+    mPlaybackFilterIds.erase(filterId);
+    mRecordFilterIds.erase(filterId);
+    mFilters.erase(filterId);
+
+    return Result::SUCCESS;
+}
+
+void Demux::startBroadcastTsFilter(vector<uint8_t> data) {
+    set<uint64_t>::iterator it;
+    uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff));
+    if (DEBUG_DEMUX) {
+        ALOGW("[Demux] start ts filter pid: %d", pid);
+    }
+    for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
+        if (pid == mFilters[*it]->getTpid()) {
+            mFilters[*it]->updateFilterOutput(data);
+        }
+    }
+}
+
+void Demux::sendFrontendInputToRecord(vector<uint8_t> data) {
+    set<uint64_t>::iterator it;
+    if (DEBUG_DEMUX) {
+        ALOGW("[Demux] update record filter output");
+    }
+    for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
+        mFilters[*it]->updateRecordOutput(data);
+    }
+}
+
+bool Demux::startBroadcastFilterDispatcher() {
+    set<uint64_t>::iterator it;
+
+    // Handle the output data per filter type
+    for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
+        if (mFilters[*it]->startFilterHandler() != Result::SUCCESS) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool Demux::startRecordFilterDispatcher() {
+    set<uint64_t>::iterator it;
+
+    for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
+        if (mFilters[*it]->startRecordFilterHandler() != Result::SUCCESS) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+Result Demux::startFilterHandler(uint64_t filterId) {
+    return mFilters[filterId]->startFilterHandler();
+}
+
+void Demux::updateFilterOutput(uint64_t filterId, vector<uint8_t> data) {
+    mFilters[filterId]->updateFilterOutput(data);
+}
+
+void Demux::updateMediaFilterOutput(uint64_t filterId, vector<uint8_t> data, uint64_t pts) {
+    updateFilterOutput(filterId, data);
+    mFilters[filterId]->updatePts(pts);
+}
+
+uint16_t Demux::getFilterTpid(uint64_t filterId) {
+    return mFilters[filterId]->getTpid();
+}
+
+void Demux::startFrontendInputLoop() {
+    pthread_create(&mFrontendInputThread, NULL, __threadLoopFrontend, this);
+    pthread_setname_np(mFrontendInputThread, "frontend_input_thread");
+}
+
+void* Demux::__threadLoopFrontend(void* user) {
+    Demux* const self = static_cast<Demux*>(user);
+    self->frontendInputThreadLoop();
+    return 0;
+}
+
+void Demux::frontendInputThreadLoop() {
+    std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
+    mFrontendInputThreadRunning = true;
+
+    if (!mDvrPlayback) {
+        ALOGW("[Demux] No software Frontend input configured. Ending Frontend thread loop.");
+        mFrontendInputThreadRunning = false;
+        return;
+    }
+
+    while (mFrontendInputThreadRunning) {
+        uint32_t efState = 0;
+        status_t status = mDvrPlayback->getDvrEventFlag()->wait(
+                static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT,
+                true /* retry on spurious wake */);
+        if (status != OK) {
+            ALOGD("[Demux] wait for data ready on the playback FMQ");
+            continue;
+        }
+        if (mDvrPlayback->getSettings().playback().dataFormat == DataFormat::ES) {
+            if (!mDvrPlayback->processEsDataOnPlayback(true /*isVirtualFrontend*/, mIsRecording)) {
+                ALOGE("[Demux] playback es data failed to be filtered. Ending thread");
+                break;
+            }
+        }
+        // Our current implementation filter the data and write it into the filter FMQ immediately
+        // after the DATA_READY from the VTS/framework
+        if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) ||
+            !mDvrPlayback->startFilterDispatcher(true /*isVirtualFrontend*/, mIsRecording)) {
+            ALOGE("[Demux] playback data failed to be filtered. Ending thread");
+            break;
+        }
+    }
+
+    mFrontendInputThreadRunning = false;
+    ALOGW("[Demux] Frontend Input thread end.");
+}
+
+void Demux::stopFrontendInput() {
+    ALOGD("[Demux] stop frontend on demux");
+    mKeepFetchingDataFromFrontend = false;
+    mFrontendInputThreadRunning = false;
+    std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
+}
+
+void Demux::setIsRecording(bool isRecording) {
+    mIsRecording = isRecording;
+}
+
+bool Demux::attachRecordFilter(uint64_t filterId) {
+    if (mFilters[filterId] == nullptr || mDvrRecord == nullptr ||
+        !mFilters[filterId]->isRecordFilter()) {
+        return false;
+    }
+
+    mRecordFilterIds.insert(filterId);
+    mFilters[filterId]->attachFilterToRecord(mDvrRecord);
+
+    return true;
+}
+
+bool Demux::detachRecordFilter(uint64_t filterId) {
+    if (mFilters[filterId] == nullptr || mDvrRecord == nullptr) {
+        return false;
+    }
+
+    mRecordFilterIds.erase(filterId);
+    mFilters[filterId]->detachFilterFromRecord();
+
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.1/default/Demux.h b/tv/tuner/1.1/default/Demux.h
new file mode 100644
index 0000000..f38f006
--- /dev/null
+++ b/tv/tuner/1.1/default/Demux.h
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_
+
+#include <android/hardware/tv/tuner/1.1/IDemux.h>
+#include <fmq/MessageQueue.h>
+#include <math.h>
+#include <set>
+#include "Dvr.h"
+#include "Filter.h"
+#include "Frontend.h"
+#include "TimeFilter.h"
+#include "Tuner.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::EventFlag;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
+
+using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+class Dvr;
+class Filter;
+class Frontend;
+class TimeFilter;
+class Tuner;
+
+class Demux : public V1_1::IDemux {
+  public:
+    Demux(uint32_t demuxId, sp<Tuner> tuner);
+
+    ~Demux();
+
+    virtual Return<void> getAvSyncHwId64Bit(const sp<IFilter>& filter,
+                                            getAvSyncHwId64Bit_cb _hidl_cb) override;
+
+    virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
+
+    virtual Return<void> openFilter(const DemuxFilterType& type, uint32_t bufferSize,
+                                    const sp<IFilterCallback>& cb, openFilter_cb _hidl_cb) override;
+
+    virtual Return<void> openTimeFilter(openTimeFilter_cb _hidl_cb) override;
+
+    virtual Return<void> getAvSyncHwId(const sp<IFilter>& filter,
+                                       getAvSyncHwId_cb _hidl_cb) override;
+
+    virtual Return<void> getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) override;
+
+    virtual Return<Result> close() override;
+
+    virtual Return<void> openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
+                                 openDvr_cb _hidl_cb) override;
+
+    virtual Return<Result> connectCiCam(uint32_t ciCamId) override;
+
+    virtual Return<Result> disconnectCiCam() override;
+
+    // Functions interacts with Tuner Service
+    void stopFrontendInput();
+    Result removeFilter(uint64_t filterId);
+    bool attachRecordFilter(uint64_t filterId);
+    bool detachRecordFilter(uint64_t filterId);
+    Result startFilterHandler(uint64_t filterId);
+    void updateFilterOutput(uint64_t filterId, vector<uint8_t> data);
+    void updateMediaFilterOutput(uint64_t filterId, vector<uint8_t> data, uint64_t pts);
+    uint16_t getFilterTpid(uint64_t filterId);
+    void setIsRecording(bool isRecording);
+    void startFrontendInputLoop();
+
+    /**
+     * A dispatcher to read and dispatch input data to all the started filters.
+     * Each filter handler handles the data filtering/output writing/filterEvent updating.
+     * Note that recording filters are not included.
+     */
+    bool startBroadcastFilterDispatcher();
+    void startBroadcastTsFilter(vector<uint8_t> data);
+
+    void sendFrontendInputToRecord(vector<uint8_t> data);
+    bool startRecordFilterDispatcher();
+
+  private:
+    // Tuner service
+    sp<Tuner> mTunerService;
+
+    // Frontend source
+    sp<Frontend> mFrontend;
+
+    // A struct that passes the arguments to a newly created filter thread
+    struct ThreadArgs {
+        Demux* user;
+        uint64_t filterId;
+    };
+
+    static void* __threadLoopFrontend(void* user);
+    void frontendInputThreadLoop();
+
+    /**
+     * To create a FilterMQ with the next available Filter ID.
+     * Creating Event Flag at the same time.
+     * Add the successfully created/saved FilterMQ into the local list.
+     *
+     * Return false is any of the above processes fails.
+     */
+    void deleteEventFlag();
+    bool readDataFromMQ();
+
+    uint32_t mDemuxId = -1;
+    uint32_t mCiCamId;
+    set<uint64_t> mPcrFilterIds;
+    /**
+     * Record the last used filter id. Initial value is -1.
+     * Filter Id starts with 0.
+     */
+    uint64_t mLastUsedFilterId = -1;
+    /**
+     * Record all the used playback filter Ids.
+     * Any removed filter id should be removed from this set.
+     */
+    set<uint64_t> mPlaybackFilterIds;
+    /**
+     * Record all the attached record filter Ids.
+     * Any removed filter id should be removed from this set.
+     */
+    set<uint64_t> mRecordFilterIds;
+    /**
+     * A list of created Filter sp.
+     * The array number is the filter ID.
+     */
+    std::map<uint64_t, sp<Filter>> mFilters;
+
+    /**
+     * Local reference to the opened Timer Filter instance.
+     */
+    sp<TimeFilter> mTimeFilter;
+
+    /**
+     * Local reference to the opened DVR object.
+     */
+    sp<Dvr> mDvrPlayback;
+    sp<Dvr> mDvrRecord;
+
+    // Thread handlers
+    pthread_t mFrontendInputThread;
+    /**
+     * If a specific filter's writing loop is still running
+     */
+    bool mFrontendInputThreadRunning;
+    bool mKeepFetchingDataFromFrontend;
+    /**
+     * If the dvr recording is running.
+     */
+    bool mIsRecording = false;
+    /**
+     * Lock to protect writes to the FMQs
+     */
+    std::mutex mWriteLock;
+    /**
+     * Lock to protect writes to the input status
+     */
+    std::mutex mFrontendInputThreadLock;
+
+    // temp handle single PES filter
+    // TODO handle mulptiple Pes filters
+    int mPesSizeLeft = 0;
+    vector<uint8_t> mPesOutput;
+
+    const bool DEBUG_DEMUX = false;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_
diff --git a/tv/tuner/1.1/default/Descrambler.cpp b/tv/tuner/1.1/default/Descrambler.cpp
new file mode 100644
index 0000000..1fbc780
--- /dev/null
+++ b/tv/tuner/1.1/default/Descrambler.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.tv.tuner@1.1-Descrambler"
+
+#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
+#include <utils/Log.h>
+
+#include "Descrambler.h"
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+Descrambler::Descrambler() {}
+
+Descrambler::~Descrambler() {}
+
+Return<Result> Descrambler::setDemuxSource(uint32_t demuxId) {
+    ALOGV("%s", __FUNCTION__);
+    if (mDemuxSet) {
+        ALOGW("[   WARN   ] Descrambler has already been set with a demux id %" PRIu32,
+              mSourceDemuxId);
+        return Result::INVALID_STATE;
+    }
+    mDemuxSet = true;
+    mSourceDemuxId = static_cast<uint32_t>(demuxId);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Descrambler::setKeyToken(const hidl_vec<uint8_t>& /* keyToken */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Descrambler::addPid(const DemuxPid& /* pid */,
+                                   const sp<IFilter>& /* optionalSourceFilter */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Descrambler::removePid(const DemuxPid& /* pid */,
+                                      const sp<IFilter>& /* optionalSourceFilter */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Descrambler::close() {
+    ALOGV("%s", __FUNCTION__);
+    mDemuxSet = false;
+
+    return Result::SUCCESS;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.1/default/Descrambler.h b/tv/tuner/1.1/default/Descrambler.h
new file mode 100644
index 0000000..ffc284d
--- /dev/null
+++ b/tv/tuner/1.1/default/Descrambler.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_DESCRAMBLER_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_1_DESCRAMBLER_H_
+
+#include <android/hardware/tv/tuner/1.0/IDescrambler.h>
+#include <android/hardware/tv/tuner/1.1/ITuner.h>
+#include <inttypes.h>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+class Descrambler : public IDescrambler {
+  public:
+    Descrambler();
+
+    virtual Return<Result> setDemuxSource(uint32_t demuxId) override;
+
+    virtual Return<Result> setKeyToken(const hidl_vec<uint8_t>& keyToken) override;
+
+    virtual Return<Result> addPid(const DemuxPid& pid,
+                                  const sp<IFilter>& optionalSourceFilter) override;
+
+    virtual Return<Result> removePid(const DemuxPid& pid,
+                                     const sp<IFilter>& optionalSourceFilter) override;
+
+    virtual Return<Result> close() override;
+
+  private:
+    virtual ~Descrambler();
+    uint32_t mSourceDemuxId;
+    bool mDemuxSet = false;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_DESCRAMBLER_H_
diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp
new file mode 100644
index 0000000..02d6a42
--- /dev/null
+++ b/tv/tuner/1.1/default/Dvr.cpp
@@ -0,0 +1,498 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.tv.tuner@1.1-Dvr"
+
+#include "Dvr.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+#define WAIT_TIMEOUT 3000000000
+
+Dvr::Dvr() {}
+
+Dvr::Dvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb, sp<Demux> demux) {
+    mType = type;
+    mBufferSize = bufferSize;
+    mCallback = cb;
+    mDemux = demux;
+}
+
+Dvr::~Dvr() {}
+
+Return<void> Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    _hidl_cb(Result::SUCCESS, *mDvrMQ->getDesc());
+    return Void();
+}
+
+Return<Result> Dvr::configure(const DvrSettings& settings) {
+    ALOGV("%s", __FUNCTION__);
+
+    mDvrSettings = settings;
+    mDvrConfigured = true;
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Dvr::attachFilter(const sp<V1_0::IFilter>& filter) {
+    ALOGV("%s", __FUNCTION__);
+
+    uint64_t filterId;
+    Result status;
+
+    sp<V1_1::IFilter> filter_v1_1 = V1_1::IFilter::castFrom(filter);
+    if (filter_v1_1 != NULL) {
+        filter_v1_1->getId64Bit([&](Result result, uint64_t id) {
+            filterId = id;
+            status = result;
+        });
+    } else {
+        filter->getId([&](Result result, uint32_t id) {
+            filterId = id;
+            status = result;
+        });
+    }
+
+    if (status != Result::SUCCESS) {
+        return status;
+    }
+
+    // TODO check if the attached filter is a record filter
+    if (!mDemux->attachRecordFilter(filterId)) {
+        return Result::INVALID_ARGUMENT;
+    }
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Dvr::detachFilter(const sp<V1_0::IFilter>& filter) {
+    ALOGV("%s", __FUNCTION__);
+
+    uint64_t filterId;
+    Result status;
+
+    sp<V1_1::IFilter> filter_v1_1 = V1_1::IFilter::castFrom(filter);
+    if (filter_v1_1 != NULL) {
+        filter_v1_1->getId64Bit([&](Result result, uint64_t id) {
+            filterId = id;
+            status = result;
+        });
+    } else {
+        filter->getId([&](Result result, uint32_t id) {
+            filterId = id;
+            status = result;
+        });
+    }
+
+    if (status != Result::SUCCESS) {
+        return status;
+    }
+
+    if (!mDemux->detachRecordFilter(filterId)) {
+        return Result::INVALID_ARGUMENT;
+    }
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Dvr::start() {
+    ALOGV("%s", __FUNCTION__);
+
+    if (!mCallback) {
+        return Result::NOT_INITIALIZED;
+    }
+
+    if (!mDvrConfigured) {
+        return Result::INVALID_STATE;
+    }
+
+    if (mType == DvrType::PLAYBACK) {
+        pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this);
+        pthread_setname_np(mDvrThread, "playback_waiting_loop");
+    } else if (mType == DvrType::RECORD) {
+        mRecordStatus = RecordStatus::DATA_READY;
+        mDemux->setIsRecording(mType == DvrType::RECORD);
+    }
+
+    // TODO start another thread to send filter status callback to the framework
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Dvr::stop() {
+    ALOGV("%s", __FUNCTION__);
+
+    mDvrThreadRunning = false;
+
+    lock_guard<mutex> lock(mDvrThreadLock);
+
+    mIsRecordStarted = false;
+    mDemux->setIsRecording(false);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Dvr::flush() {
+    ALOGV("%s", __FUNCTION__);
+
+    mRecordStatus = RecordStatus::DATA_READY;
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Dvr::close() {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+bool Dvr::createDvrMQ() {
+    ALOGV("%s", __FUNCTION__);
+
+    // Create a synchronized FMQ that supports blocking read/write
+    unique_ptr<DvrMQ> tmpDvrMQ = unique_ptr<DvrMQ>(new (nothrow) DvrMQ(mBufferSize, true));
+    if (!tmpDvrMQ->isValid()) {
+        ALOGW("[Dvr] Failed to create FMQ of DVR");
+        return false;
+    }
+
+    mDvrMQ = move(tmpDvrMQ);
+
+    if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != OK) {
+        return false;
+    }
+
+    return true;
+}
+
+EventFlag* Dvr::getDvrEventFlag() {
+    return mDvrEventFlag;
+}
+
+void* Dvr::__threadLoopPlayback(void* user) {
+    Dvr* const self = static_cast<Dvr*>(user);
+    self->playbackThreadLoop();
+    return 0;
+}
+
+void Dvr::playbackThreadLoop() {
+    ALOGD("[Dvr] playback threadLoop start.");
+    lock_guard<mutex> lock(mDvrThreadLock);
+    mDvrThreadRunning = true;
+
+    while (mDvrThreadRunning) {
+        uint32_t efState = 0;
+        status_t status =
+                mDvrEventFlag->wait(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY),
+                                    &efState, WAIT_TIMEOUT, true /* retry on spurious wake */);
+        if (status != OK) {
+            ALOGD("[Dvr] wait for data ready on the playback FMQ");
+            continue;
+        }
+
+        if (mDvrSettings.playback().dataFormat == DataFormat::ES) {
+            if (!processEsDataOnPlayback(false /*isVirtualFrontend*/, false /*isRecording*/)) {
+                ALOGE("[Dvr] playback es data failed to be filtered. Ending thread");
+                break;
+            }
+            maySendPlaybackStatusCallback();
+        }
+        // Our current implementation filter the data and write it into the filter FMQ immediately
+        // after the DATA_READY from the VTS/framework
+        if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) ||
+            !startFilterDispatcher(false /*isVirtualFrontend*/, false /*isRecording*/)) {
+            ALOGE("[Dvr] playback data failed to be filtered. Ending thread");
+            break;
+        }
+
+        maySendPlaybackStatusCallback();
+    }
+
+    mDvrThreadRunning = false;
+    ALOGD("[Dvr] playback thread ended.");
+}
+
+void Dvr::maySendPlaybackStatusCallback() {
+    lock_guard<mutex> lock(mPlaybackStatusLock);
+    int availableToRead = mDvrMQ->availableToRead();
+    int availableToWrite = mDvrMQ->availableToWrite();
+
+    PlaybackStatus newStatus = checkPlaybackStatusChange(availableToWrite, availableToRead,
+                                                         mDvrSettings.playback().highThreshold,
+                                                         mDvrSettings.playback().lowThreshold);
+    if (mPlaybackStatus != newStatus) {
+        mCallback->onPlaybackStatus(newStatus);
+        mPlaybackStatus = newStatus;
+    }
+}
+
+PlaybackStatus Dvr::checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+                                              uint32_t highThreshold, uint32_t lowThreshold) {
+    if (availableToWrite == 0) {
+        return PlaybackStatus::SPACE_FULL;
+    } else if (availableToRead > highThreshold) {
+        return PlaybackStatus::SPACE_ALMOST_FULL;
+    } else if (availableToRead < lowThreshold) {
+        return PlaybackStatus::SPACE_ALMOST_EMPTY;
+    } else if (availableToRead == 0) {
+        return PlaybackStatus::SPACE_EMPTY;
+    }
+    return mPlaybackStatus;
+}
+
+bool Dvr::readPlaybackFMQ(bool isVirtualFrontend, bool isRecording) {
+    // Read playback data from the input FMQ
+    int size = mDvrMQ->availableToRead();
+    int playbackPacketSize = mDvrSettings.playback().packetSize;
+    vector<uint8_t> dataOutputBuffer;
+    dataOutputBuffer.resize(playbackPacketSize);
+    // Dispatch the packet to the PID matching filter output buffer
+    for (int i = 0; i < size / playbackPacketSize; i++) {
+        if (!mDvrMQ->read(dataOutputBuffer.data(), playbackPacketSize)) {
+            return false;
+        }
+        if (isVirtualFrontend) {
+            if (isRecording) {
+                mDemux->sendFrontendInputToRecord(dataOutputBuffer);
+            } else {
+                mDemux->startBroadcastTsFilter(dataOutputBuffer);
+            }
+        } else {
+            startTpidFilter(dataOutputBuffer);
+        }
+    }
+
+    return true;
+}
+
+bool Dvr::processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording) {
+    // Read ES from the DVR FMQ
+    // Note that currently we only provides ES with metaData in a specific format to be parsed.
+    // The ES size should be smaller than the Playback FMQ size to avoid reading truncated data.
+    int size = mDvrMQ->availableToRead();
+    vector<uint8_t> dataOutputBuffer;
+    dataOutputBuffer.resize(size);
+    if (!mDvrMQ->read(dataOutputBuffer.data(), size)) {
+        return false;
+    }
+
+    int metaDataSize = size;
+    int totalFrames = 0;
+    int videoEsDataSize = 0;
+    int audioEsDataSize = 0;
+    int audioPid = 0;
+    int videoPid = 0;
+
+    vector<MediaEsMetaData> esMeta;
+    int videoReadPointer = 0;
+    int audioReadPointer = 0;
+    int frameCount = 0;
+    // Get meta data from the es
+    for (int i = 0; i < metaDataSize; i++) {
+        switch (dataOutputBuffer[i]) {
+            case 'm':
+                metaDataSize = 0;
+                getMetaDataValue(i, dataOutputBuffer.data(), metaDataSize);
+                videoReadPointer = metaDataSize;
+                continue;
+            case 'l':
+                getMetaDataValue(i, dataOutputBuffer.data(), totalFrames);
+                esMeta.resize(totalFrames);
+                continue;
+            case 'V':
+                getMetaDataValue(i, dataOutputBuffer.data(), videoEsDataSize);
+                audioReadPointer = metaDataSize + videoEsDataSize;
+                continue;
+            case 'A':
+                getMetaDataValue(i, dataOutputBuffer.data(), audioEsDataSize);
+                continue;
+            case 'p':
+                if (dataOutputBuffer[++i] == 'a') {
+                    getMetaDataValue(i, dataOutputBuffer.data(), audioPid);
+                } else if (dataOutputBuffer[i] == 'v') {
+                    getMetaDataValue(i, dataOutputBuffer.data(), videoPid);
+                }
+                continue;
+            case 'v':
+            case 'a':
+                if (dataOutputBuffer[i + 1] != ',') {
+                    ALOGE("[Dvr] Invalid format meta data.");
+                    return false;
+                }
+                esMeta[frameCount] = {
+                        .isAudio = dataOutputBuffer[i] == 'a' ? true : false,
+                };
+                i += 5;  // Move to Len
+                getMetaDataValue(i, dataOutputBuffer.data(), esMeta[frameCount].len);
+                if (esMeta[frameCount].isAudio) {
+                    esMeta[frameCount].startIndex = audioReadPointer;
+                    audioReadPointer += esMeta[frameCount].len;
+                } else {
+                    esMeta[frameCount].startIndex = videoReadPointer;
+                    videoReadPointer += esMeta[frameCount].len;
+                }
+                i += 4;  // move to PTS
+                getMetaDataValue(i, dataOutputBuffer.data(), esMeta[frameCount].pts);
+                frameCount++;
+                continue;
+            default:
+                continue;
+        }
+    }
+
+    if (frameCount != totalFrames) {
+        ALOGE("[Dvr] Invalid meta data, frameCount=%d, totalFrames reported=%d", frameCount,
+              totalFrames);
+        return false;
+    }
+
+    if (metaDataSize + audioEsDataSize + videoEsDataSize != size) {
+        ALOGE("[Dvr] Invalid meta data, metaSize=%d, videoSize=%d, audioSize=%d, totolSize=%d",
+              metaDataSize, videoEsDataSize, audioEsDataSize, size);
+        return false;
+    }
+
+    // Read es raw data from the FMQ per meta data built previously
+    vector<uint8_t> frameData;
+    map<uint64_t, sp<IFilter>>::iterator it;
+    int pid = 0;
+    for (int i = 0; i < totalFrames; i++) {
+        frameData.resize(esMeta[i].len);
+        pid = esMeta[i].isAudio ? audioPid : videoPid;
+        memcpy(dataOutputBuffer.data() + esMeta[i].startIndex, frameData.data(), esMeta[i].len);
+        // Send to the media filter
+        if (isVirtualFrontend && isRecording) {
+            // TODO validate record
+            mDemux->sendFrontendInputToRecord(frameData);
+        } else {
+            for (it = mFilters.begin(); it != mFilters.end(); it++) {
+                if (pid == mDemux->getFilterTpid(it->first)) {
+                    mDemux->updateMediaFilterOutput(it->first, frameData,
+                                                    static_cast<uint64_t>(esMeta[i].pts));
+                    startFilterDispatcher(isVirtualFrontend, isRecording);
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+void Dvr::getMetaDataValue(int& index, uint8_t* dataOutputBuffer, int& value) {
+    index += 2;  // Move the pointer across the ":" to the value
+    while (dataOutputBuffer[index] != ',' && dataOutputBuffer[index] != '\n') {
+        value = ((dataOutputBuffer[index++] - 48) + value * 10);
+    }
+}
+
+void Dvr::startTpidFilter(vector<uint8_t> data) {
+    map<uint64_t, sp<IFilter>>::iterator it;
+    for (it = mFilters.begin(); it != mFilters.end(); it++) {
+        uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff));
+        if (DEBUG_DVR) {
+            ALOGW("[Dvr] start ts filter pid: %d", pid);
+        }
+        if (pid == mDemux->getFilterTpid(it->first)) {
+            mDemux->updateFilterOutput(it->first, data);
+        }
+    }
+}
+
+bool Dvr::startFilterDispatcher(bool isVirtualFrontend, bool isRecording) {
+    if (isVirtualFrontend) {
+        if (isRecording) {
+            return mDemux->startRecordFilterDispatcher();
+        } else {
+            return mDemux->startBroadcastFilterDispatcher();
+        }
+    }
+
+    map<uint64_t, sp<IFilter>>::iterator it;
+    // Handle the output data per filter type
+    for (it = mFilters.begin(); it != mFilters.end(); it++) {
+        if (mDemux->startFilterHandler(it->first) != Result::SUCCESS) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool Dvr::writeRecordFMQ(const vector<uint8_t>& data) {
+    lock_guard<mutex> lock(mWriteLock);
+    if (mRecordStatus == RecordStatus::OVERFLOW) {
+        ALOGW("[Dvr] stops writing and wait for the client side flushing.");
+        return true;
+    }
+    if (mDvrMQ->write(data.data(), data.size())) {
+        mDvrEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+        maySendRecordStatusCallback();
+        return true;
+    }
+
+    maySendRecordStatusCallback();
+    return false;
+}
+
+void Dvr::maySendRecordStatusCallback() {
+    lock_guard<mutex> lock(mRecordStatusLock);
+    int availableToRead = mDvrMQ->availableToRead();
+    int availableToWrite = mDvrMQ->availableToWrite();
+
+    RecordStatus newStatus = checkRecordStatusChange(availableToWrite, availableToRead,
+                                                     mDvrSettings.record().highThreshold,
+                                                     mDvrSettings.record().lowThreshold);
+    if (mRecordStatus != newStatus) {
+        mCallback->onRecordStatus(newStatus);
+        mRecordStatus = newStatus;
+    }
+}
+
+RecordStatus Dvr::checkRecordStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+                                          uint32_t highThreshold, uint32_t lowThreshold) {
+    if (availableToWrite == 0) {
+        return DemuxFilterStatus::OVERFLOW;
+    } else if (availableToRead > highThreshold) {
+        return DemuxFilterStatus::HIGH_WATER;
+    } else if (availableToRead < lowThreshold) {
+        return DemuxFilterStatus::LOW_WATER;
+    }
+    return mRecordStatus;
+}
+
+bool Dvr::addPlaybackFilter(uint64_t filterId, sp<IFilter> filter) {
+    mFilters[filterId] = filter;
+    return true;
+}
+
+bool Dvr::removePlaybackFilter(uint64_t filterId) {
+    mFilters.erase(filterId);
+    return true;
+}
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.1/default/Dvr.h b/tv/tuner/1.1/default/Dvr.h
new file mode 100644
index 0000000..7b7efef
--- /dev/null
+++ b/tv/tuner/1.1/default/Dvr.h
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_DVR_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_1_DVR_H_
+
+#include <fmq/MessageQueue.h>
+#include <math.h>
+#include <set>
+#include "Demux.h"
+#include "Frontend.h"
+#include "Tuner.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::EventFlag;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
+
+using DvrMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+struct MediaEsMetaData {
+    bool isAudio;
+    int startIndex;
+    int len;
+    int pts;
+};
+
+class Demux;
+class Filter;
+class Frontend;
+class Tuner;
+
+class Dvr : public IDvr {
+  public:
+    Dvr();
+
+    Dvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb, sp<Demux> demux);
+
+    ~Dvr();
+
+    virtual Return<void> getQueueDesc(getQueueDesc_cb _hidl_cb) override;
+
+    virtual Return<Result> configure(const DvrSettings& settings) override;
+
+    virtual Return<Result> attachFilter(const sp<IFilter>& filter) override;
+
+    virtual Return<Result> detachFilter(const sp<IFilter>& filter) override;
+
+    virtual Return<Result> start() override;
+
+    virtual Return<Result> stop() override;
+
+    virtual Return<Result> flush() override;
+
+    virtual Return<Result> close() override;
+
+    /**
+     * To create a DvrMQ and its Event Flag.
+     *
+     * Return false is any of the above processes fails.
+     */
+    bool createDvrMQ();
+    void sendBroadcastInputToDvrRecord(vector<uint8_t> byteBuffer);
+    bool writeRecordFMQ(const std::vector<uint8_t>& data);
+    bool addPlaybackFilter(uint64_t filterId, sp<IFilter> filter);
+    bool removePlaybackFilter(uint64_t filterId);
+    bool readPlaybackFMQ(bool isVirtualFrontend, bool isRecording);
+    bool processEsDataOnPlayback(bool isVirtualFrontend, bool isRecording);
+    bool startFilterDispatcher(bool isVirtualFrontend, bool isRecording);
+    EventFlag* getDvrEventFlag();
+    DvrSettings getSettings() { return mDvrSettings; }
+
+  private:
+    // Demux service
+    sp<Demux> mDemux;
+
+    DvrType mType;
+    uint32_t mBufferSize;
+    sp<IDvrCallback> mCallback;
+    std::map<uint64_t, sp<IFilter>> mFilters;
+
+    void deleteEventFlag();
+    bool readDataFromMQ();
+    void getMetaDataValue(int& index, uint8_t* dataOutputBuffer, int& value);
+    void maySendPlaybackStatusCallback();
+    void maySendRecordStatusCallback();
+    PlaybackStatus checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+                                             uint32_t highThreshold, uint32_t lowThreshold);
+    RecordStatus checkRecordStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+                                         uint32_t highThreshold, uint32_t lowThreshold);
+    /**
+     * A dispatcher to read and dispatch input data to all the started filters.
+     * Each filter handler handles the data filtering/output writing/filterEvent updating.
+     */
+    void startTpidFilter(vector<uint8_t> data);
+    static void* __threadLoopPlayback(void* user);
+    static void* __threadLoopRecord(void* user);
+    void playbackThreadLoop();
+    void recordThreadLoop();
+
+    unique_ptr<DvrMQ> mDvrMQ;
+    EventFlag* mDvrEventFlag;
+    /**
+     * Demux callbacks used on filter events or IO buffer status
+     */
+    bool mDvrConfigured = false;
+    DvrSettings mDvrSettings;
+
+    // Thread handlers
+    pthread_t mDvrThread;
+
+    // FMQ status local records
+    PlaybackStatus mPlaybackStatus;
+    RecordStatus mRecordStatus;
+    /**
+     * If a specific filter's writing loop is still running
+     */
+    bool mDvrThreadRunning;
+    bool mKeepFetchingDataFromFrontend;
+    /**
+     * Lock to protect writes to the FMQs
+     */
+    std::mutex mWriteLock;
+    /**
+     * Lock to protect writes to the input status
+     */
+    std::mutex mPlaybackStatusLock;
+    std::mutex mRecordStatusLock;
+    std::mutex mDvrThreadLock;
+
+    const bool DEBUG_DVR = false;
+
+    // Booleans to check if recording is running.
+    // Recording is ready when both of the following are set to true.
+    bool mIsRecordStarted = false;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_1_DVR_H_
\ No newline at end of file
diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
new file mode 100644
index 0000000..108baf7
--- /dev/null
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -0,0 +1,672 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.tv.tuner@1.1-Filter"
+
+#include "Filter.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+#define WAIT_TIMEOUT 3000000000
+
+Filter::Filter() {}
+
+Filter::Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize,
+               const sp<IFilterCallback>& cb, sp<Demux> demux) {
+    mType = type;
+    mFilterId = filterId;
+    mBufferSize = bufferSize;
+    mCallback = cb;
+    mDemux = demux;
+
+    switch (mType.mainType) {
+        case DemuxFilterMainType::TS:
+            if (mType.subType.tsFilterType() == DemuxTsFilterType::AUDIO ||
+                mType.subType.tsFilterType() == DemuxTsFilterType::VIDEO) {
+                mIsMediaFilter = true;
+            }
+            if (mType.subType.tsFilterType() == DemuxTsFilterType::PCR) {
+                mIsPcrFilter = true;
+            }
+            if (mType.subType.tsFilterType() == DemuxTsFilterType::RECORD) {
+                mIsRecordFilter = true;
+            }
+            break;
+        case DemuxFilterMainType::MMTP:
+            if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO ||
+                mType.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) {
+                mIsMediaFilter = true;
+            }
+            if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::RECORD) {
+                mIsRecordFilter = true;
+            }
+            break;
+        case DemuxFilterMainType::IP:
+            break;
+        case DemuxFilterMainType::TLV:
+            break;
+        case DemuxFilterMainType::ALP:
+            break;
+        default:
+            break;
+    }
+}
+
+Filter::~Filter() {}
+
+Return<void> Filter::getId64Bit(getId64Bit_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    _hidl_cb(Result::SUCCESS, mFilterId);
+    return Void();
+}
+
+Return<void> Filter::getId(getId_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    _hidl_cb(Result::SUCCESS, static_cast<uint32_t>(mFilterId));
+    return Void();
+}
+
+Return<Result> Filter::setDataSource(const sp<V1_0::IFilter>& filter) {
+    ALOGV("%s", __FUNCTION__);
+
+    mDataSource = filter;
+    mIsDataSourceDemux = false;
+
+    return Result::SUCCESS;
+}
+
+Return<void> Filter::getQueueDesc(getQueueDesc_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    mIsUsingFMQ = true;
+
+    _hidl_cb(Result::SUCCESS, *mFilterMQ->getDesc());
+    return Void();
+}
+
+Return<Result> Filter::configure(const DemuxFilterSettings& settings) {
+    ALOGV("%s", __FUNCTION__);
+
+    mFilterSettings = settings;
+    switch (mType.mainType) {
+        case DemuxFilterMainType::TS:
+            mTpid = settings.ts().tpid;
+            break;
+        case DemuxFilterMainType::MMTP:
+            break;
+        case DemuxFilterMainType::IP:
+            break;
+        case DemuxFilterMainType::TLV:
+            break;
+        case DemuxFilterMainType::ALP:
+            break;
+        default:
+            break;
+    }
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Filter::start() {
+    ALOGV("%s", __FUNCTION__);
+
+    return startFilterLoop();
+}
+
+Return<Result> Filter::stop() {
+    ALOGV("%s", __FUNCTION__);
+
+    mFilterThreadRunning = false;
+
+    std::lock_guard<std::mutex> lock(mFilterThreadLock);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Filter::flush() {
+    ALOGV("%s", __FUNCTION__);
+
+    // temp implementation to flush the FMQ
+    int size = mFilterMQ->availableToRead();
+    char* buffer = new char[size];
+    mFilterMQ->read((unsigned char*)&buffer[0], size);
+    delete[] buffer;
+    mFilterStatus = DemuxFilterStatus::DATA_READY;
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Filter::releaseAvHandle(const hidl_handle& /*avMemory*/, uint64_t avDataId) {
+    ALOGV("%s", __FUNCTION__);
+    if (mDataId2Avfd.find(avDataId) == mDataId2Avfd.end()) {
+        return Result::INVALID_ARGUMENT;
+    }
+
+    ::close(mDataId2Avfd[avDataId]);
+    return Result::SUCCESS;
+}
+
+Return<Result> Filter::close() {
+    ALOGV("%s", __FUNCTION__);
+
+    return mDemux->removeFilter(mFilterId);
+}
+
+bool Filter::createFilterMQ() {
+    ALOGV("%s", __FUNCTION__);
+
+    // Create a synchronized FMQ that supports blocking read/write
+    std::unique_ptr<FilterMQ> tmpFilterMQ =
+            std::unique_ptr<FilterMQ>(new (std::nothrow) FilterMQ(mBufferSize, true));
+    if (!tmpFilterMQ->isValid()) {
+        ALOGW("[Filter] Failed to create FMQ of filter with id: %" PRIu64, mFilterId);
+        return false;
+    }
+
+    mFilterMQ = std::move(tmpFilterMQ);
+
+    if (EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterEventFlag) != OK) {
+        return false;
+    }
+
+    return true;
+}
+
+Result Filter::startFilterLoop() {
+    pthread_create(&mFilterThread, NULL, __threadLoopFilter, this);
+    pthread_setname_np(mFilterThread, "filter_waiting_loop");
+
+    return Result::SUCCESS;
+}
+
+void* Filter::__threadLoopFilter(void* user) {
+    Filter* const self = static_cast<Filter*>(user);
+    self->filterThreadLoop();
+    return 0;
+}
+
+void Filter::filterThreadLoop() {
+    ALOGD("[Filter] filter %" PRIu64 " threadLoop start.", mFilterId);
+    std::lock_guard<std::mutex> lock(mFilterThreadLock);
+    mFilterThreadRunning = true;
+
+    // For the first time of filter output, implementation needs to send the filter
+    // Event Callback without waiting for the DATA_CONSUMED to init the process.
+    while (mFilterThreadRunning) {
+        if (mFilterEvent.events.size() == 0) {
+            if (DEBUG_FILTER) {
+                ALOGD("[Filter] wait for filter data output.");
+            }
+            usleep(1000 * 1000);
+            continue;
+        }
+        // After successfully write, send a callback and wait for the read to be done
+        mCallback->onFilterEvent(mFilterEvent);
+        freeAvHandle();
+        mFilterEvent.events.resize(0);
+        mFilterStatus = DemuxFilterStatus::DATA_READY;
+        if (mCallback == nullptr) {
+            ALOGD("[Filter] filter %" PRIu64 " does not hava callback. Ending thread", mFilterId);
+            break;
+        }
+        mCallback->onFilterStatus(mFilterStatus);
+        break;
+    }
+
+    while (mFilterThreadRunning) {
+        uint32_t efState = 0;
+        // We do not wait for the last round of written data to be read to finish the thread
+        // because the VTS can verify the reading itself.
+        for (int i = 0; i < SECTION_WRITE_COUNT; i++) {
+            while (mFilterThreadRunning && mIsUsingFMQ) {
+                status_t status = mFilterEventFlag->wait(
+                        static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED), &efState,
+                        WAIT_TIMEOUT, true /* retry on spurious wake */);
+                if (status != OK) {
+                    ALOGD("[Filter] wait for data consumed");
+                    continue;
+                }
+                break;
+            }
+
+            maySendFilterStatusCallback();
+
+            while (mFilterThreadRunning) {
+                std::lock_guard<std::mutex> lock(mFilterEventLock);
+                if (mFilterEvent.events.size() == 0) {
+                    continue;
+                }
+                // After successfully write, send a callback and wait for the read to be done
+                mCallback->onFilterEvent(mFilterEvent);
+                mFilterEvent.events.resize(0);
+                break;
+            }
+            // We do not wait for the last read to be done
+            // VTS can verify the read result itself.
+            if (i == SECTION_WRITE_COUNT - 1) {
+                ALOGD("[Filter] filter %" PRIu64 " writing done. Ending thread", mFilterId);
+                break;
+            }
+        }
+        mFilterThreadRunning = false;
+    }
+
+    ALOGD("[Filter] filter thread ended.");
+}
+
+void Filter::freeAvHandle() {
+    if (!mIsMediaFilter) {
+        return;
+    }
+    for (int i = 0; i < mFilterEvent.events.size(); i++) {
+        ::close(mFilterEvent.events[i].media().avMemory.getNativeHandle()->data[0]);
+        native_handle_close(mFilterEvent.events[i].media().avMemory.getNativeHandle());
+    }
+}
+
+void Filter::maySendFilterStatusCallback() {
+    if (!mIsUsingFMQ) {
+        return;
+    }
+    std::lock_guard<std::mutex> lock(mFilterStatusLock);
+    int availableToRead = mFilterMQ->availableToRead();
+    int availableToWrite = mFilterMQ->availableToWrite();
+    int fmqSize = mFilterMQ->getQuantumCount();
+
+    DemuxFilterStatus newStatus = checkFilterStatusChange(
+            availableToWrite, availableToRead, ceil(fmqSize * 0.75), ceil(fmqSize * 0.25));
+    if (mFilterStatus != newStatus) {
+        mCallback->onFilterStatus(newStatus);
+        mFilterStatus = newStatus;
+    }
+}
+
+DemuxFilterStatus Filter::checkFilterStatusChange(uint32_t availableToWrite,
+                                                  uint32_t availableToRead, uint32_t highThreshold,
+                                                  uint32_t lowThreshold) {
+    if (availableToWrite == 0) {
+        return DemuxFilterStatus::OVERFLOW;
+    } else if (availableToRead > highThreshold) {
+        return DemuxFilterStatus::HIGH_WATER;
+    } else if (availableToRead < lowThreshold) {
+        return DemuxFilterStatus::LOW_WATER;
+    }
+    return mFilterStatus;
+}
+
+uint16_t Filter::getTpid() {
+    return mTpid;
+}
+
+void Filter::updateFilterOutput(vector<uint8_t> data) {
+    std::lock_guard<std::mutex> lock(mFilterOutputLock);
+    mFilterOutput.insert(mFilterOutput.end(), data.begin(), data.end());
+}
+
+void Filter::updatePts(uint64_t pts) {
+    std::lock_guard<std::mutex> lock(mFilterOutputLock);
+    mPts = pts;
+}
+
+void Filter::updateRecordOutput(vector<uint8_t> data) {
+    std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
+    mRecordFilterOutput.insert(mRecordFilterOutput.end(), data.begin(), data.end());
+}
+
+Result Filter::startFilterHandler() {
+    std::lock_guard<std::mutex> lock(mFilterOutputLock);
+    switch (mType.mainType) {
+        case DemuxFilterMainType::TS:
+            switch (mType.subType.tsFilterType()) {
+                case DemuxTsFilterType::UNDEFINED:
+                    break;
+                case DemuxTsFilterType::SECTION:
+                    startSectionFilterHandler();
+                    break;
+                case DemuxTsFilterType::PES:
+                    startPesFilterHandler();
+                    break;
+                case DemuxTsFilterType::TS:
+                    startTsFilterHandler();
+                    break;
+                case DemuxTsFilterType::AUDIO:
+                case DemuxTsFilterType::VIDEO:
+                    startMediaFilterHandler();
+                    break;
+                case DemuxTsFilterType::PCR:
+                    startPcrFilterHandler();
+                    break;
+                case DemuxTsFilterType::TEMI:
+                    startTemiFilterHandler();
+                    break;
+                default:
+                    break;
+            }
+            break;
+        case DemuxFilterMainType::MMTP:
+            /*mmtpSettings*/
+            break;
+        case DemuxFilterMainType::IP:
+            /*ipSettings*/
+            break;
+        case DemuxFilterMainType::TLV:
+            /*tlvSettings*/
+            break;
+        case DemuxFilterMainType::ALP:
+            /*alpSettings*/
+            break;
+        default:
+            break;
+    }
+    return Result::SUCCESS;
+}
+
+Result Filter::startSectionFilterHandler() {
+    if (mFilterOutput.empty()) {
+        return Result::SUCCESS;
+    }
+    if (!writeSectionsAndCreateEvent(mFilterOutput)) {
+        ALOGD("[Filter] filter %" PRIu64 " fails to write into FMQ. Ending thread", mFilterId);
+        return Result::UNKNOWN_ERROR;
+    }
+
+    mFilterOutput.clear();
+
+    return Result::SUCCESS;
+}
+
+Result Filter::startPesFilterHandler() {
+    std::lock_guard<std::mutex> lock(mFilterEventLock);
+    if (mFilterOutput.empty()) {
+        return Result::SUCCESS;
+    }
+
+    for (int i = 0; i < mFilterOutput.size(); i += 188) {
+        if (mPesSizeLeft == 0) {
+            uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) |
+                              mFilterOutput[i + 6];
+            if (DEBUG_FILTER) {
+                ALOGD("[Filter] prefix %d", prefix);
+            }
+            if (prefix == 0x000001) {
+                // TODO handle mulptiple Pes filters
+                mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
+                mPesSizeLeft += 6;
+                if (DEBUG_FILTER) {
+                    ALOGD("[Filter] pes data length %d", mPesSizeLeft);
+                }
+            } else {
+                continue;
+            }
+        }
+
+        int endPoint = min(184, mPesSizeLeft);
+        // append data and check size
+        vector<uint8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
+        vector<uint8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
+        mPesOutput.insert(mPesOutput.end(), first, last);
+        // size does not match then continue
+        mPesSizeLeft -= endPoint;
+        if (DEBUG_FILTER) {
+            ALOGD("[Filter] pes data left %d", mPesSizeLeft);
+        }
+        if (mPesSizeLeft > 0) {
+            continue;
+        }
+        // size match then create event
+        if (!writeDataToFilterMQ(mPesOutput)) {
+            ALOGD("[Filter] pes data write failed");
+            mFilterOutput.clear();
+            return Result::INVALID_STATE;
+        }
+        maySendFilterStatusCallback();
+        DemuxFilterPesEvent pesEvent;
+        pesEvent = {
+                // temp dump meta data
+                .streamId = mPesOutput[3],
+                .dataLength = static_cast<uint16_t>(mPesOutput.size()),
+        };
+        if (DEBUG_FILTER) {
+            ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
+        }
+
+        int size = mFilterEvent.events.size();
+        mFilterEvent.events.resize(size + 1);
+        mFilterEvent.events[size].pes(pesEvent);
+        mPesOutput.clear();
+    }
+
+    mFilterOutput.clear();
+
+    return Result::SUCCESS;
+}
+
+Result Filter::startTsFilterHandler() {
+    // TODO handle starting TS filter
+    return Result::SUCCESS;
+}
+
+Result Filter::startMediaFilterHandler() {
+    std::lock_guard<std::mutex> lock(mFilterEventLock);
+    if (mFilterOutput.empty()) {
+        return Result::SUCCESS;
+    }
+
+    if (mPts) {
+        return createMediaFilterEventWithIon(mFilterOutput);
+    }
+
+    for (int i = 0; i < mFilterOutput.size(); i += 188) {
+        if (mPesSizeLeft == 0) {
+            uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) |
+                              mFilterOutput[i + 6];
+            if (DEBUG_FILTER) {
+                ALOGD("[Filter] prefix %d", prefix);
+            }
+            if (prefix == 0x000001) {
+                // TODO handle mulptiple Pes filters
+                mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
+                mPesSizeLeft += 6;
+                if (DEBUG_FILTER) {
+                    ALOGD("[Filter] pes data length %d", mPesSizeLeft);
+                }
+            } else {
+                continue;
+            }
+        }
+
+        int endPoint = min(184, mPesSizeLeft);
+        // append data and check size
+        vector<uint8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
+        vector<uint8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
+        mPesOutput.insert(mPesOutput.end(), first, last);
+        // size does not match then continue
+        mPesSizeLeft -= endPoint;
+        if (DEBUG_FILTER) {
+            ALOGD("[Filter] pes data left %d", mPesSizeLeft);
+        }
+        if (mPesSizeLeft > 0 || mAvBufferCopyCount++ < 10) {
+            continue;
+        }
+
+        createMediaFilterEventWithIon(mPesOutput);
+    }
+
+    mFilterOutput.clear();
+
+    return Result::SUCCESS;
+}
+
+Result Filter::createMediaFilterEventWithIon(vector<uint8_t> output) {
+    int av_fd = createAvIonFd(output.size());
+    if (av_fd == -1) {
+        return Result::UNKNOWN_ERROR;
+    }
+    // copy the filtered data to the buffer
+    uint8_t* avBuffer = getIonBuffer(av_fd, output.size());
+    if (avBuffer == NULL) {
+        return Result::UNKNOWN_ERROR;
+    }
+    memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t));
+
+    native_handle_t* nativeHandle = createNativeHandle(av_fd);
+    if (nativeHandle == NULL) {
+        return Result::UNKNOWN_ERROR;
+    }
+    hidl_handle handle;
+    handle.setTo(nativeHandle, /*shouldOwn=*/true);
+
+    // Create a dataId and add a <dataId, av_fd> pair into the dataId2Avfd map
+    uint64_t dataId = mLastUsedDataId++ /*createdUID*/;
+    mDataId2Avfd[dataId] = dup(av_fd);
+
+    // Create mediaEvent and send callback
+    DemuxFilterMediaEvent mediaEvent;
+    mediaEvent = {
+            .avMemory = std::move(handle),
+            .dataLength = static_cast<uint32_t>(output.size()),
+            .avDataId = dataId,
+    };
+    if (mPts) {
+        mediaEvent.pts = mPts;
+        mPts = 0;
+    }
+    int size = mFilterEvent.events.size();
+    mFilterEvent.events.resize(size + 1);
+    mFilterEvent.events[size].media(mediaEvent);
+
+    // Clear and log
+    output.clear();
+    mAvBufferCopyCount = 0;
+    ::close(av_fd);
+    if (DEBUG_FILTER) {
+        ALOGD("[Filter] av data length %d", mediaEvent.dataLength);
+    }
+    return Result::SUCCESS;
+}
+
+Result Filter::startRecordFilterHandler() {
+    std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
+    if (mRecordFilterOutput.empty()) {
+        return Result::SUCCESS;
+    }
+
+    if (mDvr == nullptr || !mDvr->writeRecordFMQ(mRecordFilterOutput)) {
+        ALOGD("[Filter] dvr fails to write into record FMQ.");
+        return Result::UNKNOWN_ERROR;
+    }
+
+    mRecordFilterOutput.clear();
+    return Result::SUCCESS;
+}
+
+Result Filter::startPcrFilterHandler() {
+    // TODO handle starting PCR filter
+    return Result::SUCCESS;
+}
+
+Result Filter::startTemiFilterHandler() {
+    // TODO handle starting TEMI filter
+    return Result::SUCCESS;
+}
+
+bool Filter::writeSectionsAndCreateEvent(vector<uint8_t> data) {
+    // TODO check how many sections has been read
+    ALOGD("[Filter] section handler");
+    std::lock_guard<std::mutex> lock(mFilterEventLock);
+    if (!writeDataToFilterMQ(data)) {
+        return false;
+    }
+    int size = mFilterEvent.events.size();
+    mFilterEvent.events.resize(size + 1);
+    DemuxFilterSectionEvent secEvent;
+    secEvent = {
+            // temp dump meta data
+            .tableId = 0,
+            .version = 1,
+            .sectionNum = 1,
+            .dataLength = static_cast<uint16_t>(data.size()),
+    };
+    mFilterEvent.events[size].section(secEvent);
+    return true;
+}
+
+bool Filter::writeDataToFilterMQ(const std::vector<uint8_t>& data) {
+    std::lock_guard<std::mutex> lock(mWriteLock);
+    if (mFilterMQ->write(data.data(), data.size())) {
+        return true;
+    }
+    return false;
+}
+
+void Filter::attachFilterToRecord(const sp<Dvr> dvr) {
+    mDvr = dvr;
+}
+
+void Filter::detachFilterFromRecord() {
+    mDvr = nullptr;
+}
+
+int Filter::createAvIonFd(int size) {
+    // Create an ion fd and allocate an av fd mapped to a buffer to it.
+    int ion_fd = ion_open();
+    if (ion_fd == -1) {
+        ALOGE("[Filter] Failed to open ion fd %d", errno);
+        return -1;
+    }
+    int av_fd = -1;
+    ion_alloc_fd(dup(ion_fd), size, 0 /*align*/, ION_HEAP_SYSTEM_MASK, 0 /*flags*/, &av_fd);
+    if (av_fd == -1) {
+        ALOGE("[Filter] Failed to create av fd %d", errno);
+        return -1;
+    }
+    return av_fd;
+}
+
+uint8_t* Filter::getIonBuffer(int fd, int size) {
+    uint8_t* avBuf = static_cast<uint8_t*>(
+            mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 /*offset*/));
+    if (avBuf == MAP_FAILED) {
+        ALOGE("[Filter] fail to allocate buffer %d", errno);
+        return NULL;
+    }
+    return avBuf;
+}
+
+native_handle_t* Filter::createNativeHandle(int fd) {
+    // Create a native handle to pass the av fd via the callback event.
+    native_handle_t* nativeHandle = native_handle_create(/*numFd*/ 1, 0);
+    if (nativeHandle == NULL) {
+        ALOGE("[Filter] Failed to create native_handle %d", errno);
+        return NULL;
+    }
+    nativeHandle->data[0] = dup(fd);
+    return nativeHandle;
+}
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h
new file mode 100644
index 0000000..d5801d4
--- /dev/null
+++ b/tv/tuner/1.1/default/Filter.h
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_FILTER_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_1_FILTER_H_
+
+#include <android/hardware/tv/tuner/1.1/IFilter.h>
+#include <fmq/MessageQueue.h>
+#include <inttypes.h>
+#include <ion/ion.h>
+#include <math.h>
+#include <set>
+#include "Demux.h"
+#include "Dvr.h"
+#include "Frontend.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::EventFlag;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
+
+using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+class Demux;
+class Dvr;
+
+class Filter : public V1_1::IFilter {
+  public:
+    Filter();
+
+    Filter(DemuxFilterType type, uint64_t filterId, uint32_t bufferSize,
+           const sp<IFilterCallback>& cb, sp<Demux> demux);
+
+    ~Filter();
+
+    virtual Return<void> getId64Bit(getId64Bit_cb _hidl_cb) override;
+
+    virtual Return<void> getId(getId_cb _hidl_cb) override;
+
+    virtual Return<Result> setDataSource(const sp<V1_0::IFilter>& filter) override;
+
+    virtual Return<void> getQueueDesc(getQueueDesc_cb _hidl_cb) override;
+
+    virtual Return<Result> configure(const DemuxFilterSettings& settings) override;
+
+    virtual Return<Result> start() override;
+
+    virtual Return<Result> stop() override;
+
+    virtual Return<Result> flush() override;
+
+    virtual Return<Result> releaseAvHandle(const hidl_handle& avMemory, uint64_t avDataId) override;
+
+    virtual Return<Result> close() override;
+
+    /**
+     * To create a FilterMQ and its Event Flag.
+     *
+     * Return false is any of the above processes fails.
+     */
+    bool createFilterMQ();
+    uint16_t getTpid();
+    void updateFilterOutput(vector<uint8_t> data);
+    void updateRecordOutput(vector<uint8_t> data);
+    void updatePts(uint64_t pts);
+    Result startFilterHandler();
+    Result startRecordFilterHandler();
+    void attachFilterToRecord(const sp<Dvr> dvr);
+    void detachFilterFromRecord();
+    void freeAvHandle();
+    bool isMediaFilter() { return mIsMediaFilter; };
+    bool isPcrFilter() { return mIsPcrFilter; };
+    bool isRecordFilter() { return mIsRecordFilter; };
+
+  private:
+    // Tuner service
+    sp<Demux> mDemux;
+    // Dvr reference once the filter is attached to any
+    sp<Dvr> mDvr = nullptr;
+    /**
+     * Filter callbacks used on filter events or FMQ status
+     */
+    sp<IFilterCallback> mCallback;
+
+    uint64_t mFilterId;
+    uint32_t mBufferSize;
+    DemuxFilterType mType;
+    bool mIsMediaFilter = false;
+    bool mIsPcrFilter = false;
+    bool mIsRecordFilter = false;
+    DemuxFilterSettings mFilterSettings;
+
+    uint16_t mTpid;
+    sp<V1_0::IFilter> mDataSource;
+    bool mIsDataSourceDemux = true;
+    vector<uint8_t> mFilterOutput;
+    vector<uint8_t> mRecordFilterOutput;
+    uint64_t mPts = 0;
+    unique_ptr<FilterMQ> mFilterMQ;
+    bool mIsUsingFMQ = false;
+    EventFlag* mFilterEventFlag;
+    DemuxFilterEvent mFilterEvent;
+
+    // Thread handlers
+    pthread_t mFilterThread;
+
+    // FMQ status local records
+    DemuxFilterStatus mFilterStatus;
+    /**
+     * If a specific filter's writing loop is still running
+     */
+    bool mFilterThreadRunning;
+    bool mKeepFetchingDataFromFrontend;
+
+    /**
+     * How many times a filter should write
+     * TODO make this dynamic/random/can take as a parameter
+     */
+    const uint16_t SECTION_WRITE_COUNT = 10;
+
+    bool DEBUG_FILTER = false;
+
+    /**
+     * Filter handlers to handle the data filtering.
+     * They are also responsible to write the filtered output into the filter FMQ
+     * and update the filterEvent bound with the same filterId.
+     */
+    Result startSectionFilterHandler();
+    Result startPesFilterHandler();
+    Result startTsFilterHandler();
+    Result startMediaFilterHandler();
+    Result startPcrFilterHandler();
+    Result startTemiFilterHandler();
+    Result startFilterLoop();
+
+    void deleteEventFlag();
+    bool writeDataToFilterMQ(const std::vector<uint8_t>& data);
+    bool readDataFromMQ();
+    bool writeSectionsAndCreateEvent(vector<uint8_t> data);
+    void maySendFilterStatusCallback();
+    DemuxFilterStatus checkFilterStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+                                              uint32_t highThreshold, uint32_t lowThreshold);
+    /**
+     * A dispatcher to read and dispatch input data to all the started filters.
+     * Each filter handler handles the data filtering/output writing/filterEvent updating.
+     */
+    void startTsFilter(vector<uint8_t> data);
+    bool startFilterDispatcher();
+    static void* __threadLoopFilter(void* user);
+    void filterThreadLoop();
+
+    int createAvIonFd(int size);
+    uint8_t* getIonBuffer(int fd, int size);
+    native_handle_t* createNativeHandle(int fd);
+    Result createMediaFilterEventWithIon(vector<uint8_t> output);
+
+    /**
+     * Lock to protect writes to the FMQs
+     */
+    std::mutex mWriteLock;
+    /**
+     * Lock to protect writes to the filter event
+     */
+    // TODO make each filter separate event lock
+    std::mutex mFilterEventLock;
+    /**
+     * Lock to protect writes to the input status
+     */
+    std::mutex mFilterStatusLock;
+    std::mutex mFilterThreadLock;
+    std::mutex mFilterOutputLock;
+    std::mutex mRecordFilterOutputLock;
+
+    // temp handle single PES filter
+    // TODO handle mulptiple Pes filters
+    int mPesSizeLeft = 0;
+    vector<uint8_t> mPesOutput;
+
+    // A map from data id to ion handle
+    std::map<uint64_t, int> mDataId2Avfd;
+    uint64_t mLastUsedDataId = 1;
+    int mAvBufferCopyCount = 0;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_1_FILTER_H_
diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp
new file mode 100644
index 0000000..6f5885f
--- /dev/null
+++ b/tv/tuner/1.1/default/Frontend.cpp
@@ -0,0 +1,285 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.tv.tuner@1.1-Frontend"
+
+#include "Frontend.h"
+#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+Frontend::Frontend(FrontendType type, FrontendId id, sp<Tuner> tuner) {
+    mType = type;
+    mId = id;
+    mTunerService = tuner;
+    // Init callback to nullptr
+    mCallback = nullptr;
+}
+
+Frontend::~Frontend() {}
+
+Return<Result> Frontend::close() {
+    ALOGV("%s", __FUNCTION__);
+    // Reset callback
+    mCallback = nullptr;
+    mIsLocked = false;
+    mTunerService->removeFrontend(mId);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Frontend::setCallback(const sp<IFrontendCallback>& callback) {
+    ALOGV("%s", __FUNCTION__);
+    if (callback == nullptr) {
+        ALOGW("[   WARN   ] Set Frontend callback with nullptr");
+        return Result::INVALID_ARGUMENT;
+    }
+
+    mCallback = callback;
+    return Result::SUCCESS;
+}
+
+Return<Result> Frontend::tune(const FrontendSettings& /* settings */) {
+    ALOGV("%s", __FUNCTION__);
+    if (mCallback == nullptr) {
+        ALOGW("[   WARN   ] Frontend callback is not set when tune");
+        return Result::INVALID_STATE;
+    }
+
+    mTunerService->frontendStartTune(mId);
+    mCallback->onEvent(FrontendEventType::LOCKED);
+    mIsLocked = true;
+    return Result::SUCCESS;
+}
+
+Return<Result> Frontend::stopTune() {
+    ALOGV("%s", __FUNCTION__);
+
+    mTunerService->frontendStopTune(mId);
+    mIsLocked = false;
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Frontend::scan(const FrontendSettings& settings, FrontendScanType type) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mType == FrontendType::ATSC) {
+        FrontendScanMessage msg;
+        msg.isLocked(true);
+        mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
+        mIsLocked = true;
+        return Result::SUCCESS;
+    }
+    if (mType != FrontendType::DVBT) {
+        return Result::UNAVAILABLE;
+    }
+
+    FrontendScanMessage msg;
+
+    if (mIsLocked) {
+        msg.isEnd(true);
+        mCallback->onScanMessage(FrontendScanMessageType::END, msg);
+        return Result::SUCCESS;
+    }
+
+    uint32_t frequency = settings.dvbt().frequency;
+    if (type == FrontendScanType::SCAN_BLIND) {
+        frequency += 100;
+    }
+    msg.frequencies({frequency});
+    mCallback->onScanMessage(FrontendScanMessageType::FREQUENCY, msg);
+    msg.isLocked(true);
+    mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
+    mIsLocked = true;
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Frontend::stopScan() {
+    ALOGV("%s", __FUNCTION__);
+
+    mIsLocked = false;
+    return Result::SUCCESS;
+}
+
+Return<void> Frontend::getStatus(const hidl_vec<FrontendStatusType>& statusTypes,
+                                 getStatus_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    vector<FrontendStatus> statuses;
+    for (int i = 0; i < statusTypes.size(); i++) {
+        FrontendStatusType type = statusTypes[i];
+        FrontendStatus status;
+        // assign randomly selected values for testing.
+        switch (type) {
+            case FrontendStatusType::DEMOD_LOCK: {
+                status.isDemodLocked(true);
+                break;
+            }
+            case FrontendStatusType::SNR: {
+                status.snr(221);
+                break;
+            }
+            case FrontendStatusType::BER: {
+                status.ber(1);
+                break;
+            }
+            case FrontendStatusType::PER: {
+                status.per(2);
+                break;
+            }
+            case FrontendStatusType::PRE_BER: {
+                status.preBer(3);
+                break;
+            }
+            case FrontendStatusType::SIGNAL_QUALITY: {
+                status.signalQuality(4);
+                break;
+            }
+            case FrontendStatusType::SIGNAL_STRENGTH: {
+                status.signalStrength(5);
+                break;
+            }
+            case FrontendStatusType::SYMBOL_RATE: {
+                status.symbolRate(6);
+                break;
+            }
+            case FrontendStatusType::FEC: {
+                status.innerFec(FrontendInnerFec::FEC_2_9);  // value = 1 << 7
+                break;
+            }
+            case FrontendStatusType::MODULATION: {
+                FrontendModulationStatus modulationStatus;
+                modulationStatus.isdbt(FrontendIsdbtModulation::MOD_16QAM);  // value = 1 << 3
+                status.modulation(modulationStatus);
+                break;
+            }
+            case FrontendStatusType::SPECTRAL: {
+                status.inversion(FrontendDvbcSpectralInversion::NORMAL);
+                break;
+            }
+            case FrontendStatusType::LNB_VOLTAGE: {
+                status.lnbVoltage(LnbVoltage::VOLTAGE_5V);
+                break;
+            }
+            case FrontendStatusType::PLP_ID: {
+                status.plpId(101);  // type uint8_t
+                break;
+            }
+            case FrontendStatusType::EWBS: {
+                status.isEWBS(false);
+                break;
+            }
+            case FrontendStatusType::AGC: {
+                status.agc(7);
+                break;
+            }
+            case FrontendStatusType::LNA: {
+                status.isLnaOn(false);
+                break;
+            }
+            case FrontendStatusType::LAYER_ERROR: {
+                vector<bool> v = {false, true, true};
+                status.isLayerError(v);
+                break;
+            }
+            case FrontendStatusType::MER: {
+                status.mer(8);
+                break;
+            }
+            case FrontendStatusType::FREQ_OFFSET: {
+                status.freqOffset(9);
+                break;
+            }
+            case FrontendStatusType::HIERARCHY: {
+                status.hierarchy(FrontendDvbtHierarchy::HIERARCHY_1_NATIVE);
+                break;
+            }
+            case FrontendStatusType::RF_LOCK: {
+                status.isRfLocked(false);
+                break;
+            }
+            case FrontendStatusType::ATSC3_PLP_INFO: {
+                vector<FrontendStatusAtsc3PlpInfo> v;
+                FrontendStatusAtsc3PlpInfo info1{
+                        .plpId = 3,
+                        .isLocked = false,
+                        .uec = 313,
+                };
+                FrontendStatusAtsc3PlpInfo info2{
+                        .plpId = 5,
+                        .isLocked = true,
+                        .uec = 515,
+                };
+                v.push_back(info1);
+                v.push_back(info2);
+                status.plpInfo(v);
+                break;
+            }
+            default: {
+                continue;
+            }
+        }
+        statuses.push_back(status);
+    }
+    _hidl_cb(Result::SUCCESS, statuses);
+
+    return Void();
+}
+
+Return<Result> Frontend::setLna(bool /* bEnable */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Frontend::setLnb(uint32_t /* lnb */) {
+    ALOGV("%s", __FUNCTION__);
+    if (!supportsSatellite()) {
+        return Result::INVALID_STATE;
+    }
+    return Result::SUCCESS;
+}
+
+FrontendType Frontend::getFrontendType() {
+    return mType;
+}
+
+FrontendId Frontend::getFrontendId() {
+    return mId;
+}
+
+bool Frontend::supportsSatellite() {
+    return mType == FrontendType::DVBS || mType == FrontendType::ISDBS ||
+           mType == FrontendType::ISDBS3;
+}
+
+bool Frontend::isLocked() {
+    return mIsLocked;
+}
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h
new file mode 100644
index 0000000..89b4a6b
--- /dev/null
+++ b/tv/tuner/1.1/default/Frontend.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_FRONTEND_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_1_FRONTEND_H_
+
+#include <fstream>
+#include <iostream>
+#include "Tuner.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+class Tuner;
+
+class Frontend : public IFrontend {
+  public:
+    Frontend(FrontendType type, FrontendId id, sp<Tuner> tuner);
+
+    virtual Return<Result> close() override;
+
+    virtual Return<Result> setCallback(const sp<IFrontendCallback>& callback) override;
+
+    virtual Return<Result> tune(const FrontendSettings& settings) override;
+
+    virtual Return<Result> stopTune() override;
+
+    virtual Return<Result> scan(const FrontendSettings& settings, FrontendScanType type) override;
+
+    virtual Return<Result> stopScan() override;
+
+    virtual Return<void> getStatus(const hidl_vec<FrontendStatusType>& statusTypes,
+                                   getStatus_cb _hidl_cb) override;
+
+    virtual Return<Result> setLna(bool bEnable) override;
+
+    virtual Return<Result> setLnb(uint32_t lnb) override;
+
+    FrontendType getFrontendType();
+
+    FrontendId getFrontendId();
+
+    string getSourceFile();
+
+    bool isLocked();
+
+  private:
+    virtual ~Frontend();
+    bool supportsSatellite();
+    sp<IFrontendCallback> mCallback;
+    sp<Tuner> mTunerService;
+    FrontendType mType = FrontendType::UNDEFINED;
+    FrontendId mId = 0;
+    bool mIsLocked = false;
+
+    std::ifstream mFrontendData;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_1_FRONTEND_H_
diff --git a/tv/tuner/1.1/default/Lnb.cpp b/tv/tuner/1.1/default/Lnb.cpp
new file mode 100644
index 0000000..044727f
--- /dev/null
+++ b/tv/tuner/1.1/default/Lnb.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.tv.tuner@1.1-Lnb"
+
+#include "Lnb.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+Lnb::Lnb() {}
+Lnb::Lnb(int id) {
+    mId = id;
+}
+
+Lnb::~Lnb() {}
+
+Return<Result> Lnb::setCallback(const sp<ILnbCallback>& /* callback */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Lnb::setVoltage(LnbVoltage /* voltage */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Lnb::setTone(LnbTone /* tone */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Lnb::setSatellitePosition(LnbPosition /* position */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Lnb::sendDiseqcMessage(const hidl_vec<uint8_t>& /* diseqcMessage */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Lnb::close() {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
+int Lnb::getId() {
+    return mId;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.1/default/Lnb.h b/tv/tuner/1.1/default/Lnb.h
new file mode 100644
index 0000000..70a8e41
--- /dev/null
+++ b/tv/tuner/1.1/default/Lnb.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_LNB_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_1_LNB_H_
+
+#include <android/hardware/tv/tuner/1.0/ILnb.h>
+#include <android/hardware/tv/tuner/1.1/ITuner.h>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+class Lnb : public ILnb {
+  public:
+    Lnb();
+    Lnb(int id);
+
+    virtual Return<Result> setCallback(const sp<ILnbCallback>& callback) override;
+
+    virtual Return<Result> setVoltage(LnbVoltage voltage) override;
+
+    virtual Return<Result> setTone(LnbTone tone) override;
+
+    virtual Return<Result> setSatellitePosition(LnbPosition position) override;
+
+    virtual Return<Result> sendDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) override;
+
+    virtual Return<Result> close() override;
+
+    int getId();
+
+  private:
+    int mId;
+    virtual ~Lnb();
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_1_LNB_H_
diff --git a/tv/tuner/1.1/default/OWNERS b/tv/tuner/1.1/default/OWNERS
new file mode 100644
index 0000000..1b3d095
--- /dev/null
+++ b/tv/tuner/1.1/default/OWNERS
@@ -0,0 +1,4 @@
+nchalko@google.com
+amyjojo@google.com
+shubang@google.com
+quxiangfang@google.com
diff --git a/tv/tuner/1.1/default/TimeFilter.cpp b/tv/tuner/1.1/default/TimeFilter.cpp
new file mode 100644
index 0000000..bb243a6
--- /dev/null
+++ b/tv/tuner/1.1/default/TimeFilter.cpp
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.tv.tuner@1.1-TimeFilter"
+
+#include "TimeFilter.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+TimeFilter::TimeFilter() {}
+
+TimeFilter::TimeFilter(sp<Demux> demux) {
+    mDemux = demux;
+}
+
+TimeFilter::~TimeFilter() {}
+
+Return<Result> TimeFilter::setTimeStamp(uint64_t timeStamp) {
+    ALOGV("%s", __FUNCTION__);
+    if (timeStamp == INVALID_TIME_STAMP) {
+        return Result::INVALID_ARGUMENT;
+    }
+    mTimeStamp = timeStamp;
+    mBeginTime = time(NULL);
+
+    return Result::SUCCESS;
+}
+
+Return<Result> TimeFilter::clearTimeStamp() {
+    ALOGV("%s", __FUNCTION__);
+    mTimeStamp = INVALID_TIME_STAMP;
+
+    return Result::SUCCESS;
+}
+
+Return<void> TimeFilter::getTimeStamp(getTimeStamp_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+    if (mTimeStamp == INVALID_TIME_STAMP) {
+        _hidl_cb(Result::INVALID_STATE, mTimeStamp);
+    }
+
+    uint64_t currentTimeStamp = mTimeStamp + difftime(time(NULL), mBeginTime) * 900000;
+    _hidl_cb(Result::SUCCESS, currentTimeStamp);
+    return Void();
+}
+
+Return<void> TimeFilter::getSourceTime(getSourceTime_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    uint64_t time = 0;
+
+    _hidl_cb(Result::SUCCESS, time);
+    return Void();
+}
+
+Return<Result> TimeFilter::close() {
+    ALOGV("%s", __FUNCTION__);
+    mTimeStamp = INVALID_TIME_STAMP;
+
+    return Result::SUCCESS;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/tv/tuner/1.1/default/TimeFilter.h b/tv/tuner/1.1/default/TimeFilter.h
new file mode 100644
index 0000000..d53ad2c
--- /dev/null
+++ b/tv/tuner/1.1/default/TimeFilter.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_TIMEFILTER_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_1_TIMEFILTER_H_
+
+#include <android/hardware/tv/tuner/1.0/ITimeFilter.h>
+#include "Demux.h"
+#include "time.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+#define INVALID_TIME_STAMP -1
+
+class Demux;
+
+class TimeFilter : public ITimeFilter {
+  public:
+    TimeFilter();
+
+    TimeFilter(sp<Demux> demux);
+
+    ~TimeFilter();
+
+    virtual Return<Result> setTimeStamp(uint64_t timeStamp) override;
+
+    virtual Return<Result> clearTimeStamp() override;
+
+    virtual Return<void> getTimeStamp(getTimeStamp_cb _hidl_cb) override;
+
+    virtual Return<void> getSourceTime(getSourceTime_cb _hidl_cb) override;
+
+    virtual Return<Result> close() override;
+
+  private:
+    sp<Demux> mDemux;
+    uint64_t mTimeStamp = INVALID_TIME_STAMP;
+    time_t mBeginTime;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_1_TIMEFILTER_H_
\ No newline at end of file
diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp
new file mode 100644
index 0000000..0a0667e
--- /dev/null
+++ b/tv/tuner/1.1/default/Tuner.cpp
@@ -0,0 +1,273 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "android.hardware.tv.tuner@1.1-Tuner"
+
+#include "Tuner.h"
+#include <utils/Log.h>
+#include "Demux.h"
+#include "Descrambler.h"
+#include "Frontend.h"
+#include "Lnb.h"
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+Tuner::Tuner() {
+    // Static Frontends array to maintain local frontends information
+    // Array index matches their FrontendId in the default impl
+    mFrontendSize = 8;
+    mFrontends[0] = new Frontend(FrontendType::DVBT, 0, this);
+    mFrontends[1] = new Frontend(FrontendType::ATSC, 1, this);
+    mFrontends[2] = new Frontend(FrontendType::DVBC, 2, this);
+    mFrontends[3] = new Frontend(FrontendType::DVBS, 3, this);
+    mFrontends[4] = new Frontend(FrontendType::DVBT, 4, this);
+    mFrontends[5] = new Frontend(FrontendType::ISDBT, 5, this);
+    mFrontends[6] = new Frontend(FrontendType::ANALOG, 6, this);
+    mFrontends[7] = new Frontend(FrontendType::ATSC, 7, this);
+
+    FrontendInfo::FrontendCapabilities caps;
+    caps = FrontendInfo::FrontendCapabilities();
+    caps.dvbtCaps(FrontendDvbtCapabilities());
+    mFrontendCaps[0] = caps;
+
+    caps = FrontendInfo::FrontendCapabilities();
+    caps.atscCaps(FrontendAtscCapabilities());
+    mFrontendCaps[1] = caps;
+
+    caps = FrontendInfo::FrontendCapabilities();
+    caps.dvbcCaps(FrontendDvbcCapabilities());
+    mFrontendCaps[2] = caps;
+
+    caps = FrontendInfo::FrontendCapabilities();
+    caps.dvbsCaps(FrontendDvbsCapabilities());
+    mFrontendCaps[3] = caps;
+
+    caps = FrontendInfo::FrontendCapabilities();
+    caps.dvbtCaps(FrontendDvbtCapabilities());
+    mFrontendCaps[4] = caps;
+
+    caps = FrontendInfo::FrontendCapabilities();
+    FrontendIsdbtCapabilities isdbtCaps{
+            .modeCap = FrontendIsdbtMode::MODE_1 | FrontendIsdbtMode::MODE_2,
+            .bandwidthCap = (unsigned int)FrontendIsdbtBandwidth::BANDWIDTH_6MHZ,
+            .modulationCap = (unsigned int)FrontendIsdbtModulation::MOD_16QAM,
+            // ISDBT shares coderate and guard interval with DVBT
+            .coderateCap = FrontendDvbtCoderate::CODERATE_4_5 | FrontendDvbtCoderate::CODERATE_6_7,
+            .guardIntervalCap = (unsigned int)FrontendDvbtGuardInterval::INTERVAL_1_128,
+    };
+    caps.isdbtCaps(isdbtCaps);
+    mFrontendCaps[5] = caps;
+
+    caps = FrontendInfo::FrontendCapabilities();
+    caps.analogCaps(FrontendAnalogCapabilities());
+    mFrontendCaps[6] = caps;
+
+    caps = FrontendInfo::FrontendCapabilities();
+    caps.atscCaps(FrontendAtscCapabilities());
+    mFrontendCaps[7] = caps;
+
+    mLnbs.resize(2);
+    mLnbs[0] = new Lnb(0);
+    mLnbs[1] = new Lnb(1);
+}
+
+Tuner::~Tuner() {}
+
+Return<void> Tuner::getFrontendIds(getFrontendIds_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    vector<FrontendId> frontendIds;
+    frontendIds.resize(mFrontendSize);
+    for (int i = 0; i < mFrontendSize; i++) {
+        frontendIds[i] = mFrontends[i]->getFrontendId();
+    }
+
+    _hidl_cb(Result::SUCCESS, frontendIds);
+    return Void();
+}
+
+Return<void> Tuner::openFrontendById(uint32_t frontendId, openFrontendById_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (frontendId >= mFrontendSize || frontendId < 0) {
+        ALOGW("[   WARN   ] Frontend with id %d isn't available", frontendId);
+        _hidl_cb(Result::UNAVAILABLE, nullptr);
+        return Void();
+    }
+
+    _hidl_cb(Result::SUCCESS, mFrontends[frontendId]);
+    return Void();
+}
+
+Return<void> Tuner::openDemux(openDemux_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    uint32_t demuxId = mLastUsedId + 1;
+    mLastUsedId += 1;
+    sp<Demux> demux = new Demux(demuxId, this);
+    mDemuxes[demuxId] = demux;
+
+    _hidl_cb(Result::SUCCESS, demuxId, demux);
+    return Void();
+}
+
+Return<void> Tuner::getDemuxCaps(getDemuxCaps_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    DemuxCapabilities caps;
+
+    // IP filter can be an MMTP filter's data source.
+    caps.linkCaps = {0x00, 0x00, 0x02, 0x00, 0x00};
+    _hidl_cb(Result::SUCCESS, caps);
+    return Void();
+}
+
+Return<void> Tuner::openDescrambler(openDescrambler_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    sp<V1_0::IDescrambler> descrambler = new Descrambler();
+
+    _hidl_cb(Result::SUCCESS, descrambler);
+    return Void();
+}
+
+Return<void> Tuner::getFrontendInfo(FrontendId frontendId, getFrontendInfo_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    FrontendInfo info;
+    if (frontendId >= mFrontendSize) {
+        _hidl_cb(Result::INVALID_ARGUMENT, info);
+        return Void();
+    }
+
+    vector<FrontendStatusType> statusCaps = {
+            FrontendStatusType::DEMOD_LOCK,
+            FrontendStatusType::SNR,
+            FrontendStatusType::FEC,
+            FrontendStatusType::MODULATION,
+            FrontendStatusType::PLP_ID,
+            FrontendStatusType::LAYER_ERROR,
+            FrontendStatusType::ATSC3_PLP_INFO,
+    };
+    // assign randomly selected values for testing.
+    info = {
+            .type = mFrontends[frontendId]->getFrontendType(),
+            .minFrequency = 139,
+            .maxFrequency = 1139,
+            .minSymbolRate = 45,
+            .maxSymbolRate = 1145,
+            .acquireRange = 30,
+            .exclusiveGroupId = 57,
+            .statusCaps = statusCaps,
+            .frontendCaps = mFrontendCaps[frontendId],
+    };
+
+    _hidl_cb(Result::SUCCESS, info);
+    return Void();
+}
+
+Return<void> Tuner::getLnbIds(getLnbIds_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    vector<V1_0::LnbId> lnbIds;
+    lnbIds.resize(mLnbs.size());
+    for (int i = 0; i < lnbIds.size(); i++) {
+        lnbIds[i] = mLnbs[i]->getId();
+    }
+
+    _hidl_cb(Result::SUCCESS, lnbIds);
+    return Void();
+}
+
+Return<void> Tuner::openLnbById(V1_0::LnbId lnbId, openLnbById_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (lnbId >= mLnbs.size()) {
+        _hidl_cb(Result::INVALID_ARGUMENT, nullptr);
+        return Void();
+    }
+
+    _hidl_cb(Result::SUCCESS, mLnbs[lnbId]);
+    return Void();
+}
+
+sp<Frontend> Tuner::getFrontendById(uint32_t frontendId) {
+    ALOGV("%s", __FUNCTION__);
+
+    return mFrontends[frontendId];
+}
+
+Return<void> Tuner::openLnbByName(const hidl_string& /*lnbName*/, openLnbByName_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    sp<V1_0::ILnb> lnb = new Lnb();
+
+    _hidl_cb(Result::SUCCESS, 1234, lnb);
+    return Void();
+}
+
+void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) {
+    mFrontendToDemux[frontendId] = demuxId;
+    if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
+        mDemuxes[demuxId]->startFrontendInputLoop();
+    }
+}
+
+void Tuner::removeDemux(uint32_t demuxId) {
+    map<uint32_t, uint32_t>::iterator it;
+    for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end();) {
+        if (it->second == demuxId) {
+            it = mFrontendToDemux.erase(it);
+        } else {
+            it++;
+        }
+    }
+    mDemuxes.erase(demuxId);
+}
+
+void Tuner::removeFrontend(uint32_t frontendId) {
+    mFrontendToDemux.erase(frontendId);
+}
+
+void Tuner::frontendStopTune(uint32_t frontendId) {
+    map<uint32_t, uint32_t>::iterator it = mFrontendToDemux.find(frontendId);
+    uint32_t demuxId;
+    if (it != mFrontendToDemux.end()) {
+        demuxId = it->second;
+        mDemuxes[demuxId]->stopFrontendInput();
+    }
+}
+
+void Tuner::frontendStartTune(uint32_t frontendId) {
+    map<uint32_t, uint32_t>::iterator it = mFrontendToDemux.find(frontendId);
+    uint32_t demuxId;
+    if (it != mFrontendToDemux.end()) {
+        demuxId = it->second;
+        mDemuxes[demuxId]->startFrontendInputLoop();
+    }
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.1/default/Tuner.h b/tv/tuner/1.1/default/Tuner.h
new file mode 100644
index 0000000..3b1574b
--- /dev/null
+++ b/tv/tuner/1.1/default/Tuner.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_TUNER_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_1_TUNER_H_
+
+#include <android/hardware/tv/tuner/1.1/ITuner.h>
+#include <map>
+#include "Demux.h"
+#include "Frontend.h"
+#include "Lnb.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::tv::tuner::V1_1::ITuner;
+
+class Frontend;
+class Demux;
+class Lnb;
+
+class Tuner : public ITuner {
+  public:
+    Tuner();
+
+    virtual Return<void> getFrontendIds(getFrontendIds_cb _hidl_cb) override;
+
+    virtual Return<void> openFrontendById(uint32_t frontendId,
+                                          openFrontendById_cb _hidl_cb) override;
+
+    virtual Return<void> openDemux(openDemux_cb _hidl_cb) override;
+
+    virtual Return<void> getDemuxCaps(getDemuxCaps_cb _hidl_cb) override;
+
+    virtual Return<void> openDescrambler(openDescrambler_cb _hidl_cb) override;
+
+    virtual Return<void> getFrontendInfo(uint32_t frontendId, getFrontendInfo_cb _hidl_cb) override;
+
+    virtual Return<void> getLnbIds(getLnbIds_cb _hidl_cb) override;
+
+    virtual Return<void> openLnbById(uint32_t lnbId, openLnbById_cb _hidl_cb) override;
+
+    virtual Return<void> openLnbByName(const hidl_string& lnbName,
+                                       openLnbByName_cb _hidl_cb) override;
+
+    sp<Frontend> getFrontendById(uint32_t frontendId);
+
+    void setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId);
+
+    void frontendStartTune(uint32_t frontendId);
+    void frontendStopTune(uint32_t frontendId);
+    void removeDemux(uint32_t demuxId);
+    void removeFrontend(uint32_t frontendId);
+
+  private:
+    virtual ~Tuner();
+    // Static mFrontends array to maintain local frontends information
+    map<uint32_t, sp<Frontend>> mFrontends;
+    map<uint32_t, FrontendInfo::FrontendCapabilities> mFrontendCaps;
+    map<uint32_t, uint32_t> mFrontendToDemux;
+    map<uint32_t, sp<Demux>> mDemuxes;
+    // To maintain how many Frontends we have
+    int mFrontendSize;
+    // The last used demux id. Initial value is -1.
+    // First used id will be 0.
+    uint32_t mLastUsedId = -1;
+    vector<sp<Lnb>> mLnbs;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_1_TUNER_H_
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
new file mode 100644
index 0000000..9e228f7
--- /dev/null
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
@@ -0,0 +1,9 @@
+service vendor.tuner-hal-1-1 /vendor/bin/hw/android.hardware.tv.tuner@1.1-service-lazy
+    interface android.hardware.tv.tuner@1.1::ITuner default
+    oneshot
+    disabled
+    class hal
+    user media
+    group mediadrm drmrpc
+    ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.xml b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.xml
new file mode 100644
index 0000000..86b0445
--- /dev/null
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.tv.tuner</name>
+        <transport>hwbinder</transport>
+        <version>1.1</version>
+        <interface>
+            <name>ITuner</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
\ No newline at end of file
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
new file mode 100644
index 0000000..3718a93
--- /dev/null
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
@@ -0,0 +1,6 @@
+service vendor.tuner-hal-1-1 /vendor/bin/hw/android.hardware.tv.tuner@1.1-service
+    class hal
+    user media
+    group mediadrm drmrpc
+    ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.xml b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.xml
new file mode 100644
index 0000000..86b0445
--- /dev/null
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+    <hal format="hidl">
+        <name>android.hardware.tv.tuner</name>
+        <transport>hwbinder</transport>
+        <version>1.1</version>
+        <interface>
+            <name>ITuner</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
\ No newline at end of file
diff --git a/tv/tuner/1.1/default/service.cpp b/tv/tuner/1.1/default/service.cpp
new file mode 100644
index 0000000..2320308
--- /dev/null
+++ b/tv/tuner/1.1/default/service.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#ifdef LAZY_SERVICE
+#define LOG_TAG "android.hardware.tv.tuner@1.1-service-lazy"
+#else
+#define LOG_TAG "android.hardware.tv.tuner@1.1-service"
+#endif
+
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+
+#include "Tuner.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::LazyServiceRegistrar;
+using android::hardware::tv::tuner::V1_0::implementation::Tuner;
+using android::hardware::tv::tuner::V1_1::ITuner;
+
+#ifdef LAZY_SERVICE
+const bool kLazyService = true;
+#else
+const bool kLazyService = false;
+#endif
+
+int main() {
+    configureRpcThreadpool(8, true /* callerWillJoin */);
+
+    // Setup hwbinder service
+    android::sp<ITuner> service = new Tuner();
+    android::status_t status;
+    if (kLazyService) {
+        auto serviceRegistrar = LazyServiceRegistrar::getInstance();
+        status = serviceRegistrar.registerService(service);
+    } else {
+        status = service->registerAsService();
+    }
+    LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering tuner service: %d", status);
+
+    joinRpcThreadpool();
+    return 0;
+}
diff --git a/tv/tuner/1.1/vts/OWNERS b/tv/tuner/1.1/vts/OWNERS
new file mode 100644
index 0000000..1b3d095
--- /dev/null
+++ b/tv/tuner/1.1/vts/OWNERS
@@ -0,0 +1,4 @@
+nchalko@google.com
+amyjojo@google.com
+shubang@google.com
+quxiangfang@google.com
diff --git a/tv/tuner/1.1/vts/functional/Android.bp b/tv/tuner/1.1/vts/functional/Android.bp
new file mode 100644
index 0000000..7ab0f87
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/Android.bp
@@ -0,0 +1,48 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalTvTunerV1_1TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "VtsHalTvTunerV1_1TargetTest.cpp",
+        "FrontendTests.cpp",
+        "DemuxTests.cpp",
+        "FilterTests.cpp",
+    ],
+    static_libs: [
+        "android.hardware.cas@1.0",
+        "android.hardware.cas@1.1",
+        "android.hardware.cas@1.2",
+        "android.hardware.tv.tuner@1.0",
+        "android.hardware.tv.tuner@1.1",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "libhidlallocatorutils",
+        "libhidlmemory",
+        "libcutils",
+        "libfmq",
+    ],
+    shared_libs: [
+        "libbinder",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+
+    require_root: true,
+}
diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.cpp b/tv/tuner/1.1/vts/functional/DemuxTests.cpp
new file mode 100644
index 0000000..e0600b6
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/DemuxTests.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DemuxTests.h"
+
+AssertionResult DemuxTests::openDemux(sp<IDemux>& demux, uint32_t& demuxId) {
+    Result status;
+    mService->openDemux([&](Result result, uint32_t id, const sp<IDemux>& demuxSp) {
+        mDemux = demuxSp;
+        demux = demuxSp;
+        demuxId = id;
+        status = result;
+    });
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult DemuxTests::setDemuxFrontendDataSource(uint32_t frontendId) {
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    auto status = mDemux->setFrontendDataSource(frontendId);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DemuxTests::closeDemux() {
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    auto status = mDemux->close();
+    mDemux = nullptr;
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DemuxTests::getAvSyncId_64bit(sp<IFilter> filter, uint64_t& avSyncHwId) {
+    EXPECT_TRUE(mDemux) << "Demux is not opened yet.";
+    Result status;
+
+    sp<android::hardware::tv::tuner::V1_1::IDemux> demux_v1_1 =
+            android::hardware::tv::tuner::V1_1::IDemux::castFrom(mDemux);
+    if (demux_v1_1 != NULL) {
+        demux_v1_1->getAvSyncHwId64Bit(filter, [&](Result result, uint64_t id) {
+            status = result;
+            avSyncHwId = id;
+        });
+    } else {
+        ALOGW("[vts] Can't cast IDemux into v1_1.");
+        return failure();
+    }
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult DemuxTests::getAvSyncTime(uint32_t avSyncId) {
+    EXPECT_TRUE(mDemux) << "Demux is not opened yet.";
+    Result status;
+    uint64_t syncTime;
+    mDemux->getAvSyncTime(avSyncId, [&](Result result, uint64_t time) {
+        status = result;
+        syncTime = time;
+    });
+    return AssertionResult(status == Result::SUCCESS);
+}
\ No newline at end of file
diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.h b/tv/tuner/1.1/vts/functional/DemuxTests.h
new file mode 100644
index 0000000..393757c
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/DemuxTests.h
@@ -0,0 +1,59 @@
+/*
+ * 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/types.h>
+#include <android/hardware/tv/tuner/1.1/IDemux.h>
+#include <android/hardware/tv/tuner/1.1/IFilter.h>
+#include <android/hardware/tv/tuner/1.1/ITuner.h>
+#include <binder/MemoryDealer.h>
+#include <gtest/gtest.h>
+#include <hidl/ServiceManagement.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <map>
+
+using android::sp;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::tv::tuner::V1_0::IDemux;
+using android::hardware::tv::tuner::V1_0::IFilter;
+using android::hardware::tv::tuner::V1_0::Result;
+using android::hardware::tv::tuner::V1_1::ITuner;
+
+using ::testing::AssertionResult;
+
+class DemuxTests {
+  public:
+    void setService(sp<ITuner> tuner) { mService = tuner; }
+
+    AssertionResult openDemux(sp<IDemux>& demux, uint32_t& demuxId);
+    AssertionResult setDemuxFrontendDataSource(uint32_t frontendId);
+    AssertionResult getAvSyncId_64bit(sp<IFilter> filter, uint64_t& avSyncHwId);
+    AssertionResult getAvSyncTime(uint32_t avSyncId);
+    AssertionResult closeDemux();
+
+  protected:
+    static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+    static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+    sp<ITuner> mService;
+    sp<IDemux> mDemux;
+};
diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp
new file mode 100644
index 0000000..fb0c1a5
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FilterTests.h"
+
+AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type, uint32_t bufferSize) {
+    Result status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+
+    // Create demux callback
+    mFilterCallback = new FilterCallback();
+
+    // Add filter to the local demux
+    mDemux->openFilter(type, bufferSize, mFilterCallback,
+                       [&](Result result, const sp<IFilter>& filter) {
+                           mFilter = filter;
+                           status = result;
+                       });
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::getNewlyOpenedFilterId_64bit(uint64_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.";
+
+    sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
+            android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilter);
+    if (filter_v1_1 != NULL) {
+        filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) {
+            mFilterId = filterId;
+            status = result;
+        });
+    } else {
+        ALOGW("[vts] Can't cast IFilter into v1_1.");
+        return failure();
+    }
+
+    if (status == Result::SUCCESS) {
+        mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId);
+        mFilters[mFilterId] = mFilter;
+        mFilterCallbacks[mFilterId] = mFilterCallback;
+        filterId = mFilterId;
+    }
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint64_t filterId) {
+    Result status;
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    status = mFilters[filterId]->configure(setting);
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::getFilterMQDescriptor(uint64_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;
+    });
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::startFilter(uint64_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    Result status = mFilters[filterId]->start();
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::stopFilter(uint64_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    Result status = mFilters[filterId]->stop();
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::closeFilter(uint64_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);
+}
diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h
new file mode 100644
index 0000000..b1b6e13
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/FilterTests.h
@@ -0,0 +1,168 @@
+/*
+ * 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/IFilter.h>
+#include <android/hardware/tv/tuner/1.0/IFilterCallback.h>
+#include <android/hardware/tv/tuner/1.0/types.h>
+#include <android/hardware/tv/tuner/1.1/IFilter.h>
+#include <android/hardware/tv/tuner/1.1/ITuner.h>
+#include <fmq/MessageQueue.h>
+#include <gtest/gtest.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Status.h>
+#include <inttypes.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <map>
+
+using android::Condition;
+using android::Mutex;
+using android::sp;
+using android::hardware::EventFlag;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::kSynchronizedReadWrite;
+using android::hardware::MessageQueue;
+using android::hardware::MQDescriptorSync;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
+using android::hardware::tv::tuner::V1_0::DemuxFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
+using android::hardware::tv::tuner::V1_0::IDemux;
+using android::hardware::tv::tuner::V1_0::IFilter;
+using android::hardware::tv::tuner::V1_0::IFilterCallback;
+using android::hardware::tv::tuner::V1_0::Result;
+using android::hardware::tv::tuner::V1_1::ITuner;
+
+using ::testing::AssertionResult;
+
+using namespace std;
+
+enum FilterEventType : uint8_t {
+    UNDEFINED,
+    SECTION,
+    MEDIA,
+    PES,
+    RECORD,
+    MMTPRECORD,
+    DOWNLOAD,
+    TEMI,
+};
+
+using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+using MQDesc = MQDescriptorSync<uint8_t>;
+
+#define WAIT_TIMEOUT 3000000000
+
+class FilterCallback : public IFilterCallback {
+  public:
+    virtual Return<void> onFilterEvent(const DemuxFilterEvent& /*filterEvent*/) override {
+        return Void();
+    }
+
+    virtual Return<void> onFilterStatus(const DemuxFilterStatus /*status*/) override {
+        return Void();
+    }
+};
+
+class FilterTests {
+  public:
+    void setService(sp<ITuner> tuner) { mService = tuner; }
+    void setDemux(sp<IDemux> demux) { mDemux = demux; }
+    sp<IFilter> getFilterById(uint64_t filterId) { return mFilters[filterId]; }
+
+    std::map<uint64_t, sp<FilterCallback>> getFilterCallbacks() { return mFilterCallbacks; }
+
+    AssertionResult openFilterInDemux(DemuxFilterType type, uint32_t bufferSize);
+    AssertionResult getNewlyOpenedFilterId_64bit(uint64_t& filterId);
+    AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId);
+    AssertionResult getFilterMQDescriptor(uint64_t filterId);
+    AssertionResult startFilter(uint64_t filterId);
+    AssertionResult stopFilter(uint64_t filterId);
+    AssertionResult closeFilter(uint64_t filterId);
+
+    FilterEventType getFilterEventType(DemuxFilterType type) {
+        FilterEventType eventType = FilterEventType::UNDEFINED;
+        switch (type.mainType) {
+            case DemuxFilterMainType::TS:
+                switch (type.subType.tsFilterType()) {
+                    case DemuxTsFilterType::UNDEFINED:
+                        break;
+                    case DemuxTsFilterType::SECTION:
+                        eventType = FilterEventType::SECTION;
+                        break;
+                    case DemuxTsFilterType::PES:
+                        eventType = FilterEventType::PES;
+                        break;
+                    case DemuxTsFilterType::TS:
+                        break;
+                    case DemuxTsFilterType::AUDIO:
+                    case DemuxTsFilterType::VIDEO:
+                        eventType = FilterEventType::MEDIA;
+                        break;
+                    case DemuxTsFilterType::PCR:
+                        break;
+                    case DemuxTsFilterType::RECORD:
+                        eventType = FilterEventType::RECORD;
+                        break;
+                    case DemuxTsFilterType::TEMI:
+                        eventType = FilterEventType::TEMI;
+                        break;
+                }
+                break;
+            case DemuxFilterMainType::MMTP:
+                /*mmtpSettings*/
+                break;
+            case DemuxFilterMainType::IP:
+                /*ipSettings*/
+                break;
+            case DemuxFilterMainType::TLV:
+                /*tlvSettings*/
+                break;
+            case DemuxFilterMainType::ALP:
+                /*alpSettings*/
+                break;
+            default:
+                break;
+        }
+        return eventType;
+    }
+
+  protected:
+    static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+    static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+    sp<ITuner> mService;
+    sp<IFilter> mFilter;
+    sp<IDemux> mDemux;
+    std::map<uint64_t, sp<IFilter>> mFilters;
+    std::map<uint64_t, sp<FilterCallback>> mFilterCallbacks;
+
+    sp<FilterCallback> mFilterCallback;
+    MQDesc mFilterMQDescriptor;
+    vector<uint64_t> mUsedFilterIds;
+
+    uint64_t mFilterId = -1;
+};
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
new file mode 100644
index 0000000..8c359c5
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FrontendTests.h"
+
+Return<void> FrontendCallback::onEvent(FrontendEventType /*frontendEventType*/) {
+    return Void();
+}
+
+Return<void> FrontendCallback::onScanMessage(FrontendScanMessageType /*type*/,
+                                             const FrontendScanMessage& /*message*/) {
+    return Void();
+}
+
+AssertionResult FrontendTests::getFrontendIds() {
+    Result status;
+    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
+        status = result;
+        mFeIds = frontendIds;
+    });
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FrontendTests::getFrontendInfo(uint32_t frontendId) {
+    Result status;
+    mService->getFrontendInfo(frontendId, [&](Result result, const FrontendInfo& frontendInfo) {
+        mFrontendInfo = frontendInfo;
+        status = result;
+    });
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FrontendTests::openFrontendById(uint32_t frontendId) {
+    Result status;
+    mService->openFrontendById(frontendId, [&](Result result, const sp<IFrontend>& frontend) {
+        mFrontend = frontend;
+        status = result;
+    });
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FrontendTests::setFrontendCallback() {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+    mFrontendCallback = new FrontendCallback();
+    auto callbackStatus = mFrontend->setCallback(mFrontendCallback);
+    return AssertionResult(callbackStatus.isOk());
+}
+
+AssertionResult FrontendTests::closeFrontend() {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+    Result status;
+    status = mFrontend->close();
+    mFrontend = nullptr;
+    mFrontendCallback = nullptr;
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+void FrontendTests::getFrontendIdByType(FrontendType feType, uint32_t& feId) {
+    ASSERT_TRUE(getFrontendIds());
+    ASSERT_TRUE(mFeIds.size() > 0);
+    for (size_t i = 0; i < mFeIds.size(); i++) {
+        ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+        if (mFrontendInfo.type != feType) {
+            continue;
+        }
+        feId = mFeIds[i];
+        return;
+    }
+    feId = INVALID_ID;
+}
\ No newline at end of file
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h
new file mode 100644
index 0000000..e687589
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.h
@@ -0,0 +1,96 @@
+/*
+ * 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/IFrontend.h>
+#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
+#include <android/hardware/tv/tuner/1.0/types.h>
+#include <android/hardware/tv/tuner/1.1/ITuner.h>
+#include <binder/MemoryDealer.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/ServiceManagement.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <map>
+
+#include "VtsHalTvTunerV1_1TestConfigurations.h"
+
+#define WAIT_TIMEOUT 3000000000
+#define INVALID_ID -1
+
+using android::Condition;
+using android::IMemory;
+using android::IMemoryHeap;
+using android::MemoryDealer;
+using android::Mutex;
+using android::sp;
+using android::hardware::fromHeap;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+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::FrontendScanMessage;
+using android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
+using android::hardware::tv::tuner::V1_0::IFrontend;
+using android::hardware::tv::tuner::V1_0::IFrontendCallback;
+using android::hardware::tv::tuner::V1_0::Result;
+using android::hardware::tv::tuner::V1_1::ITuner;
+
+using ::testing::AssertionResult;
+
+using namespace std;
+
+#define INVALID_ID -1
+
+class FrontendCallback : public IFrontendCallback {
+  public:
+    virtual Return<void> onEvent(FrontendEventType frontendEventType) override;
+    virtual Return<void> onScanMessage(FrontendScanMessageType type,
+                                       const FrontendScanMessage& message) override;
+};
+
+class FrontendTests {
+  public:
+    sp<ITuner> mService;
+
+    void setService(sp<ITuner> tuner) { mService = tuner; }
+
+    AssertionResult getFrontendIds();
+    AssertionResult getFrontendInfo(uint32_t frontendId);
+    AssertionResult openFrontendById(uint32_t frontendId);
+    AssertionResult setFrontendCallback();
+    AssertionResult closeFrontend();
+
+    void getFrontendIdByType(FrontendType feType, uint32_t& feId);
+
+  protected:
+    static AssertionResult failure() { return ::testing::AssertionFailure(); }
+    static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+    sp<IFrontend> mFrontend;
+    FrontendInfo mFrontendInfo;
+    sp<FrontendCallback> mFrontendCallback;
+    hidl_vec<FrontendId> mFeIds;
+
+    bool mIsSoftwareFe = false;
+};
\ No newline at end of file
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
new file mode 100644
index 0000000..c74e29c
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
@@ -0,0 +1,99 @@
+/*
+ * 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 "VtsHalTvTunerV1_1TargetTest.h"
+
+namespace {
+
+void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf,
+                                                        FrontendConfig frontendConf) {
+    uint32_t feId;
+    uint32_t demuxId;
+    sp<IDemux> demux;
+    uint64_t filterId;
+
+    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFilterTests.setDemux(demux);
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
+    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
+TEST_P(TunerDemuxHidlTest, getAvSyncTime) {
+    description("Get the A/V sync time from a PCR filter.");
+    uint32_t feId;
+    uint32_t demuxId;
+    sp<IDemux> demux;
+    uint64_t mediaFilterId;
+    uint64_t pcrFilterId;
+    uint64_t avSyncHwId;
+    sp<IFilter> mediaFilter;
+
+    mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFilterTests.setDemux(demux);
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type,
+                                               filterArray[TS_VIDEO1].bufferSize));
+    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, mediaFilterId));
+    mediaFilter = mFilterTests.getFilterById(mediaFilterId);
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_PCR0].type,
+                                               filterArray[TS_PCR0].bufferSize));
+    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_PCR0].settings, pcrFilterId));
+    ASSERT_TRUE(mDemuxTests.getAvSyncId_64bit(mediaFilter, avSyncHwId));
+    ASSERT_TRUE(pcrFilterId == avSyncHwId);
+    ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
+TEST_P(TunerFilterHidlTest, StartFilterInDemux) {
+    description("Open and start a filter in Demux.");
+    // TODO use parameterized tests
+    configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[DVBT]);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, TunerFilterHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, TunerDemuxHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxHidlTest);
+}  // namespace
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
new file mode 100644
index 0000000..30533b1
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DemuxTests.h"
+#include "FilterTests.h"
+#include "FrontendTests.h"
+
+namespace {
+
+void initConfiguration() {
+    initFrontendConfig();
+    initFilterConfig();
+}
+
+class TunerFilterHidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        mService = ITuner::getService(GetParam());
+        ASSERT_NE(mService, nullptr);
+        initConfiguration();
+
+        mFrontendTests.setService(mService);
+        mDemuxTests.setService(mService);
+        mFilterTests.setService(mService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    void configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf);
+
+    sp<ITuner> mService;
+    FrontendTests mFrontendTests;
+    DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
+};
+
+class TunerDemuxHidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        mService = ITuner::getService(GetParam());
+        ASSERT_NE(mService, nullptr);
+        initConfiguration();
+
+        mFrontendTests.setService(mService);
+        mDemuxTests.setService(mService);
+        mFilterTests.setService(mService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    sp<ITuner> mService;
+    FrontendTests mFrontendTests;
+    DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
+};
+}  // namespace
\ No newline at end of file
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
new file mode 100644
index 0000000..23c9353
--- /dev/null
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/hardware/tv/tuner/1.0/types.h>
+#include <binder/MemoryDealer.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+
+using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
+using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
+using android::hardware::tv::tuner::V1_0::DemuxFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType;
+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::FrontendStatus;
+using android::hardware::tv::tuner::V1_0::FrontendStatusType;
+using android::hardware::tv::tuner::V1_0::FrontendType;
+
+using namespace std;
+
+const uint32_t FMQ_SIZE_1M = 0x100000;
+const uint32_t FMQ_SIZE_4M = 0x400000;
+const uint32_t FMQ_SIZE_16M = 0x1000000;
+
+typedef enum {
+    TS_VIDEO0,
+    TS_VIDEO1,
+    TS_AUDIO0,
+    TS_AUDIO1,
+    TS_PES0,
+    TS_PCR0,
+    TS_SECTION0,
+    TS_TS0,
+    TS_RECORD0,
+    FILTER_MAX,
+} Filter;
+
+typedef enum {
+    DVBT,
+    DVBS,
+    FRONTEND_MAX,
+} Frontend;
+
+struct FilterConfig {
+    uint32_t bufferSize;
+    DemuxFilterType type;
+    DemuxFilterSettings settings;
+
+    bool operator<(const FilterConfig& /*c*/) const { return false; }
+};
+
+struct FrontendConfig {
+    bool isSoftwareFe;
+    FrontendType type;
+    FrontendSettings settings;
+    vector<FrontendStatusType> tuneStatusTypes;
+    vector<FrontendStatus> expectTuneStatuses;
+};
+
+static FrontendConfig frontendArray[FILTER_MAX];
+static FilterConfig filterArray[FILTER_MAX];
+
+/** 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[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings);
+    vector<FrontendStatusType> types;
+    types.push_back(FrontendStatusType::DEMOD_LOCK);
+    FrontendStatus status;
+    status.isDemodLocked(true);
+    vector<FrontendStatus> statuses;
+    statuses.push_back(status);
+    frontendArray[DVBT].tuneStatusTypes = types;
+    frontendArray[DVBT].expectTuneStatuses = statuses;
+    frontendArray[DVBT].isSoftwareFe = true;
+    frontendArray[DVBS].type = FrontendType::DVBS;
+    frontendArray[DVBS].isSoftwareFe = true;
+};
+
+/** Configuration array for the filter test */
+inline void initFilterConfig() {
+    // TS VIDEO filter setting for default implementation testing
+    filterArray[TS_VIDEO0].type.mainType = DemuxFilterMainType::TS;
+    filterArray[TS_VIDEO0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
+    filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M;
+    filterArray[TS_VIDEO0].settings.ts().tpid = 256;
+    filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false});
+    filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS;
+    filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
+    filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M;
+    filterArray[TS_VIDEO1].settings.ts().tpid = 256;
+    filterArray[TS_VIDEO1].settings.ts().filterSettings.av({.isPassthrough = false});
+    // TS AUDIO filter setting
+    filterArray[TS_AUDIO0].type.mainType = DemuxFilterMainType::TS;
+    filterArray[TS_AUDIO0].type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
+    filterArray[TS_AUDIO0].bufferSize = FMQ_SIZE_16M;
+    filterArray[TS_AUDIO0].settings.ts().tpid = 256;
+    filterArray[TS_AUDIO0].settings.ts().filterSettings.av({.isPassthrough = false});
+    filterArray[TS_AUDIO1].type.mainType = DemuxFilterMainType::TS;
+    filterArray[TS_AUDIO1].type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
+    filterArray[TS_AUDIO1].bufferSize = FMQ_SIZE_16M;
+    filterArray[TS_AUDIO1].settings.ts().tpid = 257;
+    filterArray[TS_AUDIO1].settings.ts().filterSettings.av({.isPassthrough = false});
+    // TS PES filter setting
+    filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS;
+    filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES);
+    filterArray[TS_PES0].bufferSize = FMQ_SIZE_16M;
+    filterArray[TS_PES0].settings.ts().tpid = 256;
+    filterArray[TS_PES0].settings.ts().filterSettings.pesData({
+            .isRaw = false,
+            .streamId = 0xbd,
+    });
+    // TS PCR filter setting
+    filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS;
+    filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR);
+    filterArray[TS_PCR0].bufferSize = FMQ_SIZE_16M;
+    filterArray[TS_PCR0].settings.ts().tpid = 256;
+    filterArray[TS_PCR0].settings.ts().filterSettings.noinit();
+    // TS filter setting
+    filterArray[TS_TS0].type.mainType = DemuxFilterMainType::TS;
+    filterArray[TS_TS0].type.subType.tsFilterType(DemuxTsFilterType::TS);
+    filterArray[TS_TS0].bufferSize = FMQ_SIZE_16M;
+    filterArray[TS_TS0].settings.ts().tpid = 256;
+    filterArray[TS_TS0].settings.ts().filterSettings.noinit();
+    // TS SECTION filter setting
+    filterArray[TS_SECTION0].type.mainType = DemuxFilterMainType::TS;
+    filterArray[TS_SECTION0].type.subType.tsFilterType(DemuxTsFilterType::SECTION);
+    filterArray[TS_SECTION0].bufferSize = FMQ_SIZE_16M;
+    filterArray[TS_SECTION0].settings.ts().tpid = 256;
+    filterArray[TS_SECTION0].settings.ts().filterSettings.section({
+            .isRaw = false,
+    });
+    // TS RECORD filter setting
+    filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS;
+    filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD);
+    filterArray[TS_RECORD0].settings.ts().tpid = 81;
+    filterArray[TS_RECORD0].settings.ts().filterSettings.record({
+            .scIndexType = DemuxRecordScIndexType::NONE,
+    });
+};