Merge changes I388fc2b8,I639e8314

* changes:
  Remove Unused Function Declarations from DVR Default Implementation
  Clean Up Playback Thread in DVR Test Implementation
diff --git a/audio/core/all-versions/default/Android.bp b/audio/core/all-versions/default/Android.bp
index 901b7ee..392642d 100644
--- a/audio/core/all-versions/default/Android.bp
+++ b/audio/core/all-versions/default/Android.bp
@@ -48,6 +48,8 @@
         "libhidlbase",
         "liblog",
         "libmedia_helper",
+        "libmediautils_vendor",
+        "libmemunreachable",
         "libutils",
         "android.hardware.audio.common-util",
     ],
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp
index 130dfba..c33e6f3 100644
--- a/audio/core/all-versions/default/Device.cpp
+++ b/audio/core/all-versions/default/Device.cpp
@@ -30,6 +30,8 @@
 #include <algorithm>
 
 #include <android/log.h>
+#include <mediautils/MemoryLeakTrackUtil.h>
+#include <memunreachable/memunreachable.h>
 
 #include <HidlUtils.h>
 
@@ -456,9 +458,32 @@
 }
 #endif
 
-Return<void> Device::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) {
+Return<void> Device::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
     if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
-        analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
+        const int fd0 = fd->data[0];
+        bool dumpMem = false;
+        bool unreachableMemory = false;
+        for (const auto& option : options) {
+            if (option == "-m") {
+                dumpMem = true;
+            } else if (option == "--unreachable") {
+                unreachableMemory = true;
+            }
+        }
+
+        if (dumpMem) {
+            dprintf(fd0, "\nDumping memory:\n");
+            std::string s = dumpMemoryAddresses(100 /* limit */);
+            write(fd0, s.c_str(), s.size());
+        }
+        if (unreachableMemory) {
+            dprintf(fd0, "\nDumping unreachable memory:\n");
+            // TODO - should limit be an argument parameter?
+            std::string s = GetUnreachableMemoryString(true /* contents */, 100 /* limit */);
+            write(fd0, s.c_str(), s.size());
+        }
+
+        analyzeStatus("dump", mDevice->dump(mDevice, fd0));
     }
     return Void();
 }
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index b96cc83..787654b 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -53,6 +53,11 @@
         GTEST_SKIP() << "getMicrophones is not supported";  // returns
     }
     ASSERT_OK(res);
+
+#if MAJOR_VERSION <= 6
+    // In V7, 'getActiveMicrophones' is tested by the 'MicrophoneInfoInputStream'
+    // test which uses the actual configuration of the device.
+
     if (microphones.size() > 0) {
         // When there is microphone on the phone, try to open an input stream
         // and query for the active microphones.
@@ -60,30 +65,13 @@
             "Make sure getMicrophones always succeeds"
             "and getActiveMicrophones always succeeds when recording from these microphones.");
         AudioConfig config{};
-#if MAJOR_VERSION <= 6
         config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO);
         config.sampleRateHz = 8000;
         config.format = AudioFormat::PCM_16_BIT;
         auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
         const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
-#elif MAJOR_VERSION >= 7
-        config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO);
-        config.base.sampleRateHz = 8000;
-        config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
-        hidl_vec<hidl_string> flags;
-        const SinkMetadata initMetadata = {
-                {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC),
-                  .gain = 1,
-                  .tags = {},
-                  .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}};
-#endif
         for (auto microphone : microphones) {
-#if MAJOR_VERSION <= 6
             if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) {
-#elif MAJOR_VERSION >= 7
-            if (xsd::stringToAudioDevice(microphone.deviceAddress.deviceType) !=
-                xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC) {
-#endif
                 continue;
             }
             sp<IStreamIn> stream;
@@ -106,6 +94,7 @@
             EXPECT_NE(0U, activeMicrophones.size());
         }
     }
+#endif  // MAJOR_VERSION <= 6
 }
 
 TEST_P(AudioHidlDeviceTest, SetConnectedState) {
@@ -343,18 +332,21 @@
 #endif
 
     for (int mode : {-2, -1, maxMode + 1}) {
-        ASSERT_RESULT(Result::INVALID_ARGUMENTS, getDevice()->setMode(AudioMode(mode)))
+        EXPECT_RESULT(Result::INVALID_ARGUMENTS, getDevice()->setMode(AudioMode(mode)))
                 << "mode=" << mode;
     }
-    // Test valid values
-    for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
-                           AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
-        ASSERT_OK(getDevice()->setMode(mode)) << "mode=" << toString(mode);
-    }
+
     // AudioMode::CALL_SCREEN as support is optional
 #if MAJOR_VERSION >= 6
-    ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, getDevice()->setMode(AudioMode::CALL_SCREEN));
+    EXPECT_RESULT(okOrNotSupportedOrInvalidArgs, getDevice()->setMode(AudioMode::CALL_SCREEN));
 #endif
+    // Test valid values
+    for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
+                           AudioMode::NORMAL}) {
+        EXPECT_OK(getDevice()->setMode(mode)) << "mode=" << toString(mode);
+    }
+    // Make sure to leave the test in normal mode
+    getDevice()->setMode(AudioMode::NORMAL);
 }
 
 TEST_P(AudioPrimaryHidlTest, setBtHfpSampleRate) {
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 0b3098b..0cc6a5b 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -839,3 +839,64 @@
                         ::testing::ValuesIn(getInputDevicePcmOnlyConfigParameters()),
                         &DeviceConfigParameterToString);
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PcmOnlyConfigInputStreamTest);
+
+static const std::vector<DeviceConfigParameter>& getBuiltinMicConfigParameters() {
+    static const std::vector<DeviceConfigParameter> parameters = [] {
+        auto allParams = getInputDeviceConfigParameters();
+        std::vector<DeviceConfigParameter> builtinMicParams;
+        std::copy_if(allParams.begin(), allParams.end(), std::back_inserter(builtinMicParams),
+                     [](auto cfg) {
+                         // The built in mic may participate in various scenarios:
+                         // FAST, HW_HOTWORD, MMAP NOIRQ, which are indicated by flags.
+                         // We are only interested in testing the simplest scenario w/o any flags.
+                         if (!std::get<PARAM_FLAGS>(cfg).empty()) return false;
+                         auto maybeSourceDevice = getCachedPolicyConfig().getSourceDeviceForMixPort(
+                                 std::get<PARAM_DEVICE_NAME>(std::get<PARAM_DEVICE>(cfg)),
+                                 std::get<PARAM_PORT_NAME>(cfg));
+                         return maybeSourceDevice.has_value() &&
+                                xsd::stringToAudioDevice(maybeSourceDevice.value().deviceType) ==
+                                        xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC;
+                     });
+        return builtinMicParams;
+    }();
+    return parameters;
+}
+
+class MicrophoneInfoInputStreamTest : public InputStreamTest {};
+
+TEST_P(MicrophoneInfoInputStreamTest, GetActiveMicrophones) {
+    doc::test(
+            "Make sure getActiveMicrophones always succeeds when recording "
+            "from the built-in microphone.");
+    hidl_vec<MicrophoneInfo> microphones;
+    ASSERT_OK(getDevice()->getMicrophones(returnIn(res, microphones)));
+    if (res == Result::NOT_SUPPORTED) {
+        GTEST_SKIP() << "getMicrophones is not supported";  // returns
+    }
+    ASSERT_OK(res);
+
+    auto maybeSourceAddress =
+            getCachedPolicyConfig().getSourceDeviceForMixPort(getDeviceName(), getMixPortName());
+    ASSERT_TRUE(maybeSourceAddress.has_value())
+            << "No source device found for mix port " << getMixPortName() << " (module "
+            << getDeviceName() << ")";
+
+    for (auto microphone : microphones) {
+        if (microphone.deviceAddress == maybeSourceAddress.value()) {
+            StreamReader reader(stream.get(), stream->getBufferSize());
+            ASSERT_TRUE(reader.start());
+            reader.pause();  // This ensures that at least one read has happened.
+            EXPECT_FALSE(reader.hasError());
+
+            hidl_vec<MicrophoneInfo> activeMicrophones;
+            ASSERT_OK(stream->getActiveMicrophones(returnIn(res, activeMicrophones)));
+            ASSERT_OK(res);
+            EXPECT_NE(0U, activeMicrophones.size());
+        }
+    }
+}
+
+INSTANTIATE_TEST_CASE_P(MicrophoneInfoInputStream, MicrophoneInfoInputStreamTest,
+                        ::testing::ValuesIn(getBuiltinMicConfigParameters()),
+                        &DeviceConfigParameterToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MicrophoneInfoInputStreamTest);
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index e446a7f..9f4a295 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -30,6 +30,7 @@
         "android.hardware.audio.common.test.utility",
         "audioclient-types-aidl-cpp",
         "libaudioclient_aidl_conversion",
+        "libstagefright_foundation",
     ],
     shared_libs: [
         "libbinder",
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index aa7fd8e..340903a 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -1390,6 +1390,9 @@
                 config.channelMask.value(channelMask);
                 auto ret = stream->setAudioProperties(config);
                 EXPECT_TRUE(ret.isOk());
+                if (ret == Result::NOT_SUPPORTED) {
+                    GTEST_SKIP() << "setAudioProperties is not supported";
+                }
                 EXPECT_EQ(Result::OK, ret)
                         << profile.format << "; " << sampleRate << "; " << channelMask;
             }
diff --git a/audio/effect/all-versions/OWNERS b/audio/effect/all-versions/OWNERS
index 24071af..f9a2d6b 100644
--- a/audio/effect/all-versions/OWNERS
+++ b/audio/effect/all-versions/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 48436
 elaurent@google.com
 mnaganov@google.com
diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp
index b0e67be..cc1d839 100644
--- a/automotive/can/1.0/default/libnl++/Socket.cpp
+++ b/automotive/can/1.0/default/libnl++/Socket.cpp
@@ -162,6 +162,26 @@
     return {mFd.get(), events, 0};
 }
 
+bool Socket::addMembership(unsigned group) {
+    const auto res =
+            setsockopt(mFd.get(), SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group));
+    if (res < 0) {
+        PLOG(ERROR) << "Failed joining multicast group " << group;
+        return false;
+    }
+    return true;
+}
+
+bool Socket::dropMembership(unsigned group) {
+    const auto res =
+            setsockopt(mFd.get(), SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, &group, sizeof(group));
+    if (res < 0) {
+        PLOG(ERROR) << "Failed leaving multicast group " << group;
+        return false;
+    }
+    return true;
+}
+
 Socket::receive_iterator::receive_iterator(Socket& socket, bool end)
     : mSocket(socket), mIsEnd(end) {
     if (!end) receive();
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
index 118b9f7..7ec0f7b 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/Socket.h
@@ -192,6 +192,22 @@
     pollfd preparePoll(short events = 0);
 
     /**
+     * Join a multicast group.
+     *
+     * \param group Group ID (*not* a bitfield)
+     * \return whether the operation succeeded
+     */
+    bool addMembership(unsigned group);
+
+    /**
+     * Leave a multicast group.
+     *
+     * \param group Group ID (*not* a bitfield)
+     * \return whether the operation succeeded
+     */
+    bool dropMembership(unsigned group);
+
+    /**
      * Live iterator continuously receiving messages from Netlink socket.
      *
      * Iteration ends when socket fails to receive a buffer.
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index aabc60c..2c3422e 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -92,10 +92,12 @@
         "impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
         "impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
         "impl/vhal_v2_0/GeneratorHub.cpp",
+        "impl/vhal_v2_0/FakeObd2Frame.cpp",
     ],
     local_include_dirs: ["common/include/vhal_v2_0"],
     export_include_dirs: ["impl"],
     whole_static_libs: [
+        "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
         "android.hardware.automotive.vehicle@2.0-manager-lib",
     ],
     shared_libs: [
@@ -141,10 +143,10 @@
         "impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
         "impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
         "impl/vhal_v2_0/DefaultVehicleHalServer.cpp",
+        "impl/vhal_v2_0/FakeObd2Frame.cpp",
     ],
     whole_static_libs: [
         "android.hardware.automotive.vehicle@2.0-server-common-lib",
-        "android.hardware.automotive.vehicle@2.0-user-hal-helper-lib",
     ],
     static_libs: [
         "android.hardware.automotive.vehicle@2.0-libproto-native",
@@ -197,6 +199,7 @@
     static_libs: [
         "libbase",
         "libcutils",
+        "libgmock",
         "libjsoncpp",
         "libprotobuf-cpp-lite",
     ],
@@ -212,6 +215,10 @@
         "android.hardware.automotive.vehicle@2.0-default-impl-lib",
         "android.hardware.automotive.vehicle@2.0-libproto-native",
     ],
+    data: [
+        ":vhal_test_json",
+        ":vhal_test_override_json",
+    ],
     test_suites: ["general-tests"],
 }
 
@@ -233,7 +240,7 @@
     static_libs: [
         "android.hardware.automotive.vehicle@2.0-manager-lib",
         "android.hardware.automotive.vehicle@2.0-libproto-native",
-        "//device/generic/car/emulator/vhal_v2_0:android.hardware.automotive.vehicle@2.0-emulator-impl-lib",
+        "android.hardware.automotive.vehicle@2.0-emulator-impl-lib",
     ],
 }
 
diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp
index ba2a606..fae6e43 100644
--- a/automotive/vehicle/2.0/default/VehicleService.cpp
+++ b/automotive/vehicle/2.0/default/VehicleService.cpp
@@ -20,7 +20,6 @@
 
 #include <iostream>
 
-#include <EmulatedUserHal.h>
 #include <EmulatedVehicleConnector.h>
 #include <EmulatedVehicleHal.h>
 #include <vhal_v2_0/VehicleHalManager.h>
@@ -32,8 +31,7 @@
 int main(int /* argc */, char* /* argv */ []) {
     auto store = std::make_unique<VehiclePropertyStore>();
     auto connector = std::make_unique<impl::EmulatedVehicleConnector>();
-    auto userHal = connector->getEmulatedUserHal();
-    auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get(), userHal);
+    auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get());
     auto emulator = connector->getEmulator();
     auto service = std::make_unique<VehicleHalManager>(hal.get());
     connector->setValuePool(hal->getValuePool());
diff --git a/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.rc b/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.rc
index c8c89dc..44f9134 100644
--- a/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.rc
+++ b/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.rc
@@ -1,4 +1,4 @@
 service vendor.vehicle-hal-2.0 /vendor/bin/hw/android.hardware.automotive.vehicle@2.0-service
-    class hal
+    class early_hal
     user vehicle_network
     group system inet
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 899428e..da6de74 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -1027,14 +1027,6 @@
         {
                 .config =
                         {
-                                .prop = toInt(VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED),
-                                .access = VehiclePropertyAccess::READ_WRITE,
-                                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                        },
-        },
-        {
-                .config =
-                        {
                                 .prop = toInt(VehicleProperty::WATCHDOG_ALIVE),
                                 .access = VehiclePropertyAccess::WRITE,
                                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
index a6e2c8f..25a698b 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
@@ -15,10 +15,16 @@
  */
 #define LOG_TAG "DefaultVehicleHal_v2_0"
 
+#include <android-base/chrono_utils.h>
+#include <assert.h>
+#include <stdio.h>
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
 #include <vhal_v2_0/RecurrentTimer.h>
+#include <unordered_set>
 
+#include "FakeObd2Frame.h"
+#include "PropertyUtils.h"
 #include "VehicleUtils.h"
 
 #include "DefaultVehicleHal.h"
@@ -31,6 +37,49 @@
 
 namespace impl {
 
+namespace {
+constexpr std::chrono::nanoseconds kHeartBeatIntervalNs = 3s;
+
+const VehicleAreaConfig* getAreaConfig(const VehiclePropValue& propValue,
+                                       const VehiclePropConfig* config) {
+    if (isGlobalProp(propValue.prop)) {
+        if (config->areaConfigs.size() == 0) {
+            return nullptr;
+        }
+        return &(config->areaConfigs[0]);
+    } else {
+        for (auto& c : config->areaConfigs) {
+            if (c.areaId == propValue.areaId) {
+                return &c;
+            }
+        }
+    }
+    return nullptr;
+}
+
+VehicleHal::VehiclePropValuePtr addTimestamp(VehicleHal::VehiclePropValuePtr v) {
+    if (v.get()) {
+        v->timestamp = elapsedRealtimeNano();
+    }
+    return v;
+}
+
+bool isDebugProperty(int propId) {
+    return (propId == kGenerateFakeDataControllingProperty ||
+            propId == kSetIntPropertyFromVehicleForTest ||
+            propId == kSetFloatPropertyFromVehicleForTest ||
+            propId == kSetBooleanPropertyFromVehicleForTest);
+}
+}  // namespace
+
+VehicleHal::VehiclePropValuePtr DefaultVehicleHal::createVhalHeartBeatProp() {
+    VehicleHal::VehiclePropValuePtr v = getValuePool()->obtainInt64(uptimeMillis());
+    v->prop = static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT);
+    v->areaId = 0;
+    v->status = VehiclePropertyStatus::AVAILABLE;
+    return v;
+}
+
 DefaultVehicleHal::DefaultVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client)
     : mPropStore(propStore), mRecurrentTimer(getTimerAction()), mVehicleClient(client) {
     initStaticConfig();
@@ -40,12 +89,51 @@
             });
 }
 
+VehicleHal::VehiclePropValuePtr DefaultVehicleHal::getUserHalProp(
+        const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
+    auto propId = requestedPropValue.prop;
+    ALOGI("get(): getting value for prop %d from User HAL", propId);
+    const auto& ret = mEmulatedUserHal.onGetProperty(requestedPropValue);
+    VehicleHal::VehiclePropValuePtr v = nullptr;
+    if (!ret.ok()) {
+        ALOGE("get(): User HAL returned error: %s", ret.error().message().c_str());
+        *outStatus = StatusCode(ret.error().code());
+    } else {
+        auto value = ret.value().get();
+        if (value != nullptr) {
+            ALOGI("get(): User HAL returned value: %s", toString(*value).c_str());
+            v = getValuePool()->obtain(*value);
+            *outStatus = StatusCode::OK;
+        } else {
+            ALOGE("get(): User HAL returned null value");
+            *outStatus = StatusCode::INTERNAL_ERROR;
+        }
+    }
+    return addTimestamp(std::move(v));
+}
+
 VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(const VehiclePropValue& requestedPropValue,
                                                        StatusCode* outStatus) {
     auto propId = requestedPropValue.prop;
     ALOGV("get(%d)", propId);
 
+    if (mEmulatedUserHal.isSupported(propId)) {
+        return getUserHalProp(requestedPropValue, outStatus);
+    }
+
     VehiclePropValuePtr v = nullptr;
+    if (propId == OBD2_FREEZE_FRAME) {
+        v = getValuePool()->obtainComplex();
+        *outStatus = fillObd2FreezeFrame(mPropStore, requestedPropValue, v.get());
+        return addTimestamp(std::move(v));
+    }
+
+    if (propId == OBD2_FREEZE_FRAME_INFO) {
+        v = getValuePool()->obtainComplex();
+        *outStatus = fillObd2DtcInfo(mPropStore, v.get());
+        return addTimestamp(std::move(v));
+    }
+
     auto internalPropValue = mPropStore->readValueOrNull(requestedPropValue);
     if (internalPropValue != nullptr) {
         v = getValuePool()->obtain(*internalPropValue);
@@ -58,10 +146,7 @@
     } else {
         *outStatus = StatusCode::TRY_AGAIN;
     }
-    if (v.get()) {
-        v->timestamp = elapsedRealtimeNano();
-    }
-    return v;
+    return addTimestamp(std::move(v));
 }
 
 std::vector<VehiclePropConfig> DefaultVehicleHal::listProperties() {
@@ -69,9 +154,211 @@
 }
 
 bool DefaultVehicleHal::dump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) {
+    int nativeFd = fd->data[0];
+    if (nativeFd < 0) {
+        ALOGW("Invalid fd from HIDL handle: %d", nativeFd);
+        return false;
+    }
+    if (options.size() > 0) {
+        if (options[0] == "--help") {
+            std::string buffer;
+            buffer += "Emulated user hal usage:\n";
+            buffer += mEmulatedUserHal.showDumpHelp();
+            buffer += "\n";
+            buffer += "VHAL server debug usage:\n";
+            buffer += "--debughal: send debug command to VHAL server, see '--debughal --help'\n";
+            buffer += "\n";
+            dprintf(nativeFd, "%s", buffer.c_str());
+            return false;
+        } else if (options[0] == kUserHalDumpOption) {
+            dprintf(nativeFd, "%s", mEmulatedUserHal.dump("").c_str());
+            return false;
+        }
+    } else {
+        // No options, dump the emulated user hal state first and then send command to VHAL server
+        // to dump its state.
+        std::string buffer;
+        buffer += "Emulator user hal state:\n";
+        buffer += mEmulatedUserHal.dump("  ");
+        buffer += "\n";
+        dprintf(nativeFd, "%s", buffer.c_str());
+    }
+
     return mVehicleClient->dump(fd, options);
 }
 
+StatusCode DefaultVehicleHal::checkPropValue(const VehiclePropValue& value,
+                                             const VehiclePropConfig* config) {
+    int32_t property = value.prop;
+    VehiclePropertyType type = getPropType(property);
+    switch (type) {
+        case VehiclePropertyType::BOOLEAN:
+        case VehiclePropertyType::INT32:
+            if (value.value.int32Values.size() != 1) {
+                return StatusCode::INVALID_ARG;
+            }
+            break;
+        case VehiclePropertyType::INT32_VEC:
+            if (value.value.int32Values.size() < 1) {
+                return StatusCode::INVALID_ARG;
+            }
+            break;
+        case VehiclePropertyType::INT64:
+            if (value.value.int64Values.size() != 1) {
+                return StatusCode::INVALID_ARG;
+            }
+            break;
+        case VehiclePropertyType::INT64_VEC:
+            if (value.value.int64Values.size() < 1) {
+                return StatusCode::INVALID_ARG;
+            }
+            break;
+        case VehiclePropertyType::FLOAT:
+            if (value.value.floatValues.size() != 1) {
+                return StatusCode::INVALID_ARG;
+            }
+            break;
+        case VehiclePropertyType::FLOAT_VEC:
+            if (value.value.floatValues.size() < 1) {
+                return StatusCode::INVALID_ARG;
+            }
+            break;
+        case VehiclePropertyType::BYTES:
+            // We allow setting an empty bytes array.
+            break;
+        case VehiclePropertyType::STRING:
+            // We allow setting an empty string.
+            break;
+        case VehiclePropertyType::MIXED:
+            if (getPropGroup(property) == VehiclePropertyGroup::VENDOR) {
+                // We only checks vendor mixed properties.
+                return checkVendorMixedPropValue(value, config);
+            }
+            break;
+        default:
+            ALOGW("Unknown property type: %d", type);
+            return StatusCode::INVALID_ARG;
+    }
+    return StatusCode::OK;
+}
+
+StatusCode DefaultVehicleHal::checkVendorMixedPropValue(const VehiclePropValue& value,
+                                                        const VehiclePropConfig* config) {
+    auto configArray = config->configArray;
+    // configArray[0], 1 indicates the property has a String value, we allow the string value to
+    // be empty.
+
+    size_t int32Count = 0;
+    // configArray[1], 1 indicates the property has a Boolean value.
+    if (configArray[1] == 1) {
+        int32Count++;
+    }
+    // configArray[2], 1 indicates the property has an Integer value.
+    if (configArray[2] == 1) {
+        int32Count++;
+    }
+    // configArray[3], the number indicates the size of Integer[] in the property.
+    int32Count += static_cast<size_t>(configArray[3]);
+    if (value.value.int32Values.size() != int32Count) {
+        return StatusCode::INVALID_ARG;
+    }
+
+    size_t int64Count = 0;
+    // configArray[4], 1 indicates the property has a Long value.
+    if (configArray[4] == 1) {
+        int64Count++;
+    }
+    // configArray[5], the number indicates the size of Long[] in the property.
+    int64Count += static_cast<size_t>(configArray[5]);
+    if (value.value.int64Values.size() != int64Count) {
+        return StatusCode::INVALID_ARG;
+    }
+
+    size_t floatCount = 0;
+    // configArray[6], 1 indicates the property has a Float value.
+    if (configArray[6] == 1) {
+        floatCount++;
+    }
+    // configArray[7], the number indicates the size of Float[] in the property.
+    floatCount += static_cast<size_t>(configArray[7]);
+    if (value.value.floatValues.size() != floatCount) {
+        return StatusCode::INVALID_ARG;
+    }
+
+    // configArray[8], the number indicates the size of byte[] in the property.
+    if (configArray[8] != 0 && value.value.bytes.size() != static_cast<size_t>(configArray[8])) {
+        return StatusCode::INVALID_ARG;
+    }
+    return StatusCode::OK;
+}
+
+StatusCode DefaultVehicleHal::checkValueRange(const VehiclePropValue& value,
+                                              const VehicleAreaConfig* areaConfig) {
+    if (areaConfig == nullptr) {
+        return StatusCode::OK;
+    }
+    int32_t property = value.prop;
+    VehiclePropertyType type = getPropType(property);
+    switch (type) {
+        case VehiclePropertyType::INT32:
+            if (areaConfig->minInt32Value == 0 && areaConfig->maxInt32Value == 0) {
+                break;
+            }
+            // We already checked this in checkPropValue.
+            assert(value.value.int32Values.size() > 0);
+            if (value.value.int32Values[0] < areaConfig->minInt32Value ||
+                value.value.int32Values[0] > areaConfig->maxInt32Value) {
+                return StatusCode::INVALID_ARG;
+            }
+            break;
+        case VehiclePropertyType::INT64:
+            if (areaConfig->minInt64Value == 0 && areaConfig->maxInt64Value == 0) {
+                break;
+            }
+            // We already checked this in checkPropValue.
+            assert(value.value.int64Values.size() > 0);
+            if (value.value.int64Values[0] < areaConfig->minInt64Value ||
+                value.value.int64Values[0] > areaConfig->maxInt64Value) {
+                return StatusCode::INVALID_ARG;
+            }
+            break;
+        case VehiclePropertyType::FLOAT:
+            if (areaConfig->minFloatValue == 0 && areaConfig->maxFloatValue == 0) {
+                break;
+            }
+            // We already checked this in checkPropValue.
+            assert(value.value.floatValues.size() > 0);
+            if (value.value.floatValues[0] < areaConfig->minFloatValue ||
+                value.value.floatValues[0] > areaConfig->maxFloatValue) {
+                return StatusCode::INVALID_ARG;
+            }
+            break;
+        default:
+            // We don't check the rest of property types. Additional logic needs to be added if
+            // required for real implementation. E.g., you might want to enforce the range
+            // checks on vector as well or you might want to check the range for mixed property.
+            break;
+    }
+    return StatusCode::OK;
+}
+
+StatusCode DefaultVehicleHal::setUserHalProp(const VehiclePropValue& propValue) {
+    ALOGI("onSetProperty(): property %d will be handled by UserHal", propValue.prop);
+
+    const auto& ret = mEmulatedUserHal.onSetProperty(propValue);
+    if (!ret.ok()) {
+        ALOGE("onSetProperty(): HAL returned error: %s", ret.error().message().c_str());
+        return StatusCode(ret.error().code());
+    }
+    auto updatedValue = ret.value().get();
+    if (updatedValue != nullptr) {
+        ALOGI("onSetProperty(): updating property returned by HAL: %s",
+              toString(*updatedValue).c_str());
+        onPropertyValue(*updatedValue, true);
+    }
+    return StatusCode::OK;
+}
+
 StatusCode DefaultVehicleHal::set(const VehiclePropValue& propValue) {
     if (propValue.status != VehiclePropertyStatus::AVAILABLE) {
         // Android side cannot set property status - this value is the
@@ -79,12 +366,67 @@
         // its underlying hardware
         return StatusCode::INVALID_ARG;
     }
-    auto currentPropValue = mPropStore->readValueOrNull(propValue);
 
-    if (currentPropValue == nullptr) {
+    if (mEmulatedUserHal.isSupported(propValue.prop)) {
+        return setUserHalProp(propValue);
+    }
+
+    std::unordered_set<int32_t> powerProps(std::begin(kHvacPowerProperties),
+                                           std::end(kHvacPowerProperties));
+    if (powerProps.count(propValue.prop)) {
+        auto hvacPowerOn = mPropStore->readValueOrNull(
+                toInt(VehicleProperty::HVAC_POWER_ON),
+                (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT |
+                 VehicleAreaSeat::ROW_2_LEFT | VehicleAreaSeat::ROW_2_CENTER |
+                 VehicleAreaSeat::ROW_2_RIGHT));
+
+        if (hvacPowerOn && hvacPowerOn->value.int32Values.size() == 1 &&
+            hvacPowerOn->value.int32Values[0] == 0) {
+            return StatusCode::NOT_AVAILABLE;
+        }
+    }
+
+    if (propValue.prop == OBD2_FREEZE_FRAME_CLEAR) {
+        return clearObd2FreezeFrames(mPropStore, propValue);
+    }
+    if (propValue.prop == VEHICLE_MAP_SERVICE) {
+        // Placeholder for future implementation of VMS property in the default hal. For
+        // now, just returns OK; otherwise, hal clients crash with property not supported.
+        return StatusCode::OK;
+    }
+    if (isDebugProperty(propValue.prop)) {
+        // These are special debug properties and do not need a config or check.
+        // TODO(shanyu): Remove this after we remove debug properties.
+        return mVehicleClient->setProperty(propValue, /*updateStatus=*/false);
+    }
+
+    int32_t property = propValue.prop;
+    const VehiclePropConfig* config = mPropStore->getConfigOrNull(property);
+    if (config == nullptr) {
+        ALOGW("no config for prop 0x%x", property);
         return StatusCode::INVALID_ARG;
     }
-    if (currentPropValue->status != VehiclePropertyStatus::AVAILABLE) {
+    const VehicleAreaConfig* areaConfig = getAreaConfig(propValue, config);
+    if (!isGlobalProp(property) && areaConfig == nullptr) {
+        // Ignore areaId for global property. For non global property, check whether areaId is
+        // allowed. areaId must appear in areaConfig.
+        ALOGW("invalid area ID: 0x%x for prop 0x%x, not listed in config", propValue.areaId,
+              property);
+        return StatusCode::INVALID_ARG;
+    }
+    auto status = checkPropValue(propValue, config);
+    if (status != StatusCode::OK) {
+        ALOGW("invalid property value: %s", toString(propValue).c_str());
+        return status;
+    }
+    status = checkValueRange(propValue, areaConfig);
+    if (status != StatusCode::OK) {
+        ALOGW("property value out of range: %s", toString(propValue).c_str());
+        return status;
+    }
+
+    auto currentPropValue = mPropStore->readValueOrNull(propValue);
+    if (currentPropValue && currentPropValue->status != VehiclePropertyStatus::AVAILABLE) {
         // do not allow Android side to set() a disabled/error property
         return StatusCode::NOT_AVAILABLE;
     }
@@ -98,7 +440,13 @@
     auto configs = mVehicleClient->getAllPropertyConfig();
 
     for (const auto& cfg : configs) {
-        int32_t numAreas = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs.size();
+        if (isDiagnosticProperty(cfg)) {
+            // do not write an initial empty value for the diagnostic properties
+            // as we will initialize those separately.
+            continue;
+        }
+
+        int32_t numAreas = isGlobalProp(cfg.prop) ? 1 : cfg.areaConfigs.size();
 
         for (int i = 0; i < numAreas; i++) {
             int32_t curArea = isGlobalProp(cfg.prop) ? 0 : cfg.areaConfigs[i].areaId;
@@ -115,6 +463,37 @@
     }
 
     mVehicleClient->triggerSendAllValues();
+
+    initObd2LiveFrame(mPropStore, *mPropStore->getConfigOrDie(OBD2_LIVE_FRAME));
+    initObd2FreezeFrame(mPropStore, *mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME));
+
+    registerHeartBeatEvent();
+}
+
+DefaultVehicleHal::~DefaultVehicleHal() {
+    mRecurrentTimer.unregisterRecurrentEvent(static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT));
+}
+
+void DefaultVehicleHal::registerHeartBeatEvent() {
+    mRecurrentTimer.registerRecurrentEvent(kHeartBeatIntervalNs,
+                                           static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT));
+}
+
+VehicleHal::VehiclePropValuePtr DefaultVehicleHal::doInternalHealthCheck() {
+    VehicleHal::VehiclePropValuePtr v = nullptr;
+
+    // This is an example of very simple health checking. VHAL is considered healthy if we can read
+    // PERF_VEHICLE_SPEED. The more comprehensive health checking is required.
+    VehiclePropValue propValue = {
+            .prop = static_cast<int32_t>(VehicleProperty::PERF_VEHICLE_SPEED),
+    };
+    auto internalPropValue = mPropStore->readValueOrNull(propValue);
+    if (internalPropValue != nullptr) {
+        v = createVhalHeartBeatProp();
+    } else {
+        ALOGW("VHAL health check failed");
+    }
+    return v;
 }
 
 void DefaultVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& properties) {
@@ -127,6 +506,10 @@
             if (internalPropValue != nullptr) {
                 v = pool.obtain(*internalPropValue);
             }
+        } else if (property == static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT)) {
+            // VHAL_HEARTBEAT is not a continuous value, but it needs to be updated periodically.
+            // So, the update is done through onContinuousPropertyTimer.
+            v = doInternalHealthCheck();
         } else {
             ALOGE("Unexpected onContinuousPropertyTimer for property: 0x%x", property);
             continue;
@@ -151,6 +534,14 @@
     if (!isContinuousProperty(property)) {
         return StatusCode::INVALID_ARG;
     }
+
+    // If the config does not exist, isContinuousProperty should return false.
+    const VehiclePropConfig* config = mPropStore->getConfigOrNull(property);
+    if (sampleRate < config->minSampleRate || sampleRate > config->maxSampleRate) {
+        ALOGW("sampleRate out of range");
+        return StatusCode::INVALID_ARG;
+    }
+
     mRecurrentTimer.registerRecurrentEvent(hertzToNanoseconds(sampleRate), property);
     return StatusCode::OK;
 }
@@ -185,7 +576,21 @@
 void DefaultVehicleHal::initStaticConfig() {
     auto configs = mVehicleClient->getAllPropertyConfig();
     for (auto&& cfg : configs) {
-        mPropStore->registerProperty(cfg, nullptr);
+        VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
+
+        switch (cfg.prop) {
+            case OBD2_FREEZE_FRAME: {
+                // We use timestamp as token for OBD2_FREEZE_FRAME
+                tokenFunction = [](const VehiclePropValue& propValue) {
+                    return propValue.timestamp;
+                };
+                break;
+            }
+            default:
+                break;
+        }
+
+        mPropStore->registerProperty(cfg, tokenFunction);
     }
 }
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
index cc66c0f..7cd7ac2 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.h
@@ -19,8 +19,9 @@
 
 #include <vhal_v2_0/RecurrentTimer.h>
 #include <vhal_v2_0/VehicleHal.h>
-#include "vhal_v2_0/VehiclePropertyStore.h"
+#include <vhal_v2_0/VehiclePropertyStore.h>
 
+#include "EmulatedUserHal.h"
 #include "VehicleHalClient.h"
 
 namespace android {
@@ -35,9 +36,9 @@
 class DefaultVehicleHal : public VehicleHal {
   public:
     DefaultVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client);
-    ~DefaultVehicleHal() = default;
+    ~DefaultVehicleHal();
 
-    //  Methods from VehicleHal
+    // Initialize VHAL. Should always call registerHeartBeatEvent() during onCreate.
     void onCreate() override;
     std::vector<VehiclePropConfig> listProperties() override;
     VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
@@ -55,12 +56,46 @@
     VehiclePropertyStore* mPropStore;
     RecurrentTimer mRecurrentTimer;
     VehicleHalClient* mVehicleClient;
-    virtual bool isContinuousProperty(int32_t propId) const;
-    virtual void initStaticConfig();
-    virtual void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
+    EmulatedUserHal mEmulatedUserHal;
+
+    // The callback that would be called when a property value is updated. This function could
+    // be extended to handle specific property update event.
     virtual void onPropertyValue(const VehiclePropValue& value, bool updateStatus);
+    // Do an internal health check, vendor should add health check logic in this function.
+    virtual VehicleHal::VehiclePropValuePtr doInternalHealthCheck();
+
+    // The callback that would be called for every event generated by 'subscribe' or heartbeat.
+    // Properties contains a list of properties that need to be handled.
+    void onContinuousPropertyTimer(const std::vector<int32_t>& properties);
+    // Initiate config for all properties, would be called during onCreate().
+    void initStaticConfig();
+    // Whether the property is a continuous property.
+    bool isContinuousProperty(int32_t propId) const;
     // Returns a lambda that could be used in mRecurrentTimer.
     RecurrentTimer::Action getTimerAction();
+    // Check whether a propValue is valid according to its type.
+    StatusCode checkPropValue(const VehiclePropValue& propValue, const VehiclePropConfig* config);
+    // Check whether the property value is within the range according to area config.
+    StatusCode checkValueRange(const VehiclePropValue& propValue,
+                               const VehicleAreaConfig* areaConfig);
+    // Register the heart beat event to be sent every 3s. This is required to inform watch dog that
+    // VHAL is alive. Subclasses should always calls this function during onCreate.
+    void registerHeartBeatEvent();
+    // Get a user HAL property.
+    VehiclePropValuePtr getUserHalProp(const VehiclePropValue& requestedPropValue,
+                                       StatusCode* outStatus);
+    // Set a user HAL property.
+    StatusCode setUserHalProp(const VehiclePropValue& propValue);
+    // Create a VHAL heart beat property.
+    VehicleHal::VehiclePropValuePtr createVhalHeartBeatProp();
+
+  private:
+    // Check whether a vendor mixed value property is valid according to its config array.
+    // See 'VehiclePropertyType' documentation in 'types.hal' for detail.
+    StatusCode checkVendorMixedPropValue(const VehiclePropValue& value,
+                                         const VehiclePropConfig* config);
+    // Read the override properties from a config file.
+    void getAllPropertiesOverride();
 };
 
 }  // namespace impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
index 66849bc..0aaa4c1 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
@@ -17,12 +17,17 @@
 #define LOG_TAG "DefaultVehicleHalServer"
 
 #include <fstream>
+#include <regex>
 
 #include <android-base/format.h>
 #include <android-base/logging.h>
+#include <android-base/parsedouble.h>
+#include <android-base/parseint.h>
+#include <android-base/properties.h>
 #include <utils/SystemClock.h>
 
 #include "DefaultConfig.h"
+#include "FakeObd2Frame.h"
 #include "JsonFakeValueGenerator.h"
 #include "LinearFakeValueGenerator.h"
 
@@ -36,6 +41,10 @@
 
 namespace impl {
 
+namespace {
+const char* VENDOR_OVERRIDE_DIR = "/vendor/etc/vhaloverride/";
+}  // namespace
+
 void DefaultVehicleHalServer::storePropInitialValue(const ConfigDeclaration& config) {
     VehiclePropConfig cfg = config.config;
 
@@ -70,8 +79,13 @@
     for (auto& it : kVehicleProperties) {
         VehiclePropConfig cfg = it.config;
         mServerSidePropStore.registerProperty(cfg);
+        // Skip diagnostic properties since there is special logic to handle those.
+        if (isDiagnosticProperty(cfg)) {
+            continue;
+        }
         storePropInitialValue(it);
     }
+    maybeOverrideProperties(VENDOR_OVERRIDE_DIR);
 }
 
 void DefaultVehicleHalServer::sendAllValuesToClient() {
@@ -82,7 +96,7 @@
     }
 }
 
-GeneratorHub* DefaultVehicleHalServer::getGenerator() {
+GeneratorHub* DefaultVehicleHalServer::getGeneratorHub() {
     return &mGeneratorHub;
 }
 
@@ -145,8 +159,8 @@
                 return StatusCode::INVALID_ARG;
             }
             int32_t cookie = v.int32Values[1];
-            getGenerator()->registerGenerator(cookie,
-                                              std::make_unique<LinearFakeValueGenerator>(request));
+            getGeneratorHub()->registerGenerator(
+                    cookie, std::make_unique<LinearFakeValueGenerator>(request));
             break;
         }
         case FakeDataCommand::StartJson: {
@@ -156,8 +170,12 @@
                 return StatusCode::INVALID_ARG;
             }
             int32_t cookie = std::hash<std::string>()(v.stringValue);
-            getGenerator()->registerGenerator(cookie,
-                                              std::make_unique<JsonFakeValueGenerator>(request));
+            auto generator = std::make_unique<JsonFakeValueGenerator>(request);
+            if (!generator->hasNext()) {
+                LOG(ERROR) << __func__ << ": invalid JSON file, no events";
+                return StatusCode::INVALID_ARG;
+            }
+            getGeneratorHub()->registerGenerator(cookie, std::move(generator));
             break;
         }
         case FakeDataCommand::StopLinear: {
@@ -167,7 +185,7 @@
                 return StatusCode::INVALID_ARG;
             }
             int32_t cookie = v.int32Values[1];
-            getGenerator()->unregisterGenerator(cookie);
+            getGeneratorHub()->unregisterGenerator(cookie);
             break;
         }
         case FakeDataCommand::StopJson: {
@@ -177,7 +195,7 @@
                 return StatusCode::INVALID_ARG;
             }
             int32_t cookie = std::hash<std::string>()(v.stringValue);
-            getGenerator()->unregisterGenerator(cookie);
+            getGeneratorHub()->unregisterGenerator(cookie);
             break;
         }
         case FakeDataCommand::KeyPress: {
@@ -331,20 +349,254 @@
 }
 
 IVehicleServer::DumpResult DefaultVehicleHalServer::onDump(
-        const std::vector<std::string>& /* options */) {
+        const std::vector<std::string>& options) {
     DumpResult result;
-    result.callerShouldDumpState = true;
-
-    result.buffer += "Server side properties: \n";
-    auto values = mServerSidePropStore.readAllValues();
-    size_t i = 0;
-    for (const auto& value : values) {
-        result.buffer += fmt::format("[{}]: {}\n", i, toString(value));
-        i++;
+    if (options.size() == 0) {
+        // No options, dump all stored properties.
+        result.callerShouldDumpState = true;
+        result.buffer += "Server side properties: \n";
+        auto values = mServerSidePropStore.readAllValues();
+        size_t i = 0;
+        for (const auto& value : values) {
+            result.buffer += fmt::format("[{}]: {}\n", i, toString(value));
+            i++;
+        }
+        return result;
     }
+    if (options[0] != "--debughal") {
+        // We only expect "debughal" command. This might be some commands that the caller knows
+        // about, so let caller handle it.
+        result.callerShouldDumpState = true;
+        return result;
+    }
+
+    return debug(options);
+}
+
+IVehicleServer::DumpResult DefaultVehicleHalServer::debug(const std::vector<std::string>& options) {
+    DumpResult result;
+    // This is a debug command for the HAL, caller should not continue to dump state.
+    result.callerShouldDumpState = false;
+
+    if (options.size() < 2) {
+        result.buffer += "No command specified\n";
+        result.buffer += getHelpInfo();
+        return result;
+    }
+
+    std::string command = options[1];
+    if (command == "--help") {
+        result.buffer += getHelpInfo();
+        return result;
+    } else if (command == "--genfakedata") {
+        return genFakeData(options);
+    }
+
+    result.buffer += "Unknown command: \"" + command + "\"\n";
+    result.buffer += getHelpInfo();
     return result;
 }
 
+std::string DefaultVehicleHalServer::getHelpInfo() {
+    return "Help: \n"
+           "Generate Fake Data: \n"
+           "\tStart a linear generator: \n"
+           "\t--debughal --genfakedata --startlinear [propID(int32)] [middleValue(float)] "
+           "[currentValue(float)] [dispersion(float)] [increment(float)] [interval(int64)]\n"
+           "\tStop a linear generator: \n"
+           "\t--debughal --genfakedata --stoplinear [propID(int32)]\n"
+           "\tStart a json generator: \n"
+           "\t--debughal --genfakedata --startjson [jsonFilePath(string)] "
+           "[repetition(int32)(optional)]\n"
+           "\tStop a json generator: \n"
+           "\t--debughal --genfakedata --stopjson [jsonFilePath(string)]\n"
+           "\tGenerate key press: \n"
+           "\t--debughal --genfakedata --keypress [keyCode(int32)] [display[int32]]\n";
+}
+
+IVehicleServer::DumpResult DefaultVehicleHalServer::genFakeData(
+        const std::vector<std::string>& options) {
+    DumpResult result;
+    // This is a debug command for the HAL, caller should not continue to dump state.
+    result.callerShouldDumpState = false;
+
+    if (options.size() < 3) {
+        result.buffer += "No subcommand specified for genfakedata\n";
+        result.buffer += getHelpInfo();
+        return result;
+    }
+
+    std::string command = options[2];
+    if (command == "--startlinear") {
+        LOG(INFO) << __func__ << "FakeDataCommand::StartLinear";
+        // --debughal --genfakedata --startlinear [propID(int32)] [middleValue(float)]
+        // [currentValue(float)] [dispersion(float)] [increment(float)] [interval(int64)]
+        if (options.size() != 9) {
+            result.buffer +=
+                    "incorrect argument count, need 9 arguments for --genfakedata --startlinear\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        int32_t propId;
+        float middleValue;
+        float currentValue;
+        float dispersion;
+        float increment;
+        int64_t interval;
+        if (!android::base::ParseInt(options[3], &propId)) {
+            result.buffer += "failed to parse propdID as int: \"" + options[3] + "\"\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        if (!android::base::ParseFloat(options[4], &middleValue)) {
+            result.buffer += "failed to parse middleValue as float: \"" + options[4] + "\"\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        if (!android::base::ParseFloat(options[5], &currentValue)) {
+            result.buffer += "failed to parse currentValue as float: \"" + options[5] + "\"\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        if (!android::base::ParseFloat(options[6], &dispersion)) {
+            result.buffer += "failed to parse dispersion as float: \"" + options[6] + "\"\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        if (!android::base::ParseFloat(options[7], &increment)) {
+            result.buffer += "failed to parse increment as float: \"" + options[7] + "\"\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        if (!android::base::ParseInt(options[8], &interval)) {
+            result.buffer += "failed to parse interval as int: \"" + options[8] + "\"\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        auto generator = std::make_unique<LinearFakeValueGenerator>(
+                propId, middleValue, currentValue, dispersion, increment, interval);
+        getGeneratorHub()->registerGenerator(propId, std::move(generator));
+        return result;
+    } else if (command == "--stoplinear") {
+        LOG(INFO) << __func__ << "FakeDataCommand::StopLinear";
+        // --debughal --genfakedata --stoplinear [propID(int32)]
+        if (options.size() != 4) {
+            result.buffer +=
+                    "incorrect argument count, need 4 arguments for --genfakedata --stoplinear\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        int32_t propId;
+        if (!android::base::ParseInt(options[3], &propId)) {
+            result.buffer += "failed to parse propdID as int: \"" + options[3] + "\"\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        getGeneratorHub()->unregisterGenerator(propId);
+        return result;
+    } else if (command == "--startjson") {
+        LOG(INFO) << __func__ << "FakeDataCommand::StartJson";
+        // --debughal --genfakedata --startjson [jsonFilePath(string)] [repetition(int32)(optional)]
+        if (options.size() != 4 && options.size() != 5) {
+            result.buffer +=
+                    "incorrect argument count, need 4 or 5 arguments for --genfakedata "
+                    "--startjson\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        std::string fileName = options[3];
+        int32_t cookie = std::hash<std::string>()(fileName);
+        // Iterate infinitely if repetition number is not provided
+        int32_t repetition = -1;
+        if (options.size() == 5) {
+            if (!android::base::ParseInt(options[4], &repetition)) {
+                result.buffer += "failed to parse repetition as int: \"" + options[4] + "\"\n";
+                result.buffer += getHelpInfo();
+                return result;
+            }
+        }
+        auto generator = std::make_unique<JsonFakeValueGenerator>(fileName, repetition);
+        if (!generator->hasNext()) {
+            result.buffer += "invalid JSON file, no events";
+            return result;
+        }
+        getGeneratorHub()->registerGenerator(cookie, std::move(generator));
+        return result;
+    } else if (command == "--stopjson") {
+        LOG(INFO) << __func__ << "FakeDataCommand::StopJson";
+        // --debughal --genfakedata --stopjson [jsonFilePath(string)]
+        if (options.size() != 4) {
+            result.buffer +=
+                    "incorrect argument count, need 4 arguments for --genfakedata --stopjson\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        std::string fileName = options[3];
+        int32_t cookie = std::hash<std::string>()(fileName);
+        getGeneratorHub()->unregisterGenerator(cookie);
+        return result;
+    } else if (command == "--keypress") {
+        LOG(INFO) << __func__ << "FakeDataCommand::KeyPress";
+        int32_t keyCode;
+        int32_t display;
+        // --debughal --genfakedata --keypress [keyCode(int32)] [display[int32]]
+        if (options.size() != 5) {
+            result.buffer +=
+                    "incorrect argument count, need 5 arguments for --genfakedata --keypress\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        if (!android::base::ParseInt(options[3], &keyCode)) {
+            result.buffer += "failed to parse keyCode as int: \"" + options[3] + "\"\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        if (!android::base::ParseInt(options[4], &display)) {
+            result.buffer += "failed to parse display as int: \"" + options[4] + "\"\n";
+            result.buffer += getHelpInfo();
+            return result;
+        }
+        // Send back to HAL
+        onPropertyValueFromCar(
+                *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display),
+                /*updateStatus=*/true);
+        onPropertyValueFromCar(
+                *createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display),
+                /*updateStatus=*/true);
+        return result;
+    }
+
+    result.buffer += "Unknown command: \"" + command + "\"\n";
+    result.buffer += getHelpInfo();
+    return result;
+}
+
+void DefaultVehicleHalServer::maybeOverrideProperties(const char* overrideDir) {
+    if (android::base::GetBoolProperty("persist.vendor.vhal_init_value_override", false)) {
+        overrideProperties(overrideDir);
+    }
+}
+
+void DefaultVehicleHalServer::overrideProperties(const char* overrideDir) {
+    LOG(INFO) << "loading vendor override properties from " << overrideDir;
+    if (auto dir = opendir(overrideDir)) {
+        std::regex reg_json(".*[.]json", std::regex::icase);
+        while (auto f = readdir(dir)) {
+            if (!regex_match(f->d_name, reg_json)) {
+                continue;
+            }
+            std::string file = overrideDir + std::string(f->d_name);
+            JsonFakeValueGenerator tmpGenerator(file);
+
+            std::vector<VehiclePropValue> propValues = tmpGenerator.getAllEvents();
+            for (const VehiclePropValue& prop : propValues) {
+                mServerSidePropStore.writeValue(prop, true);
+            }
+        }
+        closedir(dir);
+    }
+}
+
 }  // namespace impl
 
 }  // namespace V2_0
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h
index 1a42cb8..5858325 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h
@@ -52,7 +52,7 @@
 
   protected:
     using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
-    GeneratorHub* getGenerator();
+    GeneratorHub* getGeneratorHub();
 
     VehiclePropValuePool* getValuePool() const;
 
@@ -67,12 +67,28 @@
 
     void storePropInitialValue(const ConfigDeclaration& config);
 
+    DumpResult debug(const std::vector<std::string>& options);
+
+    std::string getHelpInfo();
+
+    DumpResult genFakeData(const std::vector<std::string>& options);
+    // If "persist.vendor.vhal_init_value_override" is true, try to override the properties default
+    // values according to JSON files in 'overrideDir'. Would be called in constructor using
+    // VENDOR_OVERRIDE_DIR as overrideDir.
+    void maybeOverrideProperties(const char* overrideDir);
+
   protected:
     GeneratorHub mGeneratorHub{
             [this](const VehiclePropValue& value) { return onFakeValueGenerated(value); }};
 
     VehiclePropValuePool* mValuePool{nullptr};
     VehiclePropertyStore mServerSidePropStore;
+
+  private:
+    // Expose protected methods to unit test.
+    friend class DefaultVhalImplTestHelper;
+    // Override the properties using config files in 'overrideDir'.
+    void overrideProperties(const char* overrideDir);
 };
 
 }  // namespace impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeObd2Frame.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeObd2Frame.cpp
new file mode 100644
index 0000000..d95584d
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeObd2Frame.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2021 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/automotive/vehicle/2.0/types.h>
+#include <utils/Log.h>
+#include <vhal_v2_0/Obd2SensorStore.h>
+#include <vhal_v2_0/PropertyUtils.h>
+#include <vhal_v2_0/VehiclePropertyStore.h>
+#include <vhal_v2_0/VehicleUtils.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+namespace {
+
+std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorIntegerSensors,
+                                                      size_t numVendorFloatSensors) {
+    std::unique_ptr<Obd2SensorStore> sensorStore(
+            new Obd2SensorStore(numVendorIntegerSensors, numVendorFloatSensors));
+
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS,
+                                  toInt(Obd2FuelSystemStatus::CLOSED_LOOP));
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON, 0);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::IGNITION_MONITORS_SUPPORTED,
+                                  toInt(Obd2IgnitionMonitorKind::SPARK));
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::IGNITION_SPECIFIC_MONITORS,
+                                  Obd2CommonIgnitionMonitors::COMPONENTS_AVAILABLE |
+                                          Obd2CommonIgnitionMonitors::MISFIRE_AVAILABLE |
+                                          Obd2SparkIgnitionMonitors::AC_REFRIGERANT_AVAILABLE |
+                                          Obd2SparkIgnitionMonitors::EVAPORATIVE_SYSTEM_AVAILABLE);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::INTAKE_AIR_TEMPERATURE, 35);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::COMMANDED_SECONDARY_AIR_STATUS,
+                                  toInt(Obd2SecondaryAirStatus::FROM_OUTSIDE_OR_OFF));
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT, 1);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::RUNTIME_SINCE_ENGINE_START, 500);
+    sensorStore->setIntegerSensor(
+            DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON, 0);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::WARMUPS_SINCE_CODES_CLEARED, 51);
+    sensorStore->setIntegerSensor(
+            DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_SINCE_CODES_CLEARED, 365);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE, 30);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::CONTROL_MODULE_VOLTAGE, 12);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::AMBIENT_AIR_TEMPERATURE, 18);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::MAX_FUEL_AIR_EQUIVALENCE_RATIO, 1);
+    sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::FUEL_TYPE,
+                                  toInt(Obd2FuelType::GASOLINE));
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD, 0.153);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1, -0.16);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1, -0.16);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK2, -0.16);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK2, -0.16);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::INTAKE_MANIFOLD_ABSOLUTE_PRESSURE, 7.5);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ENGINE_RPM, 1250.);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::VEHICLE_SPEED, 40.);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::TIMING_ADVANCE, 2.5);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::THROTTLE_POSITION, 19.75);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::OXYGEN_SENSOR1_VOLTAGE, 0.265);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::FUEL_TANK_LEVEL_INPUT, 0.824);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::EVAPORATION_SYSTEM_VAPOR_PRESSURE,
+                                -0.373);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::CATALYST_TEMPERATURE_BANK1_SENSOR1,
+                                190.);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::RELATIVE_THROTTLE_POSITION, 3.);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ABSOLUTE_THROTTLE_POSITION_B, 0.306);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_D, 0.188);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_E, 0.094);
+    sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::COMMANDED_THROTTLE_ACTUATOR, 0.024);
+
+    return sensorStore;
+}
+
+}  // namespace
+
+void initObd2LiveFrame(VehiclePropertyStore* propStore, const VehiclePropConfig& propConfig) {
+    auto liveObd2Frame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
+    auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]),
+                                            static_cast<size_t>(propConfig.configArray[1]));
+    sensorStore->fillPropValue("", liveObd2Frame.get());
+    liveObd2Frame->prop = OBD2_LIVE_FRAME;
+
+    propStore->writeValue(*liveObd2Frame, true);
+}
+
+void initObd2FreezeFrame(VehiclePropertyStore* propStore, const VehiclePropConfig& propConfig) {
+    auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]),
+                                            static_cast<size_t>(propConfig.configArray[1]));
+
+    static std::vector<std::string> sampleDtcs = {"P0070", "P0102", "P0123"};
+    for (auto&& dtc : sampleDtcs) {
+        auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
+        sensorStore->fillPropValue(dtc, freezeFrame.get());
+        freezeFrame->prop = OBD2_FREEZE_FRAME;
+        ALOGE("freeze frame: %lld", (long long)freezeFrame->timestamp);
+
+        propStore->writeValue(*freezeFrame, true);
+    }
+}
+
+StatusCode fillObd2FreezeFrame(VehiclePropertyStore* propStore,
+                               const VehiclePropValue& requestedPropValue,
+                               VehiclePropValue* outValue) {
+    if (requestedPropValue.value.int64Values.size() != 1) {
+        ALOGE("asked for OBD2_FREEZE_FRAME without valid timestamp");
+        return StatusCode::INVALID_ARG;
+    }
+    if (propStore->readValuesForProperty(OBD2_FREEZE_FRAME).size() == 0) {
+        // Should no freeze frame be available at the given timestamp, a response of NOT_AVAILABLE
+        // must be returned by the implementation
+        return StatusCode::NOT_AVAILABLE;
+    }
+    auto timestamp = requestedPropValue.value.int64Values[0];
+    auto freezeFrame = propStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp);
+    if (freezeFrame == nullptr) {
+        ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp");
+        return StatusCode::INVALID_ARG;
+    }
+    outValue->prop = OBD2_FREEZE_FRAME;
+    outValue->value.int32Values = freezeFrame->value.int32Values;
+    outValue->value.floatValues = freezeFrame->value.floatValues;
+    outValue->value.bytes = freezeFrame->value.bytes;
+    outValue->value.stringValue = freezeFrame->value.stringValue;
+    outValue->timestamp = freezeFrame->timestamp;
+    return StatusCode::OK;
+}
+
+StatusCode fillObd2DtcInfo(VehiclePropertyStore* propStore, VehiclePropValue* outValue) {
+    std::vector<int64_t> timestamps;
+    for (const auto& freezeFrame : propStore->readValuesForProperty(OBD2_FREEZE_FRAME)) {
+        timestamps.push_back(freezeFrame.timestamp);
+    }
+    outValue->value.int64Values = timestamps;
+    outValue->prop = OBD2_FREEZE_FRAME_INFO;
+    return StatusCode::OK;
+}
+
+StatusCode clearObd2FreezeFrames(VehiclePropertyStore* propStore,
+                                 const VehiclePropValue& propValue) {
+    if (propValue.value.int64Values.size() == 0) {
+        propStore->removeValuesForProperty(OBD2_FREEZE_FRAME);
+        return StatusCode::OK;
+    } else {
+        for (int64_t timestamp : propValue.value.int64Values) {
+            auto freezeFrame = propStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp);
+            if (freezeFrame == nullptr) {
+                ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp");
+                return StatusCode::INVALID_ARG;
+            }
+            propStore->removeValue(*freezeFrame);
+        }
+    }
+    return StatusCode::OK;
+}
+
+bool isDiagnosticProperty(const VehiclePropConfig& propConfig) {
+    return (propConfig.prop == OBD2_LIVE_FRAME || propConfig.prop == OBD2_FREEZE_FRAME ||
+            propConfig.prop == OBD2_FREEZE_FRAME_CLEAR ||
+            propConfig.prop == OBD2_FREEZE_FRAME_INFO);
+}
+
+}  // namespace impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeObd2Frame.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeObd2Frame.h
new file mode 100644
index 0000000..704964c
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeObd2Frame.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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_automotive_vehicle_V2_0_impl_FakeObd2Frame_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_FakeObd2Frame_H_
+
+#include <android/hardware/automotive/vehicle/2.0/types.h>
+#include <vhal_v2_0/VehiclePropertyStore.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+void initObd2LiveFrame(VehiclePropertyStore* propStore, const VehiclePropConfig& propConfig);
+void initObd2FreezeFrame(VehiclePropertyStore* propStore, const VehiclePropConfig& propConfig);
+StatusCode fillObd2FreezeFrame(VehiclePropertyStore* propStore,
+                               const VehiclePropValue& requestedPropValue,
+                               VehiclePropValue* outValue);
+StatusCode fillObd2DtcInfo(VehiclePropertyStore* propStore, VehiclePropValue* outValue);
+StatusCode clearObd2FreezeFrames(VehiclePropertyStore* propStore,
+                                 const VehiclePropValue& propValue);
+bool isDiagnosticProperty(const VehiclePropConfig& propConfig);
+
+}  // namespace impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_V2_0_impl_FakeObd2Frame_H_
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
index b62918f..b728d62 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
@@ -33,12 +33,37 @@
 
 namespace impl {
 
+JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path, int32_t repetition) {
+    const char* file = path.c_str();
+    std::ifstream ifs(file);
+    if (!ifs) {
+        ALOGE("%s: couldn't open %s for parsing.", __func__, file);
+        mGenCfg = {
+                .index = 0,
+                .events = {},
+        };
+        mNumOfIterations = 0;
+        return;
+    }
+    mGenCfg = {
+            .index = 0,
+            .events = parseFakeValueJson(ifs),
+    };
+    mNumOfIterations = repetition;
+}
+
 JsonFakeValueGenerator::JsonFakeValueGenerator(const VehiclePropValue& request) {
     const auto& v = request.value;
     const char* file = v.stringValue.c_str();
     std::ifstream ifs(file);
     if (!ifs) {
         ALOGE("%s: couldn't open %s for parsing.", __func__, file);
+        mGenCfg = {
+                .index = 0,
+                .events = {},
+        };
+        mNumOfIterations = 0;
+        return;
     }
     mGenCfg = {
         .index = 0,
@@ -48,10 +73,16 @@
     mNumOfIterations = v.int32Values.size() < 2 ? -1 : v.int32Values[1];
 }
 
-JsonFakeValueGenerator::JsonFakeValueGenerator(std::string path) {
+JsonFakeValueGenerator::JsonFakeValueGenerator(const std::string& path) {
     std::ifstream ifs(path);
     if (!ifs) {
         ALOGE("%s: couldn't open %s for parsing.", __func__, path.c_str());
+        mGenCfg = {
+                .index = 0,
+                .events = {},
+        };
+        mNumOfIterations = 0;
+        return;
     }
     mGenCfg = {
         .index = 0,
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.h
index dc8ff66..caa3417 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.h
@@ -41,7 +41,8 @@
 
 public:
     JsonFakeValueGenerator(const VehiclePropValue& request);
-    JsonFakeValueGenerator(std::string path);
+    JsonFakeValueGenerator(const std::string& path, int32_t repetition);
+    JsonFakeValueGenerator(const std::string& path);
 
     ~JsonFakeValueGenerator() = default;
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.cpp
index 96aaafe..a2278bd 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.cpp
@@ -29,23 +29,36 @@
 
 namespace impl {
 
+LinearFakeValueGenerator::LinearFakeValueGenerator(int32_t propId, float middleValue,
+                                                   float currentValue, float dispersion,
+                                                   float increment, int64_t interval) {
+    initGenCfg(propId, middleValue, currentValue, dispersion, increment, interval);
+}
+
 LinearFakeValueGenerator::LinearFakeValueGenerator(const VehiclePropValue& request) {
     const auto& v = request.value;
+    initGenCfg(v.int32Values[1], v.floatValues[0], v.floatValues[0], v.floatValues[1],
+               v.floatValues[2], v.int64Values[0]);
+}
+
+void LinearFakeValueGenerator::initGenCfg(int32_t propId, float middleValue, float currentValue,
+                                          float dispersion, float increment, int64_t interval) {
+    if (currentValue < middleValue - dispersion || currentValue >= middleValue + dispersion) {
+        ALOGW("%s: invalid initValue: %f, out of range, default to %f", __func__, currentValue,
+              middleValue);
+        currentValue = middleValue;
+    }
     mGenCfg = GeneratorCfg{
-        .propId = v.int32Values[1],
-        .initialValue = v.floatValues[0],
-        .currentValue = v.floatValues[0],
-        .dispersion = v.floatValues[1],
-        .increment = v.floatValues[2],
-        .interval = Nanos(v.int64Values[0]),
+            .propId = propId,
+            .middleValue = middleValue,
+            .currentValue = currentValue,
+            .dispersion = dispersion,
+            .increment = increment,
+            .interval = Nanos(interval),
     };
 }
 
 VehiclePropValue LinearFakeValueGenerator::nextEvent() {
-    mGenCfg.currentValue += mGenCfg.increment;
-    if (mGenCfg.currentValue > mGenCfg.initialValue + mGenCfg.dispersion) {
-        mGenCfg.currentValue = mGenCfg.initialValue - mGenCfg.dispersion;
-    }
     // TODO: (chenhaosjtuacm) remove "{}" if AGL compiler updated
     VehiclePropValue event = {.timestamp = {}, .areaId = {}, .prop = mGenCfg.propId};
     auto& value = event.value;
@@ -67,6 +80,12 @@
     }
     TimePoint eventTime = Clock::now() + mGenCfg.interval;
     event.timestamp = eventTime.time_since_epoch().count();
+
+    mGenCfg.currentValue += mGenCfg.increment;
+    if (mGenCfg.currentValue >= mGenCfg.middleValue + mGenCfg.dispersion) {
+        // Wrap around, (i - d) + c - (i + d) = c - 2 * d
+        mGenCfg.currentValue = mGenCfg.currentValue - 2 * mGenCfg.dispersion;
+    }
     return event;
 }
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.h
index d3b666d..d870209 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/LinearFakeValueGenerator.h
@@ -35,8 +35,8 @@
 
     struct GeneratorCfg {
         int32_t propId;
-        float initialValue;
-        float currentValue;  //  Should be in range (initialValue +/- dispersion).
+        float middleValue;
+        float currentValue;  //  Should be in range (middleValue +/- dispersion).
         float dispersion;    //  Defines minimum and maximum value based on initial value.
         float increment;     //  Value that we will be added to currentValue with each timer tick.
         Nanos interval;
@@ -44,6 +44,11 @@
 
 public:
     LinearFakeValueGenerator(const VehiclePropValue& request);
+    // A linear value generator in range [middleValue - dispersion, middleValue + dispersion),
+    // starts at 'currentValue' and at each 'interval', increase by 'increment' and loop back if
+    // exceeds middleValue + dispersion.
+    LinearFakeValueGenerator(int32_t propId, float middleValue, float currentValue,
+                             float dispersion, float increment, int64_t interval);
     ~LinearFakeValueGenerator() = default;
 
     VehiclePropValue nextEvent();
@@ -52,6 +57,9 @@
 
 private:
     GeneratorCfg mGenCfg;
+
+    void initGenCfg(int32_t propId, float middleValue, float currentValue, float dispersion,
+                    float increment, int64_t interval);
 };
 
 }  // namespace impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/Android.bp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/Android.bp
new file mode 100644
index 0000000..a7d5440
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/Android.bp
@@ -0,0 +1,23 @@
+// Copyright (C) 2021 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.
+
+filegroup {
+    name: "vhal_test_json",
+    srcs: ["prop.json"],
+}
+
+filegroup {
+    name: "vhal_test_override_json",
+    srcs: ["override/*"],
+}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
index e943e67..2268df8 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
@@ -14,16 +14,45 @@
  * limitations under the License.
  */
 
+#include <android-base/file.h>
 #include <android/hardware/automotive/vehicle/2.0/types.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <sys/mman.h>
 #include <vhal_v2_0/ConcurrentQueue.h>
+#include <vhal_v2_0/DefaultConfig.h>
 #include <vhal_v2_0/DefaultVehicleConnector.h>
 #include <vhal_v2_0/DefaultVehicleHal.h>
 #include <vhal_v2_0/PropertyUtils.h>
 #include <vhal_v2_0/VehicleObjectPool.h>
 #include <vhal_v2_0/VehiclePropertyStore.h>
 
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+namespace impl {
+
+class DefaultVhalImplTestHelper {
+  public:
+    DefaultVhalImplTestHelper(DefaultVehicleHalServer* server) { mServer = server; }
+
+    void overrideProperties(const char* overrideDir) {
+        mServer->overrideProperties(overrideDir);
+    }
+
+  private:
+    DefaultVehicleHalServer* mServer;
+};
+
+}  // namespace impl
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
 namespace {
 
 using ::android::hardware::hidl_handle;
@@ -32,6 +61,7 @@
 using ::android::hardware::automotive::vehicle::V2_0::FuelType;
 using ::android::hardware::automotive::vehicle::V2_0::recyclable_ptr;
 using ::android::hardware::automotive::vehicle::V2_0::StatusCode;
+using ::android::hardware::automotive::vehicle::V2_0::VehicleHwKeyInputAction;
 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropConfig;
 using ::android::hardware::automotive::vehicle::V2_0::VehicleProperty;
 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyStatus;
@@ -40,43 +70,76 @@
 using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValuePool;
 using ::android::hardware::automotive::vehicle::V2_0::impl::DefaultVehicleConnector;
 using ::android::hardware::automotive::vehicle::V2_0::impl::DefaultVehicleHal;
+using ::android::hardware::automotive::vehicle::V2_0::impl::DefaultVhalImplTestHelper;
+using ::android::hardware::automotive::vehicle::V2_0::impl::HVAC_ALL;
+using ::android::hardware::automotive::vehicle::V2_0::impl::HVAC_LEFT;
+using ::android::hardware::automotive::vehicle::V2_0::impl::HVAC_RIGHT;
+using ::android::hardware::automotive::vehicle::V2_0::impl::kMixedTypePropertyForTest;
+using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME;
+using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME_CLEAR;
+using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME_INFO;
+using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_LIVE_FRAME;
+
+using ::testing::HasSubstr;
 
 using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
 
+// The maximum length of property ID in string.
+const size_t MAX_PROP_ID_LENGTH = 100;
+
 class DefaultVhalImplTest : public ::testing::Test {
   public:
-    ~DefaultVhalImplTest() { mEventQueue.deactivate(); }
+    ~DefaultVhalImplTest() {
+        mEventQueue.deactivate();
+        mHeartBeatQueue.deactivate();
+        // Destroy mHal before destroying its dependencies.
+        mHal.reset();
+        mConnector.reset();
+        mPropStore.reset();
+    }
 
   protected:
     void SetUp() override {
         mPropStore.reset(new VehiclePropertyStore);
         mConnector.reset(new DefaultVehicleConnector);
-        mHal.reset(new DefaultVehicleHal(mPropStore.get(), mConnector.get()));
         mConnector->setValuePool(&mValueObjectPool);
+        mHal.reset(new DefaultVehicleHal(mPropStore.get(), mConnector.get()));
+        initHal();
+    }
+
+    void initHal() {
         mHal->init(&mValueObjectPool,
                    std::bind(&DefaultVhalImplTest::onHalEvent, this, std::placeholders::_1),
                    std::bind(&DefaultVhalImplTest::onHalPropertySetError, this,
                              std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
     }
 
-  private:
-    void onHalEvent(VehiclePropValuePtr v) { mEventQueue.push(std::move(v)); }
-
-    void onHalPropertySetError(StatusCode /*errorCode*/, int32_t /*property*/, int32_t /*areaId*/) {
-    }
-
   protected:
     std::unique_ptr<DefaultVehicleHal> mHal;
     std::unique_ptr<DefaultVehicleConnector> mConnector;
     std::unique_ptr<VehiclePropertyStore> mPropStore;
     VehiclePropValuePool mValueObjectPool;
     android::ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
+    android::ConcurrentQueue<VehiclePropValuePtr> mHeartBeatQueue;
+
+  private:
+    void onHalEvent(VehiclePropValuePtr v) {
+        if (v->prop != toInt(VehicleProperty::VHAL_HEARTBEAT)) {
+            // Ignore heartbeat properties.
+            mEventQueue.push(std::move(v));
+        } else {
+            mHeartBeatQueue.push(std::move(v));
+        }
+    }
+
+    void onHalPropertySetError(StatusCode /*errorCode*/, int32_t /*property*/, int32_t /*areaId*/) {
+    }
 };
 
 TEST_F(DefaultVhalImplTest, testListProperties) {
     std::vector<VehiclePropConfig> configs = mHal->listProperties();
 
-    EXPECT_EQ((size_t)122, configs.size());
+    EXPECT_EQ((size_t)121, configs.size());
 }
 
 TEST_F(DefaultVhalImplTest, testGetDefaultPropertyFloat) {
@@ -87,7 +150,7 @@
     auto gotValue = mHal->get(value, &status);
 
     EXPECT_EQ(StatusCode::OK, status);
-    EXPECT_EQ((unsigned int)1, gotValue->value.floatValues.size());
+    ASSERT_EQ((unsigned int)1, gotValue->value.floatValues.size());
     EXPECT_EQ(15000.0f, gotValue->value.floatValues[0]);
 }
 
@@ -99,7 +162,7 @@
     auto gotValue = mHal->get(value, &status);
 
     EXPECT_EQ(StatusCode::OK, status);
-    EXPECT_EQ((unsigned int)1, gotValue->value.int32Values.size());
+    ASSERT_EQ((unsigned int)1, gotValue->value.int32Values.size());
     EXPECT_EQ((int)FuelType::FUEL_TYPE_UNLEADED, gotValue->value.int32Values[0]);
 }
 
@@ -111,7 +174,7 @@
     auto gotValue = mHal->get(value, &status);
 
     EXPECT_EQ(StatusCode::OK, status);
-    EXPECT_EQ((unsigned int)1, gotValue->value.int32Values.size());
+    ASSERT_EQ((unsigned int)1, gotValue->value.int32Values.size());
     EXPECT_EQ(2020, gotValue->value.int32Values[0]);
 }
 
@@ -143,11 +206,11 @@
     value.value.floatValues[0] = 1.0f;
 
     StatusCode status = mHal->set(value);
-    EXPECT_EQ(StatusCode::OK, status);
+    ASSERT_EQ(StatusCode::OK, status);
 
     auto gotValue = mHal->get(value, &status);
     EXPECT_EQ(StatusCode::OK, status);
-    EXPECT_EQ((unsigned int)1, gotValue->value.floatValues.size());
+    ASSERT_EQ((unsigned int)1, gotValue->value.floatValues.size());
     EXPECT_EQ(1.0f, gotValue->value.floatValues[0]);
 }
 
@@ -158,11 +221,11 @@
     value.value.int32Values[0] = (int)FuelType::FUEL_TYPE_LEADED;
 
     StatusCode status = mHal->set(value);
-    EXPECT_EQ(StatusCode::OK, status);
+    ASSERT_EQ(StatusCode::OK, status);
 
     auto gotValue = mHal->get(value, &status);
     EXPECT_EQ(StatusCode::OK, status);
-    EXPECT_EQ((unsigned int)1, gotValue->value.int32Values.size());
+    ASSERT_EQ((unsigned int)1, gotValue->value.int32Values.size());
     EXPECT_EQ((int)FuelType::FUEL_TYPE_LEADED, gotValue->value.int32Values[0]);
 }
 
@@ -187,13 +250,41 @@
     value.value.stringValue = "My Vehicle";
 
     StatusCode status = mHal->set(value);
-    EXPECT_EQ(StatusCode::OK, status);
+    ASSERT_EQ(StatusCode::OK, status);
 
     auto gotValue = mHal->get(value, &status);
     EXPECT_EQ(StatusCode::OK, status);
     EXPECT_EQ("My Vehicle", gotValue->value.stringValue);
 }
 
+TEST_F(DefaultVhalImplTest, testSetMixed) {
+    VehiclePropValue value;
+    value.prop = kMixedTypePropertyForTest;
+    // mixed prop.
+    // .configArray = {1, 1, 0, 2, 0, 0, 1, 0, 0}
+    // 1 string, 1 int, 0 bool, 2 ints, 0 int64, 0 int64s, 1 float, 0 floats, 0 bytes
+    value.value.stringValue = "test";
+    value.value.int32Values.resize(3);
+    value.value.int32Values[0] = 1;
+    value.value.int32Values[1] = 2;
+    value.value.int32Values[2] = 3;
+    value.value.floatValues.resize(1);
+    value.value.floatValues[0] = 1.0f;
+
+    StatusCode status = mHal->set(value);
+    ASSERT_EQ(StatusCode::OK, status);
+
+    auto gotValue = mHal->get(value, &status);
+    EXPECT_EQ(StatusCode::OK, status);
+    EXPECT_EQ("test", gotValue->value.stringValue);
+    ASSERT_EQ((size_t)3, gotValue->value.int32Values.size());
+    EXPECT_EQ(1, gotValue->value.int32Values[0]);
+    EXPECT_EQ(2, gotValue->value.int32Values[1]);
+    EXPECT_EQ(3, gotValue->value.int32Values[2]);
+    ASSERT_EQ((size_t)1, gotValue->value.floatValues.size());
+    EXPECT_EQ(1.0f, gotValue->value.floatValues[0]);
+}
+
 TEST_F(DefaultVhalImplTest, testSetUnknownProperty) {
     VehiclePropValue value;
     value.prop = 0;
@@ -219,7 +310,7 @@
 
     auto status = mHal->subscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 10);
 
-    EXPECT_EQ(StatusCode::OK, status);
+    ASSERT_EQ(StatusCode::OK, status);
 
     std::this_thread::sleep_for(std::chrono::milliseconds(500));
 
@@ -228,18 +319,18 @@
     value.prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
     value.value.floatValues.resize(1);
     value.value.floatValues[0] = 1.0f;
-    EXPECT_EQ(StatusCode::OK, mHal->set(value));
+    ASSERT_EQ(StatusCode::OK, mHal->set(value));
 
     std::this_thread::sleep_for(std::chrono::milliseconds(500));
 
     auto events = mEventQueue.flush();
-    EXPECT_LE((size_t)10, events.size());
+    ASSERT_LE((size_t)10, events.size());
 
     // The first event should be the default value.
-    EXPECT_EQ((size_t)1, events[0]->value.floatValues.size());
+    ASSERT_EQ((size_t)1, events[0]->value.floatValues.size());
     EXPECT_EQ(0.0f, events[0]->value.floatValues[0]);
     // The last event should be the value after update.
-    EXPECT_EQ((size_t)1, events[events.size() - 1]->value.floatValues.size());
+    ASSERT_EQ((size_t)1, events[events.size() - 1]->value.floatValues.size());
     EXPECT_EQ(1.0f, events[events.size() - 1]->value.floatValues[0]);
 }
 
@@ -247,15 +338,22 @@
     EXPECT_EQ(StatusCode::INVALID_ARG, mHal->subscribe(toInt(VehicleProperty::INFO_MAKE), 10));
 }
 
+TEST_F(DefaultVhalImplTest, testSubscribeSampleRateOutOfRange) {
+    EXPECT_EQ(StatusCode::INVALID_ARG,
+              mHal->subscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 10.1));
+    EXPECT_EQ(StatusCode::INVALID_ARG,
+              mHal->subscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 0.5));
+}
+
 TEST_F(DefaultVhalImplTest, testUnsubscribe) {
     auto status = mHal->subscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED), 10);
-    EXPECT_EQ(StatusCode::OK, status);
+    ASSERT_EQ(StatusCode::OK, status);
 
     // Wait for 0.5 seconds to generate some events.
     std::this_thread::sleep_for(std::chrono::milliseconds(500));
 
     status = mHal->unsubscribe(toInt(VehicleProperty::PERF_VEHICLE_SPEED));
-    EXPECT_EQ(StatusCode::OK, status);
+    ASSERT_EQ(StatusCode::OK, status);
 
     // Clear all the events.
     mEventQueue.flush();
@@ -272,15 +370,20 @@
     EXPECT_EQ(StatusCode::INVALID_ARG, mHal->unsubscribe(toInt(VehicleProperty::INFO_MAKE)));
 }
 
-TEST_F(DefaultVhalImplTest, testDump) {
-    hidl_vec<hidl_string> options;
-    hidl_handle fd = {};
+int createMemfd(hidl_handle* fd) {
     native_handle_t* handle = native_handle_create(/*numFds=*/1, /*numInts=*/0);
     int memfd = memfd_create("memfile", 0);
     handle->data[0] = dup(memfd);
-    fd.setTo(handle, /*shouldOwn=*/true);
+    fd->setTo(handle, /*shouldOwn=*/true);
+    return memfd;
+}
 
-    EXPECT_TRUE(mHal->dump(fd, options));
+TEST_F(DefaultVhalImplTest, testDump) {
+    hidl_vec<hidl_string> options;
+    hidl_handle fd = {};
+    int memfd = createMemfd(&fd);
+
+    ASSERT_TRUE(mHal->dump(fd, options));
 
     lseek(memfd, 0, SEEK_SET);
     char buf[10240] = {};
@@ -292,12 +395,872 @@
     StatusCode status;
     value.prop = toInt(VehicleProperty::INFO_MAKE);
     auto gotValue = mHal->get(value, &status);
-    EXPECT_EQ(StatusCode::OK, status);
+    ASSERT_EQ(StatusCode::OK, status);
     // Server side prop store does not have timestamp.
     gotValue->timestamp = 0;
 
     std::string infoMake = toString(*gotValue);
-    EXPECT_NE(std::string::npos, std::string(buf).find(infoMake));
+    EXPECT_THAT(std::string(buf), HasSubstr(infoMake));
+}
+
+TEST_F(DefaultVhalImplTest, testSetPropInvalidAreaId) {
+    VehiclePropValue propNormal = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
+                                   .areaId = HVAC_ALL,
+                                   .value.int32Values = {3}};
+    StatusCode status = mHal->set(propNormal);
+
+    EXPECT_EQ(StatusCode::OK, status);
+
+    // HVAC_FAN_SPEED only have HVAC_ALL area config and is not allowed to set by LEFT/RIGHT.
+    VehiclePropValue propWrongId = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
+                                    .areaId = HVAC_LEFT,
+                                    .value.int32Values = {3}};
+
+    status = mHal->set(propWrongId);
+
+    EXPECT_EQ(StatusCode::INVALID_ARG, status);
+}
+
+class DefaultVhalImplSetInvalidPropTest : public DefaultVhalImplTest,
+                                          public testing::WithParamInterface<VehiclePropValue> {};
+
+std::vector<VehiclePropValue> GenSetInvalidPropParams() {
+    std::vector<VehiclePropValue> props;
+    // int prop with no value.
+    VehiclePropValue intProp = {.prop = toInt(VehicleProperty::INFO_MODEL_YEAR)};
+    props.push_back(intProp);
+
+    // int prop with more than one value.
+    VehiclePropValue intPropWithValues = {.prop = toInt(VehicleProperty::INFO_MODEL_YEAR)};
+    intPropWithValues.value.int32Values.resize(2);
+    props.push_back(intPropWithValues);
+
+    // int vec prop with no value.
+    VehiclePropValue intVecProp = {.prop = toInt(VehicleProperty::INFO_FUEL_TYPE)};
+    props.push_back(intVecProp);
+
+    // int64 prop with no value.
+    VehiclePropValue int64Prop = {.prop = toInt(VehicleProperty::EPOCH_TIME)};
+    props.push_back(int64Prop);
+
+    // int64 prop with more than one value.
+    VehiclePropValue int64PropWithValues = {.prop = toInt(VehicleProperty::EPOCH_TIME)};
+    int64PropWithValues.value.int64Values.resize(2);
+    props.push_back(int64PropWithValues);
+
+    // int64 vec prop with no value.
+    VehiclePropValue int64VecProp = {.prop = toInt(VehicleProperty::WHEEL_TICK)};
+    props.push_back(int64VecProp);
+
+    // float prop with no value.
+    VehiclePropValue floatProp = {.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY)};
+    props.push_back(floatProp);
+
+    // float prop with more than one value.
+    VehiclePropValue floatPropWithValues = {.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY)};
+    floatPropWithValues.value.floatValues.resize(2);
+    props.push_back(floatPropWithValues);
+
+    // float vec prop with no value.
+    VehiclePropValue floatVecProp = {
+            .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION)};
+    props.push_back(floatVecProp);
+
+    // bool prop with no value.
+    VehiclePropValue boolProp = {
+            .prop = toInt(VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME)};
+    props.push_back(boolProp);
+
+    // bool prop with more than one value.
+    VehiclePropValue boolPropWithValues = {
+            .prop = toInt(VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME)};
+    boolPropWithValues.value.int32Values.resize(2);
+    props.push_back(boolPropWithValues);
+
+    // mixed prop.
+    // .configArray = {1, 1, 0, 2, 0, 0, 1, 0, 0}
+    // 1 string, 1 int, 0 bool, 2 ints, 0 int64, 0 int64s, 1 float, 0 floats, 0 bytes
+    VehiclePropValue mixedProp1 = {.prop = kMixedTypePropertyForTest};
+    // Expect 1 bool, and 2 ints, we only have 1 value.
+    mixedProp1.value.int32Values.resize(1);
+    mixedProp1.value.floatValues.resize(1);
+    props.push_back(mixedProp1);
+
+    VehiclePropValue mixedProp2 = {.prop = kMixedTypePropertyForTest};
+    mixedProp2.value.int32Values.resize(3);
+    // Missing float value.
+    mixedProp2.value.floatValues.resize(0);
+    props.push_back(mixedProp2);
+
+    return props;
+}
+
+TEST_P(DefaultVhalImplSetInvalidPropTest, testSetInvalidPropValue) {
+    VehiclePropValue value = GetParam();
+
+    StatusCode status = mHal->set(value);
+
+    EXPECT_EQ(StatusCode::INVALID_ARG, status);
+}
+
+INSTANTIATE_TEST_SUITE_P(DefaultVhalImplSetInvalidPropTests, DefaultVhalImplSetInvalidPropTest,
+                         testing::ValuesIn(GenSetInvalidPropParams()));
+
+struct SetPropRangeTestCase {
+    std::string name;
+    VehiclePropValue prop;
+    StatusCode code;
+};
+
+class DefaultVhalImplSetPropRangeTest : public DefaultVhalImplTest,
+                                        public testing::WithParamInterface<SetPropRangeTestCase> {};
+
+std::vector<SetPropRangeTestCase> GenSetPropRangeParams() {
+    std::vector<SetPropRangeTestCase> tc;
+    VehiclePropValue intPropNormal = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
+                                      .areaId = HVAC_ALL,
+                                      // min: 1, max: 7
+                                      .value.int32Values = {3}};
+    tc.push_back({"normal_case_int", intPropNormal, StatusCode::OK});
+
+    VehiclePropValue intPropSmall = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
+                                     .areaId = HVAC_ALL,
+                                     // min: 1, max: 7
+                                     .value.int32Values = {0}};
+    tc.push_back({"normal_case_int_too_small", intPropSmall, StatusCode::INVALID_ARG});
+
+    VehiclePropValue intPropLarge = {.prop = toInt(VehicleProperty::HVAC_FAN_SPEED),
+                                     .areaId = HVAC_ALL,
+                                     // min: 1, max: 7
+                                     .value.int32Values = {8}};
+    tc.push_back({"normal_case_int_too_large", intPropLarge, StatusCode::INVALID_ARG});
+
+    VehiclePropValue floatPropNormal = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
+                                        .areaId = HVAC_LEFT,
+                                        // min: 16, max: 32
+                                        .value.floatValues = {26}};
+    tc.push_back({"normal_case_float", floatPropNormal, StatusCode::OK});
+    VehiclePropValue floatPropSmall = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
+                                       .areaId = HVAC_LEFT,
+                                       // min: 16, max: 32
+                                       .value.floatValues = {15.5}};
+    tc.push_back({"normal_case_float_too_small", floatPropSmall, StatusCode::INVALID_ARG});
+    VehiclePropValue floatPropLarge = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
+                                       .areaId = HVAC_LEFT,
+                                       // min: 16, max: 32
+                                       .value.floatValues = {32.6}};
+    tc.push_back({"normal_case_float_too_large", floatPropLarge, StatusCode::INVALID_ARG});
+
+    return tc;
+}
+
+TEST_P(DefaultVhalImplSetPropRangeTest, testSetPropRange) {
+    SetPropRangeTestCase tc = GetParam();
+
+    StatusCode status = mHal->set(tc.prop);
+
+    EXPECT_EQ(tc.code, status);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        DefaultVhalImplSetPropRangeTests, DefaultVhalImplSetPropRangeTest,
+        testing::ValuesIn(GenSetPropRangeParams()),
+        [](const testing::TestParamInfo<DefaultVhalImplSetPropRangeTest::ParamType>& info) {
+            return info.param.name;
+        });
+
+std::string getPropIdString(VehicleProperty prop) {
+    char s[MAX_PROP_ID_LENGTH] = {};
+    snprintf(s, sizeof(s), "%d", toInt(prop));
+    return std::string(s);
+}
+
+struct OptionsTestCase {
+    std::string name;
+    hidl_vec<hidl_string> options;
+    std::string expectMsg;
+};
+
+class DefaultVhalImplOptionsTest : public DefaultVhalImplTest,
+                                   public testing::WithParamInterface<OptionsTestCase> {};
+
+TEST_P(DefaultVhalImplOptionsTest, testInvalidOptions) {
+    auto tc = GetParam();
+    hidl_handle fd = {};
+    int memfd = createMemfd(&fd);
+
+    bool shouldDump = mHal->dump(fd, tc.options);
+
+    EXPECT_FALSE(shouldDump);
+    char buf[10240] = {};
+    lseek(memfd, 0, SEEK_SET);
+    read(memfd, buf, sizeof(buf));
+    EXPECT_THAT(std::string(buf), HasSubstr(tc.expectMsg));
+}
+
+std::vector<OptionsTestCase> GenInvalidOptions() {
+    return {{"no_command", {"--debughal"}, "No command specified"},
+            {"unknown_command", {"--debughal", "--unknown"}, "Unknown command: \"--unknown\""},
+            {"help", {"--debughal", "--help"}, "Help:"},
+            {"genfakedata_no_subcommand",
+             {"--debughal", "--genfakedata"},
+             "No subcommand specified for genfakedata"},
+            {"genfakedata_unknown_subcommand",
+             {"--debughal", "--genfakedata", "--unknown"},
+             "Unknown command: \"--unknown\""},
+            {"genfakedata_start_linear_no_args",
+             {"--debughal", "--genfakedata", "--startlinear"},
+             "incorrect argument count"},
+            {"genfakedata_start_linear_invalid_propId",
+             {"--debughal", "--genfakedata", "--startlinear", "abcd", "0.1", "0.1", "0.1", "0.1",
+              "100000000"},
+             "failed to parse propdID as int: \"abcd\""},
+            {"genfakedata_start_linear_invalid_middleValue",
+             {"--debughal", "--genfakedata", "--startlinear", "1", "abcd", "0.1", "0.1", "0.1",
+              "100000000"},
+             "failed to parse middleValue as float: \"abcd\""},
+            {"genfakedata_start_linear_invalid_currentValue",
+             {"--debughal", "--genfakedata", "--startlinear", "1", "0.1", "abcd", "0.1", "0.1",
+              "100000000"},
+             "failed to parse currentValue as float: \"abcd\""},
+            {"genfakedata_start_linear_invalid_dispersion",
+             {"--debughal", "--genfakedata", "--startlinear", "1", "0.1", "0.1", "abcd", "0.1",
+              "100000000"},
+             "failed to parse dispersion as float: \"abcd\""},
+            {"genfakedata_start_linear_invalid_increment",
+             {"--debughal", "--genfakedata", "--startlinear", "1", "0.1", "0.1", "0.1", "abcd",
+              "100000000"},
+             "failed to parse increment as float: \"abcd\""},
+            {"genfakedata_start_linear_invalid_interval",
+             {"--debughal", "--genfakedata", "--startlinear", "1", "0.1", "0.1", "0.1", "0.1",
+              "0.1"},
+             "failed to parse interval as int: \"0.1\""},
+            {"genfakedata_stop_linear_no_args",
+             {"--debughal", "--genfakedata", "--stoplinear"},
+             "incorrect argument count"},
+            {"genfakedata_stop_linear_invalid_propId",
+             {"--debughal", "--genfakedata", "--stoplinear", "abcd"},
+             "failed to parse propdID as int: \"abcd\""},
+            {"genfakedata_startjson_no_args",
+             {"--debughal", "--genfakedata", "--startjson"},
+             "incorrect argument count"},
+            {"genfakedata_startjson_invalid_repetition",
+             {"--debughal", "--genfakedata", "--startjson", "file", "0.1"},
+             "failed to parse repetition as int: \"0.1\""},
+            {"genfakedata_startjson_invalid_json_file",
+             {"--debughal", "--genfakedata", "--startjson", "file", "1"},
+             "invalid JSON file"},
+            {"genfakedata_stopjson_no_args",
+             {"--debughal", "--genfakedata", "--stopjson"},
+             "incorrect argument count"},
+            {"genfakedata_keypress_no_args",
+             {"--debughal", "--genfakedata", "--keypress"},
+             "incorrect argument count"},
+            {"genfakedata_keypress_invalid_keyCode",
+             {"--debughal", "--genfakedata", "--keypress", "0.1", "1"},
+             "failed to parse keyCode as int: \"0.1\""},
+            {"genfakedata_keypress_invalid_display",
+             {"--debughal", "--genfakedata", "--keypress", "1", "0.1"},
+             "failed to parse display as int: \"0.1\""}};
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        DefaultVhalImplOptionsTests, DefaultVhalImplOptionsTest,
+        testing::ValuesIn(GenInvalidOptions()),
+        [](const testing::TestParamInfo<DefaultVhalImplOptionsTest::ParamType>& info) {
+            return info.param.name;
+        });
+
+TEST_F(DefaultVhalImplTest, testDebugGenFakeDataLinear) {
+    // Start a fake linear data generator for vehicle speed at 0.1s interval.
+    // range: 0 - 100, current value: 30, step: 20.
+    hidl_vec<hidl_string> options = {"--debughal",
+                                     "--genfakedata",
+                                     "--startlinear",
+                                     getPropIdString(VehicleProperty::PERF_VEHICLE_SPEED),
+                                     /*middleValue=*/"50",
+                                     /*currentValue=*/"30",
+                                     /*dispersion=*/"50",
+                                     /*increment=*/"20",
+                                     /*interval=*/"100000000"};
+    hidl_handle fd = {};
+    int memfd = createMemfd(&fd);
+    // Clear existing events.
+    mEventQueue.flush();
+
+    EXPECT_FALSE(mHal->dump(fd, options));
+
+    lseek(memfd, 0, SEEK_SET);
+    char buf[10240] = {};
+    // The dumped info should be empty.
+    read(memfd, buf, sizeof(buf));
+    EXPECT_STREQ("", buf);
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+
+    auto events = mEventQueue.flush();
+    // We should get 10 events ideally, but let's be safe here.
+    ASSERT_LE((size_t)5, events.size());
+    int32_t value = 30;
+    for (size_t i = 0; i < 5; i++) {
+        ASSERT_EQ((size_t)1, events[i]->value.floatValues.size());
+        EXPECT_EQ((float)value, events[i]->value.floatValues[0]);
+        value = (value + 20) % 100;
+    }
+
+    // Stop the linear generator.
+    options = {"--debughal", "--genfakedata", "--stoplinear",
+               getPropIdString(VehicleProperty::PERF_VEHICLE_SPEED)};
+    EXPECT_FALSE(mHal->dump(fd, options));
+
+    // The dumped info should be empty.
+    lseek(memfd, 0, SEEK_SET);
+    read(memfd, buf, sizeof(buf));
+    EXPECT_STREQ("", buf);
+
+    close(memfd);
+
+    // Clear existing events.
+    mEventQueue.flush();
+    std::this_thread::sleep_for(std::chrono::milliseconds(500));
+    // There should be no new events generated.
+    EXPECT_EQ((size_t)0, mEventQueue.flush().size());
+}
+
+std::string getTestFilePath(const char* filename) {
+    static std::string baseDir = android::base::GetExecutableDirectory();
+    return baseDir + "/" + filename;
+}
+
+TEST_F(DefaultVhalImplTest, testDebugGenFakeDataJson) {
+    hidl_vec<hidl_string> options = {"--debughal", "--genfakedata", "--startjson",
+                                     getTestFilePath("prop.json"), "2"};
+    hidl_handle fd = {};
+    int memfd = createMemfd(&fd);
+    // Clear existing events.
+    mEventQueue.flush();
+
+    EXPECT_FALSE(mHal->dump(fd, options));
+
+    lseek(memfd, 0, SEEK_SET);
+    char buf[10240] = {};
+    // The dumped info should be empty.
+    read(memfd, buf, sizeof(buf));
+    EXPECT_STREQ("", buf);
+
+    // wait for some time.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    auto events = mEventQueue.flush();
+    ASSERT_EQ((size_t)8, events.size());
+    // First set of events, we test 1st and the last.
+    EXPECT_EQ((size_t)1, events[0]->value.int32Values.size());
+    EXPECT_EQ(8, events[0]->value.int32Values[0]);
+    EXPECT_EQ((size_t)1, events[3]->value.int32Values.size());
+    EXPECT_EQ(10, events[3]->value.int32Values[0]);
+    // Second set of the same events.
+    EXPECT_EQ((size_t)1, events[4]->value.int32Values.size());
+    EXPECT_EQ(8, events[4]->value.int32Values[0]);
+    EXPECT_EQ((size_t)1, events[7]->value.int32Values.size());
+    EXPECT_EQ(10, events[7]->value.int32Values[0]);
+}
+
+TEST_F(DefaultVhalImplTest, testDebugGenFakeDataKeyPress) {
+    hidl_vec<hidl_string> options = {"--debughal", "--genfakedata", "--keypress", "1", "2"};
+    hidl_handle fd = {};
+    int memfd = createMemfd(&fd);
+    // Clear existing events.
+    mEventQueue.flush();
+
+    EXPECT_FALSE(mHal->dump(fd, options));
+
+    lseek(memfd, 0, SEEK_SET);
+    char buf[10240] = {};
+    // The dumped info should be empty.
+    read(memfd, buf, sizeof(buf));
+    EXPECT_STREQ("", buf);
+
+    auto events = mEventQueue.flush();
+    ASSERT_EQ((size_t)2, events.size());
+    EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT), events[0]->prop);
+    EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT), events[1]->prop);
+    ASSERT_EQ((size_t)3, events[0]->value.int32Values.size());
+    ASSERT_EQ((size_t)3, events[1]->value.int32Values.size());
+    EXPECT_EQ(toInt(VehicleHwKeyInputAction::ACTION_DOWN), events[0]->value.int32Values[0]);
+    EXPECT_EQ(1, events[0]->value.int32Values[1]);
+    EXPECT_EQ(2, events[0]->value.int32Values[2]);
+    EXPECT_EQ(toInt(VehicleHwKeyInputAction::ACTION_UP), events[1]->value.int32Values[0]);
+    EXPECT_EQ(1, events[1]->value.int32Values[1]);
+    EXPECT_EQ(2, events[1]->value.int32Values[2]);
+}
+
+TEST_F(DefaultVhalImplTest, testHeartBeatEvent) {
+    // A heart beat would be sent every 3s, but let's wait for 6s to be sure at least 2 events have
+    // been generated (at 0s and 3s).
+    std::this_thread::sleep_for(std::chrono::milliseconds(6000));
+
+    auto events = mHeartBeatQueue.flush();
+    ASSERT_GE(events.size(), (size_t)2);
+    ASSERT_EQ(toInt(VehicleProperty::VHAL_HEARTBEAT), events[0]->prop);
+}
+
+TEST_F(DefaultVhalImplTest, testVendorOverrideProperties) {
+    // Destroy the existing VHAL first to prevent it using destroyed connector or propstore.
+    mHal.reset();
+    // Create a new Default VHAL and reinitialize it to load the override properties.
+    std::string overrideDir = android::base::GetExecutableDirectory() + "/override/";
+    mPropStore.reset(new VehiclePropertyStore);
+    mConnector.reset(new DefaultVehicleConnector);
+    mConnector->setValuePool(&mValueObjectPool);
+    mHal.reset(new DefaultVehicleHal(mPropStore.get(), mConnector.get()));
+    // Set vendor override directory.
+    DefaultVhalImplTestHelper helper(mConnector.get());
+    helper.overrideProperties(overrideDir.c_str());
+
+    initHal();
+
+    VehiclePropValue value;
+    StatusCode status;
+    // This is the same as the prop in 'gear_selection.json'.
+    value.prop = toInt(VehicleProperty::GEAR_SELECTION);
+
+    auto gotValue = mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::OK, status);
+    ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
+    ASSERT_EQ(8, gotValue->value.int32Values[0]);
+
+    // If we set the value, it should update despite the override.
+    value.prop = toInt(VehicleProperty::GEAR_SELECTION);
+    value.value.int32Values.resize(1);
+    value.value.int32Values[0] = 5;
+
+    status = mHal->set(value);
+    ASSERT_EQ(StatusCode::OK, status);
+
+    gotValue = mHal->get(value, &status);
+    ASSERT_EQ(StatusCode::OK, status);
+    ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
+    ASSERT_EQ(5, gotValue->value.int32Values[0]);
+}
+
+TEST_F(DefaultVhalImplTest, testVendorOverridePropertiesMultipleAreas) {
+    // Destroy the existing VHAL first to prevent it using destroyed connector or propstore.
+    mHal.reset();
+    // Create a new Default VHAL and reinitialize it to load the override properties.
+    std::string overrideDir = android::base::GetExecutableDirectory() + "/override/";
+    mPropStore.reset(new VehiclePropertyStore);
+    mConnector.reset(new DefaultVehicleConnector);
+    mConnector->setValuePool(&mValueObjectPool);
+    mHal.reset(new DefaultVehicleHal(mPropStore.get(), mConnector.get()));
+    // Set vendor override directory.
+    DefaultVhalImplTestHelper helper(mConnector.get());
+    helper.overrideProperties(overrideDir.c_str());
+
+    initHal();
+
+    VehiclePropValue value;
+    StatusCode status;
+    // This is the same as the prop in 'hvac_temperature_set.json'.
+    value.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET);
+    value.areaId = HVAC_LEFT;
+
+    auto gotValue = mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::OK, status);
+    ASSERT_EQ((size_t)1, gotValue->value.floatValues.size());
+    ASSERT_EQ(30.0f, gotValue->value.floatValues[0]);
+
+    // HVAC_RIGHT should not be affected and return the default value.
+    value.areaId = HVAC_RIGHT;
+
+    gotValue = mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::OK, status);
+    ASSERT_EQ((size_t)1, gotValue->value.floatValues.size());
+    ASSERT_EQ(20.0f, gotValue->value.floatValues[0]);
+}
+
+TEST_F(DefaultVhalImplTest, testVendorOverridePropertiesDirDoesNotExist) {
+    // Destroy the existing VHAL first to prevent it using destroyed connector or propstore.
+    mHal.reset();
+    // Create a new Default VHAL and reinitialize it to load the override properties.
+    mPropStore.reset(new VehiclePropertyStore);
+    mConnector.reset(new DefaultVehicleConnector);
+    mConnector->setValuePool(&mValueObjectPool);
+    mHal.reset(new DefaultVehicleHal(mPropStore.get(), mConnector.get()));
+    // Set vendor override directory to a non-existing dir
+    DefaultVhalImplTestHelper helper(mConnector.get());
+    helper.overrideProperties("123");
+    initHal();
+
+    VehiclePropValue value;
+    StatusCode status;
+    value.prop = toInt(VehicleProperty::GEAR_SELECTION);
+
+    auto gotValue = mHal->get(value, &status);
+
+    // We should get the default value.
+    ASSERT_EQ(StatusCode::OK, status);
+    ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
+    ASSERT_EQ(4, gotValue->value.int32Values[0]);
+}
+
+TEST_F(DefaultVhalImplTest, testGetObd2FreezeFrameNoTimestamp) {
+    VehiclePropValue value;
+    value.prop = OBD2_FREEZE_FRAME;
+    StatusCode status;
+
+    auto gotValue = mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::INVALID_ARG, status);
+}
+
+TEST_F(DefaultVhalImplTest, testGetObd2FreezeFrameInvalidTimestamp) {
+    VehiclePropValue value;
+    value.prop = OBD2_FREEZE_FRAME;
+    value.value.int64Values.resize(1);
+    value.value.int64Values[0] = 0;
+    StatusCode status;
+
+    auto gotValue = mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::INVALID_ARG, status);
+}
+
+TEST_F(DefaultVhalImplTest, testGetObd2FreezeFrameInfoGetObd2FreezeFrame) {
+    VehiclePropValue value;
+    value.prop = OBD2_FREEZE_FRAME_INFO;
+    StatusCode status;
+
+    auto gotValue = mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::OK, status);
+    ASSERT_EQ((size_t)3, gotValue->value.int64Values.size());
+
+    std::vector<std::string> dtcs;
+    std::vector<std::string> sampleDtcs = {"P0070", "P0102", "P0123"};
+    for (int64_t timestamp : gotValue->value.int64Values) {
+        VehiclePropValue freezeFrameRequest;
+        freezeFrameRequest.prop = OBD2_FREEZE_FRAME;
+        freezeFrameRequest.value.int64Values.resize(1);
+        freezeFrameRequest.value.int64Values[0] = timestamp;
+
+        auto freezeFrameValue = mHal->get(freezeFrameRequest, &status);
+
+        ASSERT_EQ(StatusCode::OK, status);
+        // Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 1
+        EXPECT_EQ((size_t)32, freezeFrameValue->value.int32Values.size());
+        // Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 1
+        EXPECT_EQ((size_t)71, freezeFrameValue->value.floatValues.size());
+        // (intValues.size() + floatValues.size()) / 8
+        EXPECT_EQ((size_t)13, freezeFrameValue->value.bytes.size());
+
+        dtcs.push_back(freezeFrameValue->value.stringValue);
+    }
+
+    for (std::string expectDtc : sampleDtcs) {
+        EXPECT_NE(std::find(dtcs.begin(), dtcs.end(), expectDtc), dtcs.end());
+    }
+}
+
+TEST_F(DefaultVhalImplTest, testGetObd2LiveFrame) {
+    VehiclePropValue value;
+    value.prop = OBD2_LIVE_FRAME;
+    StatusCode status;
+
+    auto gotValue = mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::OK, status);
+    // Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 1
+    EXPECT_EQ((size_t)32, gotValue->value.int32Values.size());
+    // Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 1
+    EXPECT_EQ((size_t)71, gotValue->value.floatValues.size());
+    // (intValues.size() + floatValues.size()) / 8
+    EXPECT_EQ((size_t)13, gotValue->value.bytes.size());
+}
+
+TEST_F(DefaultVhalImplTest, testClearObd2FreezeFrameAll) {
+    VehiclePropValue value;
+    value.prop = OBD2_FREEZE_FRAME_CLEAR;
+    // No int64Values is to clear all frames.
+
+    auto status = mHal->set(value);
+
+    EXPECT_EQ(StatusCode::OK, status);
+
+    VehiclePropValue freezeFrameRequest;
+    freezeFrameRequest.prop = OBD2_FREEZE_FRAME;
+    freezeFrameRequest.value.int64Values.resize(1);
+
+    auto gotValue = mHal->get(freezeFrameRequest, &status);
+
+    EXPECT_EQ(StatusCode::NOT_AVAILABLE, status);
+
+    VehiclePropValue freezeFrameInfoRequest;
+    freezeFrameInfoRequest.prop = OBD2_FREEZE_FRAME_INFO;
+
+    gotValue = mHal->get(freezeFrameInfoRequest, &status);
+
+    EXPECT_EQ(StatusCode::OK, status);
+    EXPECT_EQ((size_t)0, gotValue->value.int64Values.size());
+}
+
+TEST_F(DefaultVhalImplTest, testClearObd2FreezeFrameOneFrame) {
+    // Get existing freeze frame info first.
+    VehiclePropValue frameInfoRequest;
+    frameInfoRequest.prop = OBD2_FREEZE_FRAME_INFO;
+    StatusCode status;
+    auto gotValue = mHal->get(frameInfoRequest, &status);
+    ASSERT_EQ(StatusCode::OK, status);
+    ASSERT_EQ((size_t)3, gotValue->value.int64Values.size());
+
+    VehiclePropValue clearRequest;
+    int64_t timestamp = gotValue->value.int64Values[0];
+    clearRequest.prop = OBD2_FREEZE_FRAME_CLEAR;
+    clearRequest.value.int64Values.resize(1);
+    clearRequest.value.int64Values[0] = timestamp;
+
+    // Try to clear the first frame.
+    status = mHal->set(clearRequest);
+
+    // Get freeze frame info again.
+    gotValue = mHal->get(frameInfoRequest, &status);
+
+    ASSERT_EQ(StatusCode::OK, status);
+    // Now we should only have 2 frames.
+    ASSERT_EQ((size_t)2, gotValue->value.int64Values.size());
+
+    // Try to get the deleted frame, should fail.
+    VehiclePropValue frameRequest;
+    frameRequest.prop = OBD2_FREEZE_FRAME;
+    frameRequest.value.int64Values.resize(1);
+    frameRequest.value.int64Values[0] = timestamp;
+
+    gotValue = mHal->get(frameRequest, &status);
+
+    ASSERT_EQ(StatusCode::INVALID_ARG, status);
+
+    // Clear the same frame again should fail.
+    status = mHal->set(clearRequest);
+
+    ASSERT_EQ(StatusCode::INVALID_ARG, status);
+}
+
+TEST_F(DefaultVhalImplTest, testGetUserPropertySetOnly) {
+    VehiclePropValue value;
+    value.prop = toInt(VehicleProperty::INITIAL_USER_INFO);
+    StatusCode status;
+
+    mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::INVALID_ARG, status);
+
+    value.prop = toInt(VehicleProperty::SWITCH_USER);
+
+    mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::INVALID_ARG, status);
+
+    value.prop = toInt(VehicleProperty::CREATE_USER);
+
+    mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::INVALID_ARG, status);
+
+    value.prop = toInt(VehicleProperty::REMOVE_USER);
+
+    mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::INVALID_ARG, status);
+}
+
+TEST_F(DefaultVhalImplTest, testGetUserIdAssoc) {
+    VehiclePropValue value;
+    value.prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);
+    StatusCode status;
+
+    mHal->get(value, &status);
+
+    // Default returns NOT_AVAILABLE.
+    ASSERT_EQ(StatusCode::NOT_AVAILABLE, status);
+
+    // This is the same example as used in User HAL Emulation doc.
+    VehiclePropValue setValue = {
+            .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION),
+            .areaId = 1,
+            .value.int32Values = {666, 1, 1, 2},
+    };
+
+    status = mHal->set(setValue);
+
+    ASSERT_EQ(StatusCode::OK, status);
+
+    auto gotValue = mHal->get(value, &status);
+
+    ASSERT_EQ(StatusCode::OK, status);
+    ASSERT_EQ((size_t)4, gotValue->value.int32Values.size());
+    EXPECT_EQ(1, gotValue->areaId);
+    EXPECT_EQ(666, gotValue->value.int32Values[0]);
+    EXPECT_EQ(1, gotValue->value.int32Values[1]);
+    EXPECT_EQ(1, gotValue->value.int32Values[2]);
+    EXPECT_EQ(2, gotValue->value.int32Values[3]);
+    EXPECT_EQ(toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION), gotValue->prop);
+}
+
+TEST_F(DefaultVhalImplTest, testSwitchUser) {
+    // This is the same example as used in User HAL Emulation doc.
+    VehiclePropValue setValue = {
+            .prop = toInt(VehicleProperty::SWITCH_USER),
+            .areaId = 1,
+            .value.int32Values = {666, 3, 2},
+    };
+
+    auto status = mHal->set(setValue);
+
+    ASSERT_EQ(StatusCode::OK, status);
+
+    // Simulate a request from Android side.
+    setValue = {
+            .prop = toInt(VehicleProperty::SWITCH_USER),
+            .areaId = 0,
+            .value.int32Values = {666, 3},
+    };
+    // Clear existing events.
+    mEventQueue.flush();
+
+    status = mHal->set(setValue);
+
+    ASSERT_EQ(StatusCode::OK, status);
+
+    // Should generate an event for user hal response.
+    auto events = mEventQueue.flush();
+    ASSERT_EQ((size_t)1, events.size());
+    EXPECT_EQ(1, events[0]->areaId);
+    EXPECT_EQ(toInt(VehicleProperty::SWITCH_USER), events[0]->prop);
+    ASSERT_EQ((size_t)3, events[0]->value.int32Values.size());
+    EXPECT_EQ(666, events[0]->value.int32Values[0]);
+    EXPECT_EQ(3, events[0]->value.int32Values[1]);
+    EXPECT_EQ(2, events[0]->value.int32Values[2]);
+
+    // Try to get switch_user again, should return default value.
+    status = mHal->set(setValue);
+    ASSERT_EQ(StatusCode::OK, status);
+
+    events = mEventQueue.flush();
+    ASSERT_EQ((size_t)1, events.size());
+    EXPECT_EQ(0, events[0]->areaId);
+    EXPECT_EQ(toInt(VehicleProperty::SWITCH_USER), events[0]->prop);
+    ASSERT_EQ((size_t)3, events[0]->value.int32Values.size());
+    // Request ID
+    EXPECT_EQ(666, events[0]->value.int32Values[0]);
+    // VEHICLE_RESPONSE
+    EXPECT_EQ(3, events[0]->value.int32Values[1]);
+    // SUCCESS
+    EXPECT_EQ(1, events[0]->value.int32Values[2]);
+}
+
+TEST_F(DefaultVhalImplTest, testCreateUser) {
+    // This is the same example as used in User HAL Emulation doc.
+    VehiclePropValue setValue = {
+            .prop = toInt(VehicleProperty::CREATE_USER),
+            .areaId = 1,
+            .value.int32Values = {666, 2},
+    };
+
+    auto status = mHal->set(setValue);
+
+    ASSERT_EQ(StatusCode::OK, status);
+
+    // Simulate a request from Android side.
+    setValue = {
+            .prop = toInt(VehicleProperty::CREATE_USER),
+            .areaId = 0,
+            .value.int32Values = {666},
+    };
+    // Clear existing events.
+    mEventQueue.flush();
+
+    status = mHal->set(setValue);
+
+    ASSERT_EQ(StatusCode::OK, status);
+
+    // Should generate an event for user hal response.
+    auto events = mEventQueue.flush();
+    ASSERT_EQ((size_t)1, events.size());
+    EXPECT_EQ(1, events[0]->areaId);
+    EXPECT_EQ(toInt(VehicleProperty::CREATE_USER), events[0]->prop);
+    ASSERT_EQ((size_t)2, events[0]->value.int32Values.size());
+    EXPECT_EQ(666, events[0]->value.int32Values[0]);
+    EXPECT_EQ(2, events[0]->value.int32Values[1]);
+
+    // Try to get create_user again, should return default value.
+    status = mHal->set(setValue);
+    ASSERT_EQ(StatusCode::OK, status);
+
+    events = mEventQueue.flush();
+    ASSERT_EQ((size_t)1, events.size());
+    EXPECT_EQ(0, events[0]->areaId);
+    EXPECT_EQ(toInt(VehicleProperty::CREATE_USER), events[0]->prop);
+    ASSERT_EQ((size_t)2, events[0]->value.int32Values.size());
+    // Request ID
+    EXPECT_EQ(666, events[0]->value.int32Values[0]);
+    // SUCCESS
+    EXPECT_EQ(1, events[0]->value.int32Values[1]);
+}
+
+TEST_F(DefaultVhalImplTest, testInitialUserInfo) {
+    // This is the same example as used in User HAL Emulation doc.
+    VehiclePropValue setValue = {
+            .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
+            .areaId = 1,
+            .value.int32Values = {666, 1, 11},
+    };
+
+    auto status = mHal->set(setValue);
+
+    ASSERT_EQ(StatusCode::OK, status);
+
+    // Simulate a request from Android side.
+    setValue = {
+            .prop = toInt(VehicleProperty::INITIAL_USER_INFO),
+            .areaId = 0,
+            .value.int32Values = {3},
+    };
+    // Clear existing events.
+    mEventQueue.flush();
+
+    status = mHal->set(setValue);
+
+    ASSERT_EQ(StatusCode::OK, status);
+
+    // Should generate an event for user hal response.
+    auto events = mEventQueue.flush();
+    ASSERT_EQ((size_t)1, events.size());
+    EXPECT_EQ(1, events[0]->areaId);
+    EXPECT_EQ(toInt(VehicleProperty::INITIAL_USER_INFO), events[0]->prop);
+    ASSERT_EQ((size_t)3, events[0]->value.int32Values.size());
+    EXPECT_EQ(3, events[0]->value.int32Values[0]);
+    EXPECT_EQ(1, events[0]->value.int32Values[1]);
+    EXPECT_EQ(11, events[0]->value.int32Values[2]);
+
+    // Try to get create_user again, should return default value.
+    status = mHal->set(setValue);
+    ASSERT_EQ(StatusCode::OK, status);
+
+    events = mEventQueue.flush();
+    ASSERT_EQ((size_t)1, events.size());
+    EXPECT_EQ(0, events[0]->areaId);
+    EXPECT_EQ(toInt(VehicleProperty::INITIAL_USER_INFO), events[0]->prop);
+    ASSERT_EQ((size_t)4, events[0]->value.int32Values.size());
+    // Request ID
+    EXPECT_EQ(3, events[0]->value.int32Values[0]);
+    // ACTION: DEFAULT
+    EXPECT_EQ(0, events[0]->value.int32Values[1]);
+    // User id: 0
+    EXPECT_EQ(0, events[0]->value.int32Values[2]);
+    // Flags: 0
+    EXPECT_EQ(0, events[0]->value.int32Values[3]);
 }
 
 }  // namespace
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/override/gear_selection.json b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/override/gear_selection.json
new file mode 100644
index 0000000..59666b8
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/override/gear_selection.json
@@ -0,0 +1,9 @@
+[
+  {
+    "timestamp": 1000000,
+    "areaId": 0,
+    "value": 8,
+    // GEAR_SELECTION
+    "prop": 289408000
+  }
+]
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/override/hvac_temperature_set.json b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/override/hvac_temperature_set.json
new file mode 100644
index 0000000..93a97ed
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/override/hvac_temperature_set.json
@@ -0,0 +1,10 @@
+[
+  {
+    "timestamp": 1000000,
+    // HVAC_LEFT
+    "areaId": 49,
+    "value": 30,
+    // HVAC_TEMPERATURE_SET
+    "prop": 358614275
+  }
+]
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/prop.json b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/prop.json
new file mode 100644
index 0000000..b881109
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/prop.json
@@ -0,0 +1,26 @@
+[
+  {
+    "timestamp": 1000000,
+    "areaId": 0,
+    "value": 8,
+    "prop": 289408000
+  },
+  {
+    "timestamp": 2000000,
+    "areaId": 0,
+    "value": 4,
+    "prop": 289408000
+  },
+  {
+    "timestamp": 3000000,
+    "areaId": 0,
+    "value": 16,
+    "prop": 289408000
+  },
+  {
+    "timestamp": 4000000,
+    "areaId": 0,
+    "value": 10,
+    "prop": 289408000
+  }
+]
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/Android.bp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/Android.bp
new file mode 100644
index 0000000..0058d33
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/Android.bp
@@ -0,0 +1,31 @@
+// Copyright (C) 2021 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.
+
+// Library used to emulate User HAL behavior through lshal debug requests.
+cc_library {
+    name: "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
+    vendor: true,
+    defaults: ["vhal_v2_0_target_defaults"],
+    srcs: ["EmulatedUserHal.cpp"],
+    shared_libs: [
+        "libbase",
+        "libutils",
+        "libcutils",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    whole_static_libs: [
+        "android.hardware.automotive.vehicle@2.0-user-hal-helper-lib",
+    ],
+}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/EmulatedUserHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/EmulatedUserHal.cpp
new file mode 100644
index 0000000..55dc01a
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/EmulatedUserHal.cpp
@@ -0,0 +1,353 @@
+/*
+ * 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.
+ */
+#define LOG_TAG "EmulatedUserHal"
+
+#include <cutils/log.h>
+#include <utils/SystemClock.h>
+
+#include "UserHalHelper.h"
+
+#include "EmulatedUserHal.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+namespace {
+
+using android::base::Error;
+using android::base::Result;
+
+constexpr int32_t INITIAL_USER_INFO = static_cast<int32_t>(VehicleProperty::INITIAL_USER_INFO);
+constexpr int32_t SWITCH_USER = static_cast<int32_t>(VehicleProperty::SWITCH_USER);
+constexpr int32_t CREATE_USER = static_cast<int32_t>(VehicleProperty::CREATE_USER);
+constexpr int32_t REMOVE_USER = static_cast<int32_t>(VehicleProperty::REMOVE_USER);
+constexpr int32_t USER_IDENTIFICATION_ASSOCIATION =
+        static_cast<int32_t>(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);
+
+Result<int32_t> getRequestId(const VehiclePropValue& value) {
+    if (value.value.int32Values.size() < 1) {
+        return Error(static_cast<int>(StatusCode::INVALID_ARG))
+               << "no int32values on " << toString(value);
+    }
+    return value.value.int32Values[0];
+}
+
+Result<SwitchUserMessageType> getSwitchUserMessageType(const VehiclePropValue& value) {
+    if (value.value.int32Values.size() < 2) {
+        return Error(static_cast<int>(StatusCode::INVALID_ARG))
+               << "missing switch user message type " << toString(value);
+    }
+    return user_hal_helper::verifyAndCast<SwitchUserMessageType>(value.value.int32Values[1]);
+}
+
+}  // namespace
+
+bool EmulatedUserHal::isSupported(int32_t prop) {
+    switch (prop) {
+        case INITIAL_USER_INFO:
+        case SWITCH_USER:
+        case CREATE_USER:
+        case REMOVE_USER:
+        case USER_IDENTIFICATION_ASSOCIATION:
+            return true;
+        default:
+            return false;
+    }
+}
+
+Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetProperty(
+        const VehiclePropValue& value) {
+    ALOGV("onSetProperty(): %s", toString(value).c_str());
+
+    switch (value.prop) {
+        case INITIAL_USER_INFO:
+            return onSetInitialUserInfoResponse(value);
+        case SWITCH_USER:
+            return onSetSwitchUserResponse(value);
+        case CREATE_USER:
+            return onSetCreateUserResponse(value);
+        case REMOVE_USER:
+            ALOGI("REMOVE_USER is FYI only, nothing to do...");
+            return {};
+        case USER_IDENTIFICATION_ASSOCIATION:
+            return onSetUserIdentificationAssociation(value);
+        default:
+            return Error(static_cast<int>(StatusCode::INVALID_ARG))
+                   << "Unsupported property: " << toString(value);
+    }
+}
+
+Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetProperty(
+        const VehiclePropValue& value) {
+    ALOGV("onGetProperty(%s)", toString(value).c_str());
+    switch (value.prop) {
+        case INITIAL_USER_INFO:
+        case SWITCH_USER:
+        case CREATE_USER:
+        case REMOVE_USER:
+            ALOGE("onGetProperty(): %d is only supported on SET", value.prop);
+            return Error(static_cast<int>(StatusCode::INVALID_ARG)) << "only supported on SET";
+        case USER_IDENTIFICATION_ASSOCIATION:
+            return onGetUserIdentificationAssociation(value);
+        default:
+            ALOGE("onGetProperty(): %d is not supported", value.prop);
+            return Error(static_cast<int>(StatusCode::INVALID_ARG)) << "not supported by User HAL";
+    }
+}
+
+Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetUserIdentificationAssociation(
+        const VehiclePropValue& value) {
+    if (mSetUserIdentificationAssociationResponseFromCmd == nullptr) {
+        return defaultUserIdentificationAssociation(value);
+    }
+    ALOGI("get(USER_IDENTIFICATION_ASSOCIATION): returning %s",
+          toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
+    auto newValue = std::unique_ptr<VehiclePropValue>(
+            new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd));
+    auto requestId = getRequestId(value);
+    if (requestId.ok()) {
+        // Must use the same requestId
+        newValue->value.int32Values[0] = *requestId;
+    } else {
+        ALOGE("get(USER_IDENTIFICATION_ASSOCIATION): no requestId on %s", toString(value).c_str());
+    }
+    return newValue;
+}
+
+Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetInitialUserInfoResponse(
+        const VehiclePropValue& value) {
+    auto requestId = getRequestId(value);
+    if (!requestId.ok()) {
+        ALOGE("Failed to get requestId on set(INITIAL_USER_INFO): %s",
+              requestId.error().message().c_str());
+        return requestId.error();
+    }
+
+    if (value.areaId != 0) {
+        ALOGD("set(INITIAL_USER_INFO) called from lshal; storing it: %s", toString(value).c_str());
+        mInitialUserResponseFromCmd.reset(new VehiclePropValue(value));
+        return {};
+    }
+
+    ALOGD("set(INITIAL_USER_INFO) called from Android: %s", toString(value).c_str());
+    if (mInitialUserResponseFromCmd != nullptr) {
+        ALOGI("replying INITIAL_USER_INFO with lshal value:  %s",
+              toString(*mInitialUserResponseFromCmd).c_str());
+        return sendUserHalResponse(std::move(mInitialUserResponseFromCmd), *requestId);
+    }
+
+    // Returns default response
+    auto updatedValue = user_hal_helper::toVehiclePropValue(InitialUserInfoResponse{
+            .requestId = *requestId,
+            .action = InitialUserInfoResponseAction::DEFAULT,
+    });
+    ALOGI("no lshal response; replying with InitialUserInfoResponseAction::DEFAULT: %s",
+          toString(*updatedValue).c_str());
+    return updatedValue;
+}
+
+Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetSwitchUserResponse(
+        const VehiclePropValue& value) {
+    auto requestId = getRequestId(value);
+    if (!requestId.ok()) {
+        ALOGE("Failed to get requestId on set(SWITCH_USER): %s",
+              requestId.error().message().c_str());
+        return requestId.error();
+    }
+
+    auto messageType = getSwitchUserMessageType(value);
+    if (!messageType.ok()) {
+        ALOGE("Failed to get messageType on set(SWITCH_USER): %s",
+              messageType.error().message().c_str());
+        return messageType.error();
+    }
+
+    if (value.areaId != 0) {
+        if (*messageType == SwitchUserMessageType::VEHICLE_REQUEST) {
+            // User HAL can also request a user switch, so we need to check it first
+            ALOGD("set(SWITCH_USER) called from lshal to emulate a vehicle request: %s",
+                  toString(value).c_str());
+            return std::unique_ptr<VehiclePropValue>(new VehiclePropValue(value));
+        }
+        // Otherwise, we store it
+        ALOGD("set(SWITCH_USER) called from lshal; storing it: %s", toString(value).c_str());
+        mSwitchUserResponseFromCmd.reset(new VehiclePropValue(value));
+        return {};
+    }
+    ALOGD("set(SWITCH_USER) called from Android: %s", toString(value).c_str());
+
+    if (mSwitchUserResponseFromCmd != nullptr) {
+        ALOGI("replying SWITCH_USER with lshal value:  %s",
+              toString(*mSwitchUserResponseFromCmd).c_str());
+        return sendUserHalResponse(std::move(mSwitchUserResponseFromCmd), *requestId);
+    }
+
+    if (*messageType == SwitchUserMessageType::LEGACY_ANDROID_SWITCH ||
+        *messageType == SwitchUserMessageType::ANDROID_POST_SWITCH) {
+        ALOGI("request is %s; ignoring it", toString(*messageType).c_str());
+        return {};
+    }
+
+    // Returns default response
+    auto updatedValue = user_hal_helper::toVehiclePropValue(SwitchUserResponse{
+            .requestId = *requestId,
+            .messageType = SwitchUserMessageType::VEHICLE_RESPONSE,
+            .status = SwitchUserStatus::SUCCESS,
+    });
+    ALOGI("no lshal response; replying with VEHICLE_RESPONSE / SUCCESS: %s",
+          toString(*updatedValue).c_str());
+    return updatedValue;
+}
+
+Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetCreateUserResponse(
+        const VehiclePropValue& value) {
+    auto requestId = getRequestId(value);
+    if (!requestId.ok()) {
+        ALOGE("Failed to get requestId on set(CREATE_USER): %s",
+              requestId.error().message().c_str());
+        return requestId.error();
+    }
+
+    if (value.areaId != 0) {
+        ALOGD("set(CREATE_USER) called from lshal; storing it: %s", toString(value).c_str());
+        mCreateUserResponseFromCmd.reset(new VehiclePropValue(value));
+        return {};
+    }
+    ALOGD("set(CREATE_USER) called from Android: %s", toString(value).c_str());
+
+    if (mCreateUserResponseFromCmd != nullptr) {
+        ALOGI("replying CREATE_USER with lshal value:  %s",
+              toString(*mCreateUserResponseFromCmd).c_str());
+        return sendUserHalResponse(std::move(mCreateUserResponseFromCmd), *requestId);
+    }
+
+    // Returns default response
+    auto updatedValue = user_hal_helper::toVehiclePropValue(CreateUserResponse{
+            .requestId = *requestId,
+            .status = CreateUserStatus::SUCCESS,
+    });
+    ALOGI("no lshal response; replying with SUCCESS: %s", toString(*updatedValue).c_str());
+    return updatedValue;
+}
+
+Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetUserIdentificationAssociation(
+        const VehiclePropValue& value) {
+    auto requestId = getRequestId(value);
+    if (!requestId.ok()) {
+        ALOGE("Failed to get requestId on set(USER_IDENTIFICATION_ASSOCIATION): %s",
+              requestId.error().message().c_str());
+        return requestId.error();
+    }
+
+    if (value.areaId != 0) {
+        ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from lshal; storing it: %s",
+              toString(value).c_str());
+        mSetUserIdentificationAssociationResponseFromCmd.reset(new VehiclePropValue(value));
+        return {};
+    }
+    ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from Android: %s", toString(value).c_str());
+
+    if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
+        ALOGI("replying USER_IDENTIFICATION_ASSOCIATION with lshal value:  %s",
+              toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
+        // Not moving response so it can be used on GET requests
+        auto copy = std::unique_ptr<VehiclePropValue>(
+                new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd));
+        return sendUserHalResponse(std::move(copy), *requestId);
+    }
+    // Returns default response
+    return defaultUserIdentificationAssociation(value);
+}
+
+Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::defaultUserIdentificationAssociation(
+        const VehiclePropValue& request) {
+    // TODO(b/159498909): return a response with NOT_ASSOCIATED_ANY_USER for all requested types
+    ALOGE("no lshal response for %s; replying with NOT_AVAILABLE", toString(request).c_str());
+    return Error(static_cast<int>(StatusCode::NOT_AVAILABLE)) << "not set by lshal";
+}
+
+Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::sendUserHalResponse(
+        std::unique_ptr<VehiclePropValue> response, int32_t requestId) {
+    switch (response->areaId) {
+        case 1:
+            ALOGD("returning response with right request id");
+            response->value.int32Values[0] = requestId;
+            break;
+        case 2:
+            ALOGD("returning response with wrong request id");
+            response->value.int32Values[0] = -requestId;
+            break;
+        case 3:
+            ALOGD("not generating a property change event because of lshal prop: %s",
+                  toString(*response).c_str());
+            return Error(static_cast<int>(StatusCode::NOT_AVAILABLE))
+                   << "not generating a property change event because of lshal prop: "
+                   << toString(*response);
+        default:
+            ALOGE("invalid action on lshal response: %s", toString(*response).c_str());
+            return Error(static_cast<int>(StatusCode::INTERNAL_ERROR))
+                   << "invalid action on lshal response: " << toString(*response);
+    }
+
+    ALOGD("updating property to: %s", toString(*response).c_str());
+    return response;
+}
+
+std::string EmulatedUserHal::showDumpHelp() {
+    return fmt::format("{}: dumps state used for user management\n", kUserHalDumpOption);
+}
+
+std::string EmulatedUserHal::dump(std::string indent) {
+    std::string info;
+    if (mInitialUserResponseFromCmd != nullptr) {
+        info += fmt::format("{}InitialUserInfo response: {}\n", indent.c_str(),
+                            toString(*mInitialUserResponseFromCmd).c_str());
+    } else {
+        info += fmt::format("{}No InitialUserInfo response\n", indent.c_str());
+    }
+    if (mSwitchUserResponseFromCmd != nullptr) {
+        info += fmt::format("{}SwitchUser response: {}\n", indent.c_str(),
+                            toString(*mSwitchUserResponseFromCmd).c_str());
+    } else {
+        info += fmt::format("{}No SwitchUser response\n", indent.c_str());
+    }
+    if (mCreateUserResponseFromCmd != nullptr) {
+        info += fmt::format("{}CreateUser response: {}\n", indent.c_str(),
+                            toString(*mCreateUserResponseFromCmd).c_str());
+    } else {
+        info += fmt::format("{}No CreateUser response\n", indent.c_str());
+    }
+    if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) {
+        info += fmt::format("{}SetUserIdentificationAssociation response: {}\n", indent.c_str(),
+                            toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str());
+    } else {
+        info += fmt::format("{}No SetUserIdentificationAssociation response\n", indent.c_str());
+    }
+    return info;
+}
+
+}  // namespace impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/include/EmulatedUserHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/include/EmulatedUserHal.h
new file mode 100644
index 0000000..46f6d0f
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/userhal/include/EmulatedUserHal.h
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+#ifndef android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
+#define android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
+
+#include <android-base/format.h>
+#include <android-base/result.h>
+
+#include <android/hardware/automotive/vehicle/2.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+
+namespace impl {
+
+constexpr char kUserHalDumpOption[] = "--user-hal";
+
+/**
+ * Class used to emulate a real User HAL behavior through lshal debug requests.
+ */
+class EmulatedUserHal {
+  public:
+    EmulatedUserHal() {}
+
+    ~EmulatedUserHal() = default;
+
+    /**
+     * Checks if the emulator can handle the property.
+     */
+    bool isSupported(int32_t prop);
+
+    /**
+     * Lets the emulator set the property.
+     *
+     * @return updated property and StatusCode
+     */
+    android::base::Result<std::unique_ptr<VehiclePropValue>> onSetProperty(
+            const VehiclePropValue& value);
+
+    /**
+     * Gets the property value from the emulator.
+     *
+     * @return property value and StatusCode
+     */
+    android::base::Result<std::unique_ptr<VehiclePropValue>> onGetProperty(
+            const VehiclePropValue& value);
+
+    /**
+     * Shows the User HAL emulation help.
+     */
+    std::string showDumpHelp();
+
+    /**
+     * Dump its contents.
+     */
+    std::string dump(std::string indent);
+
+  private:
+    /**
+     * INITIAL_USER_INFO is called by Android when it starts, and it's expecting a property change
+     * indicating what the initial user should be.
+     *
+     * During normal circumstances, the emulator will reply right away, passing a response if
+     * InitialUserInfoResponseAction::DEFAULT (so Android could use its own logic to decide which
+     * user to boot).
+     *
+     * But during development / testing, the behavior can be changed using lshal dump, which must
+     * use the areaId to indicate what should happen next.
+     *
+     * So, the behavior of set(INITIAL_USER_INFO) is:
+     *
+     * - if it has an areaId, store the property into mInitialUserResponseFromCmd (as it was called
+     * by lshal).
+     * - else if mInitialUserResponseFromCmd is not set, return a response with the same request id
+     * and InitialUserInfoResponseAction::DEFAULT
+     * - else the behavior is defined by the areaId on mInitialUserResponseFromCmd:
+     * - if it's 1, reply with mInitialUserResponseFromCmd and the right request id
+     * - if it's 2, reply with mInitialUserResponseFromCmd but a wrong request id (so Android can
+     * test this error scenario)
+     * - if it's 3, then don't send a property change (so Android can emulate a timeout)
+     *
+     */
+    android::base::Result<std::unique_ptr<VehiclePropValue>> onSetInitialUserInfoResponse(
+            const VehiclePropValue& value);
+
+    /**
+     * Used to emulate SWITCH_USER - see onSetInitialUserInfoResponse() for usage.
+     */
+    android::base::Result<std::unique_ptr<VehiclePropValue>> onSetSwitchUserResponse(
+            const VehiclePropValue& value);
+
+    /**
+     * Used to emulate CREATE_USER - see onSetInitialUserInfoResponse() for usage.
+     */
+    android::base::Result<std::unique_ptr<VehiclePropValue>> onSetCreateUserResponse(
+            const VehiclePropValue& value);
+
+    /**
+     * Used to emulate set USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for
+     * usage.
+     */
+    android::base::Result<std::unique_ptr<VehiclePropValue>> onSetUserIdentificationAssociation(
+            const VehiclePropValue& value);
+
+    /**
+     * Used to emulate get USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for
+     * usage.
+     */
+    android::base::Result<std::unique_ptr<VehiclePropValue>> onGetUserIdentificationAssociation(
+            const VehiclePropValue& value);
+
+    /**
+     * Creates a default USER_IDENTIFICATION_ASSOCIATION when it was not set by lshal.
+     */
+    android::base::Result<std::unique_ptr<VehiclePropValue>> defaultUserIdentificationAssociation(
+            const VehiclePropValue& request);
+
+    android::base::Result<std::unique_ptr<VehiclePropValue>> sendUserHalResponse(
+            std::unique_ptr<VehiclePropValue> response, int32_t requestId);
+
+    std::unique_ptr<VehiclePropValue> mInitialUserResponseFromCmd;
+    std::unique_ptr<VehiclePropValue> mSwitchUserResponseFromCmd;
+    std::unique_ptr<VehiclePropValue> mCreateUserResponseFromCmd;
+    std::unique_ptr<VehiclePropValue> mSetUserIdentificationAssociationResponseFromCmd;
+};
+
+}  // namespace impl
+
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_V2_0_impl_EmulatedUserHal_H_
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
index 54d3ecd..27496fb 100644
--- a/biometrics/face/aidl/Android.bp
+++ b/biometrics/face/aidl/Android.bp
@@ -15,7 +15,7 @@
     ],
     imports: [
         "android.hardware.biometrics.common",
-        "android.hardware.common",
+        "android.hardware.common-V2",
         "android.hardware.keymaster",
     ],
     stability: "vintf",
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash
index b8d5097..f5ad87f 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/.hash
@@ -1 +1 @@
-945de3635b7f5a09244820eef56035c92fdbd324
+3b10f5094c5af9fe551093597fab007d1e148256
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl
index d1c2c1d..7817864 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/1/android/hardware/biometrics/face/ISession.aidl
@@ -37,7 +37,7 @@
   void generateChallenge();
   void revokeChallenge(in long challenge);
   android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType);
-  android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface);
+  android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface);
   android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId);
   android.hardware.biometrics.common.ICancellationSignal detectInteraction();
   void enumerateEnrollments();
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
index d1c2c1d..7817864 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
@@ -37,7 +37,7 @@
   void generateChallenge();
   void revokeChallenge(in long challenge);
   android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType);
-  android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface);
+  android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface);
   android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId);
   android.hardware.biometrics.common.ICancellationSignal detectInteraction();
   void enumerateEnrollments();
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index 2a57e3a..5f06b40 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -154,7 +154,7 @@
      * operation.
      */
     ICancellationSignal enroll(in HardwareAuthToken hat, in EnrollmentType type,
-            in Feature[] features, in NativeHandle previewSurface);
+            in Feature[] features, in @nullable NativeHandle previewSurface);
 
     /**
      * authenticate:
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index 0cb7c95..01cb620 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -63,7 +63,8 @@
 
 ndk::ScopedAStatus Session::enroll(
         const keymaster::HardwareAuthToken& /*hat*/, EnrollmentType /*enrollmentType*/,
-        const std::vector<Feature>& /*features*/, const NativeHandle& /*previewSurface*/,
+        const std::vector<Feature>& /*features*/,
+        const std::optional<NativeHandle>& /*previewSurface*/,
         std::shared_ptr<biometrics::common::ICancellationSignal>* /*return_val*/) {
     LOG(INFO) << "enroll";
     if (cb_) {
@@ -107,7 +108,8 @@
 ndk::ScopedAStatus Session::getFeatures() {
     LOG(INFO) << "getFeatures";
     if (cb_) {
-        cb_->onFeaturesRetrieved({});
+        // Must error out with UNABLE_TO_PROCESS when no faces are enrolled.
+        cb_->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
     }
     return ndk::ScopedAStatus::ok();
 }
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index 4d213e3..4152909 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -41,7 +41,7 @@
 
     ndk::ScopedAStatus enroll(const keymaster::HardwareAuthToken& hat,
                               EnrollmentType enrollmentType, const std::vector<Feature>& features,
-                              const NativeHandle& previewSurface,
+                              const std::optional<NativeHandle>& previewSurface,
                               std::shared_ptr<common::ICancellationSignal>* return_val) override;
 
     ndk::ScopedAStatus authenticate(
diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
index 4dc44f1..08ab5d6 100644
--- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
+++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
@@ -60,9 +60,10 @@
         return ndk::ScopedAStatus::ok();
     }
 
-    ndk::ScopedAStatus onError(Error error, int32_t /*vendorCode*/) override {
+    ndk::ScopedAStatus onError(Error error, int32_t vendorCode) override {
         auto lock = std::lock_guard<std::mutex>{mMutex};
         mError = error;
+        mVendorCode = vendorCode;
         mOnErrorInvoked = true;
         mCv.notify_one();
         return ndk::ScopedAStatus::ok();
@@ -141,6 +142,7 @@
     std::mutex mMutex;
     std::condition_variable mCv;
     Error mError = Error::UNKNOWN;
+    int32_t mVendorCode = 0;
     int64_t mGeneratedChallenge = 0;
     int64_t mRevokedChallenge = 0;
     bool mOnChallengeGeneratedInvoked = false;
@@ -212,12 +214,14 @@
     auto hat = keymaster::HardwareAuthToken{};
     std::shared_ptr<common::ICancellationSignal> cancellationSignal;
     ASSERT_TRUE(
-            mSession->enroll(hat, EnrollmentType::DEFAULT, {}, NativeHandle{}, &cancellationSignal)
+            mSession->enroll(hat, EnrollmentType::DEFAULT, {}, std::nullopt, &cancellationSignal)
                     .isOk());
 
     // Make sure an error is returned.
     auto lock = std::unique_lock{mCb->mMutex};
     mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; });
+    EXPECT_EQ(mCb->mError, Error::UNABLE_TO_PROCESS);
+    EXPECT_EQ(mCb->mVendorCode, 0);
 }
 
 TEST_P(Face, GenerateChallengeProducesUniqueChallengesTest) {
@@ -287,13 +291,15 @@
     mCb->mCv.wait(lock, [this] { return mCb->mOnEnrollmentsRemovedInvoked; });
 }
 
-TEST_P(Face, GetFeaturesWorksTest) {
+TEST_P(Face, GetFeaturesWithoutEnrollmentsResultsInUnableToProcess) {
     // Call the method.
     ASSERT_TRUE(mSession->getFeatures().isOk());
 
     // Wait for the result.
     auto lock = std::unique_lock{mCb->mMutex};
-    mCb->mCv.wait(lock, [this] { return mCb->mOnFeaturesRetrievedInvoked; });
+    mCb->mCv.wait(lock, [this] { return mCb->mOnErrorInvoked; });
+    EXPECT_EQ(mCb->mError, Error::UNABLE_TO_PROCESS);
+    EXPECT_EQ(mCb->mVendorCode, 0);
 }
 
 TEST_P(Face, GetAuthenticatorIdWorksTest) {
diff --git a/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal b/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal
index 13f03c5..378b564 100644
--- a/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal
+++ b/biometrics/fingerprint/2.3/IBiometricsFingerprint.hal
@@ -19,6 +19,10 @@
 import @2.2::IBiometricsFingerprint;
 
 /**
+ * New use of this interface is strongly discouraged. The recommended option is
+ * to use the AIDL interface, android.hardware.biometrics.fingerprint
+ * (IFingerprint).
+ *
  * The interface for biometric fingerprint authentication.
  */
 interface IBiometricsFingerprint extends @2.2::IBiometricsFingerprint {
diff --git a/camera/metadata/3.2/types.hal b/camera/metadata/3.2/types.hal
index ad671d9..4b02830 100644
--- a/camera/metadata/3.2/types.hal
+++ b/camera/metadata/3.2/types.hal
@@ -686,7 +686,9 @@
     /** android.jpeg.maxSize [static, int32, system]
      *
      * <p>Maximum size in bytes for the compressed
-     * JPEG buffer</p>
+     * JPEG buffer, in default sensor pixel mode (see ANDROID_SENSOR_PIXEL_MODE)</p>
+     *
+     * @see ANDROID_SENSOR_PIXEL_MODE
      */
     ANDROID_JPEG_MAX_SIZE,
 
diff --git a/camera/provider/2.4/vts/functional/OWNERS b/camera/provider/2.4/vts/functional/OWNERS
new file mode 100644
index 0000000..479f465
--- /dev/null
+++ b/camera/provider/2.4/vts/functional/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 41727
+epeev@google.com
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index fb2f4e0..4b38241 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -24,7 +24,7 @@
     stability: "vintf",
     backend: {
         java: {
-            enabled: false,
+            sdk_version: "module_current",
         },
         cpp: {
             enabled: false,
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index da55347..a59be21 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -80,8 +80,6 @@
         "compatibility_matrix.current.xml",
     ],
     kernel_configs: [
-        "kernel_config_current_4.19",
-        "kernel_config_current_5.4",
         "kernel_config_current_5.10",
     ],
 }
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index d4b49af..7620d36 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -591,6 +591,14 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.tuner</name>
+        <version>1</version>
+        <interface>
+            <name>ITuner</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.usb</name>
         <version>1.0-3</version>
diff --git a/current.txt b/current.txt
index c7ce15a..09df92d 100644
--- a/current.txt
+++ b/current.txt
@@ -768,6 +768,8 @@
 98592d193a717066facf91428426e5abe211e3bd718bc372e29fb944ddbe6e7c android.hardware.wifi.supplicant@1.3::types
 
 # ABI preserving changes to HALs during Android S
+# b/193346383
+93d29fbe2fcc5e4e053a9db7c9abbd9190c46b85b443f2698a3460db2ee76c8d android.hardware.camera.metadata@3.2::types
 159a0069336035852e9eca6354b86b7990680d1b239f23ef2f631b01807c4cb9 android.hardware.camera.metadata@3.5::types
 e042522daa4b5f7fd4a0a19bcdadb93c79a1b04c09ef2c9813a3a8941032f3f5 android.hardware.contexthub@1.0::IContexthub
 c2f64133b83ede65c9939ef97ab5bd867b73faf3dba0e7e69f77c3c43d9e487e android.hardware.contexthub@1.0::IContexthubCallback
@@ -831,6 +833,7 @@
 b3caf524c46a47d67e6453a34419e1881942d059e146cda740502670e9a752c3 android.hardware.automotive.vehicle@2.0::IVehicle
 7ce8728b27600e840cacf0a832f6942819fe535f9d3797ae052d5eef5065921c android.hardware.automotive.vehicle@2.0::IVehicleCallback
 b525e91d886379c13588f4975bb04d625d46e1f41b4453792c4b2db1e7ff4340 android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint
+7a78e9963bec0b071e7d46928c6100e2174270892d3f15a1eaad074997adf279 android.hardware.biometrics.fingerprint@2.3::IBiometricsFingerprint # Added for b/160189286 for Android S
 4baf8e0eca4aa896cc9ceb7bb676aaf4fa21372ef8b49eed68eced1221c3dc0d android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvider
 d417a9212c8f96e3a06a2f221c8c5756c765355b2b81de2b2a65d4c9eee85401 android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory
 c17d9e27abd37ae5a8ff8da08fc5c9b13a264670feef6bbbc9d3ab1915216130 android.hardware.bluetooth.audio@2.1::types
diff --git a/gnss/1.1/default/Gnss.cpp b/gnss/1.1/default/Gnss.cpp
index 5043649..0d77ce4 100644
--- a/gnss/1.1/default/Gnss.cpp
+++ b/gnss/1.1/default/Gnss.cpp
@@ -1,9 +1,9 @@
 #define LOG_TAG "Gnss"
 
+#include "Gnss.h"
 #include <android/hardware/gnss/1.0/types.h>
 #include <log/log.h>
-
-#include "Gnss.h"
+#include "Constants.h"
 #include "GnssDebug.h"
 #include "GnssMeasurement.h"
 #include "Utils.h"
@@ -16,6 +16,7 @@
 
 using ::android::hardware::gnss::common::Utils;
 using GnssSvFlags = IGnssCallback::GnssSvFlags;
+using namespace ::android::hardware::gnss::common;
 
 const uint32_t MIN_INTERVAL_MILLIS = 100;
 sp<::android::hardware::gnss::V1_1::IGnssCallback> Gnss::sGnssCallback = nullptr;
@@ -197,14 +198,21 @@
 Return<GnssSvStatus> Gnss::getMockSvStatus() const {
     std::unique_lock<std::recursive_mutex> lock(mGnssConfiguration->getMutex());
     GnssSvInfo mockGnssSvInfoList[] = {
-            Utils::getMockSvInfoV1_0(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5),
-            Utils::getMockSvInfoV1_0(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5),
-            Utils::getMockSvInfoV1_0(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0),
-            Utils::getMockSvInfoV1_0(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0),
-            Utils::getMockSvInfoV1_0(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0),
-            Utils::getMockSvInfoV1_0(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0),
-            Utils::getMockSvInfoV1_0(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0),
-            Utils::getMockSvInfoV1_0(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)};
+            Utils::getMockSvInfoV1_0(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5,
+                                     kGpsL1FreqHz),
+            Utils::getMockSvInfoV1_0(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5, kGpsL1FreqHz),
+            Utils::getMockSvInfoV1_0(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0,
+                                     kGpsL5FreqHz),
+            Utils::getMockSvInfoV1_0(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0,
+                                     kGpsL5FreqHz),
+            Utils::getMockSvInfoV1_0(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0,
+                                     kGloG1FreqHz),
+            Utils::getMockSvInfoV1_0(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0,
+                                     kGloG1FreqHz),
+            Utils::getMockSvInfoV1_0(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0,
+                                     kGloG1FreqHz),
+            Utils::getMockSvInfoV1_0(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0,
+                                     kGloG1FreqHz)};
 
     GnssSvStatus svStatus = {.numSvs = sizeof(mockGnssSvInfoList) / sizeof(GnssSvInfo)};
     for (uint32_t i = 0; i < svStatus.numSvs; i++) {
diff --git a/gnss/2.0/vts/functional/OWNERS b/gnss/2.0/vts/functional/OWNERS
new file mode 100644
index 0000000..b831eb4
--- /dev/null
+++ b/gnss/2.0/vts/functional/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 393449
+yuhany@google.com
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 fcab8c4..8fa5f7e 100644
--- a/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.1/vts/functional/gnss_hal_test_cases.cpp
@@ -249,35 +249,40 @@
 
 /*
  * TestGnssSvInfoFields:
- * Gets 1 location and a GnssSvInfo, and verifies
- * 1. basebandCN0DbHz is valid.
+ * Gets 1 location and a (non-empty) GnssSvInfo, and verifies basebandCN0DbHz is valid.
  */
 TEST_P(GnssHalTest, TestGnssSvInfoFields) {
     gnss_cb_->location_cbq_.reset();
+    gnss_cb_->sv_info_list_cbq_.reset();
     StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
     int location_called_count = gnss_cb_->location_cbq_.calledCount();
-
-    // Tolerate 1 less sv status to handle edge cases in reporting.
-    int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
-    EXPECT_GE(sv_info_list_cbq_size, 0);
     ALOGD("Observed %d GnssSvStatus, while awaiting one location (%d received)",
-          sv_info_list_cbq_size, location_called_count);
+          gnss_cb_->sv_info_list_cbq_.size(), location_called_count);
 
-    // 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();
+    // Wait for up to kNumSvInfoLists events for kTimeoutSeconds for each event.
+    int kTimeoutSeconds = 2;
+    int kNumSvInfoLists = 4;
+    std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_lists;
+    hidl_vec<IGnssCallback_2_1::GnssSvInfo> last_sv_info_list;
 
+    do {
+        EXPECT_GT(gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_lists, kNumSvInfoLists,
+                                                       kTimeoutSeconds),
+                  0);
+        last_sv_info_list = sv_info_lists.back();
+    } while (last_sv_info_list.size() == 0);
+
+    ALOGD("last_sv_info size = %d", (int)last_sv_info_list.size());
     bool nonZeroCn0Found = false;
     for (auto sv_info : last_sv_info_list) {
-        ASSERT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0);
+        EXPECT_TRUE(sv_info.basebandCN0DbHz >= 0.0 && sv_info.basebandCN0DbHz <= 65.0);
         if (sv_info.basebandCN0DbHz > 0.0) {
             nonZeroCn0Found = true;
         }
     }
     // Assert at least one value is non-zero. Zero is ok in status as it's possibly
     // reporting a searched but not found satellite.
-    ASSERT_TRUE(nonZeroCn0Found);
+    EXPECT_TRUE(nonZeroCn0Found);
     StopAndClearLocations();
 }
 
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index 569dac4..d136448 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -265,50 +265,50 @@
 }
 
 hidl_vec<GnssSvInfoV2_1> Utils::getMockSvInfoListV2_1() {
-    GnssSvInfoV1_0 gnssSvInfoV1_0 =
-            Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS, 32.5, 59.1, 166.5);
+    GnssSvInfoV1_0 gnssSvInfoV1_0 = Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS,
+                                                             32.5, 59.1, 166.5, kGpsL1FreqHz);
     GnssSvInfoV2_0 gnssSvInfoV2_0 =
             Utils::getMockSvInfoV2_0(gnssSvInfoV1_0, V2_0::GnssConstellationType::GPS);
     hidl_vec<GnssSvInfoV2_1> gnssSvInfoList = {
             Utils::getMockSvInfoV2_1(gnssSvInfoV2_0, 27.5),
             getMockSvInfoV2_1(
                     getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GPS, 27.0,
-                                                        29.0, 56.5),
+                                                        29.0, 56.5, kGpsL1FreqHz),
                                       V2_0::GnssConstellationType::GPS),
                     22.0),
             getMockSvInfoV2_1(
                     getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GPS, 30.5,
-                                                        71.0, 77.0),
+                                                        71.0, 77.0, kGpsL5FreqHz),
                                       V2_0::GnssConstellationType::GPS),
                     25.5),
             getMockSvInfoV2_1(
                     getMockSvInfoV2_0(getMockSvInfoV1_0(26, V1_0::GnssConstellationType::GPS, 24.1,
-                                                        28.0, 253.0),
+                                                        28.0, 253.0, kGpsL5FreqHz),
                                       V2_0::GnssConstellationType::GPS),
                     19.1),
             getMockSvInfoV2_1(
                     getMockSvInfoV2_0(getMockSvInfoV1_0(5, V1_0::GnssConstellationType::GLONASS,
-                                                        20.5, 11.5, 116.0),
+                                                        20.5, 11.5, 116.0, kGloG1FreqHz),
                                       V2_0::GnssConstellationType::GLONASS),
                     15.5),
             getMockSvInfoV2_1(
                     getMockSvInfoV2_0(getMockSvInfoV1_0(17, V1_0::GnssConstellationType::GLONASS,
-                                                        21.5, 28.5, 186.0),
+                                                        21.5, 28.5, 186.0, kGloG1FreqHz),
                                       V2_0::GnssConstellationType::GLONASS),
                     16.5),
             getMockSvInfoV2_1(
                     getMockSvInfoV2_0(getMockSvInfoV1_0(18, V1_0::GnssConstellationType::GLONASS,
-                                                        28.3, 38.8, 69.0),
+                                                        28.3, 38.8, 69.0, kGloG1FreqHz),
                                       V2_0::GnssConstellationType::GLONASS),
                     25.3),
             getMockSvInfoV2_1(
                     getMockSvInfoV2_0(getMockSvInfoV1_0(10, V1_0::GnssConstellationType::GLONASS,
-                                                        25.0, 66.0, 247.0),
+                                                        25.0, 66.0, 247.0, kGloG1FreqHz),
                                       V2_0::GnssConstellationType::GLONASS),
                     20.0),
             getMockSvInfoV2_1(
                     getMockSvInfoV2_0(getMockSvInfoV1_0(3, V1_0::GnssConstellationType::UNKNOWN,
-                                                        22.0, 35.0, 112.0),
+                                                        22.0, 35.0, 112.0, kIrnssL5FreqHz),
                                       V2_0::GnssConstellationType::IRNSS),
                     19.7),
     };
@@ -333,21 +333,23 @@
 }
 
 GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
-                                        float cN0DbHz, float elevationDegrees,
-                                        float azimuthDegrees) {
+                                        float cN0DbHz, float elevationDegrees, float azimuthDegrees,
+                                        float carrierFrequencyHz) {
     GnssSvInfoV1_0 svInfo = {.svid = svid,
                              .constellation = type,
                              .cN0Dbhz = cN0DbHz,
                              .elevationDegrees = elevationDegrees,
                              .azimuthDegrees = azimuthDegrees,
+                             .carrierFrequencyHz = carrierFrequencyHz,
                              .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
-                                       GnssSvFlags::HAS_ALMANAC_DATA};
+                                       GnssSvFlags::HAS_ALMANAC_DATA |
+                                       GnssSvFlags::HAS_CARRIER_FREQUENCY};
     return svInfo;
 }
 
 hidl_vec<GnssAntennaInfo> Utils::getMockAntennaInfos() {
     GnssAntennaInfo mockAntennaInfo_1 = {
-            .carrierFrequencyMHz = 123412.12,
+            .carrierFrequencyMHz = kGpsL1FreqHz * 1e-6,
             .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 1,
                                                             .xUncertainty = 0.1,
                                                             .y = 2,
@@ -381,7 +383,7 @@
     };
 
     GnssAntennaInfo mockAntennaInfo_2 = {
-            .carrierFrequencyMHz = 532324.23,
+            .carrierFrequencyMHz = kGpsL5FreqHz * 1e-6,
             .phaseCenterOffsetCoordinateMillimeters = Coord{.x = 5,
                                                             .xUncertainty = 0.1,
                                                             .y = 6,
diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h
index 7581166..f205ba6 100644
--- a/gnss/common/utils/default/include/Constants.h
+++ b/gnss/common/utils/default/include/Constants.h
@@ -29,6 +29,10 @@
 const float kMockSpeedAccuracyMetersPerSecond = 1;
 const float kMockBearingAccuracyDegrees = 90;
 const int64_t kMockTimestamp = 1519930775453L;
+const float kGpsL1FreqHz = 1575.42 * 1e6;
+const float kGpsL5FreqHz = 1176.45 * 1e6;
+const float kGloG1FreqHz = 1602.0 * 1e6;
+const float kIrnssL5FreqHz = 1176.45 * 1e6;
 
 // Location replay constants
 constexpr char GNSS_PATH[] = "/dev/gnss0";
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 771d39d..43772ce 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -44,7 +44,8 @@
     static V1_0::IGnssCallback::GnssSvInfo getMockSvInfoV1_0(int16_t svid,
                                                              V1_0::GnssConstellationType type,
                                                              float cN0DbHz, float elevationDegrees,
-                                                             float azimuthDegrees);
+                                                             float azimuthDegrees,
+                                                             float carrierFrequencyHz);
     static hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo> getMockAntennaInfos();
 };
 
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 76024aa..4e07af9 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -114,6 +114,7 @@
     void reportLocation(const V2_0::GnssLocation&) const;
     void reportLocation(const V1_0::GnssLocation&) const;
     void reportSvStatus(const hidl_vec<V2_1::IGnssCallback::GnssSvInfo>&) const;
+    void reportGnssStatusValue(const V1_0::IGnssCallback::GnssStatusValue) const;
 
     Return<void> help(const hidl_handle& fd);
     Return<void> setLocation(const hidl_handle& fd, const hidl_vec<hidl_string>& options);
@@ -183,6 +184,7 @@
     }
 
     mIsActive = true;
+    this->reportGnssStatusValue(V1_0::IGnssCallback::GnssStatusValue::SESSION_BEGIN);
     mThread = std::thread([this]() {
         while (mIsActive == true) {
             auto svStatus = filterBlocklistedSatellitesV2_1(Utils::getMockSvInfoListV2_1());
@@ -234,6 +236,7 @@
 Return<bool> GnssTemplate<T_IGnss>::stop() {
     ALOGD("stop");
     mIsActive = false;
+    this->reportGnssStatusValue(V1_0::IGnssCallback::GnssStatusValue::SESSION_END);
     if (mThread.joinable()) {
         mThread.join();
     }
@@ -574,6 +577,20 @@
 }
 
 template <class T_IGnss>
+void GnssTemplate<T_IGnss>::reportGnssStatusValue(
+        const V1_0::IGnssCallback::GnssStatusValue gnssStatusValue) const {
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (sGnssCallback_2_1 == nullptr) {
+        ALOGE("%s: sGnssCallback v2.1 is null.", __func__);
+        return;
+    }
+    auto ret = sGnssCallback_2_1->gnssStatusCb(gnssStatusValue);
+    if (!ret.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+template <class T_IGnss>
 void GnssTemplate<T_IGnss>::reportSvStatus(
         const hidl_vec<V2_1::IGnssCallback::GnssSvInfo>& svInfoList) const {
     std::unique_lock<std::mutex> lock(mMutex);
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index 7a1568b..e2a0f4d 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -97,7 +97,6 @@
         renderengine::DisplaySettings clientCompositionDisplay;
         clientCompositionDisplay.physicalDisplay = Rect(mDisplayWidth, mDisplayHeight);
         clientCompositionDisplay.clip = clientCompositionDisplay.physicalDisplay;
-        clientCompositionDisplay.clearRegion = Region(clientCompositionDisplay.physicalDisplay);
 
         mTestRenderEngine->initGraphicBuffer(
                 static_cast<uint32_t>(mDisplayWidth), static_cast<uint32_t>(mDisplayHeight), 1,
@@ -458,6 +457,7 @@
                           << " pixel format: PixelFormat::RGBA_8888 dataspace: "
                           << ReadbackHelper::getDataspaceString(clientDataspace)
                           << " unsupported for display" << std::endl;
+                mReader->mCompositionChanges.clear();
                 continue;
             }
 
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index 54ba79d..ecfe66c 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "graphics_composer_hidl_hal_test@2.3"
 
 #include <algorithm>
+#include <numeric>
 
 #include <android-base/logging.h>
 #include <android-base/properties.h>
@@ -155,16 +156,31 @@
 TEST_P(GraphicsComposerHidlTest, GetDisplayIdentificationData) {
     uint8_t port0;
     std::vector<uint8_t> data0;
-    if (mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port0, &data0)) {
-        uint8_t port1;
-        std::vector<uint8_t> data1;
-        ASSERT_TRUE(mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port1, &data1));
 
-        ASSERT_EQ(port0, port1) << "ports are not stable";
-        ASSERT_TRUE(data0.size() == data1.size() &&
-                    std::equal(data0.begin(), data0.end(), data1.begin()))
-            << "data is not stable";
+    if (!mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port0, &data0)) {
+        return;
     }
+
+    ASSERT_FALSE(data0.empty());
+    constexpr size_t kEdidBlockSize = 128;
+    ASSERT_TRUE(data0.size() % kEdidBlockSize == 0)
+            << "EDID blob length is not a multiple of " << kEdidBlockSize;
+
+    const uint8_t kEdidHeader[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
+    ASSERT_TRUE(std::equal(std::begin(kEdidHeader), std::end(kEdidHeader), data0.begin()))
+            << "EDID blob doesn't start with the fixed EDID header";
+    ASSERT_EQ(0, std::accumulate(data0.begin(), data0.begin() + kEdidBlockSize,
+                                 static_cast<uint8_t>(0)))
+            << "EDID base block doesn't checksum";
+
+    uint8_t port1;
+    std::vector<uint8_t> data1;
+    ASSERT_TRUE(mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &port1, &data1));
+
+    ASSERT_EQ(port0, port1) << "ports are not stable";
+    ASSERT_TRUE(data0.size() == data1.size() &&
+                std::equal(data0.begin(), data0.end(), data1.begin()))
+            << "data is not stable";
 }
 
 /**
diff --git a/health/utils/libhealth2impl/BinderHealth.cpp b/health/utils/libhealth2impl/BinderHealth.cpp
index 625d0e0..8ec8962 100644
--- a/health/utils/libhealth2impl/BinderHealth.cpp
+++ b/health/utils/libhealth2impl/BinderHealth.cpp
@@ -35,10 +35,9 @@
 namespace V2_1 {
 namespace implementation {
 
-bool IsDeadObjectLogged(const Return<void>& ret) {
+bool IsDeadObject(const Return<void>& ret) {
     if (ret.isOk()) return false;
     if (ret.isDeadObject()) return true;
-    LOG(ERROR) << "Cannot call healthInfoChanged* on callback: " << ret.description();
     return false;
 }
 
@@ -77,7 +76,7 @@
             return;
         }
         auto ret = wrapped->Notify(health_info);
-        if (IsDeadObjectLogged(ret)) {
+        if (IsDeadObject(ret)) {
             // Remove callback reference.
             std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
             auto it = std::find_if(callbacks_.begin(), callbacks_.end(),
@@ -133,7 +132,7 @@
     std::unique_lock<decltype(callbacks_lock_)> lock(callbacks_lock_);
     for (auto it = callbacks_.begin(); it != callbacks_.end();) {
         auto ret = (*it)->Notify(health_info);
-        if (IsDeadObjectLogged(ret)) {
+        if (IsDeadObject(ret)) {
             it = callbacks_.erase(it);
         } else {
             ++it;
diff --git a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
index 13c3389..88b090b 100644
--- a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
+++ b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
@@ -44,6 +44,12 @@
  *     This category should report all GPU private allocations for the specified
  *     PID that are not accounted in /proc/<pid>/smaps.
  *
+ *     getMemory() called with PID 0 should report the global total GPU-private
+ *     memory, for MemtrackType::GL and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED.
+ *
+ *     getMemory() called with PID 0 for a MemtrackType other than GL should
+ *     report 0.
+ *
  * - MemtrackType::OTHER and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
  *     Any other memory not accounted for in /proc/<pid>/smaps if any, otherwise
  *     this should return 0.
@@ -52,6 +58,9 @@
  * VM_PFNMAP flag set. For these mappings PSS and RSS are reported as 0 in smaps.
  * Such mappings have no backing page structs from which PSS/RSS can be calculated.
  *
+ * Any memtrack operation that is not supported should return a binder status with
+ * exception code EX_UNSUPPORTED_OPERATION.
+ *
  * Constructor for the interface should be used to perform memtrack management
  * setup actions and must be called once before any calls to getMemory().
  */
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 0b49b36..d108951 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -1251,8 +1251,20 @@
  * Test IRadio.getBarringInfo() for the response returned.
  */
 TEST_P(RadioHidlTest_v1_5, getBarringInfo) {
+    // If the previous setRadioPower_1_5_emergencyCall_cancelled test has just finished.
+    // Due to radio restarting, modem may need a little more time to acquire network service
+    // and barring infos. If voice status is in-service, waiting 3s to get barring infos ready.
+    // Or waiting 10s if voice status is not in-service.
     serial = GetRandomSerialNumber();
+    radio_v1_5->getVoiceRegistrationState_1_5(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    if (isVoiceInService(radioRsp_v1_5->voiceRegResp.regState)) {
+        sleep(BARRING_INFO_MAX_WAIT_TIME_SECONDS);
+    } else {
+        sleep(VOICE_SERVICE_MAX_WAIT_TIME_SECONDS);
+    }
 
+    serial = GetRandomSerialNumber();
     Return<void> res = radio_v1_5->getBarringInfo(serial);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
index 87ce675..65442ca 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
+++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
@@ -51,6 +51,8 @@
 #define TIMEOUT_PERIOD 75
 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+#define VOICE_SERVICE_MAX_WAIT_TIME_SECONDS 10
+#define BARRING_INFO_MAX_WAIT_TIME_SECONDS 3
 
 #define RADIO_SERVICE_NAME "slot1"
 
@@ -69,6 +71,7 @@
 
     // Call
     hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
+    ::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp;
 
     // Modem
     bool isModemEnabled;
diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp
index 9b6d450..3d6fc17 100644
--- a/radio/1.5/vts/functional/radio_response.cpp
+++ b/radio/1.5/vts/functional/radio_response.cpp
@@ -763,8 +763,9 @@
 
 Return<void> RadioResponse_v1_5::getVoiceRegistrationStateResponse_1_2(
         const RadioResponseInfo& info,
-        const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) {
+        const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) {
     rspInfo = info;
+    voiceRegResp = voiceRegResponse;
     parent_v1_5.notify(info.serial);
     return Void();
 }
@@ -989,8 +990,9 @@
 
 Return<void> RadioResponse_v1_5::getVoiceRegistrationStateResponse_1_5(
         const RadioResponseInfo& info,
-        const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) {
+        const ::android::hardware::radio::V1_5::RegStateResult& regResponse) {
     rspInfo = info;
+    voiceRegResp.regState = regResponse.regState;
     parent_v1_5.notify(info.serial);
     return Void();
 }
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 386029f..77eea8a 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -94,6 +94,7 @@
         "libkeymint_vts_test_utils",
         "libpuresoftkeymasterdevice",
     ],
+    test_config: "VtsRemotelyProvisionedComponentTests.xml",
     test_suites: [
         "general-tests",
         "vts",
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index caac346..b695dee 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1493,9 +1493,8 @@
             tag.tag == TAG_ROLLBACK_RESISTANCE) {
             continue;
         }
-        if (result == ErrorCode::UNSUPPORTED_TAG &&
-            (tag.tag == TAG_ALLOW_WHILE_ON_BODY || tag.tag == TAG_TRUSTED_USER_PRESENCE_REQUIRED)) {
-            // Optional tag not supported by this KeyMint implementation.
+        if (result == ErrorCode::UNSUPPORTED_TAG && tag.tag == TAG_TRUSTED_USER_PRESENCE_REQUIRED) {
+            // Tag not required to be supported by all KeyMint implementations.
             continue;
         }
         ASSERT_EQ(result, ErrorCode::OK);
@@ -1507,9 +1506,8 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-        if (tag.tag != TAG_ATTESTATION_APPLICATION_ID) {
-            // Expect to find most of the extra tags in the key characteristics
-            // of the generated key (but not for ATTESTATION_APPLICATION_ID).
+        // Some tags are optional, so don't require them to be in the enforcements.
+        if (tag.tag != TAG_ATTESTATION_APPLICATION_ID && tag.tag != TAG_ALLOW_WHILE_ON_BODY) {
             EXPECT_TRUE(hw_enforced.Contains(tag.tag) || sw_enforced.Contains(tag.tag))
                     << tag << " not in hw:" << hw_enforced << " nor sw:" << sw_enforced;
         }
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 32765ad..af951e8 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -103,8 +103,8 @@
     return std::move(corruptSig);
 }
 
-ErrMsgOr<EekChain> corrupt_sig_chain(const EekChain& eek, int which) {
-    auto [chain, _, parseErr] = cppbor::parse(eek.chain);
+ErrMsgOr<bytevec> corrupt_sig_chain(const bytevec& encodedEekChain, int which) {
+    auto [chain, _, parseErr] = cppbor::parse(encodedEekChain);
     if (!chain || !chain->asArray()) {
         return "EekChain parse failed";
     }
@@ -126,7 +126,7 @@
             corruptChain.add(eekChain->get(ii)->clone());
         }
     }
-    return EekChain{corruptChain.encode(), eek.last_pubkey, eek.last_privkey};
+    return corruptChain.encode();
 }
 
 string device_suffix(const string& name) {
@@ -272,14 +272,14 @@
 class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests {
   protected:
     CertificateRequestTest() : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(32)) {
-        generateEek(3);
+        generateTestEekChain(3);
     }
 
-    void generateEek(size_t eekLength) {
+    void generateTestEekChain(size_t eekLength) {
         auto chain = generateEekChain(eekLength, eekId_);
         EXPECT_TRUE(chain) << chain.message();
-        if (chain) eekChain_ = chain.moveValue();
-        eekLength_ = eekLength;
+        if (chain) testEekChain_ = chain.moveValue();
+        testEekLength_ = eekLength;
     }
 
     void generateKeys(bool testMode, size_t numKeys) {
@@ -309,8 +309,9 @@
         ASSERT_TRUE(senderPubkey) << senderPubkey.message();
         EXPECT_EQ(senderPubkey->second, eekId_);
 
-        auto sessionKey = x25519_HKDF_DeriveKey(eekChain_.last_pubkey, eekChain_.last_privkey,
-                                                senderPubkey->first, false /* senderIsA */);
+        auto sessionKey =
+                x25519_HKDF_DeriveKey(testEekChain_.last_pubkey, testEekChain_.last_privkey,
+                                      senderPubkey->first, false /* senderIsA */);
         ASSERT_TRUE(sessionKey) << sessionKey.message();
 
         auto protectedDataPayload =
@@ -363,8 +364,8 @@
     }
 
     bytevec eekId_;
-    size_t eekLength_;
-    EekChain eekChain_;
+    size_t testEekLength_;
+    EekChain testEekChain_;
     bytevec challenge_;
     std::vector<MacedPublicKey> keysToSign_;
     cppbor::Array cborKeysToSign_;
@@ -378,13 +379,13 @@
     bool testMode = true;
     for (size_t eekLength : {2, 3, 7}) {
         SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateEek(eekLength);
+        generateTestEekChain(eekLength);
 
         bytevec keysToSignMac;
         DeviceInfo deviceInfo;
         ProtectedData protectedData;
         auto status = provisionable_->generateCertificateRequest(
-                testMode, {} /* keysToSign */, eekChain_.chain, challenge_, &deviceInfo,
+                testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
                 &protectedData, &keysToSignMac);
         ASSERT_TRUE(status.isOk()) << status.getMessage();
 
@@ -400,25 +401,22 @@
  */
 TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) {
     constexpr bool testMode = true;
-    constexpr size_t eekLength = 2;
-
-    generateEek(eekLength);
 
     bytevec keysToSignMac;
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
-            testMode, {} /* keysToSign */, eekChain_.chain, challenge_, &deviceInfo, &protectedData,
-            &keysToSignMac);
+            testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
     ASSERT_TRUE(status.isOk()) << status.getMessage();
 
     std::vector<BccEntryData> firstBcc;
     checkProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData,
                        &firstBcc);
 
-    status = provisionable_->generateCertificateRequest(testMode, {} /* keysToSign */,
-                                                        eekChain_.chain, challenge_, &deviceInfo,
-                                                        &protectedData, &keysToSignMac);
+    status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
     ASSERT_TRUE(status.isOk()) << status.getMessage();
 
     std::vector<BccEntryData> secondBcc;
@@ -435,28 +433,20 @@
 }
 
 /**
- * Generate an empty certificate request in prod mode.  Generation will fail because we don't have a
- * valid GEEK.
- *
- * TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be
- * able to decrypt.
+ * Generate an empty certificate request in prod mode. This test must be run explicitly, and
+ * is not run by default. Not all devices are GMS devices, and therefore they do not all
+ * trust the Google EEK root.
  */
-TEST_P(CertificateRequestTest, EmptyRequest_prodMode) {
+TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
     bool testMode = false;
-    for (size_t eekLength : {2, 3, 7}) {
-        SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateEek(eekLength);
 
-        bytevec keysToSignMac;
-        DeviceInfo deviceInfo;
-        ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(
-                testMode, {} /* keysToSign */, eekChain_.chain, challenge_, &deviceInfo,
-                &protectedData, &keysToSignMac);
-        EXPECT_FALSE(status.isOk());
-        EXPECT_EQ(status.getServiceSpecificError(),
-                  BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
-    }
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, getProdEekChain(), challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    EXPECT_TRUE(status.isOk());
 }
 
 /**
@@ -468,13 +458,13 @@
 
     for (size_t eekLength : {2, 3, 7}) {
         SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateEek(eekLength);
+        generateTestEekChain(eekLength);
 
         bytevec keysToSignMac;
         DeviceInfo deviceInfo;
         ProtectedData protectedData;
         auto status = provisionable_->generateCertificateRequest(
-                testMode, keysToSign_, eekChain_.chain, challenge_, &deviceInfo, &protectedData,
+                testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
                 &keysToSignMac);
         ASSERT_TRUE(status.isOk()) << status.getMessage();
 
@@ -483,30 +473,21 @@
 }
 
 /**
- * Generate a non-empty certificate request in prod mode.  Must fail because we don't have a valid
- * GEEK.
- *
- * TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be
- * able to decrypt.
+ * Generate a non-empty certificate request in prod mode. This test must be run explicitly, and
+ * is not run by default. Not all devices are GMS devices, and therefore they do not all
+ * trust the Google EEK root.
  */
-TEST_P(CertificateRequestTest, NonEmptyRequest_prodMode) {
+TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
     bool testMode = false;
     generateKeys(testMode, 4 /* numKeys */);
 
-    for (size_t eekLength : {2, 3, 7}) {
-        SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateEek(eekLength);
-
-        bytevec keysToSignMac;
-        DeviceInfo deviceInfo;
-        ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(
-                testMode, keysToSign_, eekChain_.chain, challenge_, &deviceInfo, &protectedData,
-                &keysToSignMac);
-        EXPECT_FALSE(status.isOk());
-        EXPECT_EQ(status.getServiceSpecificError(),
-                  BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
-    }
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, keysToSign_, getProdEekChain(), challenge_, &deviceInfo, &protectedData,
+            &keysToSignMac);
+    EXPECT_TRUE(status.isOk());
 }
 
 /**
@@ -521,8 +502,8 @@
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
-            testMode, {keyWithCorruptMac}, eekChain_.chain, challenge_, &deviceInfo, &protectedData,
-            &keysToSignMac);
+            testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk()) << status.getMessage();
     EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
 }
@@ -531,7 +512,7 @@
  * Generate a non-empty certificate request in prod mode, but with the MAC corrupted on the keypair.
  */
 TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) {
-    bool testMode = true;
+    bool testMode = false;
     generateKeys(testMode, 1 /* numKeys */);
     MacedPublicKey keyWithCorruptMac = corrupt_maced_key(keysToSign_[0]).moveValue();
 
@@ -539,38 +520,35 @@
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
-            testMode, {keyWithCorruptMac}, eekChain_.chain, challenge_, &deviceInfo, &protectedData,
-            &keysToSignMac);
+            testMode, {keyWithCorruptMac}, getProdEekChain(), challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk()) << status.getMessage();
-    auto rc = status.getServiceSpecificError();
-
-    // TODO(drysdale): drop the INVALID_EEK potential error code when a real GEEK is available.
-    EXPECT_TRUE(rc == BnRemotelyProvisionedComponent::STATUS_INVALID_EEK ||
-                rc == BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
 }
 
 /**
  * Generate a non-empty certificate request in prod mode that has a corrupt EEK chain.
  * Confirm that the request is rejected.
- *
- * TODO(drysdale): Update to use a valid GEEK, so that the test actually confirms that the
- * implementation is checking signatures.
  */
 TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) {
     bool testMode = false;
     generateKeys(testMode, 4 /* numKeys */);
 
-    for (size_t ii = 0; ii < eekLength_; ii++) {
-        auto chain = corrupt_sig_chain(eekChain_, ii);
+    auto prodEekChain = getProdEekChain();
+    auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain);
+    ASSERT_NE(parsedChain, nullptr) << parseErr;
+    ASSERT_NE(parsedChain->asArray(), nullptr);
+
+    for (int ii = 0; ii < parsedChain->asArray()->size(); ++ii) {
+        auto chain = corrupt_sig_chain(prodEekChain, ii);
         ASSERT_TRUE(chain) << chain.message();
-        EekChain corruptEek = chain.moveValue();
 
         bytevec keysToSignMac;
         DeviceInfo deviceInfo;
         ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(
-                testMode, keysToSign_, corruptEek.chain, challenge_, &deviceInfo, &protectedData,
-                &keysToSignMac);
+        auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, *chain,
+                                                                 challenge_, &deviceInfo,
+                                                                 &protectedData, &keysToSignMac);
         ASSERT_FALSE(status.isOk());
         ASSERT_EQ(status.getServiceSpecificError(),
                   BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
@@ -580,9 +558,6 @@
 /**
  * Generate a non-empty certificate request in prod mode that has an incomplete EEK chain.
  * Confirm that the request is rejected.
- *
- * TODO(drysdale): Update to use a valid GEEK, so that the test actually confirms that the
- * implementation is checking signatures.
  */
 TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) {
     bool testMode = false;
@@ -590,7 +565,7 @@
 
     // Build an EEK chain that omits the first self-signed cert.
     auto truncatedChain = cppbor::Array();
-    auto [chain, _, parseErr] = cppbor::parse(eekChain_.chain);
+    auto [chain, _, parseErr] = cppbor::parse(getProdEekChain());
     ASSERT_TRUE(chain);
     auto eekChain = chain->asArray();
     ASSERT_NE(eekChain, nullptr);
@@ -619,7 +594,7 @@
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
-            true /* testMode */, keysToSign_, eekChain_.chain, challenge_, &deviceInfo,
+            true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
             &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk());
     ASSERT_EQ(status.getServiceSpecificError(),
@@ -637,7 +612,7 @@
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
-            false /* testMode */, keysToSign_, eekChain_.chain, challenge_, &deviceInfo,
+            false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
             &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk());
     ASSERT_EQ(status.getServiceSpecificError(),
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
new file mode 100644
index 0000000..2375bde
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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 VtsHalRemotelyProvisionedComponentTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file"
+            key="VtsHalRemotelyProvisionedComponentTargetTest"
+            value="/data/local/tmp/VtsHalRemotelyProvisionedComponentTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalRemotelyProvisionedComponentTargetTest" />
+        <option name="native-test-timeout" value="900000"/> <!-- 15 minutes -->
+    </test>
+</configuration>
diff --git a/tests/lazy_cb/1.0/.hidl_for_system_ext b/tests/lazy_cb/1.0/.hidl_for_system_ext
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/lazy_cb/1.0/.hidl_for_system_ext
diff --git a/tests/lazy_cb/1.0/Android.bp b/tests/lazy_cb/1.0/Android.bp
new file mode 100644
index 0000000..4d82b63
--- /dev/null
+++ b/tests/lazy_cb/1.0/Android.bp
@@ -0,0 +1,23 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+hidl_interface {
+    name: "android.hardware.tests.lazy_cb@1.0",
+    root: "android.hardware",
+    system_ext_specific: true,
+    srcs: [
+        "ILazyCb.hal",
+    ],
+    interfaces: [
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+}
diff --git a/tests/lazy_cb/1.0/ILazyCb.hal b/tests/lazy_cb/1.0/ILazyCb.hal
new file mode 100644
index 0000000..a9046b3
--- /dev/null
+++ b/tests/lazy_cb/1.0/ILazyCb.hal
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 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.tests.lazy_cb@1.0;
+
+interface ILazyCb {
+    /**
+     * Set the eventfd used to notify that the active services
+     * callback is being executed and is about to terminate the process.
+     */
+    setEventFd(handle fds) generates (bool success);
+};
diff --git a/tv/tuner/aidl/Android.bp b/tv/tuner/aidl/Android.bp
new file mode 100644
index 0000000..c33572d
--- /dev/null
+++ b/tv/tuner/aidl/Android.bp
@@ -0,0 +1,28 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.tv.tuner",
+    vendor_available: true,
+    srcs: ["android/hardware/tv/tuner/*.aidl"],
+    imports: [
+        "android.hardware.common-V2",
+        "android.hardware.common.fmq-V1",
+    ],
+    stability: "vintf",
+    backend: {
+        java: {
+            sdk_version: "module_current",
+            srcs_available: true,
+        },
+        cpp: {
+            enabled: false,
+        },
+    },
+}
diff --git a/tv/tuner/aidl/TEST_MAPPING b/tv/tuner/aidl/TEST_MAPPING
new file mode 100644
index 0000000..222c6ed
--- /dev/null
+++ b/tv/tuner/aidl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "VtsHalTvTunerTargetTest"
+    }
+  ]
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioExtraMetaData.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioExtraMetaData.aidl
new file mode 100644
index 0000000..20c6e5f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioExtraMetaData.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable AudioExtraMetaData {
+  byte adFade;
+  byte adPan;
+  byte versionTextTag;
+  byte adGainCenter;
+  byte adGainFront;
+  byte adGainSurround;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl
new file mode 100644
index 0000000..bfd2aa8
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum AudioStreamType {
+  UNDEFINED = 0,
+  PCM = 1,
+  MP3 = 2,
+  MPEG1 = 3,
+  MPEG2 = 4,
+  MPEGH = 5,
+  AAC = 6,
+  AC3 = 7,
+  EAC3 = 8,
+  AC4 = 9,
+  DTS = 10,
+  DTS_HD = 11,
+  WMA = 12,
+  OPUS = 13,
+  VORBIS = 14,
+  DRA = 15,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AvStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AvStreamType.aidl
new file mode 100644
index 0000000..4d6acff
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AvStreamType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union AvStreamType {
+  android.hardware.tv.tuner.VideoStreamType video = android.hardware.tv.tuner.VideoStreamType.UNDEFINED;
+  android.hardware.tv.tuner.AudioStreamType audio;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
new file mode 100644
index 0000000..8e31bd9
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum Constant {
+  INVALID_TS_PID = 65535,
+  INVALID_STREAM_ID = 65535,
+  INVALID_FILTER_ID = -1,
+  INVALID_AV_SYNC_ID = -1,
+  INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = -1,
+  INVALID_FIRST_MACROBLOCK_IN_SLICE = -1,
+  INVALID_FRONTEND_SETTING_FREQUENCY = -1,
+  INVALID_IP_FILTER_CONTEXT_ID = -1,
+  INVALID_LTS_ID = -1,
+  INVALID_FRONTEND_ID = -1,
+  INVALID_LNB_ID = -1,
+  INVALID_KEYTOKEN = 0,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant64Bit.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant64Bit.aidl
new file mode 100644
index 0000000..a56a0cf
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant64Bit.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum Constant64Bit {
+  INVALID_FILTER_ID_64BIT = -1,
+  INVALID_AV_SYNC_ID_64BIT = -1,
+  INVALID_PRESENTATION_TIME_STAMP = -1,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DataFormat.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DataFormat.aidl
new file mode 100644
index 0000000..3b8fee4
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DataFormat.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DataFormat {
+  TS = 0,
+  PES = 1,
+  ES = 2,
+  SHV_TLV = 3,
+  UNDEFINED = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterSettings.aidl
new file mode 100644
index 0000000..ee8db8f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxAlpFilterSettings {
+  byte packetType;
+  android.hardware.tv.tuner.DemuxAlpLengthType lengthType = android.hardware.tv.tuner.DemuxAlpLengthType.UNDEFINED;
+  android.hardware.tv.tuner.DemuxAlpFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..6b15492
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterSettingsFilterSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxAlpFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterType.aidl
new file mode 100644
index 0000000..f0df497
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxAlpFilterType {
+  UNDEFINED = 0,
+  SECTION = 1,
+  PTP = 2,
+  PAYLOAD_THROUGH = 3,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpLengthType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpLengthType.aidl
new file mode 100644
index 0000000..ccca6de
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpLengthType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum DemuxAlpLengthType {
+  UNDEFINED = 0,
+  WITHOUT_ADDITIONAL_HEADER = 1,
+  WITH_ADDITIONAL_HEADER = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxCapabilities.aidl
new file mode 100644
index 0000000..729b797
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxCapabilities.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxCapabilities {
+  int numDemux;
+  int numRecord;
+  int numPlayback;
+  int numTsFilter;
+  int numSectionFilter;
+  int numAudioFilter;
+  int numVideoFilter;
+  int numPesFilter;
+  int numPcrFilter;
+  int numBytesInSectionFilter;
+  int filterCaps;
+  int[] linkCaps;
+  boolean bTimeFilter;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
new file mode 100644
index 0000000..95911f9
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterAvSettings {
+  boolean isPassthrough;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
new file mode 100644
index 0000000..a9e7b7c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterDownloadEvent {
+  int itemId;
+  int mpuSequenceNumber;
+  int itemFragmentIndex;
+  int lastItemFragmentIndex;
+  char dataLength;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
new file mode 100644
index 0000000..ff06888
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterDownloadSettings {
+  int downloadId;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterEvent.aidl
new file mode 100644
index 0000000..617f71c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterEvent.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterEvent {
+  android.hardware.tv.tuner.DemuxFilterSectionEvent section;
+  android.hardware.tv.tuner.DemuxFilterMediaEvent media;
+  android.hardware.tv.tuner.DemuxFilterPesEvent pes;
+  android.hardware.tv.tuner.DemuxFilterTsRecordEvent tsRecord;
+  android.hardware.tv.tuner.DemuxFilterMmtpRecordEvent mmtpRecord;
+  android.hardware.tv.tuner.DemuxFilterDownloadEvent download;
+  android.hardware.tv.tuner.DemuxFilterIpPayloadEvent ipPayload;
+  android.hardware.tv.tuner.DemuxFilterTemiEvent temi;
+  android.hardware.tv.tuner.DemuxFilterMonitorEvent monitorEvent;
+  int startId;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterIpPayloadEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterIpPayloadEvent.aidl
new file mode 100644
index 0000000..0d20f8e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterIpPayloadEvent.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterIpPayloadEvent {
+  char dataLength;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMainType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMainType.aidl
new file mode 100644
index 0000000..6abd87b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMainType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxFilterMainType {
+  UNDEFINED = 0,
+  TS = 1,
+  MMTP = 2,
+  IP = 4,
+  TLV = 8,
+  ALP = 16,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
new file mode 100644
index 0000000..351a340
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterMediaEvent {
+  char streamId;
+  boolean isPtsPresent;
+  long pts;
+  int dataLength;
+  int offset;
+  android.hardware.common.NativeHandle avMemory;
+  boolean isSecureMemory;
+  long avDataId;
+  int mpuSequenceNumber;
+  boolean isPesPrivateData;
+  android.hardware.tv.tuner.DemuxFilterMediaEventExtraMetaData extraMetaData;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
new file mode 100644
index 0000000..ab36188
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterMediaEventExtraMetaData {
+  boolean noinit;
+  android.hardware.tv.tuner.AudioExtraMetaData audio;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMmtpRecordEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMmtpRecordEvent.aidl
new file mode 100644
index 0000000..4e31ba8
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMmtpRecordEvent.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterMmtpRecordEvent {
+  int scHevcIndexMask;
+  long byteNumber;
+  long pts;
+  int mpuSequenceNumber;
+  int firstMbInSlice;
+  int tsIndexMask;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEvent.aidl
new file mode 100644
index 0000000..177de7a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEvent.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterMonitorEvent {
+  android.hardware.tv.tuner.ScramblingStatus scramblingStatus = android.hardware.tv.tuner.ScramblingStatus.UNKNOWN;
+  int cid;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl
new file mode 100644
index 0000000..5d27f76
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxFilterMonitorEventType {
+  SCRAMBLING_STATUS = 1,
+  IP_CID_CHANGE = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterPesDataSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterPesDataSettings.aidl
new file mode 100644
index 0000000..ac7f8a5
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterPesDataSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterPesDataSettings {
+  char streamId;
+  boolean isRaw;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterPesEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterPesEvent.aidl
new file mode 100644
index 0000000..a4593b4
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterPesEvent.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterPesEvent {
+  char streamId;
+  char dataLength;
+  int mpuSequenceNumber;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
new file mode 100644
index 0000000..17bdd1f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterRecordSettings {
+  int tsIndexMask;
+  android.hardware.tv.tuner.DemuxRecordScIndexType scIndexType = android.hardware.tv.tuner.DemuxRecordScIndexType.UNDEFINED;
+  android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
new file mode 100644
index 0000000..3fd1910
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterScIndexMask {
+  int scIndex;
+  int scHevc;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionBits.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionBits.aidl
new file mode 100644
index 0000000..b666c7b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionBits.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterSectionBits {
+  byte[] filter;
+  byte[] mask;
+  byte[] mode;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
new file mode 100644
index 0000000..114d1eb
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterSectionEvent {
+  char tableId;
+  char version;
+  char sectionNum;
+  char dataLength;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
new file mode 100644
index 0000000..2858565
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterSectionSettings {
+  android.hardware.tv.tuner.DemuxFilterSectionSettingsCondition condition;
+  boolean isCheckCrc;
+  boolean isRepeat;
+  boolean isRaw;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettingsCondition.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettingsCondition.aidl
new file mode 100644
index 0000000..0b101de
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettingsCondition.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterSectionSettingsCondition {
+  android.hardware.tv.tuner.DemuxFilterSectionBits sectionBits;
+  android.hardware.tv.tuner.DemuxFilterSectionSettingsConditionTableInfo tableInfo;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
new file mode 100644
index 0000000..be25137
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterSectionSettingsConditionTableInfo {
+  char tableId;
+  char version;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSettings.aidl
new file mode 100644
index 0000000..c12fde2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterSettings {
+  android.hardware.tv.tuner.DemuxTsFilterSettings ts;
+  android.hardware.tv.tuner.DemuxMmtpFilterSettings mmtp;
+  android.hardware.tv.tuner.DemuxIpFilterSettings ip;
+  android.hardware.tv.tuner.DemuxTlvFilterSettings tlv;
+  android.hardware.tv.tuner.DemuxAlpFilterSettings alp;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
new file mode 100644
index 0000000..36b40ea
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum DemuxFilterStatus {
+  DATA_READY = 1,
+  LOW_WATER = 2,
+  HIGH_WATER = 4,
+  OVERFLOW = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterTemiEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterTemiEvent.aidl
new file mode 100644
index 0000000..ce15861
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterTemiEvent.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterTemiEvent {
+  long pts;
+  byte descrTag;
+  byte[] descrData;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterTsRecordEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterTsRecordEvent.aidl
new file mode 100644
index 0000000..5c27faf
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterTsRecordEvent.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterTsRecordEvent {
+  android.hardware.tv.tuner.DemuxPid pid;
+  int tsIndexMask;
+  android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
+  long byteNumber;
+  long pts;
+  int firstMbInSlice;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterType.aidl
new file mode 100644
index 0000000..14f9202
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxFilterType {
+  android.hardware.tv.tuner.DemuxFilterMainType mainType = android.hardware.tv.tuner.DemuxFilterMainType.UNDEFINED;
+  android.hardware.tv.tuner.DemuxFilterTypeDemuxFilterSubType subType;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterTypeDemuxFilterSubType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterTypeDemuxFilterSubType.aidl
new file mode 100644
index 0000000..2aa3a89
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterTypeDemuxFilterSubType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxFilterTypeDemuxFilterSubType {
+  android.hardware.tv.tuner.DemuxTsFilterType tsFilterType = android.hardware.tv.tuner.DemuxTsFilterType.UNDEFINED;
+  android.hardware.tv.tuner.DemuxMmtpFilterType mmtpFilterType;
+  android.hardware.tv.tuner.DemuxIpFilterType ipFilterType;
+  android.hardware.tv.tuner.DemuxTlvFilterType tlvFilterType;
+  android.hardware.tv.tuner.DemuxAlpFilterType alpFilterType;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpAddress.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpAddress.aidl
new file mode 100644
index 0000000..935476a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpAddress.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxIpAddress {
+  android.hardware.tv.tuner.DemuxIpAddressIpAddress srcIpAddress;
+  android.hardware.tv.tuner.DemuxIpAddressIpAddress dstIpAddress;
+  char srcPort;
+  char dstPort;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpAddressIpAddress.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpAddressIpAddress.aidl
new file mode 100644
index 0000000..62de088
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpAddressIpAddress.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxIpAddressIpAddress {
+  byte[] v4 = {};
+  byte[] v6;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterSettings.aidl
new file mode 100644
index 0000000..2b0610b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxIpFilterSettings {
+  android.hardware.tv.tuner.DemuxIpAddress ipAddr;
+  android.hardware.tv.tuner.DemuxIpFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..daac284
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterSettingsFilterSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxIpFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+  boolean bPassthrough;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterType.aidl
new file mode 100644
index 0000000..b78ac9a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxIpFilterType {
+  UNDEFINED = 0,
+  SECTION = 1,
+  NTP = 2,
+  IP_PAYLOAD = 3,
+  IP = 4,
+  PAYLOAD_THROUGH = 5,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterSettings.aidl
new file mode 100644
index 0000000..b0fad65
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxMmtpFilterSettings {
+  char mmtpPid;
+  android.hardware.tv.tuner.DemuxMmtpFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..4b23306
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterSettingsFilterSettings.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxMmtpFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+  android.hardware.tv.tuner.DemuxFilterAvSettings av;
+  android.hardware.tv.tuner.DemuxFilterPesDataSettings pesData;
+  android.hardware.tv.tuner.DemuxFilterRecordSettings record;
+  android.hardware.tv.tuner.DemuxFilterDownloadSettings download;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl
new file mode 100644
index 0000000..7e9e3a6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxMmtpFilterType {
+  UNDEFINED = 0,
+  SECTION = 1,
+  PES = 2,
+  MMTP = 3,
+  AUDIO = 4,
+  VIDEO = 5,
+  RECORD = 6,
+  DOWNLOAD = 7,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxPid.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxPid.aidl
new file mode 100644
index 0000000..0a29f93
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxPid.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxPid {
+  char tPid;
+  char mmtpPid;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl
new file mode 100644
index 0000000..bcd0aeb
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxQueueNotifyBits {
+  DATA_READY = 1,
+  DATA_CONSUMED = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
new file mode 100644
index 0000000..91a5e52
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxRecordScIndexType {
+  NONE = 0,
+  SC = 1,
+  SC_HEVC = 2,
+  UNDEFINED = 3,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
new file mode 100644
index 0000000..3035dad
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxScHevcIndex {
+  SPS = 1,
+  AUD = 2,
+  SLICE_CE_BLA_W_LP = 4,
+  SLICE_BLA_W_RADL = 8,
+  SLICE_BLA_N_LP = 16,
+  SLICE_IDR_W_RADL = 32,
+  SLICE_IDR_N_LP = 64,
+  SLICE_TRAIL_CRA = 128,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
new file mode 100644
index 0000000..808b212
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxScIndex {
+  UNDEFINED = 0,
+  I_FRAME = 1,
+  P_FRAME = 2,
+  B_FRAME = 4,
+  SEQUENCE = 8,
+  I_SLICE = 16,
+  P_SLICE = 32,
+  B_SLICE = 64,
+  SI_SLICE = 128,
+  SP_SLICE = 256,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterSettings.aidl
new file mode 100644
index 0000000..dd94980
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxTlvFilterSettings {
+  byte packetType;
+  boolean isCompressedIpPacket;
+  android.hardware.tv.tuner.DemuxTlvFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..a9d3198
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterSettingsFilterSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxTlvFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+  boolean bPassthrough;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterType.aidl
new file mode 100644
index 0000000..a4e1ff1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxTlvFilterType {
+  UNDEFINED = 0,
+  SECTION = 1,
+  TLV = 2,
+  PAYLOAD_THROUGH = 3,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterSettings.aidl
new file mode 100644
index 0000000..131cab0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable DemuxTsFilterSettings {
+  char tpid;
+  android.hardware.tv.tuner.DemuxTsFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..5d81bb6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterSettingsFilterSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DemuxTsFilterSettingsFilterSettings {
+  boolean noinit;
+  android.hardware.tv.tuner.DemuxFilterSectionSettings section;
+  android.hardware.tv.tuner.DemuxFilterAvSettings av;
+  android.hardware.tv.tuner.DemuxFilterPesDataSettings pesData;
+  android.hardware.tv.tuner.DemuxFilterRecordSettings record;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterType.aidl
new file mode 100644
index 0000000..8b806bf
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterType.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxTsFilterType {
+  UNDEFINED = 0,
+  SECTION = 1,
+  PES = 2,
+  TS = 3,
+  AUDIO = 4,
+  VIDEO = 5,
+  PCR = 6,
+  RECORD = 7,
+  TEMI = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsIndex.aidl
new file mode 100644
index 0000000..ed03477
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsIndex.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum DemuxTsIndex {
+  FIRST_PACKET = 1,
+  PAYLOAD_UNIT_START_INDICATOR = 2,
+  CHANGE_TO_NOT_SCRAMBLED = 4,
+  CHANGE_TO_EVEN_SCRAMBLED = 8,
+  CHANGE_TO_ODD_SCRAMBLED = 16,
+  DISCONTINUITY_INDICATOR = 32,
+  RANDOM_ACCESS_INDICATOR = 64,
+  PRIORITY_INDICATOR = 128,
+  PCR_FLAG = 256,
+  OPCR_FLAG = 512,
+  SPLICING_POINT_FLAG = 1024,
+  PRIVATE_DATA = 2048,
+  ADAPTATION_EXTENSION_FLAG = 4096,
+  MPT_INDEX_MPT = 65536,
+  MPT_INDEX_VIDEO = 131072,
+  MPT_INDEX_AUDIO = 262144,
+  MPT_INDEX_TIMESTAMP_TARGET_VIDEO = 524288,
+  MPT_INDEX_TIMESTAMP_TARGET_AUDIO = 1048576,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrSettings.aidl
new file mode 100644
index 0000000..26f864a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union DvrSettings {
+  android.hardware.tv.tuner.RecordSettings record;
+  android.hardware.tv.tuner.PlaybackSettings playback;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrType.aidl
new file mode 100644
index 0000000..3a0c1e4
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum DvrType {
+  RECORD = 0,
+  PLAYBACK = 1,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl
new file mode 100644
index 0000000..6b32110
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAnalogAftFlag {
+  UNDEFINED = 0,
+  AFT_TRUE = 1,
+  AFT_FALSE = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogCapabilities.aidl
new file mode 100644
index 0000000..46131be
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAnalogCapabilities {
+  int typeCap;
+  int sifStandardCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSettings.aidl
new file mode 100644
index 0000000..efb91ca
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSettings.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAnalogSettings {
+  int frequency;
+  int endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAnalogType type = android.hardware.tv.tuner.FrontendAnalogType.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAnalogAftFlag aftFlag = android.hardware.tv.tuner.FrontendAnalogAftFlag.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAnalogSifStandard sifStandard = android.hardware.tv.tuner.FrontendAnalogSifStandard.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl
new file mode 100644
index 0000000..3502522
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAnalogSifStandard {
+  UNDEFINED = 0,
+  AUTO = 1,
+  BG = 2,
+  BG_A2 = 4,
+  BG_NICAM = 8,
+  I = 16,
+  DK = 32,
+  DK1_A2 = 64,
+  DK2_A2 = 128,
+  DK3_A2 = 256,
+  DK_NICAM = 512,
+  L = 1024,
+  M = 2048,
+  M_BTSC = 4096,
+  M_A2 = 8192,
+  M_EIAJ = 16384,
+  I_NICAM = 32768,
+  L_NICAM = 65536,
+  L_PRIME = 131072,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogType.aidl
new file mode 100644
index 0000000..33fd93d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogType.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAnalogType {
+  UNDEFINED = 0,
+  AUTO = 1,
+  PAL = 2,
+  PAL_M = 4,
+  PAL_N = 8,
+  PAL_60 = 16,
+  NTSC = 32,
+  NTSC_443 = 64,
+  SECAM = 128,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl
new file mode 100644
index 0000000..51a3fc5
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3Bandwidth {
+  UNDEFINED = 0,
+  AUTO = 1,
+  BANDWIDTH_6MHZ = 2,
+  BANDWIDTH_7MHZ = 4,
+  BANDWIDTH_8MHZ = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Capabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Capabilities.aidl
new file mode 100644
index 0000000..b2a25c7
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Capabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtsc3Capabilities {
+  int bandwidthCap;
+  int modulationCap;
+  int timeInterleaveModeCap;
+  int codeRateCap;
+  int fecCap;
+  byte demodOutputFormatCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl
new file mode 100644
index 0000000..aec0718
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3CodeRate {
+  UNDEFINED = 0,
+  AUTO = 1,
+  CODERATE_2_15 = 2,
+  CODERATE_3_15 = 4,
+  CODERATE_4_15 = 8,
+  CODERATE_5_15 = 16,
+  CODERATE_6_15 = 32,
+  CODERATE_7_15 = 64,
+  CODERATE_8_15 = 128,
+  CODERATE_9_15 = 256,
+  CODERATE_10_15 = 512,
+  CODERATE_11_15 = 1024,
+  CODERATE_12_15 = 2048,
+  CODERATE_13_15 = 4096,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl
new file mode 100644
index 0000000..8702a49
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FrontendAtsc3DemodOutputFormat {
+  UNDEFINED = 0,
+  ATSC3_LINKLAYER_PACKET = 1,
+  BASEBAND_PACKET = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl
new file mode 100644
index 0000000..a2c140a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3Fec {
+  UNDEFINED = 0,
+  AUTO = 1,
+  BCH_LDPC_16K = 2,
+  BCH_LDPC_64K = 4,
+  CRC_LDPC_16K = 8,
+  CRC_LDPC_64K = 16,
+  LDPC_16K = 32,
+  LDPC_64K = 64,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl
new file mode 100644
index 0000000..09e513d
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3Modulation {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MOD_QPSK = 2,
+  MOD_16QAM = 4,
+  MOD_64QAM = 8,
+  MOD_256QAM = 16,
+  MOD_1024QAM = 32,
+  MOD_4096QAM = 64,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3PlpSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3PlpSettings.aidl
new file mode 100644
index 0000000..b569c21
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3PlpSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtsc3PlpSettings {
+  byte plpId;
+  android.hardware.tv.tuner.FrontendAtsc3Modulation modulation = android.hardware.tv.tuner.FrontendAtsc3Modulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode interleaveMode = android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3CodeRate codeRate = android.hardware.tv.tuner.FrontendAtsc3CodeRate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3Fec fec = android.hardware.tv.tuner.FrontendAtsc3Fec.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Settings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Settings.aidl
new file mode 100644
index 0000000..bd96d14
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Settings.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtsc3Settings {
+  int frequency;
+  int endFrequency;
+  android.hardware.tv.tuner.FrontendAtsc3Bandwidth bandwidth = android.hardware.tv.tuner.FrontendAtsc3Bandwidth.UNDEFINED;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3DemodOutputFormat demodOutputFormat = android.hardware.tv.tuner.FrontendAtsc3DemodOutputFormat.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtsc3PlpSettings[] plpSettings;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl
new file mode 100644
index 0000000..a9747f0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtsc3TimeInterleaveMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  CTI = 2,
+  HTI = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscCapabilities.aidl
new file mode 100644
index 0000000..c24afae
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtscCapabilities {
+  int modulationCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscModulation.aidl
new file mode 100644
index 0000000..426fe20
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscModulation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendAtscModulation {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MOD_8VSB = 4,
+  MOD_16VSB = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscSettings.aidl
new file mode 100644
index 0000000..5ccdb85
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscSettings.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendAtscSettings {
+  int frequency;
+  int endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendAtscModulation modulation = android.hardware.tv.tuner.FrontendAtscModulation.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendBandwidth.aidl
new file mode 100644
index 0000000..5355637
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendBandwidth.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendBandwidth {
+  android.hardware.tv.tuner.FrontendAtsc3Bandwidth atsc3 = android.hardware.tv.tuner.FrontendAtsc3Bandwidth.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbcBandwidth dvbc;
+  android.hardware.tv.tuner.FrontendDvbtBandwidth dvbt;
+  android.hardware.tv.tuner.FrontendIsdbtBandwidth isdbt;
+  android.hardware.tv.tuner.FrontendDtmbBandwidth dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl
new file mode 100644
index 0000000..ff71df3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendCableTimeInterleaveMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  INTERLEAVING_128_1_0 = 2,
+  INTERLEAVING_128_1_1 = 4,
+  INTERLEAVING_64_2 = 8,
+  INTERLEAVING_32_4 = 16,
+  INTERLEAVING_16_8 = 32,
+  INTERLEAVING_8_16 = 64,
+  INTERLEAVING_128_2 = 128,
+  INTERLEAVING_128_3 = 256,
+  INTERLEAVING_128_4 = 512,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl
new file mode 100644
index 0000000..c013cd1
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCapabilities.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendCapabilities {
+  android.hardware.tv.tuner.FrontendAnalogCapabilities analogCaps;
+  android.hardware.tv.tuner.FrontendAtscCapabilities atscCaps;
+  android.hardware.tv.tuner.FrontendAtsc3Capabilities atsc3Caps;
+  android.hardware.tv.tuner.FrontendDtmbCapabilities dtmbCaps;
+  android.hardware.tv.tuner.FrontendDvbsCapabilities dvbsCaps;
+  android.hardware.tv.tuner.FrontendDvbcCapabilities dvbcCaps;
+  android.hardware.tv.tuner.FrontendDvbtCapabilities dvbtCaps;
+  android.hardware.tv.tuner.FrontendIsdbsCapabilities isdbsCaps;
+  android.hardware.tv.tuner.FrontendIsdbs3Capabilities isdbs3Caps;
+  android.hardware.tv.tuner.FrontendIsdbtCapabilities isdbtCaps;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl
new file mode 100644
index 0000000..18d71d2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbBandwidth {
+  UNDEFINED = 0,
+  AUTO = 1,
+  BANDWIDTH_8MHZ = 2,
+  BANDWIDTH_6MHZ = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCapabilities.aidl
new file mode 100644
index 0000000..8d35104
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCapabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDtmbCapabilities {
+  int transmissionModeCap;
+  int bandwidthCap;
+  int modulationCap;
+  int codeRateCap;
+  int guardIntervalCap;
+  int interleaveModeCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl
new file mode 100644
index 0000000..c9454e7
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbCodeRate {
+  UNDEFINED = 0,
+  AUTO = 1,
+  CODERATE_2_5 = 2,
+  CODERATE_3_5 = 4,
+  CODERATE_4_5 = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl
new file mode 100644
index 0000000..872eb6a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbGuardInterval {
+  UNDEFINED = 0,
+  AUTO = 1,
+  PN_420_VARIOUS = 2,
+  PN_595_CONST = 4,
+  PN_945_VARIOUS = 8,
+  PN_420_CONST = 16,
+  PN_945_CONST = 32,
+  PN_RESERVED = 64,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbModulation.aidl
new file mode 100644
index 0000000..088aac5
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbModulation.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbModulation {
+  UNDEFINED = 0,
+  AUTO = 1,
+  CONSTELLATION_4QAM = 2,
+  CONSTELLATION_4QAM_NR = 4,
+  CONSTELLATION_16QAM = 8,
+  CONSTELLATION_32QAM = 16,
+  CONSTELLATION_64QAM = 32,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbSettings.aidl
new file mode 100644
index 0000000..9a2e341
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbSettings.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDtmbSettings {
+  int frequency;
+  int endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbTransmissionMode transmissionMode = android.hardware.tv.tuner.FrontendDtmbTransmissionMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbBandwidth bandwidth = android.hardware.tv.tuner.FrontendDtmbBandwidth.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbModulation modulation = android.hardware.tv.tuner.FrontendDtmbModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbCodeRate codeRate = android.hardware.tv.tuner.FrontendDtmbCodeRate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbGuardInterval guardInterval = android.hardware.tv.tuner.FrontendDtmbGuardInterval.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode interleaveMode = android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl
new file mode 100644
index 0000000..8321ad0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbTimeInterleaveMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  TIMER_INT_240 = 2,
+  TIMER_INT_720 = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl
new file mode 100644
index 0000000..5298291
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDtmbTransmissionMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  C1 = 2,
+  C3780 = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl
new file mode 100644
index 0000000..cdfedb6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FrontendDvbcAnnex {
+  UNDEFINED = 0,
+  A = 1,
+  B = 2,
+  C = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl
new file mode 100644
index 0000000..f0fe460
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbcBandwidth {
+  UNDEFINED = 0,
+  BANDWIDTH_5MHZ = 1,
+  BANDWIDTH_6MHZ = 2,
+  BANDWIDTH_7MHZ = 4,
+  BANDWIDTH_8MHZ = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcCapabilities.aidl
new file mode 100644
index 0000000..0c0e3ee
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbcCapabilities {
+  int modulationCap;
+  long fecCap;
+  byte annexCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcModulation.aidl
new file mode 100644
index 0000000..0871777
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcModulation.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbcModulation {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MOD_16QAM = 2,
+  MOD_32QAM = 4,
+  MOD_64QAM = 8,
+  MOD_128QAM = 16,
+  MOD_256QAM = 32,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl
new file mode 100644
index 0000000..f1e92c9
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbcOuterFec {
+  UNDEFINED = 0,
+  OUTER_FEC_NONE = 1,
+  OUTER_FEC_RS = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcSettings.aidl
new file mode 100644
index 0000000..55f0402
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcSettings.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbcSettings {
+  int frequency;
+  int endFrequency;
+  android.hardware.tv.tuner.FrontendDvbcModulation modulation = android.hardware.tv.tuner.FrontendDvbcModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendInnerFec fec = android.hardware.tv.tuner.FrontendInnerFec.FEC_UNDEFINED;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendDvbcOuterFec outerFec = android.hardware.tv.tuner.FrontendDvbcOuterFec.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbcAnnex annex = android.hardware.tv.tuner.FrontendDvbcAnnex.UNDEFINED;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendCableTimeInterleaveMode interleaveMode = android.hardware.tv.tuner.FrontendCableTimeInterleaveMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbcBandwidth bandwidth = android.hardware.tv.tuner.FrontendDvbcBandwidth.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsCapabilities.aidl
new file mode 100644
index 0000000..43e8aee
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbsCapabilities {
+  int modulationCap;
+  long innerfecCap;
+  byte standard;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsCodeRate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsCodeRate.aidl
new file mode 100644
index 0000000..4c3d4e4
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsCodeRate.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbsCodeRate {
+  android.hardware.tv.tuner.FrontendInnerFec fec = android.hardware.tv.tuner.FrontendInnerFec.FEC_UNDEFINED;
+  boolean isLinear;
+  boolean isShortFrames;
+  int bitsPer1000Symbol;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsModulation.aidl
new file mode 100644
index 0000000..25951cc
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsModulation.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsModulation {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MOD_QPSK = 2,
+  MOD_8PSK = 4,
+  MOD_16QAM = 8,
+  MOD_16PSK = 16,
+  MOD_32PSK = 32,
+  MOD_ACM = 64,
+  MOD_8APSK = 128,
+  MOD_16APSK = 256,
+  MOD_32APSK = 512,
+  MOD_64APSK = 1024,
+  MOD_128APSK = 2048,
+  MOD_256APSK = 4096,
+  MOD_RESERVED = 8192,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsPilot.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsPilot.aidl
new file mode 100644
index 0000000..4f2c6eb
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsPilot.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsPilot {
+  UNDEFINED = 0,
+  ON = 1,
+  OFF = 2,
+  AUTO = 3,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl
new file mode 100644
index 0000000..56ee37b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsRolloff {
+  UNDEFINED = 0,
+  ROLLOFF_0_35 = 1,
+  ROLLOFF_0_25 = 2,
+  ROLLOFF_0_20 = 3,
+  ROLLOFF_0_15 = 4,
+  ROLLOFF_0_10 = 5,
+  ROLLOFF_0_5 = 6,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsScanType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsScanType.aidl
new file mode 100644
index 0000000..110b1d8
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsScanType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsScanType {
+  UNDEFINED = 0,
+  DIRECT = 1,
+  DISEQC = 2,
+  UNICABLE = 3,
+  JESS = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsSettings.aidl
new file mode 100644
index 0000000..8a8c76f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsSettings.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbsSettings {
+  int frequency;
+  int endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsModulation modulation = android.hardware.tv.tuner.FrontendDvbsModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsCodeRate coderate;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendDvbsRolloff rolloff = android.hardware.tv.tuner.FrontendDvbsRolloff.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsPilot pilot = android.hardware.tv.tuner.FrontendDvbsPilot.UNDEFINED;
+  int inputStreamId;
+  android.hardware.tv.tuner.FrontendDvbsStandard standard = android.hardware.tv.tuner.FrontendDvbsStandard.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsVcmMode vcmMode = android.hardware.tv.tuner.FrontendDvbsVcmMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsScanType scanType = android.hardware.tv.tuner.FrontendDvbsScanType.UNDEFINED;
+  boolean isDiseqcRxMessage;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsStandard.aidl
new file mode 100644
index 0000000..b9cb657
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsStandard.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FrontendDvbsStandard {
+  UNDEFINED = 0,
+  AUTO = 1,
+  S = 2,
+  S2 = 4,
+  S2X = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl
new file mode 100644
index 0000000..2cbff7c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbsVcmMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MANUAL = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl
new file mode 100644
index 0000000..f5d14e8
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtBandwidth {
+  UNDEFINED = 0,
+  AUTO = 1,
+  BANDWIDTH_8MHZ = 2,
+  BANDWIDTH_7MHZ = 4,
+  BANDWIDTH_6MHZ = 8,
+  BANDWIDTH_5MHZ = 16,
+  BANDWIDTH_1_7MHZ = 32,
+  BANDWIDTH_10MHZ = 64,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCapabilities.aidl
new file mode 100644
index 0000000..a0e6ce2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCapabilities.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbtCapabilities {
+  int transmissionModeCap;
+  int bandwidthCap;
+  int constellationCap;
+  int coderateCap;
+  int hierarchyCap;
+  int guardIntervalCap;
+  boolean isT2Supported;
+  boolean isMisoSupported;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl
new file mode 100644
index 0000000..8bd0489
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtCoderate {
+  UNDEFINED = 0,
+  AUTO = 1,
+  CODERATE_1_2 = 2,
+  CODERATE_2_3 = 4,
+  CODERATE_3_4 = 8,
+  CODERATE_5_6 = 16,
+  CODERATE_7_8 = 32,
+  CODERATE_3_5 = 64,
+  CODERATE_4_5 = 128,
+  CODERATE_6_7 = 256,
+  CODERATE_8_9 = 512,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl
new file mode 100644
index 0000000..bc40901
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtConstellation {
+  UNDEFINED = 0,
+  AUTO = 1,
+  CONSTELLATION_QPSK = 2,
+  CONSTELLATION_16QAM = 4,
+  CONSTELLATION_64QAM = 8,
+  CONSTELLATION_256QAM = 16,
+  CONSTELLATION_QPSK_R = 32,
+  CONSTELLATION_16QAM_R = 64,
+  CONSTELLATION_64QAM_R = 128,
+  CONSTELLATION_256QAM_R = 256,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl
new file mode 100644
index 0000000..073a77e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtGuardInterval {
+  UNDEFINED = 0,
+  AUTO = 1,
+  INTERVAL_1_32 = 2,
+  INTERVAL_1_16 = 4,
+  INTERVAL_1_8 = 8,
+  INTERVAL_1_4 = 16,
+  INTERVAL_1_128 = 32,
+  INTERVAL_19_128 = 64,
+  INTERVAL_19_256 = 128,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl
new file mode 100644
index 0000000..9ed5c8c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtHierarchy {
+  UNDEFINED = 0,
+  AUTO = 1,
+  HIERARCHY_NON_NATIVE = 2,
+  HIERARCHY_1_NATIVE = 4,
+  HIERARCHY_2_NATIVE = 8,
+  HIERARCHY_4_NATIVE = 16,
+  HIERARCHY_NON_INDEPTH = 32,
+  HIERARCHY_1_INDEPTH = 64,
+  HIERARCHY_2_INDEPTH = 128,
+  HIERARCHY_4_INDEPTH = 256,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl
new file mode 100644
index 0000000..c80bc2a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtPlpMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MANUAL = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtSettings.aidl
new file mode 100644
index 0000000..cc64549
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtSettings.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendDvbtSettings {
+  int frequency;
+  int endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtTransmissionMode transmissionMode = android.hardware.tv.tuner.FrontendDvbtTransmissionMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtBandwidth bandwidth = android.hardware.tv.tuner.FrontendDvbtBandwidth.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtConstellation constellation = android.hardware.tv.tuner.FrontendDvbtConstellation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtHierarchy hierarchy = android.hardware.tv.tuner.FrontendDvbtHierarchy.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtCoderate hpCoderate = android.hardware.tv.tuner.FrontendDvbtCoderate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtCoderate lpCoderate = android.hardware.tv.tuner.FrontendDvbtCoderate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtGuardInterval guardInterval = android.hardware.tv.tuner.FrontendDvbtGuardInterval.UNDEFINED;
+  boolean isHighPriority;
+  android.hardware.tv.tuner.FrontendDvbtStandard standard = android.hardware.tv.tuner.FrontendDvbtStandard.UNDEFINED;
+  boolean isMiso;
+  android.hardware.tv.tuner.FrontendDvbtPlpMode plpMode = android.hardware.tv.tuner.FrontendDvbtPlpMode.UNDEFINED;
+  byte plpId;
+  byte plpGroupId;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtStandard.aidl
new file mode 100644
index 0000000..c7ba68a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtStandard.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FrontendDvbtStandard {
+  UNDEFINED = 0,
+  AUTO = 1,
+  T = 2,
+  T2 = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl
new file mode 100644
index 0000000..e3ca2e3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendDvbtTransmissionMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MODE_2K = 2,
+  MODE_8K = 4,
+  MODE_4K = 8,
+  MODE_1K = 16,
+  MODE_16K = 32,
+  MODE_32K = 64,
+  MODE_8K_E = 128,
+  MODE_16K_E = 256,
+  MODE_32K_E = 512,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendEventType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendEventType.aidl
new file mode 100644
index 0000000..443313f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendEventType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendEventType {
+  LOCKED = 0,
+  NO_SIGNAL = 1,
+  LOST_LOCK = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendGuardInterval.aidl
new file mode 100644
index 0000000..3d99633
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendGuardInterval.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendGuardInterval {
+  android.hardware.tv.tuner.FrontendDvbtGuardInterval dvbt = android.hardware.tv.tuner.FrontendDvbtGuardInterval.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtGuardInterval isdbt;
+  android.hardware.tv.tuner.FrontendDtmbGuardInterval dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInfo.aidl
new file mode 100644
index 0000000..2f8e6e5
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInfo.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendInfo {
+  android.hardware.tv.tuner.FrontendType type = android.hardware.tv.tuner.FrontendType.UNDEFINED;
+  int minFrequency;
+  int maxFrequency;
+  int minSymbolRate;
+  int maxSymbolRate;
+  int acquireRange;
+  int exclusiveGroupId;
+  android.hardware.tv.tuner.FrontendStatusType[] statusCaps;
+  android.hardware.tv.tuner.FrontendCapabilities frontendCaps;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInnerFec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInnerFec.aidl
new file mode 100644
index 0000000..19599a3
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInnerFec.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="long") @VintfStability
+enum FrontendInnerFec {
+  FEC_UNDEFINED = 0,
+  AUTO = 1,
+  FEC_1_2 = 2,
+  FEC_1_3 = 4,
+  FEC_1_4 = 8,
+  FEC_1_5 = 16,
+  FEC_2_3 = 32,
+  FEC_2_5 = 64,
+  FEC_2_9 = 128,
+  FEC_3_4 = 256,
+  FEC_3_5 = 512,
+  FEC_4_5 = 1024,
+  FEC_4_15 = 2048,
+  FEC_5_6 = 4096,
+  FEC_5_9 = 8192,
+  FEC_6_7 = 16384,
+  FEC_7_8 = 32768,
+  FEC_7_9 = 65536,
+  FEC_7_15 = 131072,
+  FEC_8_9 = 262144,
+  FEC_8_15 = 524288,
+  FEC_9_10 = 1048576,
+  FEC_9_20 = 2097152,
+  FEC_11_15 = 4194304,
+  FEC_11_20 = 8388608,
+  FEC_11_45 = 16777216,
+  FEC_13_18 = 33554432,
+  FEC_13_45 = 67108864,
+  FEC_14_45 = 134217728,
+  FEC_23_36 = 268435456,
+  FEC_25_36 = 536870912,
+  FEC_26_45 = 1073741824,
+  FEC_28_45 = 2147483648,
+  FEC_29_45 = 4294967296,
+  FEC_31_45 = 8589934592,
+  FEC_32_45 = 17179869184,
+  FEC_77_90 = 34359738368,
+  FEC_2_15 = 68719476736,
+  FEC_3_15 = 137438953472,
+  FEC_5_15 = 274877906944,
+  FEC_6_15 = 549755813888,
+  FEC_9_15 = 1099511627776,
+  FEC_10_15 = 2199023255552,
+  FEC_12_15 = 4398046511104,
+  FEC_13_15 = 8796093022208,
+  FEC_18_30 = 17592186044416,
+  FEC_20_30 = 35184372088832,
+  FEC_90_180 = 70368744177664,
+  FEC_96_180 = 140737488355328,
+  FEC_104_180 = 281474976710656,
+  FEC_128_180 = 562949953421312,
+  FEC_132_180 = 1125899906842624,
+  FEC_135_180 = 2251799813685248,
+  FEC_140_180 = 4503599627370496,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
new file mode 100644
index 0000000..5e03731
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendInterleaveMode {
+  android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode atsc3 = android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendCableTimeInterleaveMode dvbc;
+  android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Capabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Capabilities.aidl
new file mode 100644
index 0000000..4be37c2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Capabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbs3Capabilities {
+  int modulationCap;
+  int coderateCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl
new file mode 100644
index 0000000..1ee7f07
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbs3Coderate {
+  UNDEFINED = 0,
+  AUTO = 1,
+  CODERATE_1_3 = 2,
+  CODERATE_2_5 = 4,
+  CODERATE_1_2 = 8,
+  CODERATE_3_5 = 16,
+  CODERATE_2_3 = 32,
+  CODERATE_3_4 = 64,
+  CODERATE_7_9 = 128,
+  CODERATE_4_5 = 256,
+  CODERATE_5_6 = 512,
+  CODERATE_7_8 = 1024,
+  CODERATE_9_10 = 2048,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl
new file mode 100644
index 0000000..3603292
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbs3Modulation {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MOD_BPSK = 2,
+  MOD_QPSK = 4,
+  MOD_8PSK = 8,
+  MOD_16APSK = 16,
+  MOD_32APSK = 32,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl
new file mode 100644
index 0000000..733760c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbs3Rolloff {
+  UNDEFINED = 0,
+  ROLLOFF_0_03 = 1,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Settings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Settings.aidl
new file mode 100644
index 0000000..b96bf32
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Settings.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbs3Settings {
+  int frequency;
+  int endFrequency;
+  char streamId;
+  android.hardware.tv.tuner.FrontendIsdbsStreamIdType streamIdType = android.hardware.tv.tuner.FrontendIsdbsStreamIdType.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbs3Modulation modulation = android.hardware.tv.tuner.FrontendIsdbs3Modulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbs3Coderate coderate = android.hardware.tv.tuner.FrontendIsdbs3Coderate.UNDEFINED;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendIsdbs3Rolloff rolloff = android.hardware.tv.tuner.FrontendIsdbs3Rolloff.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCapabilities.aidl
new file mode 100644
index 0000000..2cb892c
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbsCapabilities {
+  int modulationCap;
+  int coderateCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl
new file mode 100644
index 0000000..09e9c59
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbsCoderate {
+  UNDEFINED = 0,
+  AUTO = 1,
+  CODERATE_1_2 = 2,
+  CODERATE_2_3 = 4,
+  CODERATE_3_4 = 8,
+  CODERATE_5_6 = 16,
+  CODERATE_7_8 = 32,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl
new file mode 100644
index 0000000..7b9bde6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbsModulation {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MOD_BPSK = 2,
+  MOD_QPSK = 4,
+  MOD_TC8PSK = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl
new file mode 100644
index 0000000..a2ab154
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbsRolloff {
+  UNDEFINED = 0,
+  ROLLOFF_0_35 = 1,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsSettings.aidl
new file mode 100644
index 0000000..0b48ac5
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsSettings.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbsSettings {
+  int frequency;
+  int endFrequency;
+  char streamId;
+  android.hardware.tv.tuner.FrontendIsdbsStreamIdType streamIdType = android.hardware.tv.tuner.FrontendIsdbsStreamIdType.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbsModulation modulation = android.hardware.tv.tuner.FrontendIsdbsModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbsCoderate coderate = android.hardware.tv.tuner.FrontendIsdbsCoderate.UNDEFINED;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendIsdbsRolloff rolloff = android.hardware.tv.tuner.FrontendIsdbsRolloff.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl
new file mode 100644
index 0000000..089f611
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbsStreamIdType {
+  STREAM_ID = 0,
+  RELATIVE_STREAM_NUMBER = 1,
+  UNDEFINED = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl
new file mode 100644
index 0000000..cd49214
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtBandwidth {
+  UNDEFINED = 0,
+  AUTO = 1,
+  BANDWIDTH_8MHZ = 2,
+  BANDWIDTH_7MHZ = 4,
+  BANDWIDTH_6MHZ = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
new file mode 100644
index 0000000..097fcb8
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbtCapabilities {
+  int modeCap;
+  int bandwidthCap;
+  int modulationCap;
+  int coderateCap;
+  int guardIntervalCap;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl
new file mode 100644
index 0000000..2b747ed
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtCoderate {
+  UNDEFINED = 0,
+  AUTO = 1,
+  CODERATE_1_2 = 2,
+  CODERATE_2_3 = 4,
+  CODERATE_3_4 = 8,
+  CODERATE_5_6 = 16,
+  CODERATE_7_8 = 32,
+  CODERATE_3_5 = 64,
+  CODERATE_4_5 = 128,
+  CODERATE_6_7 = 256,
+  CODERATE_8_9 = 512,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl
new file mode 100644
index 0000000..42a023a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtGuardInterval {
+  UNDEFINED = 0,
+  AUTO = 1,
+  INTERVAL_1_32 = 2,
+  INTERVAL_1_16 = 4,
+  INTERVAL_1_8 = 8,
+  INTERVAL_1_4 = 16,
+  INTERVAL_1_128 = 32,
+  INTERVAL_19_128 = 64,
+  INTERVAL_19_256 = 128,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtMode.aidl
new file mode 100644
index 0000000..54698ab
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtMode {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MODE_1 = 2,
+  MODE_2 = 4,
+  MODE_3 = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl
new file mode 100644
index 0000000..a31e0cf
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtModulation {
+  UNDEFINED = 0,
+  AUTO = 1,
+  MOD_DQPSK = 2,
+  MOD_QPSK = 4,
+  MOD_16QAM = 8,
+  MOD_64QAM = 16,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
new file mode 100644
index 0000000..5fcdf36
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbtSettings {
+  int frequency;
+  int endFrequency;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtModulation modulation = android.hardware.tv.tuner.FrontendIsdbtModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtBandwidth bandwidth = android.hardware.tv.tuner.FrontendIsdbtBandwidth.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtMode mode = android.hardware.tv.tuner.FrontendIsdbtMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtCoderate coderate = android.hardware.tv.tuner.FrontendDvbtCoderate.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtGuardInterval guardInterval = android.hardware.tv.tuner.FrontendDvbtGuardInterval.UNDEFINED;
+  int serviceAreaId;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendModulation.aidl
new file mode 100644
index 0000000..6e396b0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendModulation.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendModulation {
+  android.hardware.tv.tuner.FrontendDvbcModulation dvbc = android.hardware.tv.tuner.FrontendDvbcModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsModulation dvbs;
+  android.hardware.tv.tuner.FrontendDvbtConstellation dvbt;
+  android.hardware.tv.tuner.FrontendIsdbsModulation isdbs;
+  android.hardware.tv.tuner.FrontendIsdbs3Modulation isdbs3;
+  android.hardware.tv.tuner.FrontendIsdbtModulation isdbt;
+  android.hardware.tv.tuner.FrontendAtscModulation atsc;
+  android.hardware.tv.tuner.FrontendAtsc3Modulation atsc3;
+  android.hardware.tv.tuner.FrontendDtmbModulation dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendModulationStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendModulationStatus.aidl
new file mode 100644
index 0000000..723fdd0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendModulationStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendModulationStatus {
+  android.hardware.tv.tuner.FrontendDvbcModulation dvbc = android.hardware.tv.tuner.FrontendDvbcModulation.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbsModulation dvbs;
+  android.hardware.tv.tuner.FrontendIsdbsModulation isdbs;
+  android.hardware.tv.tuner.FrontendIsdbs3Modulation isdbs3;
+  android.hardware.tv.tuner.FrontendIsdbtModulation isdbt;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendRollOff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendRollOff.aidl
new file mode 100644
index 0000000..c5f8b8e
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendRollOff.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendRollOff {
+  android.hardware.tv.tuner.FrontendDvbsRolloff dvbs = android.hardware.tv.tuner.FrontendDvbsRolloff.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbsRolloff isdbs;
+  android.hardware.tv.tuner.FrontendIsdbs3Rolloff isdbs3;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.aidl
new file mode 100644
index 0000000..4e217ef
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendScanAtsc3PlpInfo {
+  byte plpId;
+  boolean bLlsFlag;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessage.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessage.aidl
new file mode 100644
index 0000000..882bdad
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessage.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendScanMessage {
+  boolean isLocked;
+  boolean isEnd;
+  byte progressPercent;
+  int[] frequencies;
+  int[] symbolRates;
+  android.hardware.tv.tuner.FrontendDvbtHierarchy hierarchy;
+  android.hardware.tv.tuner.FrontendAnalogType analogType;
+  byte[] plpIds;
+  byte[] groupIds;
+  char[] inputStreamIds;
+  android.hardware.tv.tuner.FrontendScanMessageStandard std;
+  android.hardware.tv.tuner.FrontendScanAtsc3PlpInfo[] atsc3PlpInfos;
+  android.hardware.tv.tuner.FrontendModulation modulation;
+  android.hardware.tv.tuner.FrontendDvbcAnnex annex;
+  boolean isHighPriority;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageStandard.aidl
new file mode 100644
index 0000000..e163fc6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageStandard.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendScanMessageStandard {
+  android.hardware.tv.tuner.FrontendDvbsStandard sStd = android.hardware.tv.tuner.FrontendDvbsStandard.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtStandard tStd;
+  android.hardware.tv.tuner.FrontendAnalogSifStandard sifStd;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl
new file mode 100644
index 0000000..b121c85
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendScanMessageType {
+  LOCKED = 0,
+  END = 1,
+  PROGRESS_PERCENT = 2,
+  FREQUENCY = 3,
+  SYMBOL_RATE = 4,
+  HIERARCHY = 5,
+  ANALOG_TYPE = 6,
+  PLP_IDS = 7,
+  GROUP_IDS = 8,
+  INPUT_STREAM_IDS = 9,
+  STANDARD = 10,
+  ATSC3_PLP_INFO = 11,
+  MODULATION = 12,
+  DVBC_ANNEX = 13,
+  HIGH_PRIORITY = 14,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanType.aidl
new file mode 100644
index 0000000..ed42d0a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendScanType {
+  SCAN_UNDEFINED = 0,
+  SCAN_AUTO = 1,
+  SCAN_BLIND = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl
new file mode 100644
index 0000000..7eae9df
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSettings.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendSettings {
+  android.hardware.tv.tuner.FrontendAnalogSettings analog;
+  android.hardware.tv.tuner.FrontendAtscSettings atsc;
+  android.hardware.tv.tuner.FrontendAtsc3Settings atsc3;
+  android.hardware.tv.tuner.FrontendDvbsSettings dvbs;
+  android.hardware.tv.tuner.FrontendDvbcSettings dvbc;
+  android.hardware.tv.tuner.FrontendDvbtSettings dvbt;
+  android.hardware.tv.tuner.FrontendIsdbsSettings isdbs;
+  android.hardware.tv.tuner.FrontendIsdbs3Settings isdbs3;
+  android.hardware.tv.tuner.FrontendIsdbtSettings isdbt;
+  android.hardware.tv.tuner.FrontendDtmbSettings dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSpectralInversion.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSpectralInversion.aidl
new file mode 100644
index 0000000..ff11bb8
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSpectralInversion.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendSpectralInversion {
+  UNDEFINED = 0,
+  NORMAL = 1,
+  INVERTED = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
new file mode 100644
index 0000000..114b72f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendStatus {
+  boolean isDemodLocked;
+  int snr;
+  int ber;
+  int per;
+  int preBer;
+  int signalQuality;
+  int signalStrength;
+  int symbolRate;
+  android.hardware.tv.tuner.FrontendInnerFec innerFec;
+  android.hardware.tv.tuner.FrontendModulationStatus modulationStatus;
+  android.hardware.tv.tuner.FrontendSpectralInversion inversion;
+  android.hardware.tv.tuner.LnbVoltage lnbVoltage;
+  byte plpId;
+  boolean isEWBS;
+  byte agc;
+  boolean isLnaOn;
+  boolean[] isLayerError;
+  int mer;
+  int freqOffset;
+  android.hardware.tv.tuner.FrontendDvbtHierarchy hierarchy;
+  boolean isRfLocked;
+  android.hardware.tv.tuner.FrontendStatusAtsc3PlpInfo[] plpInfo;
+  android.hardware.tv.tuner.FrontendModulation[] modulations;
+  int[] bers;
+  android.hardware.tv.tuner.FrontendInnerFec[] codeRates;
+  android.hardware.tv.tuner.FrontendBandwidth bandwidth;
+  android.hardware.tv.tuner.FrontendGuardInterval interval;
+  android.hardware.tv.tuner.FrontendTransmissionMode transmissionMode;
+  int uec;
+  char systemId;
+  android.hardware.tv.tuner.FrontendInterleaveMode[] interleaving;
+  byte[] isdbtSegment;
+  int[] tsDataRate;
+  android.hardware.tv.tuner.FrontendRollOff rollOff;
+  boolean isMiso;
+  boolean isLinear;
+  boolean isShortFrames;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.aidl
new file mode 100644
index 0000000..9cd1b8a
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendStatusAtsc3PlpInfo {
+  byte plpId;
+  boolean isLocked;
+  int uec;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
new file mode 100644
index 0000000..7b8bc47
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendStatusType {
+  DEMOD_LOCK = 0,
+  SNR = 1,
+  BER = 2,
+  PER = 3,
+  PRE_BER = 4,
+  SIGNAL_QUALITY = 5,
+  SIGNAL_STRENGTH = 6,
+  SYMBOL_RATE = 7,
+  FEC = 8,
+  MODULATION = 9,
+  SPECTRAL = 10,
+  LNB_VOLTAGE = 11,
+  PLP_ID = 12,
+  EWBS = 13,
+  AGC = 14,
+  LNA = 15,
+  LAYER_ERROR = 16,
+  MER = 17,
+  FREQ_OFFSET = 18,
+  HIERARCHY = 19,
+  RF_LOCK = 20,
+  ATSC3_PLP_INFO = 21,
+  MODULATIONS = 22,
+  BERS = 23,
+  CODERATES = 24,
+  BANDWIDTH = 25,
+  GUARD_INTERVAL = 26,
+  TRANSMISSION_MODE = 27,
+  UEC = 28,
+  T2_SYSTEM_ID = 29,
+  INTERLEAVINGS = 30,
+  ISDBT_SEGMENTS = 31,
+  TS_DATA_RATES = 32,
+  ROLL_OFF = 33,
+  IS_MISO = 34,
+  IS_LINEAR = 35,
+  IS_SHORT_FRAMES = 36,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendTransmissionMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendTransmissionMode.aidl
new file mode 100644
index 0000000..72c3641
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendTransmissionMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+union FrontendTransmissionMode {
+  android.hardware.tv.tuner.FrontendDvbtTransmissionMode dvbt = android.hardware.tv.tuner.FrontendDvbtTransmissionMode.UNDEFINED;
+  android.hardware.tv.tuner.FrontendIsdbtMode isdbt;
+  android.hardware.tv.tuner.FrontendDtmbTransmissionMode dtmb;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
new file mode 100644
index 0000000..99a120b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendType {
+  UNDEFINED = 0,
+  ANALOG = 1,
+  ATSC = 2,
+  ATSC3 = 3,
+  DVBC = 4,
+  DVBS = 5,
+  DVBT = 6,
+  ISDBS = 7,
+  ISDBS3 = 8,
+  ISDBT = 9,
+  DTMB = 10,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDemux.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDemux.aidl
new file mode 100644
index 0000000..59ec92b
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDemux.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface IDemux {
+  void setFrontendDataSource(in int frontendId);
+  android.hardware.tv.tuner.IFilter openFilter(in android.hardware.tv.tuner.DemuxFilterType type, in int bufferSize, in android.hardware.tv.tuner.IFilterCallback cb);
+  android.hardware.tv.tuner.ITimeFilter openTimeFilter();
+  int getAvSyncHwId(in android.hardware.tv.tuner.IFilter filter);
+  long getAvSyncTime(in int avSyncHwId);
+  void close();
+  android.hardware.tv.tuner.IDvr openDvr(in android.hardware.tv.tuner.DvrType type, in int bufferSize, in android.hardware.tv.tuner.IDvrCallback cb);
+  void connectCiCam(in int ciCamId);
+  void disconnectCiCam();
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDescrambler.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDescrambler.aidl
new file mode 100644
index 0000000..3cf3c04
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDescrambler.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface IDescrambler {
+  void setDemuxSource(in int demuxId);
+  void setKeyToken(in byte[] keyToken);
+  void addPid(in android.hardware.tv.tuner.DemuxPid pid, in android.hardware.tv.tuner.IFilter optionalSourceFilter);
+  void removePid(in android.hardware.tv.tuner.DemuxPid pid, in android.hardware.tv.tuner.IFilter optionalSourceFilter);
+  void close();
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl
new file mode 100644
index 0000000..450cd79
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvr.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface IDvr {
+  void getQueueDesc(out android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> queue);
+  void configure(in android.hardware.tv.tuner.DvrSettings settings);
+  void attachFilter(in android.hardware.tv.tuner.IFilter filter);
+  void detachFilter(in android.hardware.tv.tuner.IFilter filter);
+  void start();
+  void stop();
+  void flush();
+  void close();
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvrCallback.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvrCallback.aidl
new file mode 100644
index 0000000..13c8644
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IDvrCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface IDvrCallback {
+  oneway void onPlaybackStatus(in android.hardware.tv.tuner.PlaybackStatus status);
+  oneway void onRecordStatus(in android.hardware.tv.tuner.RecordStatus status);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFilter.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFilter.aidl
new file mode 100644
index 0000000..a0454f4
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFilter.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface IFilter {
+  void getQueueDesc(out android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> queue);
+  void close();
+  void configure(in android.hardware.tv.tuner.DemuxFilterSettings settings);
+  void configureAvStreamType(in android.hardware.tv.tuner.AvStreamType avStreamType);
+  void configureIpCid(in int ipCid);
+  void configureMonitorEvent(in int monitorEventTypes);
+  void start();
+  void stop();
+  void flush();
+  long getAvSharedHandle(out android.hardware.common.NativeHandle avMemory);
+  int getId();
+  long getId64Bit();
+  void releaseAvHandle(in android.hardware.common.NativeHandle avMemory, in long avDataId);
+  void setDataSource(in android.hardware.tv.tuner.IFilter filter);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFilterCallback.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFilterCallback.aidl
new file mode 100644
index 0000000..d8bedba
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFilterCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface IFilterCallback {
+  oneway void onFilterEvent(in android.hardware.tv.tuner.DemuxFilterEvent[] events);
+  oneway void onFilterStatus(in android.hardware.tv.tuner.DemuxFilterStatus status);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontend.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontend.aidl
new file mode 100644
index 0000000..ed5b0c0
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontend.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface IFrontend {
+  void setCallback(in android.hardware.tv.tuner.IFrontendCallback callback);
+  void tune(in android.hardware.tv.tuner.FrontendSettings settings);
+  void stopTune();
+  void close();
+  void scan(in android.hardware.tv.tuner.FrontendSettings settings, in android.hardware.tv.tuner.FrontendScanType type);
+  void stopScan();
+  android.hardware.tv.tuner.FrontendStatus[] getStatus(in android.hardware.tv.tuner.FrontendStatusType[] statusTypes);
+  void setLnb(in int lnbId);
+  void setLna(in boolean bEnable);
+  int linkCiCam(in int ciCamId);
+  void unlinkCiCam(in int ciCamId);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontendCallback.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontendCallback.aidl
new file mode 100644
index 0000000..c22d280
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontendCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface IFrontendCallback {
+  oneway void onEvent(in android.hardware.tv.tuner.FrontendEventType frontendEventType);
+  oneway void onScanMessage(in android.hardware.tv.tuner.FrontendScanMessageType type, in android.hardware.tv.tuner.FrontendScanMessage message);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ILnb.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ILnb.aidl
new file mode 100644
index 0000000..c3fdd87
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ILnb.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface ILnb {
+  void setCallback(in android.hardware.tv.tuner.ILnbCallback callback);
+  void setVoltage(in android.hardware.tv.tuner.LnbVoltage voltage);
+  void setTone(in android.hardware.tv.tuner.LnbTone tone);
+  void setSatellitePosition(in android.hardware.tv.tuner.LnbPosition position);
+  void sendDiseqcMessage(in byte[] diseqcMessage);
+  void close();
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ILnbCallback.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ILnbCallback.aidl
new file mode 100644
index 0000000..42e84da
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ILnbCallback.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface ILnbCallback {
+  oneway void onDiseqcMessage(in byte[] diseqcMessage);
+  oneway void onEvent(in android.hardware.tv.tuner.LnbEventType lnbEventType);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITimeFilter.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITimeFilter.aidl
new file mode 100644
index 0000000..838eeba
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITimeFilter.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+interface ITimeFilter {
+  void setTimeStamp(in long timeStamp);
+  void clearTimeStamp();
+  long getTimeStamp();
+  long getSourceTime();
+  void close();
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
new file mode 100644
index 0000000..0e903d8
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@SuppressWarnings(value={"out-array"}) @VintfStability
+interface ITuner {
+  int[] getFrontendIds();
+  android.hardware.tv.tuner.IFrontend openFrontendById(in int frontendId);
+  android.hardware.tv.tuner.IDemux openDemux(out int[] demuxId);
+  android.hardware.tv.tuner.DemuxCapabilities getDemuxCaps();
+  android.hardware.tv.tuner.IDescrambler openDescrambler();
+  android.hardware.tv.tuner.FrontendInfo getFrontendInfo(in int frontendId);
+  int[] getLnbIds();
+  android.hardware.tv.tuner.ILnb openLnbById(in int lnbId);
+  android.hardware.tv.tuner.ILnb openLnbByName(in String lnbName, out int[] lnbId);
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbEventType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbEventType.aidl
new file mode 100644
index 0000000..e6e2b05
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbEventType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum LnbEventType {
+  DISEQC_RX_OVERFLOW = 0,
+  DISEQC_RX_TIMEOUT = 1,
+  DISEQC_RX_PARITY_ERROR = 2,
+  LNB_OVERLOAD = 3,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbPosition.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbPosition.aidl
new file mode 100644
index 0000000..5fc4d15
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbPosition.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum LnbPosition {
+  UNDEFINED = 0,
+  POSITION_A = 1,
+  POSITION_B = 2,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbTone.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbTone.aidl
new file mode 100644
index 0000000..3217de9
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbTone.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum LnbTone {
+  NONE = 0,
+  CONTINUOUS = 1,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbVoltage.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbVoltage.aidl
new file mode 100644
index 0000000..034c7e6
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbVoltage.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum LnbVoltage {
+  NONE = 0,
+  VOLTAGE_5V = 1,
+  VOLTAGE_11V = 2,
+  VOLTAGE_12V = 3,
+  VOLTAGE_13V = 4,
+  VOLTAGE_14V = 5,
+  VOLTAGE_15V = 6,
+  VOLTAGE_18V = 7,
+  VOLTAGE_19V = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackSettings.aidl
new file mode 100644
index 0000000..ff459e2
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable PlaybackSettings {
+  int statusMask;
+  int lowThreshold;
+  int highThreshold;
+  android.hardware.tv.tuner.DataFormat dataFormat = android.hardware.tv.tuner.DataFormat.UNDEFINED;
+  byte packetSize;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackStatus.aidl
new file mode 100644
index 0000000..850b737
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum PlaybackStatus {
+  SPACE_EMPTY = 1,
+  SPACE_ALMOST_EMPTY = 2,
+  SPACE_ALMOST_FULL = 4,
+  SPACE_FULL = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordSettings.aidl
new file mode 100644
index 0000000..447de98
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable RecordSettings {
+  int statusMask;
+  int lowThreshold;
+  int highThreshold;
+  android.hardware.tv.tuner.DataFormat dataFormat = android.hardware.tv.tuner.DataFormat.UNDEFINED;
+  byte packetSize;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordStatus.aidl
new file mode 100644
index 0000000..48bf9ec
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum RecordStatus {
+  DATA_READY = 1,
+  LOW_WATER = 2,
+  HIGH_WATER = 4,
+  OVERFLOW = 8,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ScramblingStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ScramblingStatus.aidl
new file mode 100644
index 0000000..656fe20
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ScramblingStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ScramblingStatus {
+  UNKNOWN = 1,
+  NOT_SCRAMBLED = 2,
+  SCRAMBLED = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
new file mode 100644
index 0000000..9dfd686
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum VideoStreamType {
+  UNDEFINED = 0,
+  RESERVED = 1,
+  MPEG1 = 2,
+  MPEG2 = 3,
+  MPEG4P2 = 4,
+  AVC = 5,
+  HEVC = 6,
+  VC1 = 7,
+  VP8 = 8,
+  VP9 = 9,
+  AV1 = 10,
+  AVS = 11,
+  AVS2 = 12,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioExtraMetaData.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioExtraMetaData.aidl
new file mode 100644
index 0000000..b5adb7d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioExtraMetaData.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Extra Meta Data from AD (Audio Descriptor) according to
+ * ETSI TS 101 154 V2.1.1.
+ * @hide
+ */
+@VintfStability
+parcelable AudioExtraMetaData {
+    byte adFade;
+
+    byte adPan;
+
+    byte versionTextTag;
+
+    byte adGainCenter;
+
+    byte adGainFront;
+
+    byte adGainSurround;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioStreamType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioStreamType.aidl
new file mode 100644
index 0000000..1bb5c68f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioStreamType.aidl
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Audio stream coding format.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum AudioStreamType {
+    UNDEFINED,
+
+    /*
+     * Uncompressed Audio
+     */
+    PCM,
+
+    /*
+     * MPEG Audio Layer III versions
+     */
+    MP3,
+
+    /*
+     * ISO/IEC 11172 Audio
+     */
+    MPEG1,
+
+    /*
+     * ISO/IEC 13818-3
+     */
+    MPEG2,
+
+    /*
+     * ISO/IEC 23008-3 (MPEG-H Part 3)
+     */
+    MPEGH,
+
+    /*
+     * ISO/IEC 14496-3
+     */
+    AAC,
+
+    /*
+     * Dolby Digital
+     */
+    AC3,
+
+    /*
+     * Dolby Digital Plus
+     */
+    EAC3,
+
+    /*
+     * Dolby AC-4
+     */
+    AC4,
+
+    /*
+     * Basic DTS
+     */
+    DTS,
+
+    /*
+     * High Resolution DTS
+     */
+    DTS_HD,
+
+    /*
+     * Windows Media Audio
+     */
+    WMA,
+
+    /*
+     * Opus Interactive Audio Codec
+     */
+    OPUS,
+
+    /*
+     * VORBIS Interactive Audio Codec
+     */
+    VORBIS,
+
+    /*
+     * SJ/T 11368-2006
+     */
+    DRA,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AvStreamType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AvStreamType.aidl
new file mode 100644
index 0000000..684dfb9
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AvStreamType.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.AudioStreamType;
+import android.hardware.tv.tuner.VideoStreamType;
+
+/**
+ * Stream type for A/V filter.
+ * @hide
+ */
+@VintfStability
+union AvStreamType {
+    VideoStreamType video = VideoStreamType.UNDEFINED;
+
+    AudioStreamType audio;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
new file mode 100644
index 0000000..891794a
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/Constant.aidl
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum Constant {
+    /**
+     * An invalid packet ID in transport stream according to ISO/IEC 13818-1.
+     */
+    INVALID_TS_PID = 0xFFFF,
+
+    /**
+     * An invalid Stream ID.
+     */
+    INVALID_STREAM_ID = 0xFFFF,
+
+    /**
+     * An invalid Filter ID.
+     */
+    INVALID_FILTER_ID = 0xFFFFFFFF,
+
+    /**
+     * An invalid AV sync hardware ID.
+     */
+    INVALID_AV_SYNC_ID = 0xFFFFFFFF,
+
+    /**
+     * An invalid mpuSequenceNumber.
+     */
+    INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = 0xFFFFFFFF,
+
+    /**
+     * An invalid first macroblock address.
+     */
+    INVALID_FIRST_MACROBLOCK_IN_SLICE = 0xFFFFFFFF,
+
+    /**
+     * An invalid frenquency that can be used as the default value of the frontend setting.
+     */
+    INVALID_FRONTEND_SETTING_FREQUENCY = 0xFFFFFFFF,
+
+    /**
+     * An invalid context id that can be used as the default value of the unconfigured id. It can
+     * be used to reset the configured ip context id.
+     */
+    INVALID_IP_FILTER_CONTEXT_ID = 0xFFFFFFFF,
+
+    /**
+     * An invalid local transport stream id used as the return value on a failed operation of
+     * IFrontend.linkCiCam.
+     */
+    INVALID_LTS_ID = 0xFFFFFFFF,
+
+    /**
+     * An invalid frontend ID.
+     */
+    INVALID_FRONTEND_ID = 0xFFFFFFFF,
+
+    /**
+     * An invalid LNB ID.
+     */
+    INVALID_LNB_ID = 0xFFFFFFFF,
+
+    /**
+     * An invalid key token. It is used to remove the current key from the descrambler.
+     */
+    INVALID_KEYTOKEN = 0x00,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/Constant64Bit.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/Constant64Bit.aidl
new file mode 100644
index 0000000..31a7f5b
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/Constant64Bit.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * @hide
+ */
+@VintfStability
+@Backing(type="long")
+enum Constant64Bit {
+    /**
+     * An invalid 64-bit Filter ID.
+     */
+    INVALID_FILTER_ID_64BIT = 0xFFFFFFFFFFFFFFFF,
+
+    /**
+     * An invalid 64-bit AV sync hardware ID.
+     */
+    INVALID_AV_SYNC_ID_64BIT = 0xFFFFFFFFFFFFFFFF,
+
+    /**
+     * An invalid pts.
+     */
+    INVALID_PRESENTATION_TIME_STAMP = 0xFFFFFFFFFFFFFFFF,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DataFormat.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DataFormat.aidl
new file mode 100644
index 0000000..bbc811d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DataFormat.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * A data format in demux's output or input according to ISO/IEC 13818-1.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DataFormat {
+    /**
+     * Data is Transport Stream.
+     */
+    TS,
+
+    /**
+     * Data is Packetized Elementary Stream.
+     */
+    PES,
+
+    /**
+     * Data is Elementary Stream.
+     */
+    ES,
+
+    /**
+     * Data is TLV (type-length-value) Stream for JP SHV
+     */
+    SHV_TLV,
+
+    /**
+     * Data format is undefined.
+     */
+    UNDEFINED,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpFilterSettings.aidl
new file mode 100644
index 0000000..397002d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpFilterSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxAlpFilterSettingsFilterSettings;
+import android.hardware.tv.tuner.DemuxAlpLengthType;
+
+/**
+ * Filter Settings for a ALP filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxAlpFilterSettings {
+    /**
+     * Packet type according to A/330 ATSC3.0.
+     * 0: IPv4 packet
+     * 2: Compressed IP packet
+     * 4: Link layer signaling packet
+     * 6: Packet Type Extension
+     * 8: MPEG-2 Transport Stream
+     */
+    byte packetType;
+
+    DemuxAlpLengthType lengthType = DemuxAlpLengthType.UNDEFINED;
+
+    DemuxAlpFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..9ab967e
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpFilterSettingsFilterSettings.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterSectionSettings;
+
+/**
+ * @hide
+ */
+@VintfStability
+union DemuxAlpFilterSettingsFilterSettings {
+    /**
+     * Not additional parameters. it's used by PTP, PAYLOAD_THROUGH subtype
+     * filters.
+     */
+    boolean noinit;
+
+    DemuxFilterSectionSettings section;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpFilterType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpFilterType.aidl
new file mode 100644
index 0000000..fc36b93
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpFilterType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * ALP Filter Type according to A/330 ATSC3.0.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxAlpFilterType {
+    UNDEFINED,
+    /**
+     * A filter to filter signaling data out from input stream, and queue the
+     * data to the filter's FMQ (Fast Message Queue).
+     */
+    SECTION,
+
+    /**
+     * A filter to set PTP (Precision Time Protocol) channel from input stream.
+     */
+    PTP,
+
+    /**
+     * A filter to strip out ALP message header and be a data source of another
+     * filter.
+     */
+    PAYLOAD_THROUGH,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpLengthType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpLengthType.aidl
new file mode 100644
index 0000000..7d697ad
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxAlpLengthType.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * ALP Length Type
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum DemuxAlpLengthType {
+    UNDEFINED = 0,
+
+    /**
+     * Length does NOT include additional header. Used in US region.
+     */
+    WITHOUT_ADDITIONAL_HEADER,
+
+    /**
+     * Length includes additional header. Used in Korea region.
+     */
+    WITH_ADDITIONAL_HEADER,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxCapabilities.aidl
new file mode 100644
index 0000000..49fa08d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxCapabilities.aidl
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for Demux.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxCapabilities {
+    /**
+     * The number of Demux to be supported.
+     */
+    int numDemux;
+
+    /**
+     * The number of record to be supported.
+     */
+    int numRecord;
+
+    /**
+     * The number of playback to be supported.
+     */
+    int numPlayback;
+
+    /**
+     * The number of TS Filter to be supported.
+     */
+    int numTsFilter;
+
+    /**
+     * The number of Section Filter to be supported.
+     */
+    int numSectionFilter;
+
+    /**
+     * The number of Audio Filter to be supported.
+     */
+    int numAudioFilter;
+
+    /**
+     * The number of Video Filter to be supported.
+     */
+    int numVideoFilter;
+
+    /**
+     * The number of PES Filter to be supported.
+     */
+    int numPesFilter;
+
+    /**
+     * The number of PCR Filter to be supported.
+     */
+    int numPcrFilter;
+
+    /**
+     * The maximum number of bytes is supported in the mask of Section Filter.
+     */
+    int numBytesInSectionFilter;
+
+    /**
+     * Filter Main Types defined by DemuxFilterMainType. The DemuxFilterMainTypes
+     * is set by bitwise OR.
+     */
+    int filterCaps;
+
+    /**
+     * The array has same elements as DemuxFilterMainType. linkCaps[i] presents
+     * filter's capability as source for the ith type in DemuxFilterMainType.
+     * The jth bit of linkCaps[i] is 1 if the output of ith type filter can be
+     * data source for the filter type j.
+     */
+    int[] linkCaps;
+
+    /**
+     * True if Time Filter to be supported.
+     */
+    boolean bTimeFilter;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
new file mode 100644
index 0000000..30a1054
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Settings for a Video and Audio.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterAvSettings {
+    /**
+     * true if the filter output goes to decoder directly in pass through mode.
+     */
+    boolean isPassthrough;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
new file mode 100644
index 0000000..d59dd2e
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Event for Download data.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterDownloadEvent {
+    /**
+     * ID of object/module in the carousel
+     */
+    int itemId;
+
+    /**
+     * MPU sequence number of filtered data (only for MMTP)
+     */
+    int mpuSequenceNumber;
+
+    int itemFragmentIndex;
+
+    int lastItemFragmentIndex;
+
+    /**
+     * Data size in bytes of filtered data
+     */
+    char dataLength;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
new file mode 100644
index 0000000..bd79bd5
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Settings for a Download.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterDownloadSettings {
+    /**
+     * Download ID (also known as the carousel ID) is carried in the PMT in
+     * ISO/IEC 13818-1 for the service containing the object carousel.
+     */
+    int downloadId;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterEvent.aidl
new file mode 100644
index 0000000..8de80e0
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterEvent.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterDownloadEvent;
+import android.hardware.tv.tuner.DemuxFilterIpPayloadEvent;
+import android.hardware.tv.tuner.DemuxFilterMediaEvent;
+import android.hardware.tv.tuner.DemuxFilterMmtpRecordEvent;
+import android.hardware.tv.tuner.DemuxFilterMonitorEvent;
+import android.hardware.tv.tuner.DemuxFilterPesEvent;
+import android.hardware.tv.tuner.DemuxFilterSectionEvent;
+import android.hardware.tv.tuner.DemuxFilterTemiEvent;
+import android.hardware.tv.tuner.DemuxFilterTsRecordEvent;
+
+/**
+ * Filter Event.
+ * @hide
+ */
+@VintfStability
+union DemuxFilterEvent {
+    DemuxFilterSectionEvent section;
+
+    DemuxFilterMediaEvent media;
+
+    DemuxFilterPesEvent pes;
+
+    DemuxFilterTsRecordEvent tsRecord;
+
+    DemuxFilterMmtpRecordEvent mmtpRecord;
+
+    DemuxFilterDownloadEvent download;
+
+    DemuxFilterIpPayloadEvent ipPayload;
+
+    DemuxFilterTemiEvent temi;
+
+    DemuxFilterMonitorEvent monitorEvent;
+
+    /**
+     * An unique ID to mark the start point of receiving the valid filter events after
+     * reconfiguring the filter. It must be sent at least once in the first event after the
+     * filter is restarted. 0 is reserved for the newly opened filter's first start, which is
+     * optional for HAL to send.
+     *
+     * When sending starId, DemuxFilterEvent.events should only contain one startId event.
+     */
+    int startId;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterIpPayloadEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterIpPayloadEvent.aidl
new file mode 100644
index 0000000..0619b45
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterIpPayloadEvent.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Event for IP payload data.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterIpPayloadEvent {
+    /**
+     * Data size in bytes of IP data
+     */
+    char dataLength;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMainType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMainType.aidl
new file mode 100644
index 0000000..663bdfb
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMainType.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Main Type specifies the protocol that the filter use to extract data
+ * from input stream.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxFilterMainType {
+    UNDEFINED = 0,
+
+    /**
+     * Transport Stream according to ISO/IEC 13818-1.
+     */
+    TS = 1 << 0,
+
+    /**
+     * MPEG Media Transport Protocol according to ISO/IEC 23008-1.
+     */
+    MMTP = 1 << 1,
+
+    /**
+     * Internet Protocol.
+     */
+    IP = 1 << 2,
+
+    /**
+     * Type Length Value according to ITU-R BT.1869.
+     */
+    TLV = 1 << 3,
+
+    /**
+     * ATSC Link-Layer Protocol according to A/330 ATSC3.0.
+     */
+    ALP = 1 << 4,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
new file mode 100644
index 0000000..754708c
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.common.NativeHandle;
+
+import android.hardware.tv.tuner.DemuxFilterMediaEventExtraMetaData;
+
+/**
+ * Filter Event for Audio or Video Filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterMediaEvent {
+    char streamId;
+
+    /**
+     * true if PTS is present in PES header.
+     */
+    boolean isPtsPresent;
+
+    /**
+     * Presentation Time Stamp for audio or video frame. It based on 90KHz has
+     * the same format as PTS (Presentation Time Stamp).
+     */
+    long pts;
+
+    /**
+     * Data size in bytes of audio or video frame
+     */
+    int dataLength;
+
+    /**
+     *  The offset in the memory block which is shared among multiple
+     *  MediaEvents.
+     */
+    int offset;
+
+    /**
+     * A handle associated to the memory where audio or video data stays.
+     */
+    NativeHandle avMemory;
+
+    /**
+     * True if the avMemory is in secure area, and isn't mappable.
+     */
+    boolean isSecureMemory;
+
+    /**
+     * An Id is used by HAL to provide additional information for AV data.
+     * For secure audio, it's the audio handle used by Audio Track.
+     */
+    long avDataId;
+
+    /**
+     * MPU sequence number of filtered data (only for MMTP)
+     */
+    int mpuSequenceNumber;
+
+    boolean isPesPrivateData;
+
+    DemuxFilterMediaEventExtraMetaData extraMetaData;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
new file mode 100644
index 0000000..f01952b
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEventExtraMetaData.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.AudioExtraMetaData;
+
+/**
+ * Extra Meta Data for DemuxFilterMediaEvent.
+ * @hide
+ */
+@VintfStability
+union DemuxFilterMediaEventExtraMetaData {
+    /**
+     * Not additional parameters. it's used for video.
+     */
+    boolean noinit;
+
+    AudioExtraMetaData audio;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMmtpRecordEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMmtpRecordEvent.aidl
new file mode 100644
index 0000000..39083a9
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMmtpRecordEvent.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Event for MMTP Record data.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterMmtpRecordEvent {
+    /**
+     * Indexes defined by DemuxScHevcIndex.
+     */
+    int scHevcIndexMask;
+
+    /**
+     * Byte number from beginning of the filter's output
+     */
+    long byteNumber;
+
+    /**
+     * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
+     * and has the same format as the PTS in ISO/IEC 13818-1.
+     */
+    long pts;
+
+    /**
+     * MPU sequence number of the filtered data. This is only used for MMTP.
+     */
+    int mpuSequenceNumber;
+
+    /**
+     * Specifies the address of the first macroblock in the slice defined in ITU-T Rec. H.264.
+     */
+    int firstMbInSlice;
+
+    /**
+     * TS index mask defined by DemuxTsIndex.
+     */
+    int tsIndexMask;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMonitorEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMonitorEvent.aidl
new file mode 100644
index 0000000..2dd11e2
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMonitorEvent.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.ScramblingStatus;
+
+/**
+ * Monitor event to notify monitored status change.
+ * @hide
+ */
+@VintfStability
+union DemuxFilterMonitorEvent {
+    /**
+     * New scrambling status.
+     */
+    ScramblingStatus scramblingStatus = ScramblingStatus.UNKNOWN;
+
+    /**
+     * New cid for the IP filter.
+     */
+    int cid;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl
new file mode 100644
index 0000000..87a4d9d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Monitor event type.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxFilterMonitorEventType {
+    SCRAMBLING_STATUS = 1 << 0,
+
+    IP_CID_CHANGE = 1 << 1,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterPesDataSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterPesDataSettings.aidl
new file mode 100644
index 0000000..9780f40
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterPesDataSettings.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Settings for a PES Data.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterPesDataSettings {
+    char streamId;
+
+    /**
+     * true if the filter send onFilterStatus instead of onFilterEvent.
+     */
+    boolean isRaw;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterPesEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterPesEvent.aidl
new file mode 100644
index 0000000..2b24cd9
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterPesEvent.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Event for PES data.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterPesEvent {
+    char streamId;
+
+    /**
+     * Data size in bytes of PES data
+     */
+    char dataLength;
+
+    /**
+     * MPU sequence number of filtered data (only for MMTP)
+     */
+    int mpuSequenceNumber;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
new file mode 100644
index 0000000..2f88864
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterScIndexMask;
+import android.hardware.tv.tuner.DemuxRecordScIndexType;
+
+/**
+ * Filter Settings for Record data.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterRecordSettings {
+    /**
+     * Indexes defined by DemuxTsIndex.
+     */
+    int tsIndexMask;
+
+    DemuxRecordScIndexType scIndexType = DemuxRecordScIndexType.UNDEFINED;
+
+    DemuxFilterScIndexMask scIndexMask;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
new file mode 100644
index 0000000..a9f4b6f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterScIndexMask.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxScHevcIndex;
+import android.hardware.tv.tuner.DemuxScIndex;
+
+/**
+ * @hide
+ */
+@VintfStability
+union DemuxFilterScIndexMask {
+    /**
+     * Indexes defined by DemuxScIndex.
+     */
+    int scIndex;
+
+    /**
+     * Indexes defined by DemuxScHevcIndex.
+     */
+    int scHevc;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionBits.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionBits.aidl
new file mode 100644
index 0000000..eea544f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionBits.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Bits Settings for Section Filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterSectionBits {
+    /**
+     * The bytes are configured for Section Filter
+     */
+    byte[] filter;
+
+    /**
+     * Active bits in the configured bytes to be used for filtering
+     */
+    byte[] mask;
+
+    /**
+     * Do positive match at the bit position of the configured bytes when the
+     * bit at same position of the mode is 0.
+     * Do negative match at the bit position of the configured bytes when the
+     * bit at same position of the mode is 1.
+     */
+    byte[] mode;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
new file mode 100644
index 0000000..1a327f3
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Event for Section Filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterSectionEvent {
+    /**
+     * Table ID of filtered data
+     */
+    char tableId;
+
+    /**
+     * Version number of filtered data
+     */
+    char version;
+
+    /**
+     * Section number of filtered data
+     */
+    char sectionNum;
+
+    /**
+     * Data size in bytes of filtered data
+     */
+    char dataLength;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
new file mode 100644
index 0000000..2102aa0
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterSectionSettingsCondition;
+
+/**
+ * Filter Settings for Section data according to ISO/IEC 13818-1.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterSectionSettings {
+    DemuxFilterSectionSettingsCondition condition;
+
+    /**
+     * true if the filter checks CRC and discards data with wrong CRC
+     */
+    boolean isCheckCrc;
+
+    /**
+     * true if the filter repeats the data with the same version
+     */
+    boolean isRepeat;
+
+    /**
+     * true if the filter send onFilterStatus instead of onFilterEvent.
+     */
+    boolean isRaw;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsCondition.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsCondition.aidl
new file mode 100644
index 0000000..374511a
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsCondition.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterSectionBits;
+import android.hardware.tv.tuner.DemuxFilterSectionSettingsConditionTableInfo;
+
+/**
+ * The union of Section Filter Bits Settings and Table information that can be
+ * set by client.
+ * @hide
+ */
+@VintfStability
+union DemuxFilterSectionSettingsCondition {
+    DemuxFilterSectionBits sectionBits;
+
+    DemuxFilterSectionSettingsConditionTableInfo tableInfo;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
new file mode 100644
index 0000000..c76d84c
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettingsConditionTableInfo.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Table information for Section Filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterSectionSettingsConditionTableInfo {
+    /**
+     * Table ID for Section Filter
+     */
+    char tableId;
+
+    /**
+     * Version number for Section Filter
+     */
+    char version;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSettings.aidl
new file mode 100644
index 0000000..7e9d2a1
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSettings.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxAlpFilterSettings;
+import android.hardware.tv.tuner.DemuxIpFilterSettings;
+import android.hardware.tv.tuner.DemuxMmtpFilterSettings;
+import android.hardware.tv.tuner.DemuxTlvFilterSettings;
+import android.hardware.tv.tuner.DemuxTsFilterSettings;
+
+/**
+ * Filter Settings.
+ * @hide
+ */
+@VintfStability
+union DemuxFilterSettings {
+    DemuxTsFilterSettings ts;
+
+    DemuxMmtpFilterSettings mmtp;
+
+    DemuxIpFilterSettings ip;
+
+    DemuxTlvFilterSettings tlv;
+
+    DemuxAlpFilterSettings alp;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
new file mode 100644
index 0000000..f07c26f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * A status of data in the filter's buffer.
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum DemuxFilterStatus {
+    /**
+     * The data in the filter buffer is ready to be read.
+     */
+    DATA_READY = 1 << 0,
+
+    /**
+     * The available data amount in the filter buffer is at low level which is
+     * set to 25 percent by default.
+     */
+    LOW_WATER = 1 << 1,
+
+    /**
+     * The available data amount in the filter buffer is at high level which is
+     * set to 75 percent by default.
+     */
+    HIGH_WATER = 1 << 2,
+
+    /**
+     * The data in the filter buffer is full and newly filtered data is being
+     * discarded.
+     */
+    OVERFLOW = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterTemiEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterTemiEvent.aidl
new file mode 100644
index 0000000..a752e7c
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterTemiEvent.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Filter Event for Timed External Media Information (TEMI) data.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterTemiEvent {
+    /**
+     * Presentation Time Stamp for audio or video frame. It based on 90KHz has
+     * the same format as PTS (Presentation Time Stamp) in ISO/IEC 13818-1.
+     */
+    long pts;
+
+    /**
+     * TEMI Descriptor Tag
+     */
+    byte descrTag;
+
+    /**
+     * TEMI Descriptor
+     */
+    byte[] descrData;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterTsRecordEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterTsRecordEvent.aidl
new file mode 100644
index 0000000..4992a33
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterTsRecordEvent.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterScIndexMask;
+import android.hardware.tv.tuner.DemuxPid;
+
+/**
+ * Filter Event for TS Record data.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterTsRecordEvent {
+    DemuxPid pid;
+
+    /**
+     * Indexes defined by DemuxTsIndex.
+     */
+    int tsIndexMask;
+
+    /**
+     * Indexes of record output
+     */
+    DemuxFilterScIndexMask scIndexMask;
+
+    /**
+     * Byte number from beginning of the filter's output
+     */
+    long byteNumber;
+
+    /**
+     * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
+     * and has the same format as the PTS in ISO/IEC 13818-1.
+     */
+    long pts;
+
+    /**
+     * Specifies the address of the first macroblock in the slice defined in ITU-T Rec. H.264.
+     */
+    int firstMbInSlice;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterType.aidl
new file mode 100644
index 0000000..38348b6
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterType.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterMainType;
+import android.hardware.tv.tuner.DemuxFilterTypeDemuxFilterSubType;
+
+/**
+ * Demux Filter Type.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxFilterType {
+    DemuxFilterMainType mainType = DemuxFilterMainType.UNDEFINED;
+
+    DemuxFilterTypeDemuxFilterSubType subType;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterTypeDemuxFilterSubType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterTypeDemuxFilterSubType.aidl
new file mode 100644
index 0000000..cf1a59c
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterTypeDemuxFilterSubType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxAlpFilterType;
+import android.hardware.tv.tuner.DemuxIpFilterType;
+import android.hardware.tv.tuner.DemuxMmtpFilterType;
+import android.hardware.tv.tuner.DemuxTlvFilterType;
+import android.hardware.tv.tuner.DemuxTsFilterType;
+
+/**
+ * @hide
+ */
+@VintfStability
+union DemuxFilterTypeDemuxFilterSubType {
+    DemuxTsFilterType tsFilterType = DemuxTsFilterType.UNDEFINED;
+
+    DemuxMmtpFilterType mmtpFilterType;
+
+    DemuxIpFilterType ipFilterType;
+
+    DemuxTlvFilterType tlvFilterType;
+
+    DemuxAlpFilterType alpFilterType;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpAddress.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpAddress.aidl
new file mode 100644
index 0000000..9c704a3
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpAddress.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxIpAddressIpAddress;
+
+/**
+ * IP Settings for a IP filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxIpAddress {
+    DemuxIpAddressIpAddress srcIpAddress;
+
+    DemuxIpAddressIpAddress dstIpAddress;
+
+    /**
+     * 0 is invalid. should be ignored.
+     */
+    char srcPort;
+
+    /**
+     * 0 is invalid. should be ignored.
+     */
+    char dstPort;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpAddressIpAddress.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpAddressIpAddress.aidl
new file mode 100644
index 0000000..1a57215
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpAddressIpAddress.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * @hide
+ */
+@VintfStability
+union DemuxIpAddressIpAddress {
+    /**
+     * 0.0.0.0 is invalid. should be ignored.
+     */
+    byte[] v4 = {};
+
+    /**
+     * 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 is invalid. should be ignored.
+     */
+    byte[] v6;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpFilterSettings.aidl
new file mode 100644
index 0000000..6265aa6
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpFilterSettings.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxIpAddress;
+import android.hardware.tv.tuner.DemuxIpFilterSettingsFilterSettings;
+
+/**
+ * Filter Settings for a IP filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxIpFilterSettings {
+    DemuxIpAddress ipAddr;
+
+    DemuxIpFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..b8aa9f2
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpFilterSettingsFilterSettings.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterSectionSettings;
+
+/**
+ * @hide
+ */
+@VintfStability
+union DemuxIpFilterSettingsFilterSettings {
+    /**
+     * Not additional parameters. it's used by NTP, IP_PAYLOAD,
+     * PAYLOAD_THROUGH subtype filters.
+     */
+    boolean noinit;
+
+    DemuxFilterSectionSettings section;
+
+    /**
+     * true if the data from IP subtype go to next filter directly
+     */
+    boolean bPassthrough;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpFilterType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpFilterType.aidl
new file mode 100644
index 0000000..f975195
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxIpFilterType.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * IP Filter Type.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxIpFilterType {
+    UNDEFINED,
+
+    /**
+     * A filter to filter section data out from input stream, and queue the
+     * data to the filter's FMQ (Fast Message Queue).
+     */
+    SECTION,
+
+    /**
+     * A filter to set NTP (Network Time Procotol) channel from input stream.
+     */
+    NTP,
+
+    /**
+     * A filter to strip out IP message header and queue the data to the
+     * filter's FMQ.
+     */
+    IP_PAYLOAD,
+
+    /**
+     * A filter to filter a IP stream out from input stream. The output can be
+     * either upper stream of another filter or queued to the filter's FMQ.
+     */
+    IP,
+
+    /**
+     * A filter to strip out IP message header and be a data source of another
+     * filter.
+     */
+    PAYLOAD_THROUGH,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxMmtpFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxMmtpFilterSettings.aidl
new file mode 100644
index 0000000..3759ce0
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxMmtpFilterSettings.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxMmtpFilterSettingsFilterSettings;
+
+/**
+ * Filter Settings for a MMTP filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxMmtpFilterSettings {
+    char mmtpPid;
+
+    DemuxMmtpFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxMmtpFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxMmtpFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..0f960b6
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxMmtpFilterSettingsFilterSettings.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterAvSettings;
+import android.hardware.tv.tuner.DemuxFilterDownloadSettings;
+import android.hardware.tv.tuner.DemuxFilterPesDataSettings;
+import android.hardware.tv.tuner.DemuxFilterRecordSettings;
+import android.hardware.tv.tuner.DemuxFilterSectionSettings;
+
+/**
+ * The different types of MMTP Filter Settings that can be set by client.
+ * @hide
+ */
+@VintfStability
+union DemuxMmtpFilterSettingsFilterSettings {
+    /**
+     * Not additional parameters. it's used by MMTP subtype filters.
+     */
+    boolean noinit;
+
+    DemuxFilterSectionSettings section;
+
+    DemuxFilterAvSettings av;
+
+    DemuxFilterPesDataSettings pesData;
+
+    DemuxFilterRecordSettings record;
+
+    DemuxFilterDownloadSettings download;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl
new file mode 100644
index 0000000..eb0016c
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * MMTP Filter Type according to ISO/IEC 23008-1
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxMmtpFilterType {
+    UNDEFINED,
+
+    /**
+     * A filter to filter signaling data out from input stream, and queue the
+     * data to the filter's FMQ (Fast Message Queue).
+     */
+    SECTION,
+
+    /**
+     * A filter to filter MFU (Media fragment unit) out from input stream, and
+     * queue the data to the filter's FMQ.
+     */
+    PES,
+
+    /**
+     * A filter to filter a MMTP stream out from input stream, and queue the
+     * data to the filter's FMQ.
+     */
+    MMTP,
+
+    /**
+     * A filter to filter Audio data out from input stream, and send Audio's
+     * Metadata to client through onFilterEvent.
+     */
+    AUDIO,
+
+    /**
+     * A filter to filter Video data out from input stream, and send Video's
+     * Metadata to client through onFilterEvent.
+     */
+    VIDEO,
+
+    /**
+     * A filter to filter data out from input stream, and queue the data to the
+     * buffer of the record.
+     */
+    RECORD,
+
+    /**
+     * A filter to filter application data out from input stream, and queue the
+     * data to the filter's FMQ.
+     */
+    DOWNLOAD,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxPid.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxPid.aidl
new file mode 100644
index 0000000..a76d208
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxPid.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Demux Packet ID.
+ * @hide
+ */
+@VintfStability
+union DemuxPid {
+    /**
+     * Packet ID is used to specify packets in transport stream.
+     */
+    char tPid;
+
+    /**
+     * Packet ID is used to specify packets in MMTP.
+     */
+    char mmtpPid;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl
new file mode 100644
index 0000000..b8858ef
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * The bits of EventFlag in FMQ (Fast message queue) are used by client to
+ * notify HAL the status change.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxQueueNotifyBits {
+    /**
+     * client writes data and notify HAL the data is ready.
+     */
+    DATA_READY = 1 << 0,
+
+    /**
+     * client reads data and notify HAL the data is consumed.
+     */
+    DATA_CONSUMED = 1 << 1,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
new file mode 100644
index 0000000..44b985c
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Start Code Index type to be used in the filter for record
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxRecordScIndexType {
+    /**
+     * Don't use SC index
+     */
+    NONE,
+
+    /**
+     * Use Start Code index
+     */
+    SC,
+
+    /**
+     * Use Start Code index for HEVC
+     */
+    SC_HEVC,
+
+    /**
+     * SC index is undefined
+     */
+    UNDEFINED,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
new file mode 100644
index 0000000..f2ddd00
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Indexes can be tagged by NAL unit group in HEVC according to ISO/IEC 23008-2.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxScHevcIndex {
+    SPS = 1 << 0,
+
+    AUD = 1 << 1,
+
+    SLICE_CE_BLA_W_LP = 1 << 2,
+
+    SLICE_BLA_W_RADL = 1 << 3,
+
+    SLICE_BLA_N_LP = 1 << 4,
+
+    SLICE_IDR_W_RADL = 1 << 5,
+
+    SLICE_IDR_N_LP = 1 << 6,
+
+    SLICE_TRAIL_CRA = 1 << 7,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
new file mode 100644
index 0000000..0aef739
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
+ * according to ISO/IEC 13818-1 and Slice Groups according to ISO/IEC 14496-10.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxScIndex {
+    UNDEFINED = 0,
+
+    /**
+     * Start Code is for a new I Frame
+     */
+    I_FRAME = 1 << 0,
+
+    /**
+     * Start Code is for a new P Frame
+     */
+    P_FRAME = 1 << 1,
+
+    /**
+     * Start Code is for a new B Frame
+     */
+    B_FRAME = 1 << 2,
+
+    /**
+     * Start Code is for a new Sequence
+     */
+    SEQUENCE = 1 << 3,
+
+    /**
+     * All blocks are coded as I blocks.
+     */
+    I_SLICE = 1 << 4,
+
+    /**
+     * Blocks are coded as I or P blocks.
+     */
+    P_SLICE = 1 << 5,
+
+    /**
+     * Blocks are coded as I, P or B blocks.
+     */
+    B_SLICE = 1 << 6,
+
+    /**
+     * A so-called switching I slice that is coded.
+     */
+    SI_SLICE = 1 << 7,
+
+    /**
+     * A so-called switching P slice that is coded.
+     */
+    SP_SLICE = 1 << 8,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTlvFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTlvFilterSettings.aidl
new file mode 100644
index 0000000..fd1289d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTlvFilterSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxTlvFilterSettingsFilterSettings;
+
+/**
+ * Filter Settings for a TLV filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxTlvFilterSettings {
+    /**
+     * Packet type according to ITU-R BT.1869.
+     * 0x01: IPv4 packet
+     * 0x02: IPv6 packet
+     * 0x03: IP packet with header compression
+     * 0xFE: Signaling packet
+     * 0xFF: NULL packet
+     */
+    byte packetType;
+
+    /**
+     * true if the filtered data is commpressed ip packet
+     */
+    boolean isCompressedIpPacket;
+
+    DemuxTlvFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTlvFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTlvFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..7837c1d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTlvFilterSettingsFilterSettings.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterSectionSettings;
+
+/**
+ * The different types of TLV Filter Settings that can be set by client.
+ * @hide
+ */
+@VintfStability
+union DemuxTlvFilterSettingsFilterSettings {
+    /**
+     * Not additional parameters. it's used by PAYLOAD_THROUGH subtype
+     * filters.
+     */
+    boolean noinit;
+
+    DemuxFilterSectionSettings section;
+
+    /**
+     * true if the data from TLV subtype go to next filter directly
+     */
+    boolean bPassthrough;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTlvFilterType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTlvFilterType.aidl
new file mode 100644
index 0000000..1566f74
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTlvFilterType.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * TLV Filter Type according to ITU-R BT.1869.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxTlvFilterType {
+    UNDEFINED,
+
+    /**
+     * A filter to filter signaling data out from input stream, and queue the
+     * data to the filter's FMQ (Fast Message Queue).
+     */
+    SECTION,
+
+    /**
+     * A filter to filter a TLV stream out from input stream. The output can be
+     * either upper stream of another filter or queued to the filter's FMQ.
+     */
+    TLV,
+
+    /**
+     * A filter to strip out TLV message header and be a data source of another
+     * filter.
+     */
+    PAYLOAD_THROUGH,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsFilterSettings.aidl
new file mode 100644
index 0000000..1345831
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsFilterSettings.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxTsFilterSettingsFilterSettings;
+
+/**
+ * Filter Settings for a TS filter.
+ * @hide
+ */
+@VintfStability
+parcelable DemuxTsFilterSettings {
+    /**
+     * Packet ID is used to specify packets in transport stream.
+     */
+    char tpid;
+
+    DemuxTsFilterSettingsFilterSettings filterSettings;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsFilterSettingsFilterSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsFilterSettingsFilterSettings.aidl
new file mode 100644
index 0000000..81e36f3
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsFilterSettingsFilterSettings.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterAvSettings;
+import android.hardware.tv.tuner.DemuxFilterPesDataSettings;
+import android.hardware.tv.tuner.DemuxFilterRecordSettings;
+import android.hardware.tv.tuner.DemuxFilterSectionSettings;
+
+/**
+ * The different types of TS Filter Settings that can be set by client.
+ * @hide
+ */
+@VintfStability
+union DemuxTsFilterSettingsFilterSettings {
+    /**
+     * Not additional parameters. it's used by PCR, TS, TEMI subtype
+     * filters.
+     */
+    boolean noinit;
+
+    DemuxFilterSectionSettings section;
+
+    DemuxFilterAvSettings av;
+
+    DemuxFilterPesDataSettings pesData;
+
+    DemuxFilterRecordSettings record;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsFilterType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsFilterType.aidl
new file mode 100644
index 0000000..cdf5c58
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsFilterType.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * TS Filter Type according to ISO/IEC 13818-1
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxTsFilterType {
+    UNDEFINED,
+
+    /**
+     * A filter to filter Section data out from input stream, and queue the
+     * data to the filter's FMQ (Fast Message Queue).
+     */
+    SECTION,
+
+    /**
+     * A filter to filter Packetized Elementary Stream data out from input
+     * stream, and queue the data to the filter's FMQ.
+     */
+    PES,
+
+    /**
+     * A filter to filter a Transport Stream out from input stream, and queue
+     * the data to the filter's FMQ.
+     */
+    TS,
+
+    /**
+     * A filter to filter Audio data out from input stream, and send Audio's
+     * Metadata to client through onFilterEvent.
+     */
+    AUDIO,
+
+    /**
+     * A filter to filter Video data out from input stream, and send Video's
+     * Metadata to client through onFilterEvent.
+     */
+    VIDEO,
+
+    /**
+     * A filter to set PCR (Program Clock Reference) channel from input stream.
+     */
+    PCR,
+
+    /**
+     * A filter to filter data out from input stream, and queue the data to the
+     * buffer of the record.
+     */
+    RECORD,
+
+    /**
+     * A filter to filter out Timed External Media Information (TEMI) according
+     * to ISO/IEC 13818-1:2013/ DAM 6 from input stream, and send TEMI event to
+     * client through onFilterEvent.
+     */
+    TEMI,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsIndex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsIndex.aidl
new file mode 100644
index 0000000..9d0e7c5
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxTsIndex.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Indexes can be tagged through TS (Transport Stream) header.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum DemuxTsIndex {
+    FIRST_PACKET = 1 << 0,
+
+    PAYLOAD_UNIT_START_INDICATOR = 1 << 1,
+
+    CHANGE_TO_NOT_SCRAMBLED = 1 << 2,
+
+    CHANGE_TO_EVEN_SCRAMBLED = 1 << 3,
+
+    CHANGE_TO_ODD_SCRAMBLED = 1 << 4,
+
+    DISCONTINUITY_INDICATOR = 1 << 5,
+
+    RANDOM_ACCESS_INDICATOR = 1 << 6,
+
+    PRIORITY_INDICATOR = 1 << 7,
+
+    PCR_FLAG = 1 << 8,
+
+    OPCR_FLAG = 1 << 9,
+
+    SPLICING_POINT_FLAG = 1 << 10,
+
+    PRIVATE_DATA = 1 << 11,
+
+    ADAPTATION_EXTENSION_FLAG = 1 << 12,
+
+    /**
+     * Index the address of MMT Packet Table(MPT).
+     */
+    MPT_INDEX_MPT = 1 << 16,
+
+    /**
+     * Index the address of Video.
+     */
+    MPT_INDEX_VIDEO = 1 << 17,
+
+    /**
+     * Index the address of Audio.
+     */
+    MPT_INDEX_AUDIO = 1 << 18,
+
+    /**
+     * Index to indicate this is a target of timestamp extraction for video.
+     */
+    MPT_INDEX_TIMESTAMP_TARGET_VIDEO = 1 << 19,
+
+    /**
+     * Index to indicate this is a target of timestamp extraction for audio.
+     */
+    MPT_INDEX_TIMESTAMP_TARGET_AUDIO = 1 << 20,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DvrSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DvrSettings.aidl
new file mode 100644
index 0000000..aa21cf6
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DvrSettings.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.PlaybackSettings;
+import android.hardware.tv.tuner.RecordSettings;
+
+/**
+ * The Setting for DVR.
+ * @hide
+ */
+@VintfStability
+union DvrSettings {
+    RecordSettings record;
+
+    PlaybackSettings playback;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DvrType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DvrType.aidl
new file mode 100644
index 0000000..21dcc4a
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DvrType.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * The type of DVR.
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum DvrType {
+    RECORD,
+
+    PLAYBACK,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl
new file mode 100644
index 0000000..72291a5
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * AFT flag for an Analog Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendAnalogAftFlag {
+    UNDEFINED,
+
+    AFT_TRUE,
+
+    AFT_FALSE,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogCapabilities.aidl
new file mode 100644
index 0000000..7f0cd04
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogCapabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for Analog Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendAnalogCapabilities {
+    /**
+     * Signal Types defined by FrontendAnalogType.
+     */
+    int typeCap;
+
+    /**
+     * Standard Interchange Formats defined by FrontendAnalogSifStandard.
+     */
+    int sifStandardCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogSettings.aidl
new file mode 100644
index 0000000..926929f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogSettings.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAnalogAftFlag;
+import android.hardware.tv.tuner.FrontendAnalogSifStandard;
+import android.hardware.tv.tuner.FrontendAnalogType;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
+
+/**
+ * Signal Settings for Analog Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendAnalogSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
+
+    FrontendAnalogType type = FrontendAnalogType.UNDEFINED;
+
+    FrontendAnalogAftFlag aftFlag = FrontendAnalogAftFlag.UNDEFINED;
+
+    FrontendAnalogSifStandard sifStandard = FrontendAnalogSifStandard.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl
new file mode 100644
index 0000000..3c0f9b4
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Standard Interchange Format (SIF) for Analog Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendAnalogSifStandard {
+    UNDEFINED = 0,
+
+    AUTO = 1 << 0,
+
+    BG = 1 << 1,
+
+    BG_A2 = 1 << 2,
+
+    BG_NICAM = 1 << 3,
+
+    I = 1 << 4,
+
+    DK = 1 << 5,
+
+    DK1_A2 = 1 << 6,
+
+    DK2_A2 = 1 << 7,
+
+    DK3_A2 = 1 << 8,
+
+    DK_NICAM = 1 << 9,
+
+    L = 1 << 10,
+
+    M = 1 << 11,
+
+    M_BTSC = 1 << 12,
+
+    M_A2 = 1 << 13,
+
+    M_EIAJ = 1 << 14,
+
+    I_NICAM = 1 << 15,
+
+    L_NICAM = 1 << 16,
+
+    L_PRIME = 1 << 17,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogType.aidl
new file mode 100644
index 0000000..e4b05a6
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAnalogType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Signal Type for Analog Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendAnalogType {
+    UNDEFINED = 0,
+
+    AUTO = 1 << 0,
+
+    PAL = 1 << 1,
+
+    PAL_M = 1 << 2,
+
+    PAL_N = 1 << 3,
+
+    PAL_60 = 1 << 4,
+
+    NTSC = 1 << 5,
+
+    NTSC_443 = 1 << 6,
+
+    SECAM = 1 << 7,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl
new file mode 100644
index 0000000..af78a96
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Bandwidth for ATSC3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendAtsc3Bandwidth {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set bandwidth automatically
+     */
+    AUTO = 1 << 0,
+
+    BANDWIDTH_6MHZ = 1 << 1,
+
+    BANDWIDTH_7MHZ = 1 << 2,
+
+    BANDWIDTH_8MHZ = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Capabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Capabilities.aidl
new file mode 100644
index 0000000..98c7b8d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Capabilities.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for ATSC3 Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendAtsc3Capabilities {
+    /**
+     * Bandwidth capabilities defined by FrontendAtsc3Bandwidth.
+     */
+    int bandwidthCap;
+
+    /**
+     * Modulation capabilities defined by FrontendAtsc3Modulation.
+     */
+    int modulationCap;
+
+    /**
+     * TimeInterleaveMode capabilities defined by FrontendAtsc3TimeInterleaveMode.
+     */
+    int timeInterleaveModeCap;
+
+    /**
+     * CodeRate capabilities defined by FrontendAtsc3CodeRate.
+     */
+    int codeRateCap;
+
+    /**
+     * FEC capabilities defined by FrontendAtsc3Fec.
+     */
+    int fecCap;
+
+    /**
+     * Demodulator Output Format capabilities FrontendAtsc3DemodOutputFormat.
+     */
+    byte demodOutputFormatCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl
new file mode 100644
index 0000000..8a2ee03
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Code Rate for ATSC3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendAtsc3CodeRate {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Coderate automatically
+     */
+    AUTO = 1 << 0,
+
+    CODERATE_2_15 = 1 << 1,
+
+    CODERATE_3_15 = 1 << 2,
+
+    CODERATE_4_15 = 1 << 3,
+
+    CODERATE_5_15 = 1 << 4,
+
+    CODERATE_6_15 = 1 << 5,
+
+    CODERATE_7_15 = 1 << 6,
+
+    CODERATE_8_15 = 1 << 7,
+
+    CODERATE_9_15 = 1 << 8,
+
+    CODERATE_10_15 = 1 << 9,
+
+    CODERATE_11_15 = 1 << 10,
+
+    CODERATE_12_15 = 1 << 11,
+
+    CODERATE_13_15 = 1 << 12,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl
new file mode 100644
index 0000000..b17616c
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Demodulator Output Format for an ATSC3 Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum FrontendAtsc3DemodOutputFormat {
+    /**
+     * Undefined. Scan uses this.
+     */
+    UNDEFINED = 0,
+
+    /**
+     * ALP format. Typically used in US region.
+     */
+    ATSC3_LINKLAYER_PACKET = 1 << 0,
+
+    /**
+     * BaseBand packet format. Typically used in Korea region.
+     */
+    BASEBAND_PACKET = 1 << 1,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl
new file mode 100644
index 0000000..af0bf04
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Forward Error Correction (FEC) for ATSC3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendAtsc3Fec {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set FEC automatically
+     */
+    AUTO = 1 << 0,
+
+    BCH_LDPC_16K = 1 << 1,
+
+    BCH_LDPC_64K = 1 << 2,
+
+    CRC_LDPC_16K = 1 << 3,
+
+    CRC_LDPC_64K = 1 << 4,
+
+    LDPC_16K = 1 << 5,
+
+    LDPC_64K = 1 << 6,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl
new file mode 100644
index 0000000..3108234
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Modulation Type for ATSC3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendAtsc3Modulation {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set modulation automatically
+     */
+    AUTO = 1 << 0,
+
+    MOD_QPSK = 1 << 1,
+
+    MOD_16QAM = 1 << 2,
+
+    MOD_64QAM = 1 << 3,
+
+    MOD_256QAM = 1 << 4,
+
+    MOD_1024QAM = 1 << 5,
+
+    MOD_4096QAM = 1 << 6,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3PlpSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3PlpSettings.aidl
new file mode 100644
index 0000000..5678dd3
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3PlpSettings.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAtsc3CodeRate;
+import android.hardware.tv.tuner.FrontendAtsc3Fec;
+import android.hardware.tv.tuner.FrontendAtsc3Modulation;
+import android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode;
+
+/**
+ * PLP basis Signal Settings for an ATSC3 Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendAtsc3PlpSettings {
+    byte plpId;
+
+    FrontendAtsc3Modulation modulation = FrontendAtsc3Modulation.UNDEFINED;
+
+    FrontendAtsc3TimeInterleaveMode interleaveMode = FrontendAtsc3TimeInterleaveMode.UNDEFINED;
+
+    FrontendAtsc3CodeRate codeRate = FrontendAtsc3CodeRate.UNDEFINED;
+
+    FrontendAtsc3Fec fec = FrontendAtsc3Fec.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Settings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Settings.aidl
new file mode 100644
index 0000000..dc1e520
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3Settings.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAtsc3Bandwidth;
+import android.hardware.tv.tuner.FrontendAtsc3DemodOutputFormat;
+import android.hardware.tv.tuner.FrontendAtsc3PlpSettings;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
+
+/**
+ * Signal Settings for an ATSC3 Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendAtsc3Settings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    /**
+     * Bandwidth of tuning band.
+     */
+    FrontendAtsc3Bandwidth bandwidth = FrontendAtsc3Bandwidth.UNDEFINED;
+
+    FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
+
+    FrontendAtsc3DemodOutputFormat demodOutputFormat = FrontendAtsc3DemodOutputFormat.UNDEFINED;
+
+    FrontendAtsc3PlpSettings[] plpSettings;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl
new file mode 100644
index 0000000..451a922
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Time Interleave Mode for ATSC3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendAtsc3TimeInterleaveMode {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set TimeInterleaveMode automatically
+     */
+    AUTO = 1 << 0,
+
+    CTI = 1 << 1,
+
+    HTI = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtscCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtscCapabilities.aidl
new file mode 100644
index 0000000..c8a3d2b
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtscCapabilities.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAtscModulation;
+
+/**
+ * Capabilities for ATSC Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendAtscCapabilities {
+    /**
+     * Modulation capabilities defined by FrontendAtscModulation.
+     */
+    int modulationCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtscModulation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtscModulation.aidl
new file mode 100644
index 0000000..960a299
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtscModulation.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Modulation Type for ATSC.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendAtscModulation {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set modulation automatically
+     */
+    AUTO = 1 << 0,
+
+    MOD_8VSB = 1 << 2,
+
+    MOD_16VSB = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtscSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtscSettings.aidl
new file mode 100644
index 0000000..1279b14
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendAtscSettings.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAtscModulation;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
+
+/**
+ * Signal Settings for an ATSC Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendAtscSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
+
+    FrontendAtscModulation modulation = FrontendAtscModulation.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendBandwidth.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendBandwidth.aidl
new file mode 100644
index 0000000..c1c2355
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendBandwidth.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAtsc3Bandwidth;
+import android.hardware.tv.tuner.FrontendDvbtBandwidth;
+import android.hardware.tv.tuner.FrontendIsdbtBandwidth;
+import android.hardware.tv.tuner.FrontendDtmbBandwidth;
+import android.hardware.tv.tuner.FrontendDvbcBandwidth;
+
+/**
+ * @hide
+ */
+@VintfStability
+union FrontendBandwidth {
+    FrontendAtsc3Bandwidth atsc3 = FrontendAtsc3Bandwidth.UNDEFINED;
+
+    FrontendDvbcBandwidth dvbc;
+
+    FrontendDvbtBandwidth dvbt;
+
+    FrontendIsdbtBandwidth isdbt;
+
+    FrontendDtmbBandwidth dtmb;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl
new file mode 100644
index 0000000..a2b4356
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Time Interleave Mode for DVBC Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendCableTimeInterleaveMode {
+    UNDEFINED = 0,
+
+    AUTO = 1 << 0,
+
+    INTERLEAVING_128_1_0 = 1 << 1,
+
+    INTERLEAVING_128_1_1 = 1 << 2,
+
+    INTERLEAVING_64_2 = 1 << 3,
+
+    INTERLEAVING_32_4 = 1 << 4,
+
+    INTERLEAVING_16_8 = 1 << 5,
+
+    INTERLEAVING_8_16 = 1 << 6,
+
+    INTERLEAVING_128_2 = 1 << 7,
+
+    INTERLEAVING_128_3 = 1 << 8,
+
+    INTERLEAVING_128_4 = 1 << 9,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl
new file mode 100644
index 0000000..a6f1490
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendCapabilities.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAnalogCapabilities;
+import android.hardware.tv.tuner.FrontendAtsc3Capabilities;
+import android.hardware.tv.tuner.FrontendAtscCapabilities;
+import android.hardware.tv.tuner.FrontendDtmbCapabilities;
+import android.hardware.tv.tuner.FrontendDvbcCapabilities;
+import android.hardware.tv.tuner.FrontendDvbsCapabilities;
+import android.hardware.tv.tuner.FrontendDvbtCapabilities;
+import android.hardware.tv.tuner.FrontendIsdbs3Capabilities;
+import android.hardware.tv.tuner.FrontendIsdbsCapabilities;
+import android.hardware.tv.tuner.FrontendIsdbtCapabilities;
+
+/**
+ * @hide
+ */
+@VintfStability
+union FrontendCapabilities {
+    FrontendAnalogCapabilities analogCaps;
+
+    FrontendAtscCapabilities atscCaps;
+
+    FrontendAtsc3Capabilities atsc3Caps;
+
+    FrontendDtmbCapabilities dtmbCaps;
+
+    FrontendDvbsCapabilities dvbsCaps;
+
+    FrontendDvbcCapabilities dvbcCaps;
+
+    FrontendDvbtCapabilities dvbtCaps;
+
+    FrontendIsdbsCapabilities isdbsCaps;
+
+    FrontendIsdbs3Capabilities isdbs3Caps;
+
+    FrontendIsdbtCapabilities isdbtCaps;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl
new file mode 100644
index 0000000..4dc3f0f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Bandwidth Type for DTMB.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDtmbBandwidth {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Bandwidth automatically
+     */
+    AUTO = 1 << 0,
+
+    BANDWIDTH_8MHZ = 1 << 1,
+
+    BANDWIDTH_6MHZ = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbCapabilities.aidl
new file mode 100644
index 0000000..eda0d46
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbCapabilities.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for DTMB Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendDtmbCapabilities {
+    /**
+     * Transmission Modes defined by FrontendDtmbTransmissionMode.
+     */
+    int transmissionModeCap;
+
+    /**
+     * Bandwidth Types defined by FrontendDtmbBandwidth.
+     */
+    int bandwidthCap;
+
+    /**
+     * Modulations defined by FrontendDtmbModulation.
+     */
+    int modulationCap;
+
+    /**
+     * CODERATE Types defined by FrontendDtmbCodeRate.
+     */
+    int codeRateCap;
+
+    /**
+     * Guard Interval Types defined by FrontendDtmbGuardInterval.
+     */
+    int guardIntervalCap;
+
+    /**
+     * Time Interleave Mode Type defined by FrontendDtmbTimeInterleaveMode.
+     */
+    int interleaveModeCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl
new file mode 100644
index 0000000..7b4a438
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * CODERATE Type for DTMB.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDtmbCodeRate {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set code rate automatically
+     */
+    AUTO = 1 << 0,
+
+    CODERATE_2_5 = 1 << 1,
+
+    CODERATE_3_5 = 1 << 2,
+
+    CODERATE_4_5 = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl
new file mode 100644
index 0000000..3c2e06a
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Guard Interval Type for DTMB.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDtmbGuardInterval {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Guard Interval automatically
+     */
+    AUTO = 1 << 0,
+
+    PN_420_VARIOUS = 1 << 1,
+
+    PN_595_CONST = 1 << 2,
+
+    PN_945_VARIOUS = 1 << 3,
+
+    PN_420_CONST = 1 << 4,
+
+    PN_945_CONST = 1 << 5,
+
+    PN_RESERVED = 1 << 6,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbModulation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbModulation.aidl
new file mode 100644
index 0000000..87bd8da
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbModulation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Frontend Modulation Type for DTMB.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDtmbModulation {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Constellation automatically
+     */
+    AUTO = 1 << 0,
+
+    CONSTELLATION_4QAM = 1 << 1,
+
+    CONSTELLATION_4QAM_NR = 1 << 2,
+
+    CONSTELLATION_16QAM = 1 << 3,
+
+    CONSTELLATION_32QAM = 1 << 4,
+
+    CONSTELLATION_64QAM = 1 << 5,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbSettings.aidl
new file mode 100644
index 0000000..ccac650
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbSettings.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendDtmbBandwidth;
+import android.hardware.tv.tuner.FrontendDtmbCodeRate;
+import android.hardware.tv.tuner.FrontendDtmbGuardInterval;
+import android.hardware.tv.tuner.FrontendDtmbModulation;
+import android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode;
+import android.hardware.tv.tuner.FrontendDtmbTransmissionMode;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
+
+/**
+ * Signal Setting for DTMB Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendDtmbSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
+
+    FrontendDtmbTransmissionMode transmissionMode = FrontendDtmbTransmissionMode.UNDEFINED;
+
+    FrontendDtmbBandwidth bandwidth = FrontendDtmbBandwidth.UNDEFINED;
+
+    FrontendDtmbModulation modulation = FrontendDtmbModulation.UNDEFINED;
+
+    FrontendDtmbCodeRate codeRate = FrontendDtmbCodeRate.UNDEFINED;
+
+    FrontendDtmbGuardInterval guardInterval = FrontendDtmbGuardInterval.UNDEFINED;
+
+    FrontendDtmbTimeInterleaveMode interleaveMode = FrontendDtmbTimeInterleaveMode.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl
new file mode 100644
index 0000000..a992524
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Time Interleave Mode Type for DTMB.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDtmbTimeInterleaveMode {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set time interleave mode automatically
+     */
+    AUTO = 1 << 0,
+
+    TIMER_INT_240 = 1 << 1,
+
+    TIMER_INT_720 = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl
new file mode 100644
index 0000000..7ebed84
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Transmission Mode for DTMB.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDtmbTransmissionMode {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Transmission Mode automatically
+     */
+    AUTO = 1 << 0,
+
+    C1 = 1 << 1,
+
+    C3780 = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl
new file mode 100644
index 0000000..3d99cee
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Annex Type for DVBC.
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum FrontendDvbcAnnex {
+    UNDEFINED = 0,
+
+    A = 1 << 0,
+
+    B = 1 << 1,
+
+    C = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl
new file mode 100644
index 0000000..ff921a7
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Bandwidth Type for Cable Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbcBandwidth {
+    UNDEFINED = 0,
+
+    BANDWIDTH_5MHZ = 1 << 0,
+
+    BANDWIDTH_6MHZ = 1 << 1,
+
+    BANDWIDTH_7MHZ = 1 << 2,
+
+    BANDWIDTH_8MHZ = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcCapabilities.aidl
new file mode 100644
index 0000000..bd7f180
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for DVBC Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendDvbcCapabilities {
+    /**
+     * Modulation Types defined by FrontendDvbcModulation.
+     */
+    int modulationCap;
+
+    /**
+     * Inner Forward Error Correction types defined by FrontendInnerFec.
+     */
+    long fecCap;
+
+    /**
+     * Annex Types defined by FrontendDvbcAnnex.
+     */
+    byte annexCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcModulation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcModulation.aidl
new file mode 100644
index 0000000..3435e76
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcModulation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Modulation Type for DVBC.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbcModulation {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Modulation automatically
+     */
+    AUTO = 1 << 0,
+
+    MOD_16QAM = 1 << 1,
+
+    MOD_32QAM = 1 << 2,
+
+    MOD_64QAM = 1 << 3,
+
+    MOD_128QAM = 1 << 4,
+
+    MOD_256QAM = 1 << 5,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl
new file mode 100644
index 0000000..7dc3f0f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Outer Forward Error Correction (FEC) Type for DVBC.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbcOuterFec {
+    UNDEFINED = 0,
+
+    OUTER_FEC_NONE,
+
+    OUTER_FEC_RS,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcSettings.aidl
new file mode 100644
index 0000000..d18d373
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbcSettings.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendCableTimeInterleaveMode;
+import android.hardware.tv.tuner.FrontendDvbcAnnex;
+import android.hardware.tv.tuner.FrontendDvbcBandwidth;
+import android.hardware.tv.tuner.FrontendDvbcModulation;
+import android.hardware.tv.tuner.FrontendDvbcOuterFec;
+import android.hardware.tv.tuner.FrontendInnerFec;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
+
+/**
+ * Signal Settings for an DVBC Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendDvbcSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    FrontendDvbcModulation modulation = FrontendDvbcModulation.UNDEFINED;
+
+    FrontendInnerFec fec = FrontendInnerFec.FEC_UNDEFINED;
+
+    /**
+     * Symbols per second
+     */
+    int symbolRate;
+
+    FrontendDvbcOuterFec outerFec = FrontendDvbcOuterFec.UNDEFINED;
+
+    FrontendDvbcAnnex annex = FrontendDvbcAnnex.UNDEFINED;
+
+    FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
+
+    FrontendCableTimeInterleaveMode interleaveMode = FrontendCableTimeInterleaveMode.UNDEFINED;
+
+    FrontendDvbcBandwidth bandwidth = FrontendDvbcBandwidth.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsCapabilities.aidl
new file mode 100644
index 0000000..acff012
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for DVBS Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendDvbsCapabilities {
+    /**
+     * Modulation Types defined by FrontendDvbsModulation..
+     */
+    int modulationCap;
+
+    /**
+     * Inner Forward Error Correction types defined by FrontendInnerFec.
+    */
+    long innerfecCap;
+
+    /**
+     * Sub standards defined by FrontendDvbsStandard.
+     */
+    byte standard;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsCodeRate.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsCodeRate.aidl
new file mode 100644
index 0000000..70ea3ab
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsCodeRate.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendInnerFec;
+
+/**
+ * Code Rate for DVBS.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendDvbsCodeRate {
+    FrontendInnerFec fec = FrontendInnerFec.FEC_UNDEFINED;
+
+    boolean isLinear;
+
+    /**
+     * true if enable short frame
+     */
+    boolean isShortFrames;
+
+    /**
+     * bits number in 1000 symbol. 0 if use the default.
+     */
+    int bitsPer1000Symbol;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsModulation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsModulation.aidl
new file mode 100644
index 0000000..3ba4c5b
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsModulation.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Modulation Type for DVBS.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbsModulation {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Modulation automatically
+     */
+    AUTO = 1 << 0,
+
+    MOD_QPSK = 1 << 1,
+
+    MOD_8PSK = 1 << 2,
+
+    MOD_16QAM = 1 << 3,
+
+    MOD_16PSK = 1 << 4,
+
+    MOD_32PSK = 1 << 5,
+
+    MOD_ACM = 1 << 6,
+
+    MOD_8APSK = 1 << 7,
+
+    MOD_16APSK = 1 << 8,
+
+    MOD_32APSK = 1 << 9,
+
+    MOD_64APSK = 1 << 10,
+
+    MOD_128APSK = 1 << 11,
+
+    MOD_256APSK = 1 << 12,
+
+    /**
+     * Reserved for Proprietary modulation
+     */
+    MOD_RESERVED = 1 << 13,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsPilot.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsPilot.aidl
new file mode 100644
index 0000000..625ac2d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsPilot.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Pilot mode for DVBS.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbsPilot {
+    UNDEFINED,
+
+    ON,
+
+    OFF,
+
+    AUTO,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl
new file mode 100644
index 0000000..76d0e16
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Roll Off value for DVBS.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbsRolloff {
+    UNDEFINED,
+
+    ROLLOFF_0_35,
+
+    ROLLOFF_0_25,
+
+    ROLLOFF_0_20,
+
+    ROLLOFF_0_15,
+
+    ROLLOFF_0_10,
+
+    ROLLOFF_0_5,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsScanType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsScanType.aidl
new file mode 100644
index 0000000..1afbd93
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsScanType.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Scan type for a DVBS Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbsScanType {
+    UNDEFINED = 0,
+
+    DIRECT,
+
+    DISEQC,
+
+    UNICABLE,
+
+    JESS,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsSettings.aidl
new file mode 100644
index 0000000..d285ac1
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsSettings.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendDvbsCodeRate;
+import android.hardware.tv.tuner.FrontendDvbsModulation;
+import android.hardware.tv.tuner.FrontendDvbsPilot;
+import android.hardware.tv.tuner.FrontendDvbsRolloff;
+import android.hardware.tv.tuner.FrontendDvbsStandard;
+import android.hardware.tv.tuner.FrontendDvbsVcmMode;
+import android.hardware.tv.tuner.FrontendDvbsScanType;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
+
+/**
+ * Signal Settings for an DVBS Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendDvbsSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
+
+    FrontendDvbsModulation modulation = FrontendDvbsModulation.UNDEFINED;
+
+    FrontendDvbsCodeRate coderate;
+
+    /**
+     * Symbols per second
+     */
+    int symbolRate;
+
+    FrontendDvbsRolloff rolloff = FrontendDvbsRolloff.UNDEFINED;
+
+    FrontendDvbsPilot pilot = FrontendDvbsPilot.UNDEFINED;
+
+    int inputStreamId;
+
+    FrontendDvbsStandard standard = FrontendDvbsStandard.UNDEFINED;
+
+    FrontendDvbsVcmMode vcmMode = FrontendDvbsVcmMode.UNDEFINED;
+
+    FrontendDvbsScanType scanType = FrontendDvbsScanType.UNDEFINED;
+
+    boolean isDiseqcRxMessage;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsStandard.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsStandard.aidl
new file mode 100644
index 0000000..bc8e0ea
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsStandard.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Sub standards in DVBS.
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum FrontendDvbsStandard {
+    UNDEFINED = 0,
+
+    AUTO = 1 << 0,
+
+    S = 1 << 1,
+
+    S2 = 1 << 2,
+
+    S2X = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl
new file mode 100644
index 0000000..2b41dcd
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * VCM mode in DVBS.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbsVcmMode {
+    UNDEFINED,
+
+    AUTO,
+
+    MANUAL,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl
new file mode 100644
index 0000000..1d31358
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Bandwidth Type for DVBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbtBandwidth {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Bandwidth automatically
+     */
+    AUTO = 1 << 0,
+
+    BANDWIDTH_8MHZ = 1 << 1,
+
+    BANDWIDTH_7MHZ = 1 << 2,
+
+    BANDWIDTH_6MHZ = 1 << 3,
+
+    BANDWIDTH_5MHZ = 1 << 4,
+
+    BANDWIDTH_1_7MHZ = 1 << 5,
+
+    BANDWIDTH_10MHZ = 1 << 6,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtCapabilities.aidl
new file mode 100644
index 0000000..6bb473d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtCapabilities.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for DVBT Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendDvbtCapabilities {
+    /**
+     * Transmission Modes defined by FrontendDvbtTransmissionMode.
+     */
+    int transmissionModeCap;
+
+    /**
+     * Bandwidth Types defined by FrontendDvbtBandwidth.
+     */
+    int bandwidthCap;
+
+    /**
+     * Extended Constellations defined by FrontendDvbtConstellation.
+     */
+    int constellationCap;
+
+    /**
+     * Code Rates defined by FrontendDvbtCoderate.
+     */
+    int coderateCap;
+
+    /**
+     * Hierarchy Types defined by FrontendDvbtHierarchy.
+     */
+    int hierarchyCap;
+
+    /**
+     * Guard Interval Types defined by FrontendDvbtGuardInterval.
+     */
+    int guardIntervalCap;
+
+    boolean isT2Supported;
+
+    boolean isMisoSupported;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl
new file mode 100644
index 0000000..5111003
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Code Rate for DVBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbtCoderate {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Hierarchy automatically
+     */
+    AUTO = 1 << 0,
+
+    CODERATE_1_2 = 1 << 1,
+
+    CODERATE_2_3 = 1 << 2,
+
+    CODERATE_3_4 = 1 << 3,
+
+    CODERATE_5_6 = 1 << 4,
+
+    CODERATE_7_8 = 1 << 5,
+
+    CODERATE_3_5 = 1 << 6,
+
+    CODERATE_4_5 = 1 << 7,
+
+    CODERATE_6_7 = 1 << 8,
+
+    CODERATE_8_9 = 1 << 9,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl
new file mode 100644
index 0000000..2680778
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Extended Constellation for DVBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbtConstellation {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Constellation automatically
+     */
+    AUTO = 1 << 0,
+
+    CONSTELLATION_QPSK = 1 << 1,
+
+    CONSTELLATION_16QAM = 1 << 2,
+
+    CONSTELLATION_64QAM = 1 << 3,
+
+    CONSTELLATION_256QAM = 1 << 4,
+
+    CONSTELLATION_QPSK_R = 1 << 5,
+
+    CONSTELLATION_16QAM_R = 1 << 6,
+
+    CONSTELLATION_64QAM_R = 1 << 7,
+
+    CONSTELLATION_256QAM_R = 1 << 8,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl
new file mode 100644
index 0000000..8d60b2f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Guard Interval Type for DVBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbtGuardInterval {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Guard Interval automatically
+     */
+    AUTO = 1 << 0,
+
+    INTERVAL_1_32 = 1 << 1,
+
+    INTERVAL_1_16 = 1 << 2,
+
+    INTERVAL_1_8 = 1 << 3,
+
+    INTERVAL_1_4 = 1 << 4,
+
+    INTERVAL_1_128 = 1 << 5,
+
+    INTERVAL_19_128 = 1 << 6,
+
+    INTERVAL_19_256 = 1 << 7,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl
new file mode 100644
index 0000000..859c760
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Hierarchy Type for DVBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbtHierarchy {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Hierarchy automatically
+     */
+    AUTO = 1 << 0,
+
+    HIERARCHY_NON_NATIVE = 1 << 1,
+
+    HIERARCHY_1_NATIVE = 1 << 2,
+
+    HIERARCHY_2_NATIVE = 1 << 3,
+
+    HIERARCHY_4_NATIVE = 1 << 4,
+
+    HIERARCHY_NON_INDEPTH = 1 << 5,
+
+    HIERARCHY_1_INDEPTH = 1 << 6,
+
+    HIERARCHY_2_INDEPTH = 1 << 7,
+
+    HIERARCHY_4_INDEPTH = 1 << 8,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl
new file mode 100644
index 0000000..fa70cc7
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Physical Layer Pipe (PLP) Mode for DVBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbtPlpMode {
+    UNDEFINED,
+
+    AUTO,
+
+    MANUAL,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtSettings.aidl
new file mode 100644
index 0000000..4af0d10
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtSettings.aidl
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendDvbtBandwidth;
+import android.hardware.tv.tuner.FrontendDvbtCoderate;
+import android.hardware.tv.tuner.FrontendDvbtConstellation;
+import android.hardware.tv.tuner.FrontendDvbtGuardInterval;
+import android.hardware.tv.tuner.FrontendDvbtHierarchy;
+import android.hardware.tv.tuner.FrontendDvbtPlpMode;
+import android.hardware.tv.tuner.FrontendDvbtStandard;
+import android.hardware.tv.tuner.FrontendDvbtTransmissionMode;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
+
+/**
+ * Signal Settings for DVBT Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendDvbtSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
+
+    FrontendDvbtTransmissionMode transmissionMode = FrontendDvbtTransmissionMode.UNDEFINED;
+
+    FrontendDvbtBandwidth bandwidth = FrontendDvbtBandwidth.UNDEFINED;
+
+    FrontendDvbtConstellation constellation = FrontendDvbtConstellation.UNDEFINED;
+
+    FrontendDvbtHierarchy hierarchy = FrontendDvbtHierarchy.UNDEFINED;
+
+    /**
+     * Code Rate for High Priority level
+     */
+    FrontendDvbtCoderate hpCoderate = FrontendDvbtCoderate.UNDEFINED;
+
+    /**
+     * Code Rate for Low Priority level
+     */
+    FrontendDvbtCoderate lpCoderate = FrontendDvbtCoderate.UNDEFINED;
+
+    FrontendDvbtGuardInterval guardInterval = FrontendDvbtGuardInterval.UNDEFINED;
+
+    boolean isHighPriority;
+
+    FrontendDvbtStandard standard = FrontendDvbtStandard.UNDEFINED;
+
+    boolean isMiso;
+
+    FrontendDvbtPlpMode plpMode = FrontendDvbtPlpMode.UNDEFINED;
+
+    /**
+     * Physical Layer Pipe (PLP) Id
+     */
+    byte plpId;
+
+    /**
+     * Group Id for Physical Layer Pipe (PLP)
+     */
+    byte plpGroupId;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtStandard.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtStandard.aidl
new file mode 100644
index 0000000..bf18618
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtStandard.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Sub standards in DVBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum FrontendDvbtStandard {
+    UNDEFINED = 0,
+
+    AUTO = 1 << 0,
+
+    T = 1 << 1,
+
+    T2 = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl
new file mode 100644
index 0000000..ef2ceef
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Extended Transmission Mode for DVBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendDvbtTransmissionMode {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Transmission Mode automatically
+     */
+    AUTO = 1 << 0,
+
+    MODE_2K = 1 << 1,
+
+    MODE_8K = 1 << 2,
+
+    MODE_4K = 1 << 3,
+
+    MODE_1K = 1 << 4,
+
+    MODE_16K = 1 << 5,
+
+    MODE_32K = 1 << 6,
+
+    MODE_8K_E = 1 << 7,
+
+    MODE_16K_E = 1 << 8,
+
+    MODE_32K_E = 1 << 9,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendEventType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendEventType.aidl
new file mode 100644
index 0000000..40b5161
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Frontend Event Type.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendEventType {
+    /**
+     * The frontend has locked to the signal specified by the tune method.
+     */
+    LOCKED,
+
+    /**
+     * The frontend is unable to lock to the signal specified by the tune method.
+     */
+    NO_SIGNAL,
+
+    /**
+     * The frontend has lost the lock to the signal specified by the tune method.
+     */
+    LOST_LOCK,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendGuardInterval.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendGuardInterval.aidl
new file mode 100644
index 0000000..3893523
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendGuardInterval.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendDvbtGuardInterval;
+import android.hardware.tv.tuner.FrontendDtmbGuardInterval;
+
+/**
+ * @hide
+ */
+@VintfStability
+union FrontendGuardInterval {
+    FrontendDvbtGuardInterval dvbt = FrontendDvbtGuardInterval.UNDEFINED;
+
+    FrontendDvbtGuardInterval isdbt;
+
+    FrontendDtmbGuardInterval dtmb;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInfo.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInfo.aidl
new file mode 100644
index 0000000..9f178db
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInfo.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendCapabilities;
+import android.hardware.tv.tuner.FrontendStatusType;
+import android.hardware.tv.tuner.FrontendType;
+
+/**
+ * Information for the Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendInfo {
+    FrontendType type = FrontendType.UNDEFINED;
+
+    /**
+     * Frequency in Hertz
+     */
+    int minFrequency;
+
+    /**
+     * Frequency in Hertz
+     */
+    int maxFrequency;
+
+    /**
+     * Minimum symbols per second
+     */
+    int minSymbolRate;
+
+    /**
+     * Maximum symbols per second
+     */
+    int maxSymbolRate;
+
+    /**
+     * Range in Hertz
+     */
+    int acquireRange;
+
+    /**
+     * Frontends are assigned with the same exclusiveGroupId if they can't
+     * function at same time. For instance, they share same hardware module.
+     */
+    int exclusiveGroupId;
+
+    /**
+     * A list of supported status types which client can inquiry
+     */
+    FrontendStatusType[] statusCaps;
+
+    FrontendCapabilities frontendCaps;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInnerFec.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInnerFec.aidl
new file mode 100644
index 0000000..b94af4b
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInnerFec.aidl
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1
+ * and ETSI EN 302 307-2 V1.1.1.
+ * @hide
+ */
+@VintfStability
+@Backing(type="long")
+enum FrontendInnerFec {
+    /**
+     * Not defined
+     */
+    FEC_UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set FEC automatically
+     */
+    AUTO = 1L << 0,
+
+    /**
+     * 1/2 conv. code rate
+     */
+    FEC_1_2 = 1L << 1,
+
+    /**
+     * 1/3 conv. code rate
+     */
+    FEC_1_3 = 1L << 2,
+
+    /**
+     * 1/4 conv. code rate
+     */
+    FEC_1_4 = 1L << 3,
+
+    /**
+     * 1/5 conv. code rate
+     */
+    FEC_1_5 = 1L << 4,
+
+    /**
+     * 2/3 conv. code rate
+     */
+    FEC_2_3 = 1L << 5,
+
+    /**
+     * 2/5 conv. code rate
+     */
+    FEC_2_5 = 1L << 6,
+
+    /**
+     * 2/9 conv. code rate
+     */
+    FEC_2_9 = 1L << 7,
+
+    /**
+     * 3/4 conv. code rate
+     */
+    FEC_3_4 = 1L << 8,
+
+    /**
+     * 3/5 conv. code rate
+     */
+    FEC_3_5 = 1L << 9,
+
+    /**
+     * 4/5 conv. code rate
+     */
+    FEC_4_5 = 1L << 10,
+
+    /**
+     * 4/15 conv. code rate
+     */
+    FEC_4_15 = 1L << 11,
+
+    /**
+     * 5/6 conv. code rate
+     */
+    FEC_5_6 = 1L << 12,
+
+    /**
+     * 5/9 conv. code rate
+     */
+    FEC_5_9 = 1L << 13,
+
+    /**
+     * 6/7 conv. code rate
+     */
+    FEC_6_7 = 1L << 14,
+
+    /**
+     * 7/8 conv. code rate
+     */
+    FEC_7_8 = 1L << 15,
+
+    /**
+     * 7/9 conv. code rate
+     */
+    FEC_7_9 = 1L << 16,
+
+    /**
+     * 7/15 conv. code rate
+     */
+    FEC_7_15 = 1L << 17,
+
+    /**
+     * 8/9 conv. code rate
+     */
+    FEC_8_9 = 1L << 18,
+
+    /**
+     * 8/15 conv. code rate
+     */
+    FEC_8_15 = 1L << 19,
+
+    /**
+     * 9/10 conv. code rate
+     */
+    FEC_9_10 = 1L << 20,
+
+    /**
+     * 9/20 conv. code rate
+     */
+    FEC_9_20 = 1L << 21,
+
+    /**
+     * 11/15 conv. code rate
+     */
+    FEC_11_15 = 1L << 22,
+
+    /**
+     * 11/20 conv. code rate
+     */
+    FEC_11_20 = 1L << 23,
+
+    /**
+     * 11/45 conv. code rate
+     */
+    FEC_11_45 = 1L << 24,
+
+    /**
+     * 13/18 conv. code rate
+     */
+    FEC_13_18 = 1L << 25,
+
+    /**
+     * 13/45 conv. code rate
+     */
+    FEC_13_45 = 1L << 26,
+
+    /**
+     * 14/45 conv. code rate
+     */
+    FEC_14_45 = 1L << 27,
+
+    /**
+     * 23/36 conv. code rate
+     */
+    FEC_23_36 = 1L << 28,
+
+    /**
+     * 25/36 conv. code rate
+     */
+    FEC_25_36 = 1L << 29,
+
+    /**
+     * 26/45 conv. code rate
+     */
+    FEC_26_45 = 1L << 30,
+
+    /**
+     * 28/45 conv. code rate
+     */
+    FEC_28_45 = 1L << 31,
+
+    /**
+     * 29/45 conv. code rate
+     */
+    FEC_29_45 = 1L << 32,
+
+    /**
+     * 31/45 conv. code rate
+     */
+    FEC_31_45 = 1L << 33,
+
+    /**
+     * 32/45 conv. code rate
+     */
+    FEC_32_45 = 1L << 34,
+
+    /**
+     * 77/90 conv. code rate
+     */
+    FEC_77_90 = 1L << 35,
+
+    /**
+     * 2/15 conv. code rate
+     */
+    FEC_2_15 = 1L << 36,
+
+    /**
+     * 3/15 conv. code rate
+     */
+    FEC_3_15 = 1L << 37,
+
+    /**
+     * 5/15 conv. code rate
+     */
+    FEC_5_15 = 1L << 38,
+
+    /**
+     * 6/15 conv. code rate
+     */
+    FEC_6_15 = 1L << 39,
+
+    /**
+     * 9/15 conv. code rate
+     */
+    FEC_9_15 = 1L << 40,
+
+    /**
+     * 10/15 conv. code rate
+     */
+    FEC_10_15 = 1L << 41,
+
+    /**
+     * 12/15 conv. code rate
+     */
+    FEC_12_15 = 1L << 42,
+
+    /**
+     * 13/15 conv. code rate
+     */
+    FEC_13_15 = 1L << 43,
+
+    /**
+     * 18/30 conv. code rate
+     */
+    FEC_18_30 = 1L << 44,
+
+    /**
+     * 20/30 conv. code rate
+     */
+    FEC_20_30 = 1L << 45,
+
+    /**
+     * 90/180 conv. code rate
+     */
+    FEC_90_180 = 1L << 46,
+
+    /**
+     * 96/180 conv. code rate
+     */
+    FEC_96_180 = 1L << 47,
+
+    /**
+     * 104/180 conv. code rate
+     */
+    FEC_104_180 = 1L << 48,
+
+    /**
+     * 128/180 conv. code rate
+     */
+    FEC_128_180 = 1L << 49,
+
+    /**
+     * 132/180 conv. code rate
+     */
+    FEC_132_180 = 1L << 50,
+
+    /**
+     * 135/180 conv. code rate
+     */
+    FEC_135_180 = 1L << 51,
+
+    /**
+     * 140/180 conv. code rate
+     */
+    FEC_140_180 = 1L << 52,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
new file mode 100644
index 0000000..3aa17dd
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode;
+import android.hardware.tv.tuner.FrontendCableTimeInterleaveMode;
+import android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode;
+
+/**
+ * @hide
+ */
+@VintfStability
+union FrontendInterleaveMode {
+    FrontendAtsc3TimeInterleaveMode atsc3
+        = FrontendAtsc3TimeInterleaveMode.UNDEFINED;
+
+    FrontendCableTimeInterleaveMode dvbc;
+
+    FrontendDtmbTimeInterleaveMode dtmb;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Capabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Capabilities.aidl
new file mode 100644
index 0000000..a98e1b3
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Capabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for ISDBS3 Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIsdbs3Capabilities {
+    /**
+     * Modulaltion Types defined by FrontendIsdbs3Modulation.
+     */
+    int modulationCap;
+
+    /**
+     * Code Rate Types defined by FrontendIsdbs3Coderate.
+     */
+    int coderateCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl
new file mode 100644
index 0000000..9e36c1e
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Code Rate Type for ISDBS3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbs3Coderate {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Code Rate automatically
+     */
+    AUTO = 1 << 0,
+
+    CODERATE_1_3 = 1 << 1,
+
+    CODERATE_2_5 = 1 << 2,
+
+    CODERATE_1_2 = 1 << 3,
+
+    CODERATE_3_5 = 1 << 4,
+
+    CODERATE_2_3 = 1 << 5,
+
+    CODERATE_3_4 = 1 << 6,
+
+    CODERATE_7_9 = 1 << 7,
+
+    CODERATE_4_5 = 1 << 8,
+
+    CODERATE_5_6 = 1 << 9,
+
+    CODERATE_7_8 = 1 << 10,
+
+    CODERATE_9_10 = 1 << 11,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl
new file mode 100644
index 0000000..5041f63
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Modulaltion Type for ISDBS3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbs3Modulation {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Modulation automatically
+     */
+    AUTO = 1 << 0,
+
+    MOD_BPSK = 1 << 1,
+
+    MOD_QPSK = 1 << 2,
+
+    MOD_8PSK = 1 << 3,
+
+    MOD_16APSK = 1 << 4,
+
+    MOD_32APSK = 1 << 5,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl
new file mode 100644
index 0000000..bdef4d7
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Roll of Type for ISDBS3.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbs3Rolloff {
+    UNDEFINED,
+
+    ROLLOFF_0_03,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Settings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Settings.aidl
new file mode 100644
index 0000000..a7c85ac
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbs3Settings.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendIsdbs3Coderate;
+import android.hardware.tv.tuner.FrontendIsdbs3Modulation;
+import android.hardware.tv.tuner.FrontendIsdbs3Rolloff;
+import android.hardware.tv.tuner.FrontendIsdbsStreamIdType;
+
+/**
+ * Signal Settings for ISDBS3 Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIsdbs3Settings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    char streamId;
+
+    FrontendIsdbsStreamIdType streamIdType = FrontendIsdbsStreamIdType.UNDEFINED;
+
+    FrontendIsdbs3Modulation modulation = FrontendIsdbs3Modulation.UNDEFINED;
+
+    FrontendIsdbs3Coderate coderate = FrontendIsdbs3Coderate.UNDEFINED;
+
+    /**
+     * Symbols per second
+     */
+    int symbolRate;
+
+    FrontendIsdbs3Rolloff rolloff = FrontendIsdbs3Rolloff.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsCapabilities.aidl
new file mode 100644
index 0000000..842609e
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsCapabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for ISDBS Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIsdbsCapabilities {
+    /**
+     * Modulation Types defined by FrontendIsdbsModulation.
+     */
+    int modulationCap;
+
+    /**
+     * Code Rates defined by FrontendIsdbsCoderate.
+     */
+    int coderateCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl
new file mode 100644
index 0000000..afcb05e
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Code Rate Type for ISDBS.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbsCoderate {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Code Rate automatically
+     */
+    AUTO = 1 << 0,
+
+    CODERATE_1_2 = 1 << 1,
+
+    CODERATE_2_3 = 1 << 2,
+
+    CODERATE_3_4 = 1 << 3,
+
+    CODERATE_5_6 = 1 << 4,
+
+    CODERATE_7_8 = 1 << 5,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl
new file mode 100644
index 0000000..051580c
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Modulation Type for ISDBS.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbsModulation {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Modulation automatically
+     */
+    AUTO = 1 << 0,
+
+    MOD_BPSK = 1 << 1,
+
+    MOD_QPSK = 1 << 2,
+
+    MOD_TC8PSK = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl
new file mode 100644
index 0000000..961f16b
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Roll Off Type for ISDBS.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbsRolloff {
+    UNDEFINED,
+
+    ROLLOFF_0_35,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsSettings.aidl
new file mode 100644
index 0000000..dde3002
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsSettings.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendIsdbsCoderate;
+import android.hardware.tv.tuner.FrontendIsdbsModulation;
+import android.hardware.tv.tuner.FrontendIsdbsRolloff;
+import android.hardware.tv.tuner.FrontendIsdbsStreamIdType;
+
+/**
+ * Signal Settings for ISDBS Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIsdbsSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    char streamId;
+
+    FrontendIsdbsStreamIdType streamIdType = FrontendIsdbsStreamIdType.UNDEFINED;
+
+    FrontendIsdbsModulation modulation = FrontendIsdbsModulation.UNDEFINED;
+
+    FrontendIsdbsCoderate coderate = FrontendIsdbsCoderate.UNDEFINED;
+
+    /**
+     * Symbols per second
+     */
+    int symbolRate;
+
+    FrontendIsdbsRolloff rolloff = FrontendIsdbsRolloff.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl
new file mode 100644
index 0000000..66b5694
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Stream Id Type for ISDBS.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbsStreamIdType {
+    STREAM_ID,
+
+    RELATIVE_STREAM_NUMBER,
+
+    UNDEFINED,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl
new file mode 100644
index 0000000..f4a1450
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Bandwidth for ISDBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbtBandwidth {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Bandwidth automatically
+     */
+    AUTO = 1 << 0,
+
+    BANDWIDTH_8MHZ = 1 << 1,
+
+    BANDWIDTH_7MHZ = 1 << 2,
+
+    BANDWIDTH_6MHZ = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
new file mode 100644
index 0000000..1480906
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Capabilities for ISDBT Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIsdbtCapabilities {
+    /**
+     * Modes defined by FrontendIsdbtMode.
+     */
+    int modeCap;
+
+    /**
+     * Bandwidths defined by FrontendIsdbtBandwidth.
+     */
+    int bandwidthCap;
+
+    /**
+     * Modulations defined by FrontendIsdbtModulation.
+     */
+    int modulationCap;
+
+    /**
+     * Code Rates defined by FrontendDvbtCoderate.
+     */
+    int coderateCap;
+
+    /**
+     * Guard Interval Types defined by FrontendDvbtGuardInterval.
+     */
+    int guardIntervalCap;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl
new file mode 100644
index 0000000..0a857b1
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Hierarchy Type for ISDBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbtCoderate {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Hierarchy automatically
+     */
+    AUTO = 1 << 0,
+
+    CODERATE_1_2 = 1 << 1,
+
+    CODERATE_2_3 = 1 << 2,
+
+    CODERATE_3_4 = 1 << 3,
+
+    CODERATE_5_6 = 1 << 4,
+
+    CODERATE_7_8 = 1 << 5,
+
+    CODERATE_3_5 = 1 << 6,
+
+    CODERATE_4_5 = 1 << 7,
+
+    CODERATE_6_7 = 1 << 8,
+
+    CODERATE_8_9 = 1 << 9,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl
new file mode 100644
index 0000000..a3540dc
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Guard Interval Type for ISDBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbtGuardInterval {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Guard Interval automatically
+     */
+    AUTO = 1 << 0,
+
+    INTERVAL_1_32 = 1 << 1,
+
+    INTERVAL_1_16 = 1 << 2,
+
+    INTERVAL_1_8 = 1 << 3,
+
+    INTERVAL_1_4 = 1 << 4,
+
+    INTERVAL_1_128 = 1 << 5,
+
+    INTERVAL_19_128 = 1 << 6,
+
+    INTERVAL_19_256 = 1 << 7,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtMode.aidl
new file mode 100644
index 0000000..1a130fb
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtMode.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Mode for ISDBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbtMode {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Mode automatically
+     */
+    AUTO = 1 << 0,
+
+    MODE_1 = 1 << 1,
+
+    MODE_2 = 1 << 2,
+
+    MODE_3 = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl
new file mode 100644
index 0000000..b94f578
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Modulation for ISDBT.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbtModulation {
+    UNDEFINED = 0,
+
+    /**
+     * hardware is able to detect and set Modulation automatically
+     */
+    AUTO = 1 << 0,
+
+    MOD_DQPSK = 1 << 1,
+
+    MOD_QPSK = 1 << 2,
+
+    MOD_16QAM = 1 << 3,
+
+    MOD_64QAM = 1 << 4,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
new file mode 100644
index 0000000..73d935a
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendDvbtCoderate;
+import android.hardware.tv.tuner.FrontendDvbtGuardInterval;
+import android.hardware.tv.tuner.FrontendIsdbtBandwidth;
+import android.hardware.tv.tuner.FrontendIsdbtMode;
+import android.hardware.tv.tuner.FrontendIsdbtModulation;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
+
+/**
+ * Signal Settings for ISDBT Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIsdbtSettings {
+    /**
+     * Signal frequency in Hertz
+     */
+    int frequency;
+
+    /**
+     * Signal end frequency in Hertz used by scan
+     */
+    int endFrequency;
+
+    FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
+
+    FrontendIsdbtModulation modulation = FrontendIsdbtModulation.UNDEFINED;
+
+    FrontendIsdbtBandwidth bandwidth = FrontendIsdbtBandwidth.UNDEFINED;
+
+    FrontendIsdbtMode mode = FrontendIsdbtMode.UNDEFINED;
+
+    FrontendDvbtCoderate coderate = FrontendDvbtCoderate.UNDEFINED;
+
+    FrontendDvbtGuardInterval guardInterval = FrontendDvbtGuardInterval.UNDEFINED;
+
+    int serviceAreaId;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendModulation.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendModulation.aidl
new file mode 100644
index 0000000..dd09ff6
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendModulation.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAtsc3Modulation;
+import android.hardware.tv.tuner.FrontendAtscModulation;
+import android.hardware.tv.tuner.FrontendDvbcModulation;
+import android.hardware.tv.tuner.FrontendDvbsModulation;
+import android.hardware.tv.tuner.FrontendIsdbs3Modulation;
+import android.hardware.tv.tuner.FrontendIsdbsModulation;
+import android.hardware.tv.tuner.FrontendIsdbtModulation;
+import android.hardware.tv.tuner.FrontendDtmbModulation;
+import android.hardware.tv.tuner.FrontendDvbtConstellation;
+
+/**
+ * @hide
+ */
+@VintfStability
+union FrontendModulation {
+    FrontendDvbcModulation dvbc = FrontendDvbcModulation.UNDEFINED;
+
+    FrontendDvbsModulation dvbs;
+
+    FrontendDvbtConstellation dvbt;
+
+    FrontendIsdbsModulation isdbs;
+
+    FrontendIsdbs3Modulation isdbs3;
+
+    FrontendIsdbtModulation isdbt;
+
+    FrontendAtscModulation atsc;
+
+    FrontendAtsc3Modulation atsc3;
+
+    FrontendDtmbModulation dtmb;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendModulationStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendModulationStatus.aidl
new file mode 100644
index 0000000..8630c7d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendModulationStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendDvbcModulation;
+import android.hardware.tv.tuner.FrontendDvbsModulation;
+import android.hardware.tv.tuner.FrontendIsdbs3Modulation;
+import android.hardware.tv.tuner.FrontendIsdbsModulation;
+import android.hardware.tv.tuner.FrontendIsdbtModulation;
+
+/**
+ * Modulation Type for Frontend's status.
+ * @hide
+ */
+@VintfStability
+union FrontendModulationStatus {
+    FrontendDvbcModulation dvbc = FrontendDvbcModulation.UNDEFINED;
+
+    FrontendDvbsModulation dvbs;
+
+    FrontendIsdbsModulation isdbs;
+
+    FrontendIsdbs3Modulation isdbs3;
+
+    FrontendIsdbtModulation isdbt;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendRollOff.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendRollOff.aidl
new file mode 100644
index 0000000..2b8e887
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendRollOff.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendDvbsRolloff;
+import android.hardware.tv.tuner.FrontendIsdbs3Rolloff;
+import android.hardware.tv.tuner.FrontendIsdbsRolloff;
+
+/**
+ * @hide
+ */
+@VintfStability
+union FrontendRollOff {
+    FrontendDvbsRolloff dvbs = FrontendDvbsRolloff.UNDEFINED;
+
+    FrontendIsdbsRolloff isdbs;
+
+    FrontendIsdbs3Rolloff isdbs3;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.aidl
new file mode 100644
index 0000000..1fe2b1f
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanAtsc3PlpInfo.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * ATSC3.0 PLP information for scan
+ * @hide
+ */
+@VintfStability
+parcelable FrontendScanAtsc3PlpInfo {
+    byte plpId;
+
+    boolean bLlsFlag;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessage.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessage.aidl
new file mode 100644
index 0000000..d89e9b1
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessage.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAnalogType;
+import android.hardware.tv.tuner.FrontendDvbcAnnex;
+import android.hardware.tv.tuner.FrontendDvbtHierarchy;
+import android.hardware.tv.tuner.FrontendModulation;
+import android.hardware.tv.tuner.FrontendScanAtsc3PlpInfo;
+import android.hardware.tv.tuner.FrontendScanMessageStandard;
+
+/**
+ * Scan Message for Frontend.
+ * @hide
+ */
+@VintfStability
+union FrontendScanMessage {
+    boolean isLocked;
+
+    boolean isEnd;
+
+    /**
+     * scan progress percent (0..100)
+     */
+    byte progressPercent;
+
+    /**
+     * Signal frequencies in Hertz
+     */
+    int[] frequencies;
+
+    /**
+     * Symbols per second
+     */
+    int[] symbolRates;
+
+    FrontendDvbtHierarchy hierarchy;
+
+    FrontendAnalogType analogType;
+
+    byte[] plpIds;
+
+    byte[] groupIds;
+
+    char[] inputStreamIds;
+
+    FrontendScanMessageStandard std;
+
+    /**
+     * A list of PLP status in a tuned frequency band for ATSC3 frontend.
+     */
+    FrontendScanAtsc3PlpInfo[] atsc3PlpInfos;
+
+    FrontendModulation modulation;
+
+    FrontendDvbcAnnex annex;
+
+    boolean isHighPriority;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageStandard.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageStandard.aidl
new file mode 100644
index 0000000..9df725e
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageStandard.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAnalogSifStandard;
+import android.hardware.tv.tuner.FrontendDvbsStandard;
+import android.hardware.tv.tuner.FrontendDvbtStandard;
+
+/**
+ * @hide
+ */
+@VintfStability
+union FrontendScanMessageStandard {
+    FrontendDvbsStandard sStd = FrontendDvbsStandard.UNDEFINED;
+
+    FrontendDvbtStandard tStd;
+
+    FrontendAnalogSifStandard sifStd;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageType.aidl
new file mode 100644
index 0000000..2b91216
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageType.aidl
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Scan Message Type for Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendScanMessageType {
+    /**
+     * Scan locked the signal.
+     */
+    LOCKED,
+
+    /**
+     * Scan stopped.
+     */
+    END,
+
+    /**
+     * Scan progress report.
+     */
+    PROGRESS_PERCENT,
+
+    /**
+     * Locked frequency report.
+     */
+    FREQUENCY,
+
+    /**
+     * Locked symbol rate.
+     */
+    SYMBOL_RATE,
+
+    /**
+     * Locked HIERARCHY for DVBT2 frontend.
+     */
+    HIERARCHY,
+
+    ANALOG_TYPE,
+
+    /**
+     * Locked Plp Ids for DVBT2 frontend.
+     */
+
+    PLP_IDS,
+
+    /**
+     * Locked group Ids for DVBT2 frontend.
+     */
+    GROUP_IDS,
+
+    /**
+     * Stream Ids.
+     */
+    INPUT_STREAM_IDS,
+
+    /**
+     * Locked signal standard.
+     */
+    STANDARD,
+
+    /**
+     * PLP status in a tuned frequency band for ATSC3 frontend.
+     */
+    ATSC3_PLP_INFO,
+
+    MODULATION,
+
+    DVBC_ANNEX,
+
+    HIGH_PRIORITY,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanType.aidl
new file mode 100644
index 0000000..a548a3d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanType.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Scan type for Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendScanType {
+    SCAN_UNDEFINED = 0,
+
+    SCAN_AUTO = 1 << 0,
+
+    SCAN_BLIND = 1 << 1,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl
new file mode 100644
index 0000000..f78b2ae
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSettings.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendAnalogSettings;
+import android.hardware.tv.tuner.FrontendAtsc3Settings;
+import android.hardware.tv.tuner.FrontendAtscSettings;
+import android.hardware.tv.tuner.FrontendDvbcSettings;
+import android.hardware.tv.tuner.FrontendDvbsSettings;
+import android.hardware.tv.tuner.FrontendDvbtSettings;
+import android.hardware.tv.tuner.FrontendIsdbs3Settings;
+import android.hardware.tv.tuner.FrontendIsdbsSettings;
+import android.hardware.tv.tuner.FrontendIsdbtSettings;
+import android.hardware.tv.tuner.FrontendDtmbSettings;
+
+/**
+ * Signal Settings for Frontend.
+ * @hide
+ */
+@VintfStability
+union FrontendSettings {
+    FrontendAnalogSettings analog;
+
+    FrontendAtscSettings atsc;
+
+    FrontendAtsc3Settings atsc3;
+
+    FrontendDvbsSettings dvbs;
+
+    FrontendDvbcSettings dvbc;
+
+    FrontendDvbtSettings dvbt;
+
+    FrontendIsdbsSettings isdbs;
+
+    FrontendIsdbs3Settings isdbs3;
+
+    FrontendIsdbtSettings isdbt;
+
+    FrontendDtmbSettings dtmb;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSpectralInversion.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSpectralInversion.aidl
new file mode 100644
index 0000000..232385b
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendSpectralInversion.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Spectral Inversion Type.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendSpectralInversion {
+    UNDEFINED,
+
+    NORMAL,
+
+    INVERTED,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
new file mode 100644
index 0000000..b9f73ad
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendBandwidth;
+import android.hardware.tv.tuner.FrontendDvbtHierarchy;
+import android.hardware.tv.tuner.FrontendGuardInterval;
+import android.hardware.tv.tuner.FrontendInnerFec;
+import android.hardware.tv.tuner.FrontendInterleaveMode;
+import android.hardware.tv.tuner.FrontendModulation;
+import android.hardware.tv.tuner.FrontendModulationStatus;
+import android.hardware.tv.tuner.FrontendRollOff;
+import android.hardware.tv.tuner.FrontendSpectralInversion;
+import android.hardware.tv.tuner.FrontendStatusAtsc3PlpInfo;
+import android.hardware.tv.tuner.FrontendTransmissionMode;
+import android.hardware.tv.tuner.LnbVoltage;
+
+/**
+ * The status for Frontend.
+ * @hide
+ */
+@VintfStability
+union FrontendStatus {
+    /**
+     * Lock status for Demod in True/False.
+     */
+    boolean isDemodLocked;
+
+    /**
+     * SNR value measured by 0.001 dB.
+     */
+    int snr;
+
+    /**
+     * The number of error bit per 1 billion bits.
+     */
+    int ber;
+
+    /**
+     * The number of error package per 1 billion packages.
+     */
+    int per;
+
+    /**
+     * The number of error bit per 1 billion bits before FEC.
+     */
+    int preBer;
+
+    /**
+     * Signal Quality in percent.
+     */
+    int signalQuality;
+
+    /**
+     * Signal Strength measured by 0.001 dBm.
+     */
+    int signalStrength;
+
+    /**
+     * Symbols per second
+     */
+    int symbolRate;
+
+    FrontendInnerFec innerFec;
+
+    FrontendModulationStatus modulationStatus;
+
+    FrontendSpectralInversion inversion;
+
+    LnbVoltage lnbVoltage;
+
+    byte plpId;
+
+    boolean isEWBS;
+
+    /**
+     * AGC value is normalized from 0 to 255.
+     */
+    byte agc;
+
+    boolean isLnaOn;
+
+    boolean[] isLayerError;
+
+    /**
+     * MER value measured by 0.001 dB
+     */
+    int mer;
+
+    /**
+     * Frequency difference in Hertz.
+     */
+    int freqOffset;
+
+    FrontendDvbtHierarchy hierarchy;
+
+    boolean isRfLocked;
+
+    /**
+     * A list of PLP status for tuned PLPs for ATSC3 frontend.
+     */
+    FrontendStatusAtsc3PlpInfo[] plpInfo;
+
+    /**
+     * Modulation status.
+     */
+    FrontendModulation[] modulations;
+
+    /**
+     * Bit error ratio status.
+     */
+    int[] bers;
+
+    /**
+     * Code rate status.
+     */
+    FrontendInnerFec[] codeRates;
+
+    /**
+     * Bandwidth status.
+     */
+    FrontendBandwidth bandwidth;
+
+    /**
+     * Guard interval status.
+     */
+    FrontendGuardInterval interval;
+
+    /**
+     * Transmission mode status.
+     */
+    FrontendTransmissionMode transmissionMode;
+
+    /**
+     * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP)
+     * since the last tune operation.
+     */
+    int uec;
+
+    /**
+     * The current DVB-T2 system id status.
+     */
+    char systemId;
+
+    /**
+     * Frontend Interleaving Modes.
+     */
+    FrontendInterleaveMode[] interleaving;
+
+    /**
+     * Segments in ISDB-T Specification of all the channels.
+     */
+    byte[] isdbtSegment;
+
+    /**
+     * Transport Stream Data Rate in BPS of the current channel.
+     */
+    int[] tsDataRate;
+
+    /**
+     * Roll Off Type status of the frontend.
+     */
+    FrontendRollOff rollOff;
+
+    /**
+     * If the frontend currently supports MISO or not.
+     */
+    boolean isMiso;
+
+    /**
+     * If the frontend code rate is linear or not.
+     */
+    boolean isLinear;
+
+    /**
+     * If short frames is enabled or not.
+     */
+    boolean isShortFrames;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.aidl
new file mode 100644
index 0000000..c10a08c
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusAtsc3PlpInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Status for each tuning PLPs
+ * @hide
+ */
+@VintfStability
+parcelable FrontendStatusAtsc3PlpInfo {
+    /**
+     * PLP Id value.
+     */
+    byte plpId;
+
+    /**
+     * Demod Lock/Unlock status of this particular PLP.
+     */
+    boolean isLocked;
+
+    /**
+     * Uncorrectable Error Counts (UEC) of this particular PLP since last tune operation.
+     */
+    int uec;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
new file mode 100644
index 0000000..93b75b0
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Frontend Status Type.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendStatusType {
+    /**
+     * Lock status for Demod.
+     */
+    DEMOD_LOCK,
+
+    /**
+     * Signal to Noise Ratio.
+     */
+    SNR,
+
+    /**
+     * Bit Error Ratio.
+     */
+    BER,
+
+    /**
+     * Packages Error Ratio.
+     */
+    PER,
+
+    /**
+     * Bit Error Ratio before FEC.
+     */
+    PRE_BER,
+
+    /**
+     * Signal Quality (0..100). Good data over total data in percent can be
+     * used as a way to present Signal Quality.
+     */
+    SIGNAL_QUALITY,
+
+    /**
+     * Signal Strength.
+     */
+    SIGNAL_STRENGTH,
+
+    /**
+     * Symbol Rate.
+     */
+    SYMBOL_RATE,
+
+    /**
+     * Forward Error Correction Type.
+     */
+    FEC,
+
+    /**
+     * Modulation Type.
+     */
+    MODULATION,
+
+    /**
+     * Spectral Inversion Type.
+     */
+    SPECTRAL,
+
+    /**
+     * LNB Voltage.
+     */
+    LNB_VOLTAGE,
+
+    /**
+     * Physical Layer Pipe ID.
+     */
+    PLP_ID,
+
+    /**
+     * Status for Emergency Warning Broadcasting System.
+     */
+    EWBS,
+
+    /**
+     * Automatic Gain Control.
+     */
+    AGC,
+
+    /**
+     * Low Noise Amplifier.
+     */
+    LNA,
+
+    /**
+     * Error status by layer.
+     */
+    LAYER_ERROR,
+
+    /**
+     * Moduration Error Ratio.
+     */
+    MER,
+
+    /**
+     * Difference between tuning frequency and actual locked frequency.
+     */
+    FREQ_OFFSET,
+
+    /**
+     * Hierarchy for DVBT.
+     */
+    HIERARCHY,
+
+    /**
+     * Lock status for RF.
+     */
+    RF_LOCK,
+
+    /**
+     * PLP information in a frequency band for ATSC3.0 frontend.
+     */
+    ATSC3_PLP_INFO,
+
+    /**
+     * Modulation Types.
+     */
+    MODULATIONS,
+
+    /**
+     * Bit Error Ratios.
+     */
+    BERS,
+    /**
+     * Code Rates.
+     */
+    CODERATES,
+
+    /**
+     * Extended Bandwidth.
+     */
+    BANDWIDTH,
+
+    /**
+     * Extended Guard Intervals.
+     */
+    GUARD_INTERVAL,
+
+    /**
+     * Extended Transmission Mode.
+     */
+    TRANSMISSION_MODE,
+
+    /**
+     * Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP)
+     * since the last tune operation.
+     */
+    UEC,
+
+    /**
+     * DVB-T2 System Id.
+     */
+    T2_SYSTEM_ID,
+
+    /**
+     * Frontend Interleaving Modes.
+     */
+    INTERLEAVINGS,
+
+    /**
+     * Segments in ISDB-T Specification of all the channels.
+     */
+    ISDBT_SEGMENTS,
+
+    /**
+     * Transport Stream Data Rate in BPS of the current channel.
+     */
+    TS_DATA_RATES,
+
+    /**
+     * Roll Off Type status of the frontend.
+     */
+    ROLL_OFF,
+
+    /**
+     * If the frontend currently supports MISO or not.
+     */
+    IS_MISO,
+
+    /**
+     * If the frontend code rate is linear or not.
+     */
+    IS_LINEAR,
+
+    /**
+     * If short frames is enabled or not.
+     */
+    IS_SHORT_FRAMES,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendTransmissionMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendTransmissionMode.aidl
new file mode 100644
index 0000000..42b8718
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendTransmissionMode.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendIsdbtMode;
+import android.hardware.tv.tuner.FrontendDtmbTransmissionMode;
+import android.hardware.tv.tuner.FrontendDvbtTransmissionMode;
+
+/**
+ * @hide
+ */
+@VintfStability
+union FrontendTransmissionMode {
+    FrontendDvbtTransmissionMode dvbt = FrontendDvbtTransmissionMode.UNDEFINED;
+
+    FrontendIsdbtMode isdbt;
+
+    FrontendDtmbTransmissionMode dtmb;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl
new file mode 100644
index 0000000..8ade389
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendType.aidl
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Extended Frontend Type.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendType {
+    UNDEFINED = 0,
+
+    ANALOG,
+
+    /**
+     * Advanced Television Systems Committee (ATSC) Standard A/72.
+     */
+    ATSC,
+
+    /**
+     * Advanced Television Systems Committee (ATSC 3.0) Standard A/300.
+     */
+    ATSC3,
+
+    /**
+     * Digital Video Broadcasting - Cable
+     * DVB Cable Frontend Standard ETSI EN 300 468 V1.15.1.
+     */
+    DVBC,
+
+    /**
+     * Digital Video Broadcasting - Satellite
+     * DVB Satellite Frontend Standard ETSI EN 300 468 V1.15.1 and
+     * ETSI EN 302 307-2 V1.1.1.
+     */
+    DVBS,
+
+    /**
+     * Digital Video Broadcasting - Terrestrial
+     * DVB Terrestrial Frontend Standard ETSI EN 300 468 V1.15.1 and
+     * ETSI EN 302 755 V1.4.1.
+     */
+    DVBT,
+
+    /**
+     * Integrated Services Digital Broadcasting-Satellite (ISDB-S)
+     * ARIB STD-B20 is technical document of ISDB-S.
+     */
+    ISDBS,
+
+    /**
+     * Integrated Services Digital Broadcasting-Satellite (ISDB-S)
+     * ARIB STD-B44 is technical document of ISDB-S3.
+     */
+    ISDBS3,
+
+    /**
+     * Integrated Services Digital Broadcasting-Terrestrial (ISDB-T or SBTVD)
+     * ABNT NBR 15603 is technical document of ISDB-T.
+     */
+    ISDBT,
+
+    /**
+     * DTMB (Digital Terrestrial Multimedia Broadcast) standard.
+     */
+    DTMB,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IDemux.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IDemux.aidl
new file mode 100644
index 0000000..7d69240
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IDemux.aidl
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterType;
+import android.hardware.tv.tuner.DvrType;
+import android.hardware.tv.tuner.IDvr;
+import android.hardware.tv.tuner.IDvrCallback;
+import android.hardware.tv.tuner.IFilter;
+import android.hardware.tv.tuner.IFilterCallback;
+import android.hardware.tv.tuner.ITimeFilter;
+
+/**
+ * Demultiplexer(Demux) takes a single multiplexed input and splits it into
+ * one or more output.
+ * @hide
+ */
+@VintfStability
+interface IDemux {
+    /**
+     * Set a frontend resource as data input of the demux
+     *
+     * It is used by the client to specify a hardware frontend as data source of
+     * this demux instance. A demux instance can have only one data source.
+     */
+    void setFrontendDataSource(in int frontendId);
+
+    /**
+     * Open a new filter in the demux
+     *
+     * It is used by the client to open a filter in the demux.
+     *
+     * @param type the type of the filter to be added.
+     * @param bufferSize the buffer size of the filter to be opened. It's used
+     * to create a FMQ(Fast Message Queue) to hold data output from the filter.
+     * @param cb the callback for the filter to be used to send notifications
+     * back to the client.
+     *
+     * @return the filter instance of the newly added.
+     */
+    IFilter openFilter(in DemuxFilterType type, in int bufferSize,
+        in IFilterCallback cb);
+
+    /**
+     * Open time filter of the demux
+     *
+     * It is used by the client to open time filter of the demux.
+     *
+     * @return the time filter instance of the newly added.
+     */
+    ITimeFilter openTimeFilter();
+
+    /**
+     * Get 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 the ID of hardware A/V sync.
+     */
+    int getAvSyncHwId(in IFilter filter);
+
+    /**
+     * Get current time stamp to use for A/V sync
+     *
+     * It is used by the client to get current time stamp for A/V sync. HW is
+     * supported to increment and maintain current time stamp.
+     *
+     * @param avSyncHwId the hardware id of A/V sync.
+     *
+     * @return the current time stamp of hardware A/V sync. The time stamp
+     * based on 90KHz has the same format as PTS (Presentation Time Stamp).
+     */
+    long getAvSyncTime(in int avSyncHwId);
+
+    /**
+     * Close the Demux instance
+     *
+     * It is used by the client to release the demux instance. HAL clear
+     * underneath resource. client mustn't access the instance any more.
+     */
+    void close();
+
+    /**
+     * Open a DVR (Digital Video Record) instance in the demux
+     *
+     * It is used by the client to record and playback.
+     *
+     * @param type specify which kind of DVR to open.
+     * @param bufferSize the buffer size of the output to be added. It's used to
+     * create a FMQ(Fast Message Queue) to hold data from selected filters.
+     * @param cb the callback for the DVR to be used to send notifications
+     * back to the client.
+     *
+     * @return the newly opened DVR instance.
+     */
+    IDvr openDvr(in DvrType type, in int bufferSize, in IDvrCallback cb);
+
+    /**
+     * Connect Conditional Access Modules (CAM) through Common Interface (CI)
+     *
+     * It is used by the client to connect CI-CAM. The demux uses the output
+     * from the frontend as the input by default, and must change to use the
+     * output from CI-CAM as the input after this call take place.
+     *
+     * @param ciCamId specify CI-CAM Id to connect.
+     */
+    void connectCiCam(in int ciCamId);
+
+    /**
+     * Disconnect Conditional Access Modules (CAM)
+     *
+     * It is used by the client to disconnect CI-CAM. The demux will use the
+     * output from the frontend as the input after this call take place.
+     *
+     */
+    void disconnectCiCam();
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IDescrambler.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IDescrambler.aidl
new file mode 100644
index 0000000..8643828
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IDescrambler.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxPid;
+import android.hardware.tv.tuner.IFilter;
+
+/**
+ * Descrambler is used to descramble input data.
+ * @hide
+ */
+@VintfStability
+interface IDescrambler {
+    /**
+     * Set a demux as source of the descrambler
+     *
+     * It is used by the client to specify a demux as source of this
+     * descrambler. A descrambler instance can have only one source, and
+     * this method can be only called once.
+     *
+     * @param demuxId the id of the demux to be used as descrambler's source.
+     */
+    void setDemuxSource(in int demuxId);
+
+    /**
+     * Set a key token to link descrambler to a key slot
+     *
+     * It is used by the client to link a hardware key slot to a descrambler.
+     * A descrambler instance can have only one key slot to link, but a key
+     * slot can hold a few keys for different purposes.
+     *
+     * @param keyToken the token to be used to link the key slot.
+     */
+    void setKeyToken(in byte[] keyToken);
+
+    /**
+     * Add packets' PID to the descrambler for descrambling
+     *
+     * It is used by the client to specify Package ID (PID) of packets which the
+     * descrambler start to descramble. Multiple PIDs can be added into one
+     * descrambler instance because descambling can happen simultaneously on
+     * packets from different PIDs.
+     *
+     * @param pid the PID of packets to start to be descrambled.
+     * @param filter an optional filter instance to identify upper stream.
+     */
+    void addPid(in DemuxPid pid, in IFilter optionalSourceFilter);
+
+    /**
+     * Remove packets' PID from the descrambler
+     *
+     * It is used by the client to specify Package ID (PID) of packets which the
+     * descrambler stop to descramble.
+     *
+     * @param pid the PID of packets to stop to be descrambled.
+     * @param filter an optional filter instance to identify upper stream.
+     */
+    void removePid(in DemuxPid pid, in IFilter optionalSourceFilter);
+
+    /**
+     * Release the descrambler instance
+     *
+     * It is used by the client to release the descrambler instance. HAL clear
+     * underneath resource. client mustn't access the instance any more.
+     */
+    void close();
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl
new file mode 100644
index 0000000..0534f9d
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IDvr.aidl
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+
+import android.hardware.tv.tuner.DvrSettings;
+import android.hardware.tv.tuner.IFilter;
+
+/**
+ * Digtal Video Record (DVR) interface provides record control on Demux's
+ * output buffer and playback control on Demux's input buffer.
+ * @hide
+ */
+@VintfStability
+interface IDvr {
+    /**
+     * Get the descriptor of the DVR's FMQ
+     *
+     * It is used by the client to get the descriptor of the DVR's Fast
+     * Message Queue. The FMQ is used to transfer record or playback data
+     * between the client and the HAL.
+     *
+     * @return the descriptor of the DVR's FMQ
+     */
+    void getQueueDesc(out MQDescriptor<byte, SynchronizedReadWrite> queue);
+
+    /**
+     * Configure the DVR.
+     *
+     * It is used by the client to configure the DVR interface.
+     *
+     * @param settings the settings of the DVR interface.
+     */
+    void configure(in DvrSettings settings);
+
+    /**
+     * Attach one filter to DVR interface for recording.
+     *
+     * It is used by the client to add the data filtered out from the filter
+     * to record.
+     *
+     * @param filter the instance of the attached filter.
+     */
+    void attachFilter(in IFilter filter);
+
+    /**
+     * Detach one filter from the DVR's recording.
+     *
+     * It is used by the client to remove the data of the filter from DVR's
+     * recording.
+     *
+     * @param filter the instance of the detached filter.
+     */
+    void detachFilter(in IFilter filter);
+
+    /**
+     * Start DVR.
+     *
+     * It is used by the client to ask the DVR to start consuming playback data
+     * or producing data for record.
+     */
+    void start();
+
+    /**
+     * Stop DVR.
+     *
+     * It is used by the client to ask the DVR to stop consuming playback data
+     * or producing data for record.
+     */
+    void stop();
+
+    /**
+     * Flush DVR data.
+     *
+     * It is used by the client to ask the DVR to flush the data which is
+     * not consumed by HAL for playback or the client for record yet.
+     */
+    void flush();
+
+    /**
+     * close the DVR instance to release resource for DVR.
+     *
+     * It is used by the client to close the DVR instance, and HAL clears
+     * underneath resource for this DVR instance. Client mustn't access the
+     * instance any more and all methods should return a failure.
+     */
+    void close();
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IDvrCallback.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IDvrCallback.aidl
new file mode 100644
index 0000000..46d4856
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IDvrCallback.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.PlaybackStatus;
+import android.hardware.tv.tuner.RecordStatus;
+
+/**
+ * This interface is used by the HAL to notify the DVR playback and record status
+ * back to the client, the cient implements the interfaces and passes a handle to
+ * the HAL.
+ * @hide
+ */
+@VintfStability
+oneway interface IDvrCallback {
+    /**
+     * Notify the client a new status of the demux's playback.
+     *
+     * @param status a new status of the demux's playback.
+     */
+    void onPlaybackStatus(in PlaybackStatus status);
+
+    /**
+     * Notify the client a new status of the demux's record.
+     *
+     * @param status a new status of the demux's record.
+     */
+    void onRecordStatus(in RecordStatus status);
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IFilter.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IFilter.aidl
new file mode 100644
index 0000000..63fe1dd
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IFilter.aidl
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.hardware.common.NativeHandle;
+
+import android.hardware.tv.tuner.DemuxFilterSettings;
+import android.hardware.tv.tuner.IFilter;
+import android.hardware.tv.tuner.AvStreamType;
+import android.hardware.tv.tuner.DemuxFilterMonitorEventType;
+
+/**
+ * The Filter is used to filter wanted data according to the filter's
+ * configuration.
+ *
+ * Note that reconfiguring Filter must happen after the Filter is stopped.
+ * @hide
+ */
+@VintfStability
+interface IFilter {
+    /**
+     * Get the descriptor of the filter's FMQ
+     *
+     * It is used by the client to get the descriptor of the filter's Fast
+     * Message Queue. The data in FMQ is filtered out from demux input or upper
+     * stream's filter. The data is origanized to data blocks which may have
+     * different length. The length's information of one or multiple data blocks
+     * is sent to client through DemuxFilterEvent. The data in each block
+     * follows the stardard specified by filter's type.
+     * E.X. one data block from the filter with Main_Type==TS and Sub_Type==PES
+     * is Packetized Elementary Stream from Transport Stream according to
+     * ISO/IEC 13818-1.
+     *
+     * @return the descriptor of the filter's FMQ
+     */
+    void getQueueDesc(out MQDescriptor<byte, SynchronizedReadWrite> queue);
+
+    /**
+     * Release the Filter instance
+     *
+     * It is used by the client to release the Filter instance. HAL clear
+     * underneath resource. client mustn't access the instance any more.
+     */
+    void close();
+
+    /**
+     * Configure the filter.
+     *
+     * It is used by the client to configure the filter so that it can filter out
+     * intended data.
+     *
+     * @param settings the settings of the filter.
+     */
+    void configure(in DemuxFilterSettings settings);
+
+    /**
+     * Configure A/V filter’s stream type. This API only applies to A/V filters.
+     *
+     * @param avStreamType the stream type for A/V.
+     */
+    void configureAvStreamType(in AvStreamType avStreamType);
+
+    /**
+     * Configure additional Context ID on the IP filter.
+     *
+     * @param ipCid Context Id of the IP filter.
+     */
+    void configureIpCid(in int ipCid);
+
+    /**
+     * Configure the monitor event.
+     *
+     * The event for Scrambling Status should be sent at the following two scenarios:
+     *   1. When this method is called, the first detected scrambling status should be sent.
+     *   2. When the Scrambling status transits into different status, event should be sent.
+     *
+     * The event for IP CID change should be sent at the following two scenarios:
+     *   1. When this method is called, the first detected CID for the IP should be sent.
+     *   2. When the CID is changed to different value for the IP filter, event should be sent.
+     *
+     * @param monitorEventypes the DemuxFilterMonitorEventType events to monitor. Set
+     *        corresponding bit of the event to monitor. Reset to stop monitoring.
+     */
+    void configureMonitorEvent(in int monitorEventTypes);
+
+    /**
+     * Start the filter.
+     *
+     * It is used by the client to ask the filter to start filterring data.
+     */
+    void start();
+
+    /**
+     * Stop the filter.
+     *
+     * It is used by the client to ask the filter to stop filterring data.
+     * It won't discard the data already filtered out by the filter. The filter
+     * will be stopped and removed automatically if the demux is closed.
+     */
+    void stop();
+
+    /**
+     * Flush the filter.
+     *
+     * It is used by the client to ask the filter to flush the data which is
+     * already produced but not consumed yet.
+     */
+    void flush();
+
+    /**
+     * Get the shared AV memory handle. Use IFilter.releaseAvHandle to release
+     * the handle.
+     *
+     * When media filters are opened, call this API to initialize the share
+     * memory handle if it's needed.
+     *
+     * If DemuxFilterMediaEvent.avMemory contains file descriptor, share memory
+     * should be ignored.
+     *
+     * @param out avMemory A handle associated to the shared memory for audio or
+     *         video. avMemory.data[0] is normally an fd for ION memory. When
+     *         the avMemory->numFd is 0, the share memory is not initialized and
+     *         does not contain valid fd. avMemory.data[avMemory.numFds] is an
+     *         index used as a parameter of C2DataIdInfo to build C2 buffer in
+     *         Codec. No C2 buffer would be created if the index does not exist.
+     *
+     * @return the size of the shared av memory. It should be ignored when the share
+     *         memory is not initialized.
+     */
+    long getAvSharedHandle(out NativeHandle avMemory);
+
+    /**
+     * Get the 32-bit filter Id.
+     *
+     * It is used by the client to ask the hardware resource id for the filter.
+     *
+     * @return the hardware 32-bit resource Id for the filter.
+     */
+    int getId();
+
+    /**
+     * Get the 64-bit filter Id.
+     *
+     * It is used by the client to ask the hardware resource id for the filter.
+     *
+     * @return the hardware 64-bit resource Id for the filter.
+     */
+    long getId64Bit();
+
+    /**
+     * Release the handle reported by the HAL for AV memory.
+     *
+     * It is used by the client to notify the HAL that the AV handle won't be
+     * used any more in client side, so that the HAL can mark the memory
+     * presented by file descripor in the handle as released.
+     *
+     * @param avMemory A handle associated to the memory for audio or video.
+     * @param avDataId An Id provides additional information for AV data.
+     */
+    void releaseAvHandle(in NativeHandle avMemory, in long avDataId);
+
+    /**
+     * Set the filter's data source.
+     *
+     * A filter uses demux as data source by default. If the data was packetized
+     * by multiple protocols, multiple filters may need to work together to
+     * extract all protocols' header. Then a filter's data source can be output
+     * from another filter.
+     *
+     * @param filter the filter instance which provides data input. Switch to
+     * use demux as data source if the filter instance is NULL.
+     */
+    void setDataSource(in IFilter filter);
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IFilterCallback.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IFilterCallback.aidl
new file mode 100644
index 0000000..f4e01ee
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IFilterCallback.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxFilterEvent;
+import android.hardware.tv.tuner.DemuxFilterStatus;
+
+/**
+ * This interface is used by the HAL to notify the filter event and scan status
+ * back to the client, the cient implements the interfaces and passes a handle
+ * to the HAL.
+ * @hide
+ */
+@VintfStability
+oneway interface IFilterCallback {
+    /**
+     * Notify the client that a new filter event happened.
+     *
+     * @param events an array of DemuxFilterEvent.
+     */
+    void onFilterEvent(in DemuxFilterEvent[] events);
+
+    /**
+     * Notify the client a new status of a filter.
+     *
+     * @param status a new status of the filter.
+     */
+    void onFilterStatus(in DemuxFilterStatus status);
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IFrontend.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IFrontend.aidl
new file mode 100644
index 0000000..b2717db
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IFrontend.aidl
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendScanType;
+import android.hardware.tv.tuner.FrontendSettings;
+import android.hardware.tv.tuner.FrontendStatus;
+import android.hardware.tv.tuner.FrontendStatusType;
+import android.hardware.tv.tuner.IFrontendCallback;
+
+/**
+ * A Tuner Frontend is used to tune to a frequency and lock signal.
+ *
+ * IFrontend provides a bit stream to the Tuner Demux interface.
+ * @hide
+ */
+@VintfStability
+interface IFrontend {
+    /**
+     * Set the frontend callback.
+     *
+     * IFrontendCallback is used by the client to receive events from the Frontend.
+     * Only one callback per IFrontend instance is supported. The callback
+     * will be replaced if it's set again.
+     *
+     * @param callback Callback object to pass Frontend events to the system.
+     *        The previously registered callback must be replaced with this one.
+     *        It can be null.
+     */
+    void setCallback(in IFrontendCallback callback);
+
+    /**
+     * Tunes the frontend to using the settings given.
+     *
+     * This locks the frontend to a frequency by providing signal
+     * delivery information. If previous tuning isn't completed, this call MUST
+     * stop previous tuning, and start a new tuning.
+     * Tune is an async call, with LOCKED or NO_SIGNAL events sent via callback.
+     *
+     * @param settings Signal delivery information the frontend uses to
+     * search and lock the signal.
+     */
+    void tune(in FrontendSettings settings);
+
+    /**
+     * Stops a previous tuning.
+     *
+     * If the method completes successfully the frontend is no longer tuned and no data
+     * will be sent to attached demuxes.
+     */
+    void stopTune();
+
+    /**
+     * Releases the Frontend instance
+     *
+     * Associated resources are released.  close may be called more than once.
+     * Calls to any other method after this will return an error
+     */
+    void close();
+
+    /**
+     * Scan the frontend to use the settings given.
+     *
+     * This uses the frontend to start a scan from signal delivery information.
+     * If previous scan isn't completed, this call MUST stop previous scan,
+     * and start a new scan.
+     * Scan is an async call, with FrontendScanMessage sent via callback.
+     *
+     * @param settings Signal delivery information which the frontend uses to
+     * scan the signal.
+     * @param type the type which the frontend uses to scan the signal.
+     */
+    void scan(in FrontendSettings settings, in FrontendScanType type);
+
+    /**
+     * Stops a previous scanning.
+     *
+     * If the method completes successfully, the frontend stop previous
+     * scanning.
+     */
+    void stopScan();
+
+    /**
+     * Gets the statuses of the frontend.
+     *
+     * This retrieve the statuses of the frontend for given status types.
+     *
+     * @param statusTypes an array of status type which the caller request.
+     *
+     * @return an array of statuses which response the caller's request.
+     */
+    FrontendStatus[] getStatus(in FrontendStatusType[] statusTypes);
+
+    /**
+     * Sets Low-Noise Block downconverter (LNB) for satellite frontend.
+     *
+     * This assigns a hardware LNB resource to the satellite frontend. It can be
+     * called multiple times to update LNB assignment. The LNB resource must be
+     * released when the frontend is closed.
+     *
+     * @param lnbId the Id of assigned LNB resource.
+     */
+    void setLnb(in int lnbId);
+
+    /**
+     * Enable or Disable Low Noise Amplifier (LNA).
+     *
+     * @param bEnable true if activate LNA module; false if deactivate LNA
+     */
+    void setLna(in boolean bEnable);
+
+    /**
+     * Link Conditional Access Modules (CAM) to Frontend support Common
+     * Interface (CI) bypass mode.
+     *
+     * The client may use this to link CI-CAM to a frontend. CI bypass mode
+     * requires that the CICAM also receives the TS concurrently from the
+     * frontend when the Demux is receiving the TS directly from the frontend.
+     *
+     * @param ciCamId specify CI-CAM Id to link.
+     *
+     * @return the Local Transport Stream Id.
+     */
+    int linkCiCam(in int ciCamId);
+
+    /**
+     * Unlink Conditional Access Modules (CAM) to Frontend.
+     *
+     * @param ciCamId specify CI-CAM Id to unlink.
+     */
+    void unlinkCiCam(in int ciCamId);
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IFrontendCallback.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IFrontendCallback.aidl
new file mode 100644
index 0000000..6822869
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IFrontendCallback.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.FrontendEventType;
+import android.hardware.tv.tuner.FrontendScanMessage;
+import android.hardware.tv.tuner.FrontendScanMessageType;
+
+/**
+ * This interface is used by the HAL to notify the fronted event and scan messages
+ * back to the client, the cient implements the interfaces and passes a handle to
+ * the HAL.
+ * @hide
+ */
+@VintfStability
+oneway interface IFrontendCallback {
+    /**
+     * Notify the client that a new event happened on the frontend.
+     *
+     * @param frontendEventType the event type.
+     */
+    void onEvent(in FrontendEventType frontendEventType);
+
+    /**
+     * The callback function that must be called by HAL implementation to notify
+     * the client of scan messages.
+     *
+     * @param type the type of scan message.
+     * @param message the scan message sent by HAL to the client.
+     */
+    void onScanMessage(in FrontendScanMessageType type,
+        in FrontendScanMessage message);
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/ILnb.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/ILnb.aidl
new file mode 100644
index 0000000..28eae45
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/ILnb.aidl
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.ILnbCallback;
+import android.hardware.tv.tuner.LnbPosition;
+import android.hardware.tv.tuner.LnbTone;
+import android.hardware.tv.tuner.LnbVoltage;
+
+/**
+ * A Tuner LNB (low-noise block downconverter) is used by satellite frontend
+ * to receive the microwave signal from the satellite, amplify it, and
+ * downconvert the frequency to a lower frequency.
+ * @hide
+ */
+@VintfStability
+interface ILnb {
+    /**
+     * Set the lnb callback.
+     *
+     * ILnbCallback is used by the client to receive events from the Lnb.
+     * Only one callback per ILnb instance is supported. The callback
+     * will be replaced if it's set again.
+     *
+     * @param callback Callback object to pass Lnb events to the system.
+     *        The previously registered callback must be replaced with this one.
+     *        It can be null.
+     */
+    void setCallback(in ILnbCallback callback);
+
+    /**
+     * Set the lnb's power voltage.
+     *
+     * @param voltage the power's voltage the Lnb to use.
+     */
+    void setVoltage(in LnbVoltage voltage);
+
+    /**
+     * Set the lnb's tone mode.
+     *
+     * @param tone the tone mode the Lnb to use.
+     */
+    void setTone(in LnbTone tone);
+
+    /**
+     * Select the lnb's position.
+     *
+     * @param position the position the Lnb to use.
+     */
+    void setSatellitePosition(in LnbPosition position);
+
+    /**
+     *  Sends DiSEqC (Digital Satellite Equipment Control) message.
+     *
+     * Client sends DiSeqc message to DiSEqc to LNB. The response message from
+     * the device comes back to the client through frontend's callback
+     * onDiseqcMessage.
+     *
+     * @param diseqcMessage a byte array of data for DiSEqC message which is
+     *        specified by EUTELSAT Bus Functional Specification Version 4.2.
+     */
+    void sendDiseqcMessage(in byte[] diseqcMessage);
+
+    /**
+     * Releases the LNB instance
+     *
+     * Associated resources are released.  close may be called more than once.
+     * Calls to any other method after this will return an error
+     */
+    void close();
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/ILnbCallback.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/ILnbCallback.aidl
new file mode 100644
index 0000000..98ef141
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/ILnbCallback.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.LnbEventType;
+
+/**
+ * This interface is used by the HAL to notify the Lnb event and DiSEqC (Digital
+ * Satellite Equipment Control) message back to the client, the cient implements
+ * the interfaces and passes a handle to the HAL.
+ * @hide
+ */
+@VintfStability
+oneway interface ILnbCallback {
+    /**
+     * The callback function that must be called by HAL implementation to notify
+     * the client of new DiSEqC message.
+     *
+     * @param diseqcMessage a byte array of data for DiSEqC (Digital Satellite
+     * Equipment Control) message which is specified by EUTELSAT Bus Functional
+     * Specification Version 4.2.
+     */
+    void onDiseqcMessage(in byte[] diseqcMessage);
+
+    /**
+     * Notify the client that a new event happened on the Lnb.
+     *
+     * @param LnbEventType the event type.
+     */
+    void onEvent(in LnbEventType lnbEventType);
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/ITimeFilter.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/ITimeFilter.aidl
new file mode 100644
index 0000000..dee6cd8
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/ITimeFilter.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Timer Filter is used by Demux to filter data based on time stamp.
+ * @hide
+ */
+@VintfStability
+interface ITimeFilter {
+    /**
+     * Set time stamp for time based filter.
+     *
+     * It is used by the client to set initial time stamp and enable time
+     * filtering. The time will be incremented locally. The demux discards
+     * the content which time stamp is older than the time in the time filter.
+     *
+     * @param timeStamp initial time stamp for the time filter. It based on
+     * 90KHz has the same format as PTS (Presentation Time Stamp).
+     */
+    void setTimeStamp(in long timeStamp);
+
+    /**
+     * Clear the time stamp in the time filter.
+     *
+     * It is used by the client to clear the time value of the time filter,
+     * then disable time filter.
+     */
+    void clearTimeStamp();
+
+    /**
+     * Get the current time in the time filter.
+     *
+     * It is used by the client to inquiry current time in the time filter.
+     *
+     * @return the current time stamp in the time filter.
+     */
+    long getTimeStamp();
+
+    /**
+     * Get the time from the beginning of current data source.
+     *
+     * It is used by the client to inquiry the time stamp from the beginning
+     * of current data source.
+     *
+     * @return the time stamp from the beginning of current data source.
+     */
+    long getSourceTime();
+
+    /**
+     * Close the Time Filter instance
+     *
+     * It is used by the client to release the demux instance. HAL clear
+     * underneath resource. client mustn't access the instance any more.
+     */
+    void close();
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
new file mode 100644
index 0000000..f881082
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DemuxCapabilities;
+import android.hardware.tv.tuner.FrontendInfo;
+import android.hardware.tv.tuner.IDemux;
+import android.hardware.tv.tuner.IDescrambler;
+import android.hardware.tv.tuner.IFrontend;
+import android.hardware.tv.tuner.ILnb;
+import android.hardware.tv.tuner.FrontendDtmbCapabilities;
+
+/**
+ * Top level interface to manage Frontend, Demux and Decrambler hardware
+ * resources which are needed for Android TV.
+ * @hide
+ */
+@VintfStability
+@SuppressWarnings(value={"out-array"})
+interface ITuner {
+    /**
+     * Get Frontend IDs
+     *
+     * It is used by the client to get all available frontends' IDs.
+     *
+     * @return an array of IDs for the available Frontends.
+     */
+    int[] getFrontendIds();
+
+    /**
+     * Create a new instance of Frontend given a frontendId.
+     *
+     * It is used by the client to create a frontend instance.
+     *
+     * @param frontendId the id of the frontend to be opened.
+     *
+     * @return the newly created frontend interface.
+     */
+    IFrontend openFrontendById(in int frontendId);
+
+    /**
+     * Create a new instance of Demux.
+     *
+     * It is used by the client to create a Demux instance.
+     *
+     * @param out demuxId the newly created demux id will be the first
+     *        element of the array.
+     *
+     * @return the newly created demux interface.
+     */
+    IDemux openDemux(out int[] demuxId);
+
+    /**
+     * Retrieve the Demux's Capabilities.
+     *
+     * @return the Demux's Capabilities.
+     */
+    DemuxCapabilities getDemuxCaps();
+
+    /**
+     * Create a new instance of Descrambler.
+     *
+     * It is used by the client to create a Descrambler instance.
+     *
+     * @return the newly created descrambler interface.
+     */
+    IDescrambler openDescrambler();
+
+    /**
+     * Retrieve the frontend's information.
+     *
+     * @return the frontend's information.
+     */
+    FrontendInfo getFrontendInfo(in int frontendId);
+
+    /**
+     * Get low-noise block downconverter (LNB) IDs.
+     *
+     * It is used by the client to get all available LNBs' IDs.
+     *
+     * @return an array of LnbId for the available LNBs.
+     */
+    int[] getLnbIds();
+
+    /**
+     * Create a new instance of Lnb given a lnbId.
+     *
+     * It is used by the client to create a Lnb instance for satellite Frontend.
+     *
+     * @param lnbId the id of the LNB to be opened.
+     *
+     * @return the newly created Lnb interface.
+     */
+    ILnb openLnbById(in int lnbId);
+
+    /**
+     * Create a new instance of Lnb given a LNB name.
+     *
+     * It is used by the client to create a LNB instance for external device.
+     *
+     * @param lnbName the name for an external LNB to be opened. The app
+     *        provides the name. Frammework doesn't depend on the name, instead
+     *        use lnbId return from this call.
+     * @param out demuxId the newly opened Lnb id will be the first element of
+     *        the array.
+     *
+     * @return the newly opened Lnb iterface.
+     */
+    ILnb openLnbByName(in String lnbName, out int[] lnbId);
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/LnbEventType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/LnbEventType.aidl
new file mode 100644
index 0000000..a6230b0
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/LnbEventType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Lnb Event Type.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum LnbEventType {
+    DISEQC_RX_OVERFLOW,
+
+    /**
+     * If LNB detect that outgoing Diseqc message isn't delivered on time.
+     */
+    DISEQC_RX_TIMEOUT,
+
+    /**
+     * If LNB detect that the incoming Diseqc message has parity error.
+     */
+    DISEQC_RX_PARITY_ERROR,
+
+    /**
+     * If LNB detect that the LNB is overload.
+     */
+    LNB_OVERLOAD,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/LnbPosition.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/LnbPosition.aidl
new file mode 100644
index 0000000..067f6b1
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/LnbPosition.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * The Position of LNB.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum LnbPosition {
+    UNDEFINED,
+
+    POSITION_A,
+
+    POSITION_B,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/LnbTone.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/LnbTone.aidl
new file mode 100644
index 0000000..f1d1598
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/LnbTone.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Tone Type for LNB.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum LnbTone {
+    NONE,
+
+    CONTINUOUS,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/LnbVoltage.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/LnbVoltage.aidl
new file mode 100644
index 0000000..03a42f2
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/LnbVoltage.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Power Voltage Type for LNB.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum LnbVoltage {
+    NONE,
+
+    VOLTAGE_5V,
+
+    VOLTAGE_11V,
+
+    VOLTAGE_12V,
+
+    VOLTAGE_13V,
+
+    VOLTAGE_14V,
+
+    VOLTAGE_15V,
+
+    VOLTAGE_18V,
+
+    VOLTAGE_19V,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/PlaybackSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/PlaybackSettings.aidl
new file mode 100644
index 0000000..47d3db6
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/PlaybackSettings.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DataFormat;
+
+/**
+ * The Setting for the playback in DVR.
+ * @hide
+ */
+@VintfStability
+parcelable PlaybackSettings {
+    /**
+     * Register for interested PlaybackStatus events so that the HAL can send these
+     * PlaybackStatus events back to client.
+     */
+    int statusMask;
+
+    /**
+     * Unused space size in bytes in the playback. The HAL uses it to trigger
+     * InputStatus::SPACE_ALMOST_EMPTY.
+     */
+    int lowThreshold;
+
+    /**
+     * Unused space size in bytes in the playback. The HAL uses it to trigger
+     * InputStatus::SPACE_ALMOST_FULL.
+     */
+    int highThreshold;
+
+    /**
+     * The data format in the playback.
+     */
+    DataFormat dataFormat = DataFormat.UNDEFINED;
+
+    /**
+     * The packet size in bytes in the playback.
+     */
+    byte packetSize;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/PlaybackStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/PlaybackStatus.aidl
new file mode 100644
index 0000000..545dc89
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/PlaybackStatus.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * A status of the playback in DVR.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum PlaybackStatus {
+    /**
+     * The space of the demux's playback is empty.
+     */
+    SPACE_EMPTY = 1 << 0,
+
+    /**
+     * The spece of the demux's playback is almost empty.
+     */
+    SPACE_ALMOST_EMPTY = 1 << 1,
+
+    /**
+     * The space of the demux's playback is almost full.
+     */
+    SPACE_ALMOST_FULL = 1 << 2,
+
+    /**
+     * The space of the demux's playback is full.
+     */
+    SPACE_FULL = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/RecordSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/RecordSettings.aidl
new file mode 100644
index 0000000..94370d6
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/RecordSettings.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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;
+
+import android.hardware.tv.tuner.DataFormat;
+
+/**
+ * The Settings for the record in DVR.
+ * @hide
+ */
+@VintfStability
+parcelable RecordSettings {
+    /**
+     * Register for interested RecordStatus events so that the HAL can send these
+     * PlaybackStatus events back to client.
+     */
+    int statusMask;
+
+    /**
+     * Unconsumed data size in bytes in the record. The HAL uses it to trigger
+     * OutputStatus::LOW_WATER.
+     */
+    int lowThreshold;
+
+    /**
+     * Unconsumed data size in bytes in the record. The HAL uses it to trigger
+     * OutputStatus::High_WATER.
+     */
+    int highThreshold;
+
+    /**
+     * The data format in the record.
+     */
+    DataFormat dataFormat = DataFormat.UNDEFINED;
+
+    /**
+     * The packet size in bytes in the record.
+     */
+    byte packetSize;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/RecordStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/RecordStatus.aidl
new file mode 100644
index 0000000..64d9bd4
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/RecordStatus.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * A status of data in the filter's buffer.
+ * @hide
+ */
+@VintfStability
+@Backing(type="byte")
+enum RecordStatus {
+    /**
+     * The data in the filter buffer is ready to be read.
+     */
+    DATA_READY = 1 << 0,
+
+    /**
+     * The available data amount in the filter buffer is at low level which is
+     * set to 25 percent by default.
+     */
+    LOW_WATER = 1 << 1,
+
+    /**
+     * The available data amount in the filter buffer is at high level which is
+     * set to 75 percent by default.
+     */
+    HIGH_WATER = 1 << 2,
+
+    /**
+     * The data in the filter buffer is full and newly filtered data is being
+     * discarded.
+     */
+    OVERFLOW = 1 << 3,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/ScramblingStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/ScramblingStatus.aidl
new file mode 100644
index 0000000..76f56ae
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/ScramblingStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Scrambling Status Type.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum ScramblingStatus {
+    /**
+     * Content’s scrambling status is unknown
+     */
+    UNKNOWN = 1 << 0,
+
+    /**
+     * Content is not scrambled.
+     */
+    NOT_SCRAMBLED = 1 << 1,
+
+    /**
+     * Content is scrambled.
+     */
+    SCRAMBLED = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl
new file mode 100644
index 0000000..108d986
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/VideoStreamType.aidl
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2021 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;
+
+/**
+ * Video stream coding format.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum VideoStreamType {
+    UNDEFINED,
+
+    /*
+     * ITU-T | ISO/IEC Reserved
+     */
+    RESERVED,
+
+    /*
+     * ISO/IEC 11172
+     */
+    MPEG1,
+
+    /*
+     * ITU-T Rec.H.262 and ISO/IEC 13818-2
+     */
+    MPEG2,
+
+    /*
+     * ISO/IEC 14496-2 (MPEG-4 H.263 based video)
+     */
+    MPEG4P2,
+
+    /*
+     * ITU-T Rec.H.264 and ISO/IEC 14496-10
+     */
+    AVC,
+
+    /*
+     * ITU-T Rec. H.265 and ISO/IEC 23008-2
+     */
+    HEVC,
+
+    /*
+     * Microsoft VC.1
+     */
+    VC1,
+
+    /*
+     * Google VP8
+     */
+    VP8,
+
+    /*
+     * Google VP9
+     */
+    VP9,
+
+    /*
+     * AOMedia Video 1
+     */
+    AV1,
+
+    /*
+     * Chinese Standard
+     */
+    AVS,
+
+    /*
+     * New Chinese Standard
+     */
+    AVS2,
+}
diff --git a/tv/tuner/aidl/default/Android.bp b/tv/tuner/aidl/default/Android.bp
new file mode 100644
index 0000000..ba4af44
--- /dev/null
+++ b/tv/tuner/aidl/default/Android.bp
@@ -0,0 +1,46 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+    name: "android.hardware.tv.tuner-service.example",
+    relative_install_path: "hw",
+    init_rc: ["tuner-default.rc"],
+    vintf_fragments: ["tuner-default.xml"],
+    vendor: true,
+    compile_multilib: "first",
+    srcs: [
+        "Demux.cpp",
+        "Descrambler.cpp",
+        "Dvr.cpp",
+        "Filter.cpp",
+        "Frontend.cpp",
+        "Lnb.cpp",
+        "TimeFilter.cpp",
+        "Tuner.cpp",
+        "service.cpp",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+    ],
+    shared_libs: [
+        "android.hardware.common.fmq-V1-ndk_platform",
+        "android.hardware.tv.tuner-V1-ndk_platform",
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libdmabufheap",
+        "libfmq",
+        "libion",
+        "liblog",
+        "libutils",
+    ],
+    header_libs: [
+        "media_plugin_headers",
+    ],
+}
diff --git a/tv/tuner/aidl/default/Demux.cpp b/tv/tuner/aidl/default/Demux.cpp
new file mode 100644
index 0000000..15022ee
--- /dev/null
+++ b/tv/tuner/aidl/default/Demux.cpp
@@ -0,0 +1,427 @@
+/*
+ * Copyright 2021 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
+#define LOG_TAG "android.hardware.tv.tuner-service.example-Demux"
+
+#include <aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.h>
+
+#include <utils/Log.h>
+#include "Demux.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+#define WAIT_TIMEOUT 3000000000
+
+Demux::Demux(int32_t demuxId, std::shared_ptr<Tuner> tuner) {
+    mDemuxId = demuxId;
+    mTunerService = tuner;
+}
+
+Demux::~Demux() {
+    mFrontendInputThreadRunning = false;
+    std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
+}
+
+::ndk::ScopedAStatus Demux::setFrontendDataSource(int32_t in_frontendId) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mTunerService == nullptr) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_NO_INIT);
+    }
+
+    mFrontend = mTunerService->getFrontendById(in_frontendId);
+
+    if (mFrontend == nullptr) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    mTunerService->setFrontendAsDemuxSource(in_frontendId, mDemuxId);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Demux::openFilter(const DemuxFilterType& in_type, int32_t in_bufferSize,
+                                       const std::shared_ptr<IFilterCallback>& in_cb,
+                                       std::shared_ptr<IFilter>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    int64_t filterId;
+    filterId = ++mLastUsedFilterId;
+
+    if (in_cb == nullptr) {
+        ALOGW("[Demux] callback can't be null");
+        *_aidl_return = nullptr;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    std::shared_ptr<Filter> filter =
+            ndk::SharedRefBase::make<Filter>(in_type, filterId, in_bufferSize, in_cb, ref<Demux>());
+    if (!filter->createFilterMQ()) {
+        *_aidl_return = nullptr;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+    }
+
+    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);
+        }
+    }
+
+    if (!result) {
+        *_aidl_return = nullptr;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    *_aidl_return = filter;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Demux::openTimeFilter(std::shared_ptr<ITimeFilter>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    mTimeFilter = ndk::SharedRefBase::make<TimeFilter>(ref<Demux>());
+
+    *_aidl_return = mTimeFilter;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Demux::getAvSyncHwId(const std::shared_ptr<IFilter>& in_filter,
+                                          int32_t* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    int64_t id;
+    ::ndk::ScopedAStatus status;
+
+    status = in_filter->getId64Bit(&id);
+    if (!status.isOk()) {
+        ALOGE("[Demux] Can't get filter Id.");
+        *_aidl_return = -1;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    if (!mFilters[id]->isMediaFilter()) {
+        ALOGE("[Demux] Given filter is not a media filter.");
+        *_aidl_return = -1;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    if (!mPcrFilterIds.empty()) {
+        // Return the lowest pcr filter id in the default implementation as the av sync id
+        *_aidl_return = *mPcrFilterIds.begin();
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    ALOGE("[Demux] No PCR filter opened.");
+    *_aidl_return = -1;
+    return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+}
+
+::ndk::ScopedAStatus Demux::getAvSyncTime(int32_t in_avSyncHwId, int64_t* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mPcrFilterIds.empty()) {
+        *_aidl_return = -1;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+    if (in_avSyncHwId != *mPcrFilterIds.begin()) {
+        *_aidl_return = -1;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    *_aidl_return = -1;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Demux::close() {
+    ALOGV("%s", __FUNCTION__);
+
+    set<int64_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);
+    mFrontendInputThreadRunning = false;
+    std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Demux::openDvr(DvrType in_type, int32_t in_bufferSize,
+                                    const std::shared_ptr<IDvrCallback>& in_cb,
+                                    std::shared_ptr<IDvr>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (in_cb == nullptr) {
+        ALOGW("[Demux] DVR callback can't be null");
+        *_aidl_return = nullptr;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    set<int64_t>::iterator it;
+    switch (in_type) {
+        case DvrType::PLAYBACK:
+            mDvrPlayback =
+                    ndk::SharedRefBase::make<Dvr>(in_type, in_bufferSize, in_cb, ref<Demux>());
+            if (!mDvrPlayback->createDvrMQ()) {
+                mDvrPlayback = nullptr;
+                *_aidl_return = mDvrPlayback;
+                return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+            }
+
+            for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
+                if (!mDvrPlayback->addPlaybackFilter(*it, mFilters[*it])) {
+                    ALOGE("[Demux] Can't get filter info for DVR playback");
+                    mDvrPlayback = nullptr;
+                    *_aidl_return = mDvrPlayback;
+                    return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+                }
+            }
+
+            *_aidl_return = mDvrPlayback;
+            return ::ndk::ScopedAStatus::ok();
+        case DvrType::RECORD:
+            mDvrRecord = ndk::SharedRefBase::make<Dvr>(in_type, in_bufferSize, in_cb, ref<Demux>());
+            if (!mDvrRecord->createDvrMQ()) {
+                mDvrRecord = nullptr;
+                *_aidl_return = mDvrRecord;
+                return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+            }
+
+            *_aidl_return = mDvrRecord;
+            return ::ndk::ScopedAStatus::ok();
+        default:
+            *_aidl_return = nullptr;
+            return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+}
+
+::ndk::ScopedAStatus Demux::connectCiCam(int32_t in_ciCamId) {
+    ALOGV("%s", __FUNCTION__);
+
+    mCiCamId = in_ciCamId;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Demux::disconnectCiCam() {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Demux::removeFilter(int64_t filterId) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mDvrPlayback != nullptr) {
+        mDvrPlayback->removePlaybackFilter(filterId);
+    }
+    mPlaybackFilterIds.erase(filterId);
+    mRecordFilterIds.erase(filterId);
+    mFilters.erase(filterId);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+void Demux::startBroadcastTsFilter(vector<int8_t> data) {
+    set<int64_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<int8_t> data) {
+    set<int64_t>::iterator it;
+    if (DEBUG_DEMUX) {
+        ALOGW("[Demux] update record filter output");
+    }
+    for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
+        mFilters[*it]->updateRecordOutput(data);
+    }
+}
+
+void Demux::sendFrontendInputToRecord(vector<int8_t> data, uint16_t pid, uint64_t pts) {
+    sendFrontendInputToRecord(data);
+    set<int64_t>::iterator it;
+    for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
+        if (pid == mFilters[*it]->getTpid()) {
+            mFilters[*it]->updatePts(pts);
+        }
+    }
+}
+
+bool Demux::startBroadcastFilterDispatcher() {
+    set<int64_t>::iterator it;
+
+    // Handle the output data per filter type
+    for (it = mPlaybackFilterIds.begin(); it != mPlaybackFilterIds.end(); it++) {
+        if (!mFilters[*it]->startFilterHandler().isOk()) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool Demux::startRecordFilterDispatcher() {
+    set<int64_t>::iterator it;
+
+    for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
+        if (!mFilters[*it]->startRecordFilterHandler().isOk()) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+::ndk::ScopedAStatus Demux::startFilterHandler(int64_t filterId) {
+    return mFilters[filterId]->startFilterHandler();
+}
+
+void Demux::updateFilterOutput(int64_t filterId, vector<int8_t> data) {
+    mFilters[filterId]->updateFilterOutput(data);
+}
+
+void Demux::updateMediaFilterOutput(int64_t filterId, vector<int8_t> data, uint64_t pts) {
+    updateFilterOutput(filterId, data);
+    mFilters[filterId]->updatePts(pts);
+}
+
+uint16_t Demux::getFilterTpid(int64_t filterId) {
+    return mFilters[filterId]->getTpid();
+}
+
+void Demux::startFrontendInputLoop() {
+    mFrontendInputThreadRunning = true;
+    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() {
+    if (!mFrontendInputThreadRunning) {
+        return;
+    }
+
+    std::lock_guard<std::mutex> lock(mFrontendInputThreadLock);
+    if (!mDvrPlayback) {
+        ALOGW("[Demux] No software Frontend input configured. Ending Frontend thread loop.");
+        mFrontendInputThreadRunning = false;
+        return;
+    }
+
+    while (mFrontendInputThreadRunning) {
+        uint32_t efState = 0;
+        ::android::status_t status = mDvrPlayback->getDvrEventFlag()->wait(
+                static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT,
+                true /* retry on spurious wake */);
+        if (status != ::android::OK) {
+            ALOGD("[Demux] wait for data ready on the playback FMQ");
+            continue;
+        }
+        if (mDvrPlayback->getSettings().get<DvrSettings::Tag::playback>().dataFormat ==
+            DataFormat::ES) {
+            if (!mDvrPlayback->processEsDataOnPlayback(true /*isVirtualFrontend*/, mIsRecording)) {
+                ALOGE("[Demux] playback es data failed to be filtered. Ending thread");
+                break;
+            }
+            continue;
+        }
+        // Our current implementation filter the data and write it into the filter FMQ immediately
+        // after the DATA_READY from the VTS/framework
+        // This is for the non-ES data source, real playback use case handling.
+        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::isRecording() {
+    return mIsRecording;
+}
+
+bool Demux::attachRecordFilter(int64_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(int64_t filterId) {
+    if (mFilters[filterId] == nullptr || mDvrRecord == nullptr) {
+        return false;
+    }
+
+    mRecordFilterIds.erase(filterId);
+    mFilters[filterId]->detachFilterFromRecord();
+
+    return true;
+}
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Demux.h b/tv/tuner/aidl/default/Demux.h
new file mode 100644
index 0000000..9f96d0f
--- /dev/null
+++ b/tv/tuner/aidl/default/Demux.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnDemux.h>
+
+#include <fmq/AidlMessageQueue.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 aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::hardware::EventFlag;
+
+using FilterMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+
+class Dvr;
+class Filter;
+class Frontend;
+class TimeFilter;
+class Tuner;
+
+class Demux : public BnDemux {
+  public:
+    Demux(int32_t demuxId, std::shared_ptr<Tuner> tuner);
+    ~Demux();
+
+    ::ndk::ScopedAStatus setFrontendDataSource(int32_t in_frontendId) override;
+    ::ndk::ScopedAStatus openFilter(const DemuxFilterType& in_type, int32_t in_bufferSize,
+                                    const std::shared_ptr<IFilterCallback>& in_cb,
+                                    std::shared_ptr<IFilter>* _aidl_return) override;
+    ::ndk::ScopedAStatus openTimeFilter(std::shared_ptr<ITimeFilter>* _aidl_return) override;
+    ::ndk::ScopedAStatus getAvSyncHwId(const std::shared_ptr<IFilter>& in_filter,
+                                       int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getAvSyncTime(int32_t in_avSyncHwId, int64_t* _aidl_return) override;
+    ::ndk::ScopedAStatus close() override;
+    ::ndk::ScopedAStatus openDvr(DvrType in_type, int32_t in_bufferSize,
+                                 const std::shared_ptr<IDvrCallback>& in_cb,
+                                 std::shared_ptr<IDvr>* _aidl_return) override;
+    ::ndk::ScopedAStatus connectCiCam(int32_t in_ciCamId) override;
+    ::ndk::ScopedAStatus disconnectCiCam() override;
+
+    // Functions interacts with Tuner Service
+    void stopFrontendInput();
+    ::ndk::ScopedAStatus removeFilter(int64_t filterId);
+    bool attachRecordFilter(int64_t filterId);
+    bool detachRecordFilter(int64_t filterId);
+    ::ndk::ScopedAStatus startFilterHandler(int64_t filterId);
+    void updateFilterOutput(int64_t filterId, vector<int8_t> data);
+    void updateMediaFilterOutput(int64_t filterId, vector<int8_t> data, uint64_t pts);
+    uint16_t getFilterTpid(int64_t filterId);
+    void setIsRecording(bool isRecording);
+    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<int8_t> data);
+
+    void sendFrontendInputToRecord(vector<int8_t> data);
+    void sendFrontendInputToRecord(vector<int8_t> data, uint16_t pid, uint64_t pts);
+    bool startRecordFilterDispatcher();
+
+  private:
+    // Tuner service
+    std::shared_ptr<Tuner> mTunerService;
+
+    // Frontend source
+    std::shared_ptr<Frontend> mFrontend;
+
+    // A struct that passes the arguments to a newly created filter thread
+    struct ThreadArgs {
+        Demux* user;
+        int64_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();
+
+    int32_t mDemuxId = -1;
+    int32_t mCiCamId;
+    set<int64_t> mPcrFilterIds;
+    /**
+     * Record the last used filter id. Initial value is -1.
+     * Filter Id starts with 0.
+     */
+    int64_t mLastUsedFilterId = -1;
+    /**
+     * Record all the used playback filter Ids.
+     * Any removed filter id should be removed from this set.
+     */
+    set<int64_t> mPlaybackFilterIds;
+    /**
+     * Record all the attached record filter Ids.
+     * Any removed filter id should be removed from this set.
+     */
+    set<int64_t> mRecordFilterIds;
+    /**
+     * A list of created Filter sp.
+     * The array number is the filter ID.
+     */
+    std::map<int64_t, std::shared_ptr<Filter>> mFilters;
+
+    /**
+     * Local reference to the opened Timer Filter instance.
+     */
+    std::shared_ptr<TimeFilter> mTimeFilter;
+
+    /**
+     * Local reference to the opened DVR object.
+     */
+    std::shared_ptr<Dvr> mDvrPlayback;
+    std::shared_ptr<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 tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Descrambler.cpp b/tv/tuner/aidl/default/Descrambler.cpp
new file mode 100644
index 0000000..8af3a92
--- /dev/null
+++ b/tv/tuner/aidl/default/Descrambler.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2021 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
+#define LOG_TAG "android.hardware.tv.tuner-service.example-Descrambler"
+
+#include <aidl/android/hardware/tv/tuner/IFrontendCallback.h>
+#include <utils/Log.h>
+
+#include "Descrambler.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+Descrambler::Descrambler() {}
+
+Descrambler::~Descrambler() {}
+
+::ndk::ScopedAStatus Descrambler::setDemuxSource(int32_t in_demuxId) {
+    ALOGV("%s", __FUNCTION__);
+    if (mDemuxSet) {
+        ALOGW("[   WARN   ] Descrambler has already been set with a demux id %" PRIu32,
+              mSourceDemuxId);
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+    mDemuxSet = true;
+    mSourceDemuxId = in_demuxId;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Descrambler::setKeyToken(const std::vector<uint8_t>& /* in_keyToken */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Descrambler::addPid(
+        const DemuxPid& /* in_pid */,
+        const std::shared_ptr<IFilter>& /* in_optionalSourceFilter */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Descrambler::removePid(
+        const DemuxPid& /* in_pid */,
+        const std::shared_ptr<IFilter>& /* in_optionalSourceFilter */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Descrambler::close() {
+    ALOGV("%s", __FUNCTION__);
+    mDemuxSet = false;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Descrambler.h b/tv/tuner/aidl/default/Descrambler.h
new file mode 100644
index 0000000..ddf2c1d
--- /dev/null
+++ b/tv/tuner/aidl/default/Descrambler.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnDescrambler.h>
+#include <aidl/android/hardware/tv/tuner/ITuner.h>
+#include <inttypes.h>
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+class Descrambler : public BnDescrambler {
+  public:
+    Descrambler();
+
+    ::ndk::ScopedAStatus setDemuxSource(int32_t in_demuxId) override;
+    ::ndk::ScopedAStatus setKeyToken(const std::vector<uint8_t>& in_keyToken) override;
+    ::ndk::ScopedAStatus addPid(const DemuxPid& in_pid,
+                                const std::shared_ptr<IFilter>& in_optionalSourceFilter) override;
+    ::ndk::ScopedAStatus removePid(
+            const DemuxPid& in_pid,
+            const std::shared_ptr<IFilter>& in_optionalSourceFilter) override;
+    ::ndk::ScopedAStatus close() override;
+
+  private:
+    virtual ~Descrambler();
+    int32_t mSourceDemuxId;
+    bool mDemuxSet = false;
+};
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Dvr.cpp b/tv/tuner/aidl/default/Dvr.cpp
new file mode 100644
index 0000000..a042dc3
--- /dev/null
+++ b/tv/tuner/aidl/default/Dvr.cpp
@@ -0,0 +1,489 @@
+/*
+ * Copyright 2021 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
+#define LOG_TAG "android.hardware.tv.tuner-service.example-Dvr"
+
+#include <aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.h>
+
+#include <utils/Log.h>
+#include "Dvr.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+#define WAIT_TIMEOUT 3000000000
+
+Dvr::Dvr(DvrType type, uint32_t bufferSize, const std::shared_ptr<IDvrCallback>& cb,
+         std::shared_ptr<Demux> demux) {
+    mType = type;
+    mBufferSize = bufferSize;
+    mCallback = cb;
+    mDemux = demux;
+}
+
+Dvr::~Dvr() {
+    mDvrThreadRunning = false;
+    lock_guard<mutex> lock(mDvrThreadLock);
+}
+
+::ndk::ScopedAStatus Dvr::getQueueDesc(MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue) {
+    ALOGV("%s", __FUNCTION__);
+
+    *out_queue = mDvrMQ->dupeDesc();
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Dvr::configure(const DvrSettings& in_settings) {
+    ALOGV("%s", __FUNCTION__);
+
+    mDvrSettings = in_settings;
+    mDvrConfigured = true;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Dvr::attachFilter(const std::shared_ptr<IFilter>& in_filter) {
+    ALOGV("%s", __FUNCTION__);
+
+    int64_t filterId;
+    ::ndk::ScopedAStatus status = in_filter->getId64Bit(&filterId);
+    if (!status.isOk()) {
+        return status;
+    }
+
+    if (!mDemux->attachRecordFilter(filterId)) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Dvr::detachFilter(const std::shared_ptr<IFilter>& in_filter) {
+    ALOGV("%s", __FUNCTION__);
+
+    int64_t filterId;
+    ::ndk::ScopedAStatus status = in_filter->getId64Bit(&filterId);
+    if (!status.isOk()) {
+        return status;
+    }
+
+    if (!mDemux->detachRecordFilter(filterId)) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Dvr::start() {
+    ALOGV("%s", __FUNCTION__);
+    if (mDvrThreadRunning) {
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    if (!mCallback) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_NO_INIT);
+    }
+
+    if (!mDvrConfigured) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    if (mType == DvrType::PLAYBACK) {
+        mDvrThreadRunning = true;
+        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 ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Dvr::stop() {
+    ALOGV("%s", __FUNCTION__);
+
+    mDvrThreadRunning = false;
+    lock_guard<mutex> lock(mDvrThreadLock);
+
+    mIsRecordStarted = false;
+    mDemux->setIsRecording(false);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Dvr::flush() {
+    ALOGV("%s", __FUNCTION__);
+
+    mRecordStatus = RecordStatus::DATA_READY;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Dvr::close() {
+    ALOGV("%s", __FUNCTION__);
+
+    mDvrThreadRunning = false;
+    lock_guard<mutex> lock(mDvrThreadLock);
+    return ::ndk::ScopedAStatus::ok();
+}
+
+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) != ::android::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);
+
+    while (mDvrThreadRunning) {
+        uint32_t efState = 0;
+        ::android::status_t status =
+                mDvrEventFlag->wait(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY),
+                                    &efState, WAIT_TIMEOUT, true /* retry on spurious wake */);
+        if (status != ::android::OK) {
+            ALOGD("[Dvr] wait for data ready on the playback FMQ");
+            continue;
+        }
+
+        // If the both dvr playback and dvr record are created, the playback will be treated as
+        // the source of the record. isVirtualFrontend set to true would direct the dvr playback
+        // input to the demux record filters or live broadcast filters.
+        bool isRecording = mDemux->isRecording();
+        bool isVirtualFrontend = isRecording;
+
+        if (mDvrSettings.get<DvrSettings::Tag::playback>().dataFormat == DataFormat::ES) {
+            if (!processEsDataOnPlayback(isVirtualFrontend, isRecording)) {
+                ALOGE("[Dvr] playback es data failed to be filtered. Ending thread");
+                break;
+            }
+            maySendPlaybackStatusCallback();
+            continue;
+        }
+
+        // Our current implementation filter the data and write it into the filter FMQ immediately
+        // after the DATA_READY from the VTS/framework
+        // This is for the non-ES data source, real playback use case handling.
+        if (!readPlaybackFMQ(isVirtualFrontend, isRecording) ||
+            !startFilterDispatcher(isVirtualFrontend, 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.get<DvrSettings::Tag::playback>().highThreshold,
+                                      mDvrSettings.get<DvrSettings::Tag::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.get<DvrSettings::Tag::playback>().packetSize;
+    vector<int8_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<int8_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<int8_t> frameData;
+    map<int64_t, std::shared_ptr<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(frameData.data(), dataOutputBuffer.data() + esMeta[i].startIndex, esMeta[i].len);
+        // Send to the media filters or record filters
+        if (!isRecording) {
+            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));
+                }
+            }
+        } else {
+            mDemux->sendFrontendInputToRecord(frameData, pid, static_cast<uint64_t>(esMeta[i].pts));
+        }
+        startFilterDispatcher(isVirtualFrontend, isRecording);
+        frameData.clear();
+    }
+
+    return true;
+}
+
+void Dvr::getMetaDataValue(int& index, int8_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<int8_t> data) {
+    map<int64_t, std::shared_ptr<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<int64_t, std::shared_ptr<IFilter>>::iterator it;
+    // Handle the output data per filter type
+    for (it = mFilters.begin(); it != mFilters.end(); it++) {
+        if (mDemux->startFilterHandler(it->first).isOk()) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool Dvr::writeRecordFMQ(const vector<int8_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.get<DvrSettings::Tag::record>().highThreshold,
+                                    mDvrSettings.get<DvrSettings::Tag::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 RecordStatus::OVERFLOW;
+    } else if (availableToRead > highThreshold) {
+        return RecordStatus::HIGH_WATER;
+    } else if (availableToRead < lowThreshold) {
+        return RecordStatus::LOW_WATER;
+    }
+    return mRecordStatus;
+}
+
+bool Dvr::addPlaybackFilter(int64_t filterId, std::shared_ptr<IFilter> filter) {
+    mFilters[filterId] = filter;
+    return true;
+}
+
+bool Dvr::removePlaybackFilter(int64_t filterId) {
+    mFilters.erase(filterId);
+    return true;
+}
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Dvr.h b/tv/tuner/aidl/default/Dvr.h
new file mode 100644
index 0000000..fb22a2e
--- /dev/null
+++ b/tv/tuner/aidl/default/Dvr.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnDvr.h>
+#include <aidl/android/hardware/tv/tuner/RecordStatus.h>
+
+#include <fmq/AidlMessageQueue.h>
+#include <math.h>
+#include <set>
+#include "Demux.h"
+#include "Frontend.h"
+#include "Tuner.h"
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::hardware::EventFlag;
+
+using DvrMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+
+struct MediaEsMetaData {
+    bool isAudio;
+    int startIndex;
+    int len;
+    int pts;
+};
+
+class Demux;
+class Filter;
+class Frontend;
+class Tuner;
+
+class Dvr : public BnDvr {
+  public:
+    Dvr(DvrType type, uint32_t bufferSize, const std::shared_ptr<IDvrCallback>& cb,
+        std::shared_ptr<Demux> demux);
+    ~Dvr();
+
+    ::ndk::ScopedAStatus getQueueDesc(
+            MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue) override;
+    ::ndk::ScopedAStatus configure(const DvrSettings& in_settings) override;
+    ::ndk::ScopedAStatus attachFilter(const std::shared_ptr<IFilter>& in_filter) override;
+    ::ndk::ScopedAStatus detachFilter(const std::shared_ptr<IFilter>& in_filter) override;
+    ::ndk::ScopedAStatus start() override;
+    ::ndk::ScopedAStatus stop() override;
+    ::ndk::ScopedAStatus flush() override;
+    ::ndk::ScopedAStatus close() override;
+
+    /**
+     * To create a DvrMQ and its Event Flag.
+     *
+     * Return false is any of the above processes fails.
+     */
+    bool createDvrMQ();
+    bool writeRecordFMQ(const std::vector<int8_t>& data);
+    bool addPlaybackFilter(int64_t filterId, std::shared_ptr<IFilter> filter);
+    bool removePlaybackFilter(int64_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
+    std::shared_ptr<Demux> mDemux;
+
+    DvrType mType;
+    uint32_t mBufferSize;
+    std::shared_ptr<IDvrCallback> mCallback;
+    std::map<int64_t, std::shared_ptr<IFilter>> mFilters;
+
+    void deleteEventFlag();
+    bool readDataFromMQ();
+    void getMetaDataValue(int& index, int8_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<int8_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 tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
new file mode 100644
index 0000000..18c1f00
--- /dev/null
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -0,0 +1,1103 @@
+/*
+ * Copyright 2021 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
+#define LOG_TAG "android.hardware.tv.tuner-service.example-Filter"
+
+#include <BufferAllocator/BufferAllocator.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterMonitorEventType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <utils/Log.h>
+
+#include "Filter.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+#define WAIT_TIMEOUT 3000000000
+
+Filter::Filter() {}
+
+Filter::Filter(DemuxFilterType type, int64_t filterId, uint32_t bufferSize,
+               const std::shared_ptr<IFilterCallback>& cb, std::shared_ptr<Demux> demux) {
+    mType = type;
+    mFilterId = filterId;
+    mBufferSize = bufferSize;
+    mDemux = demux;
+    mCallback = cb;
+
+    switch (mType.mainType) {
+        case DemuxFilterMainType::TS:
+            if (mType.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>() ==
+                        DemuxTsFilterType::AUDIO ||
+                mType.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>() ==
+                        DemuxTsFilterType::VIDEO) {
+                mIsMediaFilter = true;
+            }
+            if (mType.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>() ==
+                DemuxTsFilterType::PCR) {
+                mIsPcrFilter = true;
+            }
+            if (mType.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>() ==
+                DemuxTsFilterType::RECORD) {
+                mIsRecordFilter = true;
+            }
+            break;
+        case DemuxFilterMainType::MMTP:
+            if (mType.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>() ==
+                        DemuxMmtpFilterType::AUDIO ||
+                mType.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>() ==
+                        DemuxMmtpFilterType::VIDEO) {
+                mIsMediaFilter = true;
+            }
+            if (mType.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>() ==
+                DemuxMmtpFilterType::RECORD) {
+                mIsRecordFilter = true;
+            }
+            break;
+        case DemuxFilterMainType::IP:
+            break;
+        case DemuxFilterMainType::TLV:
+            break;
+        case DemuxFilterMainType::ALP:
+            break;
+        default:
+            break;
+    }
+}
+
+Filter::~Filter() {
+    mFilterThreadRunning = false;
+    std::lock_guard<std::mutex> lock(mFilterThreadLock);
+}
+
+::ndk::ScopedAStatus Filter::getId64Bit(int64_t* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    *_aidl_return = mFilterId;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::getId(int32_t* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    *_aidl_return = static_cast<int32_t>(mFilterId);
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::setDataSource(const std::shared_ptr<IFilter>& in_filter) {
+    ALOGV("%s", __FUNCTION__);
+
+    mDataSource = in_filter;
+    mIsDataSourceDemux = false;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::getQueueDesc(MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue) {
+    ALOGV("%s", __FUNCTION__);
+
+    mIsUsingFMQ = mIsRecordFilter ? false : true;
+
+    *out_queue = mFilterMQ->dupeDesc();
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::configure(const DemuxFilterSettings& in_settings) {
+    ALOGV("%s", __FUNCTION__);
+
+    mFilterSettings = in_settings;
+    switch (mType.mainType) {
+        case DemuxFilterMainType::TS:
+            mTpid = in_settings.get<DemuxFilterSettings::Tag::ts>().tpid;
+            break;
+        case DemuxFilterMainType::MMTP:
+            break;
+        case DemuxFilterMainType::IP:
+            break;
+        case DemuxFilterMainType::TLV:
+            break;
+        case DemuxFilterMainType::ALP:
+            break;
+        default:
+            break;
+    }
+
+    mConfigured = true;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::start() {
+    ALOGV("%s", __FUNCTION__);
+    mFilterThreadRunning = true;
+    vector<DemuxFilterEvent> events;
+    // All the filter event callbacks in start are for testing purpose.
+    switch (mType.mainType) {
+        case DemuxFilterMainType::TS:
+            createMediaEvent(events);
+            mCallback->onFilterEvent(events);
+            createTsRecordEvent(events);
+            mCallback->onFilterEvent(events);
+            createTemiEvent(events);
+            mCallback->onFilterEvent(events);
+            break;
+        case DemuxFilterMainType::MMTP:
+            createDownloadEvent(events);
+            mCallback->onFilterEvent(events);
+            createMmtpRecordEvent(events);
+            mCallback->onFilterEvent(events);
+            break;
+        case DemuxFilterMainType::IP:
+            createSectionEvent(events);
+            mCallback->onFilterEvent(events);
+            createIpPayloadEvent(events);
+            mCallback->onFilterEvent(events);
+            break;
+        case DemuxFilterMainType::TLV:
+            createMonitorEvent(events);
+            mCallback->onFilterEvent(events);
+            break;
+        case DemuxFilterMainType::ALP:
+            createMonitorEvent(events);
+            mCallback->onFilterEvent(events);
+            break;
+        default:
+            break;
+    }
+    return startFilterLoop();
+}
+
+::ndk::ScopedAStatus Filter::stop() {
+    ALOGV("%s", __FUNCTION__);
+    mFilterThreadRunning = false;
+    std::lock_guard<std::mutex> lock(mFilterThreadLock);
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::flush() {
+    ALOGV("%s", __FUNCTION__);
+
+    // temp implementation to flush the FMQ
+    int size = mFilterMQ->availableToRead();
+    int8_t* buffer = new int8_t[size];
+    mFilterMQ->read(buffer, size);
+    delete[] buffer;
+    mFilterStatus = DemuxFilterStatus::DATA_READY;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::releaseAvHandle(const NativeHandle& in_avMemory, int64_t in_avDataId) {
+    ALOGV("%s", __FUNCTION__);
+
+    if ((mSharedAvMemHandle != nullptr) && (in_avMemory.fds.size() > 0) &&
+        (sameFile(in_avMemory.fds[0].get(), mSharedAvMemHandle->data[0]))) {
+        freeSharedAvHandle();
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    if (mDataId2Avfd.find(in_avDataId) == mDataId2Avfd.end()) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    ::close(mDataId2Avfd[in_avDataId]);
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::close() {
+    ALOGV("%s", __FUNCTION__);
+
+    mFilterThreadRunning = false;
+    std::lock_guard<std::mutex> lock(mFilterThreadLock);
+    return mDemux->removeFilter(mFilterId);
+}
+
+::ndk::ScopedAStatus Filter::configureIpCid(int32_t in_ipCid) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mType.mainType != DemuxFilterMainType::IP) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    mCid = in_ipCid;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::getAvSharedHandle(NativeHandle* out_avMemory, int64_t* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (!mIsMediaFilter) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    if (mSharedAvMemHandle != nullptr) {
+        *out_avMemory = ::android::dupToAidl(mSharedAvMemHandle);
+        *_aidl_return = BUFFER_SIZE_16M;
+        mUsingSharedAvMem = true;
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    int av_fd = createAvIonFd(BUFFER_SIZE_16M);
+    if (av_fd < 0) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_NO_MEMORY);
+    }
+
+    mSharedAvMemHandle = createNativeHandle(av_fd);
+    if (mSharedAvMemHandle == nullptr) {
+        ::close(av_fd);
+        *_aidl_return = 0;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+    }
+    ::close(av_fd);
+    mUsingSharedAvMem = true;
+
+    *out_avMemory = ::android::dupToAidl(mSharedAvMemHandle);
+    *_aidl_return = BUFFER_SIZE_16M;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::configureAvStreamType(const AvStreamType& in_avStreamType) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (!mIsMediaFilter) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    switch (in_avStreamType.getTag()) {
+        case AvStreamType::Tag::audio:
+            mAudioStreamType =
+                    static_cast<uint32_t>(in_avStreamType.get<AvStreamType::Tag::audio>());
+            break;
+        case AvStreamType::Tag::video:
+            mVideoStreamType =
+                    static_cast<uint32_t>(in_avStreamType.get<AvStreamType::Tag::video>());
+            break;
+        default:
+            break;
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::configureMonitorEvent(int in_monitorEventTypes) {
+    ALOGV("%s", __FUNCTION__);
+
+    int32_t newScramblingStatus =
+            in_monitorEventTypes &
+            static_cast<int32_t>(DemuxFilterMonitorEventType::SCRAMBLING_STATUS);
+    int32_t newIpCid =
+            in_monitorEventTypes & static_cast<int32_t>(DemuxFilterMonitorEventType::IP_CID_CHANGE);
+
+    // if scrambling status monitoring flipped, record the new state and send msg on enabling
+    if (newScramblingStatus ^ mScramblingStatusMonitored) {
+        mScramblingStatusMonitored = newScramblingStatus;
+        if (mScramblingStatusMonitored) {
+            if (mCallback != nullptr) {
+                // Assuming current status is always NOT_SCRAMBLED
+                vector<DemuxFilterEvent> events;
+                DemuxFilterMonitorEvent monitorEvent;
+                events.resize(1);
+                monitorEvent.set<DemuxFilterMonitorEvent::Tag::scramblingStatus>(
+                        ScramblingStatus::NOT_SCRAMBLED);
+                events[0].set<DemuxFilterEvent::monitorEvent>(monitorEvent);
+                mCallback->onFilterEvent(events);
+            } else {
+                return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+            }
+        }
+    }
+
+    // if ip cid monitoring flipped, record the new state and send msg on enabling
+    if (newIpCid ^ mIpCidMonitored) {
+        mIpCidMonitored = newIpCid;
+        if (mIpCidMonitored) {
+            if (mCallback != nullptr) {
+                // Return random cid
+                vector<DemuxFilterEvent> events;
+                DemuxFilterMonitorEvent monitorEvent;
+                events.resize(1);
+                monitorEvent.set<DemuxFilterMonitorEvent::Tag::cid>(1);
+                events[0].set<DemuxFilterEvent::monitorEvent>(monitorEvent);
+                mCallback->onFilterEvent(events);
+            } else {
+                return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+            }
+        }
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+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(), &mFilterEventsFlag) !=
+        ::android::OK) {
+        return false;
+    }
+
+    return true;
+}
+
+::ndk::ScopedAStatus Filter::startFilterLoop() {
+    pthread_create(&mFilterThread, NULL, __threadLoopFilter, this);
+    pthread_setname_np(mFilterThread, "filter_waiting_loop");
+    return ::ndk::ScopedAStatus::ok();
+}
+
+void* Filter::__threadLoopFilter(void* user) {
+    Filter* const self = static_cast<Filter*>(user);
+    self->filterThreadLoop();
+    return 0;
+}
+
+void Filter::filterThreadLoop() {
+    if (!mFilterThreadRunning) {
+        return;
+    }
+    std::lock_guard<std::mutex> lock(mFilterThreadLock);
+    ALOGD("[Filter] filter %" PRIu64 " threadLoop start.", mFilterId);
+
+    // 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 (mFilterEvents.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
+        if (mCallback != nullptr) {
+            if (mConfigured) {
+                vector<DemuxFilterEvent> startEvent;
+                startEvent.resize(1);
+                startEvent[0].set<DemuxFilterEvent::Tag::startId>(mStartId++);
+                mCallback->onFilterEvent(startEvent);
+                mConfigured = false;
+            }
+            mCallback->onFilterEvent(mFilterEvents);
+        } else {
+            ALOGD("[Filter] filter callback is not configured yet.");
+            mFilterThreadRunning = false;
+            return;
+        }
+
+        mFilterEvents.resize(0);
+        mFilterStatus = DemuxFilterStatus::DATA_READY;
+        if (mCallback != nullptr) {
+            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++) {
+            if (!mFilterThreadRunning) {
+                break;
+            }
+            while (mFilterThreadRunning && mIsUsingFMQ) {
+                ::android::status_t status = mFilterEventsFlag->wait(
+                        static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED), &efState,
+                        WAIT_TIMEOUT, true /* retry on spurious wake */);
+                if (status != ::android::OK) {
+                    ALOGD("[Filter] wait for data consumed");
+                    continue;
+                }
+                break;
+            }
+
+            maySendFilterStatusCallback();
+
+            while (mFilterThreadRunning) {
+                std::lock_guard<std::mutex> lock(mFilterEventsLock);
+                if (mFilterEvents.size() == 0) {
+                    continue;
+                }
+                // After successfully write, send a callback and wait for the read to be done
+                if (mCallback != nullptr) {
+                    mCallback->onFilterEvent(mFilterEvents);
+                }
+                mFilterEvents.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;
+            }
+        }
+        break;
+    }
+    ALOGD("[Filter] filter thread ended.");
+}
+
+void Filter::freeSharedAvHandle() {
+    if (!mIsMediaFilter) {
+        return;
+    }
+    native_handle_close(mSharedAvMemHandle);
+    native_handle_delete(mSharedAvMemHandle);
+    mSharedAvMemHandle = nullptr;
+}
+
+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) {
+        if (mCallback != nullptr) {
+            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<int8_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<int8_t> data) {
+    std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
+    mRecordFilterOutput.insert(mRecordFilterOutput.end(), data.begin(), data.end());
+}
+
+::ndk::ScopedAStatus Filter::startFilterHandler() {
+    std::lock_guard<std::mutex> lock(mFilterOutputLock);
+    switch (mType.mainType) {
+        case DemuxFilterMainType::TS:
+            switch (mType.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::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 ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::startSectionFilterHandler() {
+    if (mFilterOutput.empty()) {
+        return ::ndk::ScopedAStatus::ok();
+    }
+    if (!writeSectionsAndCreateEvent(mFilterOutput)) {
+        ALOGD("[Filter] filter %" PRIu64 " fails to write into FMQ. Ending thread", mFilterId);
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+    }
+
+    mFilterOutput.clear();
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::startPesFilterHandler() {
+    std::lock_guard<std::mutex> lock(mFilterEventsLock);
+    if (mFilterOutput.empty()) {
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    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<int8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
+        vector<int8_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 ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+        }
+        maySendFilterStatusCallback();
+        DemuxFilterPesEvent pesEvent;
+        pesEvent = {
+                // temp dump meta data
+                .streamId = static_cast<char16_t>(mPesOutput[3]),
+                .dataLength = static_cast<char16_t>(mPesOutput.size()),
+        };
+        if (DEBUG_FILTER) {
+            ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
+        }
+
+        int size = mFilterEvents.size();
+        mFilterEvents.resize(size + 1);
+        mFilterEvents[size].set<DemuxFilterEvent::Tag::pes>(pesEvent);
+        mPesOutput.clear();
+    }
+
+    mFilterOutput.clear();
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::startTsFilterHandler() {
+    // TODO handle starting TS filter
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::startMediaFilterHandler() {
+    std::lock_guard<std::mutex> lock(mFilterEventsLock);
+    if (mFilterOutput.empty()) {
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    ::ndk::ScopedAStatus result;
+    if (mPts) {
+        result = createMediaFilterEventWithIon(mFilterOutput);
+        if (result.isOk()) {
+            mFilterOutput.clear();
+        }
+        return result;
+    }
+
+    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<int8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
+        vector<int8_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;
+        }
+
+        result = createMediaFilterEventWithIon(mPesOutput);
+        if (result.isOk()) {
+            return result;
+        }
+    }
+
+    mFilterOutput.clear();
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::createMediaFilterEventWithIon(vector<int8_t>& output) {
+    if (mUsingSharedAvMem) {
+        if (mSharedAvMemHandle == nullptr) {
+            return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+        }
+        return createShareMemMediaEvents(output);
+    }
+
+    return createIndependentMediaEvents(output);
+}
+
+::ndk::ScopedAStatus Filter::startRecordFilterHandler() {
+    std::lock_guard<std::mutex> lock(mRecordFilterOutputLock);
+    if (mRecordFilterOutput.empty()) {
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    if (mDvr == nullptr || !mDvr->writeRecordFMQ(mRecordFilterOutput)) {
+        ALOGD("[Filter] dvr fails to write into record FMQ.");
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+    }
+
+    DemuxFilterTsRecordEvent recordEvent;
+    recordEvent = {
+            .byteNumber = static_cast<int64_t>(mRecordFilterOutput.size()),
+            .pts = (mPts == 0) ? static_cast<int64_t>(time(NULL)) * 900000 : mPts,
+            .firstMbInSlice = 0,  // random address
+    };
+
+    int size;
+    size = mFilterEvents.size();
+    mFilterEvents.resize(size + 1);
+    mFilterEvents[size].set<DemuxFilterEvent::Tag::tsRecord>(recordEvent);
+
+    mRecordFilterOutput.clear();
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::startPcrFilterHandler() {
+    // TODO handle starting PCR filter
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::startTemiFilterHandler() {
+    // TODO handle starting TEMI filter
+    return ::ndk::ScopedAStatus::ok();
+}
+
+bool Filter::writeSectionsAndCreateEvent(vector<int8_t>& data) {
+    // TODO check how many sections has been read
+    ALOGD("[Filter] section handler");
+    std::lock_guard<std::mutex> lock(mFilterEventsLock);
+    if (!writeDataToFilterMQ(data)) {
+        return false;
+    }
+    int size = mFilterEvents.size();
+    mFilterEvents.resize(size + 1);
+    DemuxFilterSectionEvent secEvent;
+    secEvent = {
+            // temp dump meta data
+            .tableId = 0,
+            .version = 1,
+            .sectionNum = 1,
+            .dataLength = static_cast<char16_t>(data.size()),
+    };
+    mFilterEvents[size].set<DemuxFilterEvent::Tag::section>(secEvent);
+    return true;
+}
+
+bool Filter::writeDataToFilterMQ(const std::vector<int8_t>& data) {
+    std::lock_guard<std::mutex> lock(mWriteLock);
+    if (mFilterMQ->write(data.data(), data.size())) {
+        return true;
+    }
+    return false;
+}
+
+void Filter::attachFilterToRecord(const std::shared_ptr<Dvr> dvr) {
+    mDvr = dvr;
+}
+
+void Filter::detachFilterFromRecord() {
+    mDvr = nullptr;
+}
+
+int Filter::createAvIonFd(int size) {
+    // Create an DMA-BUF fd and allocate an av fd mapped to a buffer to it.
+    auto buffer_allocator = std::make_unique<BufferAllocator>();
+    if (!buffer_allocator) {
+        ALOGE("[Filter] Unable to create BufferAllocator object");
+        return -1;
+    }
+    int av_fd = -1;
+    av_fd = buffer_allocator->Alloc("system-uncached", size);
+    if (av_fd < 0) {
+        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) {
+    native_handle_t* nativeHandle;
+    if (fd < 0) {
+        nativeHandle = native_handle_create(/*numFd*/ 0, 0);
+    } else {
+        // Create a native handle to pass the av fd via the callback event.
+        nativeHandle = native_handle_create(/*numFd*/ 1, 0);
+    }
+    if (nativeHandle == NULL) {
+        ALOGE("[Filter] Failed to create native_handle %d", errno);
+        return NULL;
+    }
+    if (nativeHandle->numFds > 0) {
+        nativeHandle->data[0] = dup(fd);
+    }
+    return nativeHandle;
+}
+
+::ndk::ScopedAStatus Filter::createIndependentMediaEvents(vector<int8_t>& output) {
+    int av_fd = createAvIonFd(output.size());
+    if (av_fd == -1) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+    }
+    // copy the filtered data to the buffer
+    uint8_t* avBuffer = getIonBuffer(av_fd, output.size());
+    if (avBuffer == NULL) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+    }
+    memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t));
+
+    native_handle_t* nativeHandle = createNativeHandle(av_fd);
+    if (nativeHandle == NULL) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+    }
+
+    // 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
+    int size = mFilterEvents.size();
+    mFilterEvents.resize(size + 1);
+
+    mFilterEvents[size] = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
+    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().avMemory =
+            ::android::dupToAidl(nativeHandle);
+    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().dataLength =
+            static_cast<int32_t>(output.size());
+    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().avDataId = static_cast<int64_t>(dataId);
+    if (mPts) {
+        mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().pts = mPts;
+        mPts = 0;
+    }
+
+    // Clear and log
+    native_handle_close(nativeHandle);
+    native_handle_delete(nativeHandle);
+    output.clear();
+    mAvBufferCopyCount = 0;
+    if (DEBUG_FILTER) {
+        ALOGD("[Filter] av data length %d", static_cast<int32_t>(output.size()));
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Filter::createShareMemMediaEvents(vector<int8_t>& output) {
+    // copy the filtered data to the shared buffer
+    uint8_t* sharedAvBuffer =
+            getIonBuffer(mSharedAvMemHandle->data[0], output.size() + mSharedAvMemOffset);
+    if (sharedAvBuffer == NULL) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+    }
+    memcpy(sharedAvBuffer + mSharedAvMemOffset, output.data(), output.size() * sizeof(uint8_t));
+
+    // Create a memory handle with numFds == 0
+    native_handle_t* nativeHandle = createNativeHandle(-1);
+    if (nativeHandle == NULL) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_UNKNOWN_ERROR);
+    }
+
+    // Create mediaEvent and send callback
+    int size = mFilterEvents.size();
+    mFilterEvents.resize(size + 1);
+    mFilterEvents[size] = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
+    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().avMemory =
+            ::android::dupToAidl(nativeHandle);
+    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().offset =
+            static_cast<int32_t>(mSharedAvMemOffset);
+    mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().dataLength =
+            static_cast<int32_t>(output.size());
+    if (mPts) {
+        mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().pts = mPts;
+        mPts = 0;
+    }
+    mSharedAvMemOffset += output.size();
+
+    // Clear and log
+    native_handle_close(nativeHandle);
+    native_handle_delete(nativeHandle);
+    output.clear();
+    if (DEBUG_FILTER) {
+        ALOGD("[Filter] shared av data length %d", static_cast<int32_t>(output.size()));
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+bool Filter::sameFile(int fd1, int fd2) {
+    struct stat stat1, stat2;
+    if (fstat(fd1, &stat1) < 0 || fstat(fd2, &stat2) < 0) {
+        return false;
+    }
+    return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
+}
+
+void Filter::createMediaEvent(vector<DemuxFilterEvent>& events) {
+    AudioExtraMetaData audio;
+    events.resize(1);
+
+    audio.adFade = 1;
+    audio.adPan = 2;
+    audio.versionTextTag = 3;
+    audio.adGainCenter = 4;
+    audio.adGainFront = 5;
+    audio.adGainSurround = 6;
+
+    events[0] = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
+    events[0].get<DemuxFilterEvent::Tag::media>().streamId = 1;
+    events[0].get<DemuxFilterEvent::Tag::media>().isPtsPresent = true;
+    events[0].get<DemuxFilterEvent::Tag::media>().dataLength = 3;
+    events[0].get<DemuxFilterEvent::Tag::media>().offset = 4;
+    events[0].get<DemuxFilterEvent::Tag::media>().isSecureMemory = true;
+    events[0].get<DemuxFilterEvent::Tag::media>().mpuSequenceNumber = 6;
+    events[0].get<DemuxFilterEvent::Tag::media>().isPesPrivateData = true;
+    events[0]
+            .get<DemuxFilterEvent::Tag::media>()
+            .extraMetaData.set<DemuxFilterMediaEventExtraMetaData::Tag::audio>(audio);
+
+    int av_fd = createAvIonFd(BUFFER_SIZE_16M);
+    if (av_fd == -1) {
+        return;
+    }
+
+    native_handle_t* nativeHandle = createNativeHandle(av_fd);
+    if (nativeHandle == nullptr) {
+        ::close(av_fd);
+        ALOGE("[Filter] Failed to create native_handle %d", errno);
+        return;
+    }
+
+    // Create a dataId and add a <dataId, av_fd> pair into the dataId2Avfd map
+    uint64_t dataId = mLastUsedDataId++ /*createdUID*/;
+    mDataId2Avfd[dataId] = dup(av_fd);
+
+    events[0].get<DemuxFilterEvent::Tag::media>().avDataId = static_cast<int64_t>(dataId);
+    events[0].get<DemuxFilterEvent::Tag::media>().avMemory = ::android::dupToAidl(nativeHandle);
+
+    native_handle_close(nativeHandle);
+    native_handle_delete(nativeHandle);
+}
+
+void Filter::createTsRecordEvent(vector<DemuxFilterEvent>& events) {
+    events.resize(2);
+
+    DemuxPid pid;
+    DemuxFilterScIndexMask mask;
+    DemuxFilterTsRecordEvent tsRecord1;
+    pid.set<DemuxPid::Tag::tPid>(1);
+    mask.set<DemuxFilterScIndexMask::Tag::scIndex>(1);
+    tsRecord1.pid = pid;
+    tsRecord1.tsIndexMask = 1;
+    tsRecord1.scIndexMask = mask;
+    tsRecord1.byteNumber = 2;
+
+    DemuxFilterTsRecordEvent tsRecord2;
+    tsRecord2.pts = 1;
+    tsRecord2.firstMbInSlice = 2;  // random address
+
+    events[0].set<DemuxFilterEvent::Tag::tsRecord>(tsRecord1);
+    events[1].set<DemuxFilterEvent::Tag::tsRecord>(tsRecord2);
+}
+
+void Filter::createMmtpRecordEvent(vector<DemuxFilterEvent>& events) {
+    events.resize(2);
+
+    DemuxFilterMmtpRecordEvent mmtpRecord1;
+    mmtpRecord1.scHevcIndexMask = 1;
+    mmtpRecord1.byteNumber = 2;
+
+    DemuxFilterMmtpRecordEvent mmtpRecord2;
+    mmtpRecord2.pts = 1;
+    mmtpRecord2.mpuSequenceNumber = 2;
+    mmtpRecord2.firstMbInSlice = 3;
+    mmtpRecord2.tsIndexMask = 4;
+
+    events[0].set<DemuxFilterEvent::Tag::mmtpRecord>(mmtpRecord1);
+    events[1].set<DemuxFilterEvent::Tag::mmtpRecord>(mmtpRecord2);
+}
+
+void Filter::createSectionEvent(vector<DemuxFilterEvent>& events) {
+    events.resize(1);
+
+    DemuxFilterSectionEvent section;
+    section.tableId = 1;
+    section.version = 2;
+    section.sectionNum = 3;
+    section.dataLength = 0;
+
+    events[0].set<DemuxFilterEvent::Tag::section>(section);
+}
+
+void Filter::createPesEvent(vector<DemuxFilterEvent>& events) {
+    events.resize(1);
+
+    DemuxFilterPesEvent pes;
+    pes.streamId = 1;
+    pes.dataLength = 1;
+    pes.mpuSequenceNumber = 2;
+
+    events[0].set<DemuxFilterEvent::Tag::pes>(pes);
+}
+
+void Filter::createDownloadEvent(vector<DemuxFilterEvent>& events) {
+    events.resize(1);
+
+    DemuxFilterDownloadEvent download;
+    download.itemId = 1;
+    download.mpuSequenceNumber = 2;
+    download.itemFragmentIndex = 3;
+    download.lastItemFragmentIndex = 4;
+    download.dataLength = 0;
+
+    events[0].set<DemuxFilterEvent::Tag::download>(download);
+}
+
+void Filter::createIpPayloadEvent(vector<DemuxFilterEvent>& events) {
+    events.resize(1);
+
+    DemuxFilterIpPayloadEvent ipPayload;
+    ipPayload.dataLength = 0;
+
+    events[0].set<DemuxFilterEvent::Tag::ipPayload>(ipPayload);
+}
+
+void Filter::createTemiEvent(vector<DemuxFilterEvent>& events) {
+    events.resize(1);
+
+    DemuxFilterTemiEvent temi;
+    temi.pts = 1;
+    temi.descrTag = 2;
+    temi.descrData = {3};
+
+    events[0].set<DemuxFilterEvent::Tag::temi>(temi);
+}
+
+void Filter::createMonitorEvent(vector<DemuxFilterEvent>& events) {
+    events.resize(1);
+
+    DemuxFilterMonitorEvent monitor;
+    monitor.set<DemuxFilterMonitorEvent::Tag::scramblingStatus>(ScramblingStatus::SCRAMBLED);
+    events[0].set<DemuxFilterEvent::Tag::monitorEvent>(monitor);
+}
+
+void Filter::createRestartEvent(vector<DemuxFilterEvent>& events) {
+    events.resize(1);
+
+    events[0].set<DemuxFilterEvent::Tag::startId>(1);
+}
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
new file mode 100644
index 0000000..7a037e6
--- /dev/null
+++ b/tv/tuner/aidl/default/Filter.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnFilter.h>
+#include <aidl/android/hardware/tv/tuner/Constant.h>
+
+#include <fmq/AidlMessageQueue.h>
+#include <inttypes.h>
+#include <ion/ion.h>
+#include <math.h>
+#include <sys/stat.h>
+#include <set>
+#include "Demux.h"
+#include "Dvr.h"
+#include "Frontend.h"
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+using ::aidl::android::hardware::common::NativeHandle;
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::hardware::EventFlag;
+
+using FilterMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+const uint32_t BUFFER_SIZE_16M = 0x1000000;
+
+class Demux;
+class Dvr;
+
+class Filter : public BnFilter {
+  public:
+    Filter();
+
+    Filter(DemuxFilterType type, int64_t filterId, uint32_t bufferSize,
+           const std::shared_ptr<IFilterCallback>& cb, std::shared_ptr<Demux> demux);
+
+    ~Filter();
+
+    ::ndk::ScopedAStatus getQueueDesc(
+            MQDescriptor<int8_t, SynchronizedReadWrite>* out_queue) override;
+    ::ndk::ScopedAStatus close() override;
+    ::ndk::ScopedAStatus configure(const DemuxFilterSettings& in_settings) override;
+    ::ndk::ScopedAStatus configureAvStreamType(const AvStreamType& in_avStreamType) override;
+    ::ndk::ScopedAStatus configureIpCid(int32_t in_ipCid) override;
+    ::ndk::ScopedAStatus configureMonitorEvent(int32_t in_monitorEventTypes) override;
+    ::ndk::ScopedAStatus start() override;
+    ::ndk::ScopedAStatus stop() override;
+    ::ndk::ScopedAStatus flush() override;
+    ::ndk::ScopedAStatus getAvSharedHandle(NativeHandle* out_avMemory,
+                                           int64_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getId64Bit(int64_t* _aidl_return) override;
+    ::ndk::ScopedAStatus releaseAvHandle(const NativeHandle& in_avMemory,
+                                         int64_t in_avDataId) override;
+    ::ndk::ScopedAStatus setDataSource(const std::shared_ptr<IFilter>& in_filter) 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<int8_t> data);
+    void updateRecordOutput(vector<int8_t> data);
+    void updatePts(uint64_t pts);
+    ::ndk::ScopedAStatus startFilterHandler();
+    ::ndk::ScopedAStatus startRecordFilterHandler();
+    void attachFilterToRecord(const std::shared_ptr<Dvr> dvr);
+    void detachFilterFromRecord();
+    void freeSharedAvHandle();
+    bool isMediaFilter() { return mIsMediaFilter; };
+    bool isPcrFilter() { return mIsPcrFilter; };
+    bool isRecordFilter() { return mIsRecordFilter; };
+
+  private:
+    // Tuner service
+    std::shared_ptr<Demux> mDemux;
+    // Dvr reference once the filter is attached to any
+    std::shared_ptr<Dvr> mDvr = nullptr;
+    /**
+     * Filter callbacks used on filter events or FMQ status
+     */
+    std::shared_ptr<IFilterCallback> mCallback = nullptr;
+
+    int64_t mFilterId;
+    int32_t mCid = static_cast<int32_t>(Constant::INVALID_IP_FILTER_CONTEXT_ID);
+    uint32_t mBufferSize;
+    DemuxFilterType mType;
+    bool mIsMediaFilter = false;
+    bool mIsPcrFilter = false;
+    bool mIsRecordFilter = false;
+    DemuxFilterSettings mFilterSettings;
+
+    uint16_t mTpid;
+    std::shared_ptr<IFilter> mDataSource;
+    bool mIsDataSourceDemux = true;
+    vector<int8_t> mFilterOutput;
+    vector<int8_t> mRecordFilterOutput;
+    int64_t mPts = 0;
+    unique_ptr<FilterMQ> mFilterMQ;
+    bool mIsUsingFMQ = false;
+    EventFlag* mFilterEventsFlag;
+    vector<DemuxFilterEvent> mFilterEvents;
+
+    // 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.
+     */
+    ::ndk::ScopedAStatus startSectionFilterHandler();
+    ::ndk::ScopedAStatus startPesFilterHandler();
+    ::ndk::ScopedAStatus startTsFilterHandler();
+    ::ndk::ScopedAStatus startMediaFilterHandler();
+    ::ndk::ScopedAStatus startPcrFilterHandler();
+    ::ndk::ScopedAStatus startTemiFilterHandler();
+    ::ndk::ScopedAStatus startFilterLoop();
+
+    void deleteEventFlag();
+    bool writeDataToFilterMQ(const std::vector<int8_t>& data);
+    bool readDataFromMQ();
+    bool writeSectionsAndCreateEvent(vector<int8_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.
+     */
+    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);
+    ::ndk::ScopedAStatus createMediaFilterEventWithIon(vector<int8_t>& output);
+    ::ndk::ScopedAStatus createIndependentMediaEvents(vector<int8_t>& output);
+    ::ndk::ScopedAStatus createShareMemMediaEvents(vector<int8_t>& output);
+    bool sameFile(int fd1, int fd2);
+
+    void createMediaEvent(vector<DemuxFilterEvent>&);
+    void createTsRecordEvent(vector<DemuxFilterEvent>&);
+    void createMmtpRecordEvent(vector<DemuxFilterEvent>&);
+    void createSectionEvent(vector<DemuxFilterEvent>&);
+    void createPesEvent(vector<DemuxFilterEvent>&);
+    void createDownloadEvent(vector<DemuxFilterEvent>&);
+    void createIpPayloadEvent(vector<DemuxFilterEvent>&);
+    void createTemiEvent(vector<DemuxFilterEvent>&);
+    void createMonitorEvent(vector<DemuxFilterEvent>&);
+    void createRestartEvent(vector<DemuxFilterEvent>&);
+
+    /**
+     * 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 mFilterEventsLock;
+    /**
+     * 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<int8_t> mPesOutput;
+
+    // A map from data id to ion handle
+    std::map<uint64_t, int> mDataId2Avfd;
+    uint64_t mLastUsedDataId = 1;
+    int mAvBufferCopyCount = 0;
+
+    // Shared A/V memory handle
+    native_handle_t* mSharedAvMemHandle = nullptr;
+    bool mUsingSharedAvMem = false;
+    uint32_t mSharedAvMemOffset = 0;
+
+    uint32_t mAudioStreamType;
+    uint32_t mVideoStreamType;
+
+    // Scrambling status to be monitored
+    uint32_t mStatuses = 0;
+
+    bool mConfigured = false;
+    int mStartId = 0;
+    uint8_t mScramblingStatusMonitored = 0;
+    uint8_t mIpCidMonitored = 0;
+};
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
new file mode 100644
index 0000000..2be13d3
--- /dev/null
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -0,0 +1,721 @@
+/*
+ * Copyright 2021 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
+#define LOG_TAG "android.hardware.tv.tuner-service.example-Frontend"
+
+#include "Frontend.h"
+#include <utils/Log.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+Frontend::Frontend(FrontendType type, int32_t id, std::shared_ptr<Tuner> tuner) {
+    mType = type;
+    mId = id;
+    mTunerService = tuner;
+    // Init callback to nullptr
+    mCallback = nullptr;
+}
+
+Frontend::~Frontend() {}
+
+::ndk::ScopedAStatus Frontend::close() {
+    ALOGV("%s", __FUNCTION__);
+    // Reset callback
+    mCallback = nullptr;
+    mIsLocked = false;
+    mTunerService->removeFrontend(mId);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::setCallback(const std::shared_ptr<IFrontendCallback>& in_callback) {
+    ALOGV("%s", __FUNCTION__);
+    if (in_callback == nullptr) {
+        ALOGW("[   WARN   ] Set Frontend callback with nullptr");
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    mCallback = in_callback;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::tune(const FrontendSettings& /* in_settings */) {
+    ALOGV("%s", __FUNCTION__);
+    if (mCallback == nullptr) {
+        ALOGW("[   WARN   ] Frontend callback is not set when tune");
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    mTunerService->frontendStartTune(mId);
+    mCallback->onEvent(FrontendEventType::LOCKED);
+    mIsLocked = true;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::stopTune() {
+    ALOGV("%s", __FUNCTION__);
+
+    mTunerService->frontendStopTune(mId);
+    mIsLocked = false;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::scan(const FrontendSettings& in_settings, FrontendScanType in_type) {
+    ALOGV("%s", __FUNCTION__);
+    FrontendScanMessage msg;
+
+    if (mIsLocked) {
+        msg.set<FrontendScanMessage::Tag::isEnd>(true);
+        mCallback->onScanMessage(FrontendScanMessageType::END, msg);
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    int32_t frequency = 0;
+    switch (in_settings.getTag()) {
+        case FrontendSettings::Tag::analog:
+            frequency = in_settings.get<FrontendSettings::Tag::analog>().frequency;
+            break;
+        case FrontendSettings::Tag::atsc:
+            frequency = in_settings.get<FrontendSettings::Tag::atsc>().frequency;
+            break;
+        case FrontendSettings::Tag::atsc3:
+            frequency = in_settings.get<FrontendSettings::Tag::atsc3>().frequency;
+            break;
+        case FrontendSettings::Tag::dvbs:
+            frequency = in_settings.get<FrontendSettings::Tag::dvbs>().frequency;
+            break;
+        case FrontendSettings::Tag::dvbc:
+            frequency = in_settings.get<FrontendSettings::Tag::dvbc>().frequency;
+            break;
+        case FrontendSettings::Tag::dvbt:
+            frequency = in_settings.get<FrontendSettings::Tag::dvbt>().frequency;
+            break;
+        case FrontendSettings::Tag::isdbs:
+            frequency = in_settings.get<FrontendSettings::Tag::isdbs>().frequency;
+            break;
+        case FrontendSettings::Tag::isdbs3:
+            frequency = in_settings.get<FrontendSettings::Tag::isdbs3>().frequency;
+            break;
+        case FrontendSettings::Tag::isdbt:
+            frequency = in_settings.get<FrontendSettings::Tag::isdbt>().frequency;
+            break;
+        default:
+            break;
+    }
+
+    if (in_type == FrontendScanType::SCAN_BLIND) {
+        frequency += 100;
+    }
+
+    {
+        FrontendScanMessage msg;
+        vector<int32_t> frequencies = {frequency};
+        msg.set<FrontendScanMessage::Tag::frequencies>(frequencies);
+        mCallback->onScanMessage(FrontendScanMessageType::FREQUENCY, msg);
+    }
+
+    {
+        FrontendScanMessage msg;
+        msg.set<FrontendScanMessage::Tag::progressPercent>(20);
+        mCallback->onScanMessage(FrontendScanMessageType::PROGRESS_PERCENT, msg);
+    }
+
+    {
+        FrontendScanMessage msg;
+        vector<int32_t> symbolRates = {30};
+        msg.set<FrontendScanMessage::Tag::symbolRates>(symbolRates);
+        mCallback->onScanMessage(FrontendScanMessageType::SYMBOL_RATE, msg);
+    }
+
+    if (mType == FrontendType::DVBT) {
+        FrontendScanMessage msg;
+        msg.set<FrontendScanMessage::Tag::hierarchy>(FrontendDvbtHierarchy::HIERARCHY_NON_NATIVE);
+        mCallback->onScanMessage(FrontendScanMessageType::HIERARCHY, msg);
+    }
+
+    if (mType == FrontendType::ANALOG) {
+        FrontendScanMessage msg;
+        msg.set<FrontendScanMessage::Tag::analogType>(FrontendAnalogType::PAL);
+        mCallback->onScanMessage(FrontendScanMessageType::ANALOG_TYPE, msg);
+    }
+
+    {
+        FrontendScanMessage msg;
+        vector<uint8_t> plpIds = {2};
+        msg.set<FrontendScanMessage::Tag::plpIds>(plpIds);
+        mCallback->onScanMessage(FrontendScanMessageType::PLP_IDS, msg);
+    }
+
+    {
+        FrontendScanMessage msg;
+        vector<uint8_t> groupIds = {3};
+        msg.set<FrontendScanMessage::Tag::groupIds>(groupIds);
+        mCallback->onScanMessage(FrontendScanMessageType::GROUP_IDS, msg);
+    }
+
+    {
+        FrontendScanMessage msg;
+        vector<char16_t> inputStreamIds = {1};
+        msg.set<FrontendScanMessage::Tag::inputStreamIds>(inputStreamIds);
+        mCallback->onScanMessage(FrontendScanMessageType::INPUT_STREAM_IDS, msg);
+    }
+
+    switch (mType) {
+        case FrontendType::DVBT: {
+            FrontendScanMessage msg;
+            FrontendScanMessageStandard std;
+            std.set<FrontendScanMessageStandard::Tag::tStd>(FrontendDvbtStandard::AUTO);
+            msg.set<FrontendScanMessage::Tag::std>(std);
+            mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
+            break;
+        }
+        case FrontendType::DVBS: {
+            FrontendScanMessage msg;
+            FrontendScanMessageStandard std;
+            std.set<FrontendScanMessageStandard::Tag::sStd>(FrontendDvbsStandard::AUTO);
+            msg.set<FrontendScanMessage::Tag::std>(std);
+            mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
+            break;
+        }
+        case FrontendType::ANALOG: {
+            FrontendScanMessage msg;
+            FrontendScanMessageStandard std;
+            std.set<FrontendScanMessageStandard::Tag::sifStd>(FrontendAnalogSifStandard::AUTO);
+            msg.set<FrontendScanMessage::Tag::std>(std);
+            mCallback->onScanMessage(FrontendScanMessageType::STANDARD, msg);
+            break;
+        }
+        default:
+            break;
+    }
+
+    {
+        FrontendScanMessage msg;
+        FrontendScanAtsc3PlpInfo info;
+        info.plpId = 1;
+        info.bLlsFlag = false;
+        vector<FrontendScanAtsc3PlpInfo> atsc3PlpInfos = {info};
+        msg.set<FrontendScanMessage::Tag::atsc3PlpInfos>(atsc3PlpInfos);
+        mCallback->onScanMessage(FrontendScanMessageType::ATSC3_PLP_INFO, msg);
+    }
+
+    {
+        FrontendScanMessage msg;
+        FrontendModulation modulation;
+        modulation.set<FrontendModulation::Tag::dvbc>(FrontendDvbcModulation::MOD_16QAM);
+        msg.set<FrontendScanMessage::Tag::modulation>(modulation);
+        mCallback->onScanMessage(FrontendScanMessageType::MODULATION, msg);
+    }
+
+    {
+        FrontendScanMessage msg;
+        msg.set<FrontendScanMessage::Tag::isHighPriority>(true);
+        mCallback->onScanMessage(FrontendScanMessageType::HIGH_PRIORITY, msg);
+    }
+
+    {
+        FrontendScanMessage msg;
+        msg.set<FrontendScanMessage::Tag::isLocked>(true);
+        mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
+        mIsLocked = true;
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::stopScan() {
+    ALOGV("%s", __FUNCTION__);
+
+    mIsLocked = false;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::getStatus(const std::vector<FrontendStatusType>& in_statusTypes,
+                                         std::vector<FrontendStatus>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    for (int i = 0; i < in_statusTypes.size(); i++) {
+        FrontendStatusType type = in_statusTypes[i];
+        FrontendStatus status;
+        // assign randomly selected values for testing.
+        switch (type) {
+            case FrontendStatusType::DEMOD_LOCK: {
+                status.set<FrontendStatus::isDemodLocked>(true);
+                break;
+            }
+            case FrontendStatusType::SNR: {
+                status.set<FrontendStatus::snr>(221);
+                break;
+            }
+            case FrontendStatusType::BER: {
+                status.set<FrontendStatus::ber>(1);
+                break;
+            }
+            case FrontendStatusType::PER: {
+                status.set<FrontendStatus::per>(2);
+                break;
+            }
+            case FrontendStatusType::PRE_BER: {
+                status.set<FrontendStatus::preBer>(3);
+                break;
+            }
+            case FrontendStatusType::SIGNAL_QUALITY: {
+                status.set<FrontendStatus::signalQuality>(4);
+                break;
+            }
+            case FrontendStatusType::SIGNAL_STRENGTH: {
+                status.set<FrontendStatus::signalStrength>(5);
+                break;
+            }
+            case FrontendStatusType::SYMBOL_RATE: {
+                status.set<FrontendStatus::symbolRate>(6);
+                break;
+            }
+            case FrontendStatusType::FEC: {
+                status.set<FrontendStatus::innerFec>(FrontendInnerFec::FEC_2_9);  // value = 1 << 7
+                break;
+            }
+            case FrontendStatusType::MODULATION: {
+                switch (mType) {
+                    case FrontendType::ISDBS: {
+                        FrontendModulationStatus modulationStatus;
+                        modulationStatus.set<FrontendModulationStatus::Tag::isdbs>(
+                                FrontendIsdbsModulation::MOD_BPSK);  // value = 1 << 1
+                        status.set<FrontendStatus::modulationStatus>(modulationStatus);
+                        break;
+                    }
+                    case FrontendType::DVBC: {
+                        FrontendModulationStatus modulationStatus;
+                        modulationStatus.set<FrontendModulationStatus::Tag::dvbc>(
+                                FrontendDvbcModulation::MOD_16QAM);  // value = 1 << 1
+                        status.set<FrontendStatus::modulationStatus>(modulationStatus);
+                        break;
+                    }
+                    case FrontendType::DVBS: {
+                        FrontendModulationStatus modulationStatus;
+                        modulationStatus.set<FrontendModulationStatus::Tag::dvbs>(
+                                FrontendDvbsModulation::MOD_QPSK);  // value = 1 << 1
+                        status.set<FrontendStatus::modulationStatus>(modulationStatus);
+                        break;
+                    }
+                    case FrontendType::ISDBS3: {
+                        FrontendModulationStatus modulationStatus;
+                        modulationStatus.set<FrontendModulationStatus::Tag::isdbs3>(
+                                FrontendIsdbs3Modulation::MOD_BPSK);  // value = 1 << 1
+                        status.set<FrontendStatus::modulationStatus>(modulationStatus);
+                        break;
+                    }
+                    case FrontendType::ISDBT: {
+                        FrontendModulationStatus modulationStatus;
+                        modulationStatus.set<FrontendModulationStatus::Tag::isdbt>(
+                                FrontendIsdbtModulation::MOD_DQPSK);  // value = 1 << 1
+                        status.set<FrontendStatus::modulationStatus>(modulationStatus);
+                        break;
+                    }
+                    default:
+                        break;
+                }
+                break;
+            }
+            case FrontendStatusType::SPECTRAL: {
+                status.set<FrontendStatus::inversion>(FrontendSpectralInversion::NORMAL);
+                break;
+            }
+            case FrontendStatusType::LNB_VOLTAGE: {
+                status.set<FrontendStatus::lnbVoltage>(LnbVoltage::VOLTAGE_5V);
+                break;
+            }
+            case FrontendStatusType::PLP_ID: {
+                status.set<FrontendStatus::plpId>(101);  // type uint8_t
+                break;
+            }
+            case FrontendStatusType::EWBS: {
+                status.set<FrontendStatus::isEWBS>(false);
+                break;
+            }
+            case FrontendStatusType::AGC: {
+                status.set<FrontendStatus::agc>(7);
+                break;
+            }
+            case FrontendStatusType::LNA: {
+                status.set<FrontendStatus::isLnaOn>(false);
+                break;
+            }
+            case FrontendStatusType::LAYER_ERROR: {
+                vector<bool> v = {false, true, true};
+                status.set<FrontendStatus::isLayerError>(v);
+                break;
+            }
+            case FrontendStatusType::MER: {
+                status.set<FrontendStatus::mer>(8);
+                break;
+            }
+            case FrontendStatusType::FREQ_OFFSET: {
+                status.set<FrontendStatus::freqOffset>(9);
+                break;
+            }
+            case FrontendStatusType::HIERARCHY: {
+                status.set<FrontendStatus::hierarchy>(FrontendDvbtHierarchy::HIERARCHY_1_NATIVE);
+                break;
+            }
+            case FrontendStatusType::RF_LOCK: {
+                status.set<FrontendStatus::isRfLocked>(false);
+                break;
+            }
+            case FrontendStatusType::ATSC3_PLP_INFO: {
+                FrontendStatusAtsc3PlpInfo info1;
+                info1.plpId = 3;
+                info1.isLocked = false;
+                info1.uec = 313;
+                FrontendStatusAtsc3PlpInfo info2;
+                info2.plpId = 5;
+                info2.isLocked = true;
+                info2.uec = 515;
+                vector<FrontendStatusAtsc3PlpInfo> infos = {info1, info2};
+                status.set<FrontendStatus::plpInfo>(infos);
+                break;
+            }
+            case FrontendStatusType::MODULATIONS: {
+                FrontendModulation modulation;
+                vector<FrontendModulation> modulations;
+                switch (mType) {
+                    case FrontendType::ISDBS: {
+                        modulation.set<FrontendModulation::Tag::isdbs>(
+                                FrontendIsdbsModulation::MOD_BPSK);  // value = 1 << 1
+                        modulations.push_back(modulation);
+                        status.set<FrontendStatus::modulations>(modulations);
+                        break;
+                    }
+                    case FrontendType::DVBC: {
+                        modulation.set<FrontendModulation::Tag::dvbc>(
+                                FrontendDvbcModulation::MOD_16QAM);  // value = 1 << 1
+                        modulations.push_back(modulation);
+                        status.set<FrontendStatus::modulations>(modulations);
+                        break;
+                    }
+                    case FrontendType::DVBS: {
+                        modulation.set<FrontendModulation::Tag::dvbs>(
+                                FrontendDvbsModulation::MOD_QPSK);  // value = 1 << 1
+                        modulations.push_back(modulation);
+                        status.set<FrontendStatus::modulations>(modulations);
+                        break;
+                    }
+                    case FrontendType::DVBT: {
+                        modulation.set<FrontendModulation::Tag::dvbt>(
+                                FrontendDvbtConstellation::CONSTELLATION_16QAM_R);  // value = 1 <<
+                                                                                    // 16
+                        modulations.push_back(modulation);
+                        status.set<FrontendStatus::modulations>(modulations);
+                        break;
+                    }
+                    case FrontendType::ISDBS3: {
+                        modulation.set<FrontendModulation::Tag::isdbs3>(
+                                FrontendIsdbs3Modulation::MOD_BPSK);  //  value = 1 << 1
+                        modulations.push_back(modulation);
+                        status.set<FrontendStatus::modulations>(modulations);
+                        break;
+                    }
+                    case FrontendType::ISDBT: {
+                        modulation.set<FrontendModulation::Tag::isdbt>(
+                                FrontendIsdbtModulation::MOD_DQPSK);  // value = 1 << 1
+                        modulations.push_back(modulation);
+                        status.set<FrontendStatus::modulations>(modulations);
+                        break;
+                    }
+                    case FrontendType::ATSC: {
+                        modulation.set<FrontendModulation::Tag::atsc>(
+                                FrontendAtscModulation::MOD_8VSB);  // value = 1 << 2
+                        modulations.push_back(modulation);
+                        status.set<FrontendStatus::modulations>(modulations);
+                        break;
+                    }
+                    case FrontendType::ATSC3: {
+                        modulation.set<FrontendModulation::Tag::atsc3>(
+                                FrontendAtsc3Modulation::MOD_QPSK);  // value = 1 << 1
+                        modulations.push_back(modulation);
+                        status.set<FrontendStatus::modulations>(modulations);
+                        break;
+                    }
+                    case FrontendType::DTMB: {
+                        modulation.set<FrontendModulation::Tag::dtmb>(
+                                FrontendDtmbModulation::CONSTELLATION_4QAM);  // value = 1 << 1
+                        modulations.push_back(modulation);
+                        status.set<FrontendStatus::modulations>(modulations);
+                        break;
+                    }
+                    default:
+                        break;
+                }
+                break;
+            }
+            case FrontendStatusType::BERS: {
+                vector<int32_t> bers = {1};
+                status.set<FrontendStatus::bers>(bers);
+                break;
+            }
+            case FrontendStatusType::CODERATES: {
+                vector<FrontendInnerFec> rates;
+                rates.push_back(FrontendInnerFec::FEC_6_15);  // value = 1 << 39
+                status.set<FrontendStatus::codeRates>(rates);
+                break;
+            }
+            case FrontendStatusType::BANDWIDTH: {
+                FrontendBandwidth bandwidth;
+                switch (mType) {
+                    case FrontendType::DVBC: {
+                        bandwidth.set<FrontendBandwidth::Tag::dvbc>(
+                                FrontendDvbcBandwidth::BANDWIDTH_6MHZ);  // value = 1 << 1
+                        status.set<FrontendStatus::bandwidth>(bandwidth);
+                        break;
+                    }
+                    case FrontendType::DVBT: {
+                        bandwidth.set<FrontendBandwidth::Tag::dvbt>(
+                                FrontendDvbtBandwidth::BANDWIDTH_8MHZ);  // value = 1 << 1
+                        status.set<FrontendStatus::bandwidth>(bandwidth);
+                        break;
+                    }
+                    case FrontendType::ISDBT: {
+                        bandwidth.set<FrontendBandwidth::Tag::isdbt>(
+                                FrontendIsdbtBandwidth::BANDWIDTH_8MHZ);  // value = 1 << 1
+                        status.set<FrontendStatus::bandwidth>(bandwidth);
+                        break;
+                    }
+                    case FrontendType::ATSC3: {
+                        bandwidth.set<FrontendBandwidth::Tag::atsc3>(
+                                FrontendAtsc3Bandwidth::BANDWIDTH_6MHZ);  // value = 1 << 1
+                        status.set<FrontendStatus::bandwidth>(bandwidth);
+                        break;
+                    }
+                    case FrontendType::DTMB: {
+                        bandwidth.set<FrontendBandwidth::Tag::dtmb>(
+                                FrontendDtmbBandwidth::BANDWIDTH_8MHZ);  // value = 1 << 1
+                        status.set<FrontendStatus::bandwidth>(bandwidth);
+                        break;
+                    }
+                    default:
+                        break;
+                }
+                break;
+            }
+            case FrontendStatusType::GUARD_INTERVAL: {
+                FrontendGuardInterval interval;
+                switch (mType) {
+                    case FrontendType::DVBT: {
+                        interval.set<FrontendGuardInterval::Tag::dvbt>(
+                                FrontendDvbtGuardInterval::INTERVAL_1_32);  // value = 1 << 1
+                        status.set<FrontendStatus::interval>(interval);
+                        break;
+                    }
+                    case FrontendType::ISDBT: {
+                        interval.set<FrontendGuardInterval::Tag::isdbt>(
+                                FrontendDvbtGuardInterval::INTERVAL_1_32);  // value = 1 << 1
+                        status.set<FrontendStatus::interval>(interval);
+                        break;
+                    }
+                    case FrontendType::DTMB: {
+                        interval.set<FrontendGuardInterval::Tag::dtmb>(
+                                FrontendDtmbGuardInterval::PN_420_VARIOUS);  // value = 1 << 1
+                        status.set<FrontendStatus::interval>(interval);
+                        break;
+                    }
+                    default:
+                        break;
+                }
+                break;
+            }
+            case FrontendStatusType::TRANSMISSION_MODE: {
+                FrontendTransmissionMode transMode;
+                switch (mType) {
+                    case FrontendType::DVBT: {
+                        transMode.set<FrontendTransmissionMode::Tag::dvbt>(
+                                FrontendDvbtTransmissionMode::MODE_16K_E);  // value = 1 << 8
+                        status.set<FrontendStatus::transmissionMode>(transMode);
+                        break;
+                    }
+                    case FrontendType::ISDBT: {
+                        transMode.set<FrontendTransmissionMode::Tag::isdbt>(
+                                FrontendIsdbtMode::MODE_1);  // value = 1 << 1
+                        status.set<FrontendStatus::transmissionMode>(transMode);
+                        break;
+                    }
+                    case FrontendType::DTMB: {
+                        transMode.set<FrontendTransmissionMode::Tag::dtmb>(
+                                FrontendDtmbTransmissionMode::C1);  // value = 1 << 1
+                        status.set<FrontendStatus::transmissionMode>(transMode);
+                        break;
+                    }
+                    default:
+                        break;
+                }
+                break;
+            }
+            case FrontendStatusType::UEC: {
+                status.set<FrontendStatus::uec>(4);
+                break;
+            }
+            case FrontendStatusType::T2_SYSTEM_ID: {
+                status.set<FrontendStatus::systemId>(5);
+                break;
+            }
+            case FrontendStatusType::INTERLEAVINGS: {
+                FrontendInterleaveMode interleave;
+                vector<FrontendInterleaveMode> interleaves;
+                switch (mType) {
+                    case FrontendType::DVBC: {
+                        // value = 1 << 1
+                        interleave.set<FrontendInterleaveMode::Tag::dvbc>(
+                                FrontendCableTimeInterleaveMode::INTERLEAVING_128_1_0);
+                        interleaves.push_back(interleave);
+                        status.set<FrontendStatus::interleaving>(interleaves);
+                        break;
+                    }
+                    case FrontendType::ATSC3: {
+                        interleave.set<FrontendInterleaveMode::Tag::atsc3>(
+                                FrontendAtsc3TimeInterleaveMode::CTI);  // value = 1 << 1
+                        interleaves.push_back(interleave);
+                        status.set<FrontendStatus::interleaving>(interleaves);
+                        break;
+                    }
+                    case FrontendType::DTMB: {
+                        interleave.set<FrontendInterleaveMode::Tag::dtmb>(
+                                FrontendDtmbTimeInterleaveMode::TIMER_INT_240);  // value = 1 << 1
+                        interleaves.push_back(interleave);
+                        status.set<FrontendStatus::interleaving>(interleaves);
+                        break;
+                    }
+                    default:
+                        break;
+                }
+                break;
+            }
+            case FrontendStatusType::ISDBT_SEGMENTS: {
+                vector<uint8_t> segments = {2, 3};
+                status.set<FrontendStatus::isdbtSegment>(segments);
+                break;
+            }
+            case FrontendStatusType::TS_DATA_RATES: {
+                vector<int32_t> dataRates = {4, 5};
+                status.set<FrontendStatus::tsDataRate>(dataRates);
+                break;
+            }
+            case FrontendStatusType::ROLL_OFF: {
+                FrontendRollOff rollOff;
+                switch (mType) {
+                    case FrontendType::DVBS: {
+                        rollOff.set<FrontendRollOff::Tag::dvbs>(
+                                FrontendDvbsRolloff::ROLLOFF_0_35);  // value = 1
+                        status.set<FrontendStatus::rollOff>(rollOff);
+                        break;
+                    }
+                    case FrontendType::ISDBS: {
+                        rollOff.set<FrontendRollOff::Tag::isdbs>(
+                                FrontendIsdbsRolloff::ROLLOFF_0_35);  // value = 1
+                        status.set<FrontendStatus::rollOff>(rollOff);
+                        break;
+                    }
+                    case FrontendType::ISDBS3: {
+                        rollOff.set<FrontendRollOff::Tag::isdbs3>(
+                                FrontendIsdbs3Rolloff::ROLLOFF_0_03);  // value = 1
+                        status.set<FrontendStatus::rollOff>(rollOff);
+                        break;
+                    }
+                    default:
+                        break;
+                }
+                break;
+            }
+            case FrontendStatusType::IS_MISO: {
+                status.set<FrontendStatus::isMiso>(true);
+                break;
+            }
+            case FrontendStatusType::IS_LINEAR: {
+                status.set<FrontendStatus::isLinear>(true);
+                break;
+            }
+            case FrontendStatusType::IS_SHORT_FRAMES: {
+                status.set<FrontendStatus::isShortFrames>(true);
+                break;
+            }
+            default: {
+                continue;
+            }
+        }
+        _aidl_return->push_back(status);
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::setLna(bool /* in_bEnable */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::setLnb(int32_t /* in_lnbId */) {
+    ALOGV("%s", __FUNCTION__);
+    if (!supportsSatellite()) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::linkCiCam(int32_t in_ciCamId, int32_t* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    mCiCamId = in_ciCamId;
+    *_aidl_return = 0;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Frontend::unlinkCiCam(int32_t /* in_ciCamId */) {
+    ALOGV("%s", __FUNCTION__);
+
+    mCiCamId = -1;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+FrontendType Frontend::getFrontendType() {
+    return mType;
+}
+
+int32_t Frontend::getFrontendId() {
+    return mId;
+}
+
+bool Frontend::supportsSatellite() {
+    return mType == FrontendType::DVBS || mType == FrontendType::ISDBS ||
+           mType == FrontendType::ISDBS3;
+}
+
+bool Frontend::isLocked() {
+    return mIsLocked;
+}
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Frontend.h b/tv/tuner/aidl/default/Frontend.h
new file mode 100644
index 0000000..f89e74d
--- /dev/null
+++ b/tv/tuner/aidl/default/Frontend.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnFrontend.h>
+#include <fstream>
+#include <iostream>
+#include "Tuner.h"
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+class Tuner;
+
+class Frontend : public BnFrontend {
+  public:
+    Frontend(FrontendType type, int32_t id, std::shared_ptr<Tuner> tuner);
+
+    ::ndk::ScopedAStatus setCallback(
+            const std::shared_ptr<IFrontendCallback>& in_callback) override;
+    ::ndk::ScopedAStatus tune(const FrontendSettings& in_settings) override;
+    ::ndk::ScopedAStatus stopTune() override;
+    ::ndk::ScopedAStatus close() override;
+    ::ndk::ScopedAStatus scan(const FrontendSettings& in_settings,
+                              FrontendScanType in_type) override;
+    ::ndk::ScopedAStatus stopScan() override;
+    ::ndk::ScopedAStatus getStatus(const std::vector<FrontendStatusType>& in_statusTypes,
+                                   std::vector<FrontendStatus>* _aidl_return) override;
+    ::ndk::ScopedAStatus setLnb(int32_t in_lnbId) override;
+    ::ndk::ScopedAStatus setLna(bool in_bEnable) override;
+    ::ndk::ScopedAStatus linkCiCam(int32_t in_ciCamId, int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus unlinkCiCam(int32_t in_ciCamId) override;
+
+    FrontendType getFrontendType();
+    int32_t getFrontendId();
+    string getSourceFile();
+    bool isLocked();
+
+  private:
+    virtual ~Frontend();
+    bool supportsSatellite();
+    std::shared_ptr<IFrontendCallback> mCallback;
+    std::shared_ptr<Tuner> mTunerService;
+    FrontendType mType = FrontendType::UNDEFINED;
+    int32_t mId = 0;
+    bool mIsLocked = false;
+    int32_t mCiCamId;
+
+    std::ifstream mFrontendData;
+};
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Lnb.cpp b/tv/tuner/aidl/default/Lnb.cpp
new file mode 100644
index 0000000..35d2da6
--- /dev/null
+++ b/tv/tuner/aidl/default/Lnb.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2021 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
+#define LOG_TAG "android.hardware.tv.tuner-service.example-Lnb"
+
+#include "Lnb.h"
+#include <utils/Log.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+Lnb::Lnb() {}
+
+Lnb::Lnb(int id) {
+    mId = id;
+}
+
+Lnb::~Lnb() {}
+
+::ndk::ScopedAStatus Lnb::setCallback(const std::shared_ptr<ILnbCallback>& /* in_callback */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Lnb::setVoltage(LnbVoltage /* in_voltage */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Lnb::setTone(LnbTone /* in_tone */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Lnb::setSatellitePosition(LnbPosition /* in_position */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Lnb::sendDiseqcMessage(const std::vector<uint8_t>& /* in_diseqcMessage */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Lnb::close() {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+int Lnb::getId() {
+    return mId;
+}
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Lnb.h b/tv/tuner/aidl/default/Lnb.h
new file mode 100644
index 0000000..bfe3097
--- /dev/null
+++ b/tv/tuner/aidl/default/Lnb.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnLnb.h>
+#include <aidl/android/hardware/tv/tuner/ITuner.h>
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+class Lnb : public BnLnb {
+  public:
+    Lnb();
+    Lnb(int id);
+
+    ::ndk::ScopedAStatus setCallback(const std::shared_ptr<ILnbCallback>& in_callback) override;
+    ::ndk::ScopedAStatus setVoltage(LnbVoltage in_voltage) override;
+    ::ndk::ScopedAStatus setTone(LnbTone in_tone) override;
+    ::ndk::ScopedAStatus setSatellitePosition(LnbPosition in_position) override;
+    ::ndk::ScopedAStatus sendDiseqcMessage(const std::vector<uint8_t>& in_diseqcMessage) override;
+    ::ndk::ScopedAStatus close() override;
+
+    int getId();
+
+  private:
+    int mId;
+    virtual ~Lnb();
+};
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/OWNERS b/tv/tuner/aidl/default/OWNERS
new file mode 100644
index 0000000..bf2b609
--- /dev/null
+++ b/tv/tuner/aidl/default/OWNERS
@@ -0,0 +1,3 @@
+hgchen@google.com
+shubang@google.com
+quxiangfang@google.com
diff --git a/tv/tuner/aidl/default/TimeFilter.cpp b/tv/tuner/aidl/default/TimeFilter.cpp
new file mode 100644
index 0000000..4fd8d21
--- /dev/null
+++ b/tv/tuner/aidl/default/TimeFilter.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2021 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
+#define LOG_TAG "android.hardware.tv.tuner-service.example-TimeFilter"
+
+#include "TimeFilter.h"
+#include <utils/Log.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+TimeFilter::TimeFilter() {}
+
+TimeFilter::TimeFilter(std::shared_ptr<Demux> demux) {
+    mDemux = demux;
+}
+
+TimeFilter::~TimeFilter() {}
+
+::ndk::ScopedAStatus TimeFilter::setTimeStamp(int64_t in_timeStamp) {
+    ALOGV("%s", __FUNCTION__);
+    if (in_timeStamp == INVALID_TIME_STAMP) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+    mTimeStamp = in_timeStamp;
+    mBeginTime = time(NULL);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TimeFilter::clearTimeStamp() {
+    ALOGV("%s", __FUNCTION__);
+    mTimeStamp = INVALID_TIME_STAMP;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TimeFilter::getTimeStamp(int64_t* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+    if (mTimeStamp == INVALID_TIME_STAMP) {
+        *_aidl_return = mTimeStamp;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    uint64_t currentTimeStamp = mTimeStamp + difftime(time(NULL), mBeginTime) * 900000;
+    *_aidl_return = currentTimeStamp;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TimeFilter::getSourceTime(int64_t* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    *_aidl_return = 0;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus TimeFilter::close() {
+    ALOGV("%s", __FUNCTION__);
+    mTimeStamp = INVALID_TIME_STAMP;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/TimeFilter.h b/tv/tuner/aidl/default/TimeFilter.h
new file mode 100644
index 0000000..ff35c47
--- /dev/null
+++ b/tv/tuner/aidl/default/TimeFilter.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnTimeFilter.h>
+#include "Demux.h"
+#include "time.h"
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+#define INVALID_TIME_STAMP -1
+
+class Demux;
+
+class TimeFilter : public BnTimeFilter {
+  public:
+    TimeFilter();
+    TimeFilter(std::shared_ptr<Demux> demux);
+    ~TimeFilter();
+
+    ::ndk::ScopedAStatus setTimeStamp(int64_t in_timeStamp) override;
+    ::ndk::ScopedAStatus clearTimeStamp() override;
+    ::ndk::ScopedAStatus getTimeStamp(int64_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getSourceTime(int64_t* _aidl_return) override;
+    ::ndk::ScopedAStatus close() override;
+
+  private:
+    std::shared_ptr<Demux> mDemux;
+    uint64_t mTimeStamp = INVALID_TIME_STAMP;
+    time_t mBeginTime;
+};
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Tuner.cpp b/tv/tuner/aidl/default/Tuner.cpp
new file mode 100644
index 0000000..dc0bd5e
--- /dev/null
+++ b/tv/tuner/aidl/default/Tuner.cpp
@@ -0,0 +1,347 @@
+/*
+ * Copyright 2021 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
+#define LOG_TAG "android.hardware.tv.tuner-service.example-Tuner"
+
+#include "Tuner.h"
+#include <utils/Log.h>
+#include "Demux.h"
+#include "Descrambler.h"
+#include "Frontend.h"
+#include "Lnb.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+Tuner::Tuner() {
+    // Static Frontends array to maintain local frontends information
+    // Array index matches their FrontendId in the default impl
+    mFrontendSize = 10;
+    mFrontends[0] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS, 0, ref<Tuner>());
+    mFrontends[1] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC3, 1, ref<Tuner>());
+    mFrontends[2] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBC, 2, ref<Tuner>());
+    mFrontends[3] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBS, 3, ref<Tuner>());
+    mFrontends[4] = ndk::SharedRefBase::make<Frontend>(FrontendType::DVBT, 4, ref<Tuner>());
+    mFrontends[5] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBT, 5, ref<Tuner>());
+    mFrontends[6] = ndk::SharedRefBase::make<Frontend>(FrontendType::ANALOG, 6, ref<Tuner>());
+    mFrontends[7] = ndk::SharedRefBase::make<Frontend>(FrontendType::ATSC, 7, ref<Tuner>());
+    mFrontends[8] = ndk::SharedRefBase::make<Frontend>(FrontendType::ISDBS3, 8, ref<Tuner>());
+    mFrontends[9] = ndk::SharedRefBase::make<Frontend>(FrontendType::DTMB, 9, ref<Tuner>());
+
+    vector<FrontendStatusType> statusCaps;
+
+    FrontendCapabilities capsIsdbs;
+    capsIsdbs.set<FrontendCapabilities::Tag::isdbsCaps>(FrontendIsdbsCapabilities());
+    mFrontendCaps[0] = capsIsdbs;
+    statusCaps = {
+            FrontendStatusType::DEMOD_LOCK,  FrontendStatusType::SNR,
+            FrontendStatusType::FEC,         FrontendStatusType::MODULATION,
+            FrontendStatusType::MODULATIONS, FrontendStatusType::ROLL_OFF,
+    };
+    mFrontendStatusCaps[0] = statusCaps;
+
+    FrontendCapabilities capsAtsc3;
+    capsAtsc3.set<FrontendCapabilities::Tag::atsc3Caps>(FrontendAtsc3Capabilities());
+    mFrontendCaps[1] = capsAtsc3;
+    statusCaps = {
+            FrontendStatusType::BER,
+            FrontendStatusType::PER,
+            FrontendStatusType::ATSC3_PLP_INFO,
+            FrontendStatusType::MODULATIONS,
+            FrontendStatusType::BERS,
+            FrontendStatusType::INTERLEAVINGS,
+            FrontendStatusType::BANDWIDTH,
+    };
+    mFrontendStatusCaps[1] = statusCaps;
+
+    FrontendCapabilities capsDvbc;
+    capsDvbc.set<FrontendCapabilities::Tag::dvbcCaps>(FrontendDvbcCapabilities());
+    mFrontendCaps[2] = capsDvbc;
+    statusCaps = {
+            FrontendStatusType::PRE_BER,       FrontendStatusType::SIGNAL_QUALITY,
+            FrontendStatusType::MODULATION,    FrontendStatusType::SPECTRAL,
+            FrontendStatusType::MODULATIONS,   FrontendStatusType::CODERATES,
+            FrontendStatusType::INTERLEAVINGS, FrontendStatusType::BANDWIDTH,
+    };
+    mFrontendStatusCaps[2] = statusCaps;
+
+    FrontendCapabilities capsDvbs;
+    capsDvbs.set<FrontendCapabilities::Tag::dvbsCaps>(FrontendDvbsCapabilities());
+    mFrontendCaps[3] = capsDvbs;
+    statusCaps = {
+            FrontendStatusType::SIGNAL_STRENGTH, FrontendStatusType::SYMBOL_RATE,
+            FrontendStatusType::MODULATION,      FrontendStatusType::MODULATIONS,
+            FrontendStatusType::ROLL_OFF,        FrontendStatusType::IS_MISO,
+    };
+    mFrontendStatusCaps[3] = statusCaps;
+
+    FrontendCapabilities capsDvbt;
+    capsDvbt.set<FrontendCapabilities::Tag::dvbtCaps>(FrontendDvbtCapabilities());
+    mFrontendCaps[4] = capsDvbt;
+    statusCaps = {
+            FrontendStatusType::EWBS,
+            FrontendStatusType::PLP_ID,
+            FrontendStatusType::HIERARCHY,
+            FrontendStatusType::MODULATIONS,
+            FrontendStatusType::BANDWIDTH,
+            FrontendStatusType::GUARD_INTERVAL,
+            FrontendStatusType::TRANSMISSION_MODE,
+            FrontendStatusType::T2_SYSTEM_ID,
+    };
+    mFrontendStatusCaps[4] = statusCaps;
+
+    FrontendCapabilities capsIsdbt;
+    FrontendIsdbtCapabilities isdbtCaps{
+            .modeCap = (int)FrontendIsdbtMode::MODE_1 | (int)FrontendIsdbtMode::MODE_2,
+            .bandwidthCap = (int)FrontendIsdbtBandwidth::BANDWIDTH_6MHZ,
+            .modulationCap = (int)FrontendIsdbtModulation::MOD_16QAM,
+            // ISDBT shares coderate and guard interval with DVBT
+            .coderateCap = (int)FrontendDvbtCoderate::CODERATE_4_5 |
+                           (int)FrontendDvbtCoderate::CODERATE_6_7,
+            .guardIntervalCap = (int)FrontendDvbtGuardInterval::INTERVAL_1_128,
+    };
+    capsIsdbt.set<FrontendCapabilities::Tag::isdbtCaps>(isdbtCaps);
+    mFrontendCaps[5] = capsIsdbt;
+    statusCaps = {
+            FrontendStatusType::AGC,
+            FrontendStatusType::LNA,
+            FrontendStatusType::MODULATION,
+            FrontendStatusType::MODULATIONS,
+            FrontendStatusType::BANDWIDTH,
+            FrontendStatusType::GUARD_INTERVAL,
+            FrontendStatusType::TRANSMISSION_MODE,
+            FrontendStatusType::ISDBT_SEGMENTS,
+    };
+    mFrontendStatusCaps[5] = statusCaps;
+
+    FrontendCapabilities capsAnalog;
+    capsAnalog.set<FrontendCapabilities::Tag::analogCaps>(FrontendAnalogCapabilities());
+    mFrontendCaps[6] = capsAnalog;
+    statusCaps = {
+            FrontendStatusType::LAYER_ERROR,
+            FrontendStatusType::MER,
+            FrontendStatusType::UEC,
+            FrontendStatusType::TS_DATA_RATES,
+    };
+    mFrontendStatusCaps[6] = statusCaps;
+
+    FrontendCapabilities capsAtsc;
+    capsAtsc.set<FrontendCapabilities::Tag::atscCaps>(FrontendAtscCapabilities());
+    mFrontendCaps[7] = capsAtsc;
+    statusCaps = {
+            FrontendStatusType::FREQ_OFFSET,
+            FrontendStatusType::RF_LOCK,
+            FrontendStatusType::MODULATIONS,
+            FrontendStatusType::IS_LINEAR,
+    };
+    mFrontendStatusCaps[7] = statusCaps;
+
+    FrontendCapabilities capsIsdbs3;
+    capsIsdbs3.set<FrontendCapabilities::Tag::isdbs3Caps>(FrontendIsdbs3Capabilities());
+    mFrontendCaps[8] = capsIsdbs3;
+    statusCaps = {
+            FrontendStatusType::DEMOD_LOCK,      FrontendStatusType::MODULATION,
+            FrontendStatusType::MODULATIONS,     FrontendStatusType::ROLL_OFF,
+            FrontendStatusType::IS_SHORT_FRAMES,
+    };
+    mFrontendStatusCaps[8] = statusCaps;
+
+    FrontendCapabilities capsDtmb;
+    capsDtmb.set<FrontendCapabilities::Tag::dtmbCaps>(FrontendDtmbCapabilities());
+    mFrontendCaps[9] = capsDtmb;
+    statusCaps = {
+            FrontendStatusType::MODULATIONS,       FrontendStatusType::INTERLEAVINGS,
+            FrontendStatusType::BANDWIDTH,         FrontendStatusType::GUARD_INTERVAL,
+            FrontendStatusType::TRANSMISSION_MODE,
+    };
+    mFrontendStatusCaps[9] = statusCaps;
+
+    mLnbs.resize(2);
+    mLnbs[0] = ndk::SharedRefBase::make<Lnb>(0);
+    mLnbs[1] = ndk::SharedRefBase::make<Lnb>(1);
+}
+
+Tuner::~Tuner() {}
+
+::ndk::ScopedAStatus Tuner::getFrontendIds(std::vector<int32_t>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    _aidl_return->resize(mFrontendSize);
+    for (int i = 0; i < mFrontendSize; i++) {
+        (*_aidl_return)[i] = mFrontends[i]->getFrontendId();
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Tuner::openFrontendById(int32_t in_frontendId,
+                                             std::shared_ptr<IFrontend>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (in_frontendId >= mFrontendSize || in_frontendId < 0) {
+        ALOGW("[   WARN   ] Frontend with id %d isn't available", in_frontendId);
+        *_aidl_return = nullptr;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    *_aidl_return = mFrontends[in_frontendId];
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Tuner::openDemux(std::vector<int32_t>* out_demuxId,
+                                      std::shared_ptr<IDemux>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    mLastUsedId += 1;
+    mDemuxes[mLastUsedId] = ndk::SharedRefBase::make<Demux>(mLastUsedId, ref<Tuner>());
+
+    out_demuxId->push_back(mLastUsedId);
+    *_aidl_return = mDemuxes[mLastUsedId];
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Tuner::getDemuxCaps(DemuxCapabilities* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    // IP filter can be an MMTP filter's data source.
+    _aidl_return->linkCaps = {0x00, 0x00, 0x02, 0x00, 0x00};
+    // Support time filter testing
+    _aidl_return->bTimeFilter = true;
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Tuner::openDescrambler(std::shared_ptr<IDescrambler>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    *_aidl_return = ndk::SharedRefBase::make<Descrambler>();
+
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Tuner::getFrontendInfo(int32_t in_frontendId, FrontendInfo* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (in_frontendId >= mFrontendSize) {
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    // assign randomly selected values for testing.
+    *_aidl_return = {
+            .type = mFrontends[in_frontendId]->getFrontendType(),
+            .minFrequency = 139,
+            .maxFrequency = 1139,
+            .minSymbolRate = 45,
+            .maxSymbolRate = 1145,
+            .acquireRange = 30,
+            .exclusiveGroupId = 57,
+            .statusCaps = mFrontendStatusCaps[in_frontendId],
+            .frontendCaps = mFrontendCaps[in_frontendId],
+    };
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Tuner::getLnbIds(std::vector<int32_t>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    _aidl_return->resize(mLnbs.size());
+    for (int i = 0; i < mLnbs.size(); i++) {
+        (*_aidl_return)[i] = mLnbs[i]->getId();
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Tuner::openLnbById(int32_t in_lnbId, std::shared_ptr<ILnb>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (in_lnbId >= mLnbs.size()) {
+        *_aidl_return = nullptr;
+        return ::ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+    }
+
+    *_aidl_return = mLnbs[in_lnbId];
+    return ::ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<Frontend> Tuner::getFrontendById(int32_t frontendId) {
+    ALOGV("%s", __FUNCTION__);
+
+    return mFrontends[frontendId];
+}
+
+::ndk::ScopedAStatus Tuner::openLnbByName(const std::string& /* in_lnbName */,
+                                          std::vector<int32_t>* out_lnbId,
+                                          std::shared_ptr<ILnb>* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    out_lnbId->push_back(1234);
+    *_aidl_return = ndk::SharedRefBase::make<Lnb>();
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+void Tuner::setFrontendAsDemuxSource(int32_t frontendId, int32_t demuxId) {
+    mFrontendToDemux[frontendId] = demuxId;
+    if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
+        mDemuxes[demuxId]->startFrontendInputLoop();
+    }
+}
+
+void Tuner::removeDemux(int32_t demuxId) {
+    map<int32_t, int32_t>::iterator it;
+    for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end(); it++) {
+        if (it->second == demuxId) {
+            it = mFrontendToDemux.erase(it);
+            break;
+        }
+    }
+    mDemuxes.erase(demuxId);
+}
+
+void Tuner::removeFrontend(int32_t frontendId) {
+    mFrontendToDemux.erase(frontendId);
+}
+
+void Tuner::frontendStopTune(int32_t frontendId) {
+    map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
+    int32_t demuxId;
+    if (it != mFrontendToDemux.end()) {
+        demuxId = it->second;
+        mDemuxes[demuxId]->stopFrontendInput();
+    }
+}
+
+void Tuner::frontendStartTune(int32_t frontendId) {
+    map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
+    int32_t demuxId;
+    if (it != mFrontendToDemux.end()) {
+        demuxId = it->second;
+        mDemuxes[demuxId]->startFrontendInputLoop();
+    }
+}
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/Tuner.h b/tv/tuner/aidl/default/Tuner.h
new file mode 100644
index 0000000..e69990d
--- /dev/null
+++ b/tv/tuner/aidl/default/Tuner.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnTuner.h>
+#include <aidl/android/hardware/tv/tuner/FrontendCapabilities.h>
+
+#include <map>
+#include "Demux.h"
+#include "Frontend.h"
+#include "Lnb.h"
+
+using namespace std;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+
+class Frontend;
+class Demux;
+class Lnb;
+
+class Tuner : public BnTuner {
+  public:
+    Tuner();
+    virtual ~Tuner();
+
+    ::ndk::ScopedAStatus getFrontendIds(std::vector<int32_t>* _aidl_return) override;
+    ::ndk::ScopedAStatus openFrontendById(int32_t in_frontendId,
+                                          std::shared_ptr<IFrontend>* _aidl_return) override;
+    ::ndk::ScopedAStatus openDemux(std::vector<int32_t>* out_demuxId,
+                                   std::shared_ptr<IDemux>* _aidl_return) override;
+    ::ndk::ScopedAStatus getDemuxCaps(DemuxCapabilities* _aidl_return) override;
+    ::ndk::ScopedAStatus openDescrambler(std::shared_ptr<IDescrambler>* _aidl_return) override;
+    ::ndk::ScopedAStatus getFrontendInfo(int32_t in_frontendId,
+                                         FrontendInfo* _aidl_return) override;
+    ::ndk::ScopedAStatus getLnbIds(std::vector<int32_t>* _aidl_return) override;
+    ::ndk::ScopedAStatus openLnbById(int32_t in_lnbId,
+                                     std::shared_ptr<ILnb>* _aidl_return) override;
+    ::ndk::ScopedAStatus openLnbByName(const std::string& in_lnbName,
+                                       std::vector<int32_t>* out_lnbId,
+                                       std::shared_ptr<ILnb>* _aidl_return) override;
+
+    std::shared_ptr<Frontend> getFrontendById(int32_t frontendId);
+    void setFrontendAsDemuxSource(int32_t frontendId, int32_t demuxId);
+    void frontendStartTune(int32_t frontendId);
+    void frontendStopTune(int32_t frontendId);
+    void removeDemux(int32_t demuxId);
+    void removeFrontend(int32_t frontendId);
+
+  private:
+    // Static mFrontends array to maintain local frontends information
+    map<int32_t, std::shared_ptr<Frontend>> mFrontends;
+    map<int32_t, FrontendCapabilities> mFrontendCaps;
+    map<int32_t, vector<FrontendStatusType>> mFrontendStatusCaps;
+    map<int32_t, int32_t> mFrontendToDemux;
+    map<int32_t, std::shared_ptr<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.
+    int32_t mLastUsedId = -1;
+    vector<std::shared_ptr<Lnb>> mLnbs;
+};
+
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/tv/tuner/aidl/default/service.cpp b/tv/tuner/aidl/default/service.cpp
new file mode 100644
index 0000000..649b763
--- /dev/null
+++ b/tv/tuner/aidl/default/service.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 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
+#define LOG_TAG "android.hardware.tv.tuner-service.example"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "Tuner.h"
+
+using ::aidl::android::hardware::tv::tuner::Tuner;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(8);
+    std::shared_ptr<Tuner> tuner = ndk::SharedRefBase::make<Tuner>();
+
+    const std::string instance = std::string() + Tuner::descriptor + "/default";
+    binder_status_t status = AServiceManager_addService(tuner->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reached
+}
diff --git a/tv/tuner/aidl/default/tuner-default.rc b/tv/tuner/aidl/default/tuner-default.rc
new file mode 100644
index 0000000..fa09456
--- /dev/null
+++ b/tv/tuner/aidl/default/tuner-default.rc
@@ -0,0 +1,6 @@
+service vendor.tuner-default /vendor/bin/hw/android.hardware.tv.tuner-service.example
+    class hal
+    user media
+    group mediadrm drmrpc
+    ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/tv/tuner/aidl/default/tuner-default.xml b/tv/tuner/aidl/default/tuner-default.xml
new file mode 100644
index 0000000..f0d03ad
--- /dev/null
+++ b/tv/tuner/aidl/default/tuner-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.tv.tuner</name>
+        <fqname>ITuner/default</fqname>
+    </hal>
+</manifest>
diff --git a/tv/tuner/aidl/vts/OWNERS b/tv/tuner/aidl/vts/OWNERS
new file mode 100644
index 0000000..bf2b609
--- /dev/null
+++ b/tv/tuner/aidl/vts/OWNERS
@@ -0,0 +1,3 @@
+hgchen@google.com
+shubang@google.com
+quxiangfang@google.com
diff --git a/tv/tuner/aidl/vts/functional/Android.bp b/tv/tuner/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..119230e
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/Android.bp
@@ -0,0 +1,77 @@
+//
+// Copyright 2021 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalTvTunerTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "DemuxTests.cpp",
+        "DescramblerTests.cpp",
+        "DvrTests.cpp",
+        "FilterTests.cpp",
+        "FrontendTests.cpp",
+        "LnbTests.cpp",
+        "VtsHalTvTunerTargetTest.cpp",
+    ],
+    generated_headers: [
+        "tuner_testing_dynamic_configuration_V1_0_enums",
+        "tuner_testing_dynamic_configuration_V1_0_parser",
+    ],
+    generated_sources: [
+        "tuner_testing_dynamic_configuration_V1_0_enums",
+        "tuner_testing_dynamic_configuration_V1_0_parser",
+    ],
+    header_libs: ["libxsdc-utils"],
+    static_libs: [
+        "android.hardware.cas@1.0",
+        "android.hardware.cas@1.1",
+        "android.hardware.cas@1.2",
+        "android.hardware.common-V2-ndk_platform",
+        "android.hardware.common.fmq-V1-ndk_platform",
+        "android.hardware.tv.tuner-V1-ndk_platform",
+        "libaidlcommonsupport",
+        "libfmq",
+        "libcutils",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libvndksupport",
+        "libxml2",
+    ],
+    data: [
+        ":tuner_frontend_input_ts",
+        ":tuner_frontend_input_es",
+        ":tuner_testing_dynamic_configuration_V1_0",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+
+    require_root: true,
+}
diff --git a/tv/tuner/aidl/vts/functional/AndroidTest.xml b/tv/tuner/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..f93ed78
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 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 VtsHalTvTunerTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <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="VtsHalTvTunerTargetTest->/data/local/tmp/VtsHalTvTunerTargetTest" />
+        <option name="push" value="test.es->/data/local/tmp/test.es" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalTvTunerTargetTest" />
+        <option name="native-test-timeout" value="30m" />
+    </test>
+</configuration>
diff --git a/tv/tuner/aidl/vts/functional/DemuxTests.cpp b/tv/tuner/aidl/vts/functional/DemuxTests.cpp
new file mode 100644
index 0000000..9de01e1
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/DemuxTests.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2021 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(std::shared_ptr<IDemux>& demux, int32_t& demuxId) {
+    std::vector<int32_t> id;
+    auto status = mService->openDemux(&id, &mDemux);
+    if (status.isOk()) {
+        demux = mDemux;
+        demuxId = id[0];
+    }
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DemuxTests::setDemuxFrontendDataSource(int32_t frontendId) {
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    auto status = mDemux->setFrontendDataSource(frontendId);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DemuxTests::getDemuxCaps(DemuxCapabilities& demuxCaps) {
+    if (!mDemux) {
+        ALOGW("[vts] Test with openDemux first.");
+        return failure();
+    }
+    auto status = mService->getDemuxCaps(&demuxCaps);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DemuxTests::getAvSyncId(std::shared_ptr<IFilter> filter, int32_t& avSyncHwId) {
+    EXPECT_TRUE(mDemux) << "Demux is not opened yet.";
+
+    auto status = mDemux->getAvSyncHwId(filter, &avSyncHwId);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DemuxTests::getAvSyncTime(int32_t avSyncId) {
+    EXPECT_TRUE(mDemux) << "Demux is not opened yet.";
+
+    int64_t syncTime;
+    auto status = mDemux->getAvSyncTime(avSyncId, &syncTime);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DemuxTests::closeDemux() {
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    auto status = mDemux->close();
+    mDemux = nullptr;
+    return AssertionResult(status.isOk());
+}
diff --git a/tv/tuner/aidl/vts/functional/DemuxTests.h b/tv/tuner/aidl/vts/functional/DemuxTests.h
new file mode 100644
index 0000000..7698de3
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/DemuxTests.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/DemuxCapabilities.h>
+#include <aidl/android/hardware/tv/tuner/IDemux.h>
+#include <aidl/android/hardware/tv/tuner/IFilter.h>
+#include <aidl/android/hardware/tv/tuner/ITuner.h>
+
+#include <gtest/gtest.h>
+#include <log/log.h>
+
+using ::testing::AssertionResult;
+
+using namespace aidl::android::hardware::tv::tuner;
+
+class DemuxTests {
+  public:
+    void setService(std::shared_ptr<ITuner> tuner) { mService = tuner; }
+
+    AssertionResult openDemux(std::shared_ptr<IDemux>& demux, int32_t& demuxId);
+    AssertionResult setDemuxFrontendDataSource(int32_t frontendId);
+    AssertionResult getAvSyncId(std::shared_ptr<IFilter> filter, int32_t& avSyncHwId);
+    AssertionResult getAvSyncTime(int32_t avSyncId);
+    AssertionResult getDemuxCaps(DemuxCapabilities& demuxCaps);
+    AssertionResult closeDemux();
+
+  protected:
+    static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+    static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+    std::shared_ptr<ITuner> mService;
+    std::shared_ptr<IDemux> mDemux;
+};
diff --git a/tv/tuner/aidl/vts/functional/DescramblerTests.cpp b/tv/tuner/aidl/vts/functional/DescramblerTests.cpp
new file mode 100644
index 0000000..e0ee391
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/DescramblerTests.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2021 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 "DescramblerTests.h"
+
+using namespace std;
+
+AssertionResult DescramblerTests::createCasPlugin(int32_t caSystemId) {
+    auto status = mMediaCasService->isSystemIdSupported(caSystemId);
+    if (!status.isOk() || !status) {
+        ALOGW("[vts] Failed to check isSystemIdSupported.");
+        return failure();
+    }
+
+    mCasListener = new MediaCasListener();
+    auto pluginStatus = mMediaCasService->createPluginExt(caSystemId, mCasListener);
+    if (!pluginStatus.isOk()) {
+        ALOGW("[vts] Failed to createPluginExt.");
+        return failure();
+    }
+    mCas = ICas::castFrom(pluginStatus);
+    if (mCas == nullptr) {
+        ALOGW("[vts] Failed to get ICas.");
+        return failure();
+    }
+    return success();
+}
+
+AssertionResult DescramblerTests::openCasSession(vector<uint8_t>& sessionId,
+                                                 vector<uint8_t>& hidlPvtData) {
+    Status sessionStatus;
+    SessionIntent intent = SessionIntent::LIVE;
+    ScramblingMode mode = ScramblingMode::RESERVED;
+    auto returnVoid =
+            mCas->openSession_1_2(intent, mode, [&](Status status, const hidl_vec<uint8_t>& id) {
+                sessionStatus = status;
+                sessionId = id;
+            });
+    if (!returnVoid.isOk() || (sessionStatus != Status::OK)) {
+        ALOGW("[vts] Failed to open cas session.");
+        mCas->closeSession(sessionId);
+        return failure();
+    }
+
+    if (hidlPvtData.size() > 0) {
+        auto status = mCas->setSessionPrivateData(sessionId, hidlPvtData);
+        if (status != android::hardware::cas::V1_0::Status::OK) {
+            ALOGW("[vts] Failed to set session private data");
+            mCas->closeSession(sessionId);
+            return failure();
+        }
+    }
+
+    return success();
+}
+
+AssertionResult DescramblerTests::getKeyToken(int32_t caSystemId, string& provisonStr,
+                                              vector<uint8_t>& hidlPvtData,
+                                              vector<uint8_t>& token) {
+    if (createCasPlugin(caSystemId) != success()) {
+        ALOGW("[vts] createCasPlugin failed.");
+        return failure();
+    }
+
+    if (provisonStr.size() > 0) {
+        auto returnStatus = mCas->provision(hidl_string(provisonStr));
+        if (returnStatus != android::hardware::cas::V1_0::Status::OK) {
+            ALOGW("[vts] provision failed.");
+            return failure();
+        }
+    }
+
+    return openCasSession(token, hidlPvtData);
+}
+
+AssertionResult DescramblerTests::openDescrambler(int32_t demuxId) {
+    ndk::ScopedAStatus status;
+    status = mService->openDescrambler(&mDescrambler);
+    if (!status.isOk()) {
+        ALOGW("[vts] openDescrambler failed.");
+        return failure();
+    }
+
+    status = mDescrambler->setDemuxSource(demuxId);
+    if (!status.isOk()) {
+        ALOGW("[vts] setDemuxSource failed.");
+        return failure();
+    }
+
+    return success();
+}
+
+AssertionResult DescramblerTests::setKeyToken(vector<uint8_t>& token) {
+    ndk::ScopedAStatus status;
+    if (!mDescrambler) {
+        ALOGW("[vts] Descrambler is not opened yet.");
+        return failure();
+    }
+
+    status = mDescrambler->setKeyToken(token);
+    if (!status.isOk()) {
+        ALOGW("[vts] setKeyToken failed.");
+        return failure();
+    }
+
+    return success();
+}
+
+AssertionResult DescramblerTests::addPid(DemuxPid pid,
+                                         std::shared_ptr<IFilter> optionalSourceFilter) {
+    ndk::ScopedAStatus status;
+    if (!mDescrambler) {
+        ALOGW("[vts] Descrambler is not opened yet.");
+        return failure();
+    }
+
+    status = mDescrambler->addPid(pid, optionalSourceFilter);
+    if (!status.isOk()) {
+        ALOGW("[vts] addPid failed.");
+        return failure();
+    }
+
+    return success();
+}
+
+AssertionResult DescramblerTests::removePid(DemuxPid pid,
+                                            std::shared_ptr<IFilter> optionalSourceFilter) {
+    ndk::ScopedAStatus status;
+    if (!mDescrambler) {
+        ALOGW("[vts] Descrambler is not opened yet.");
+        return failure();
+    }
+
+    status = mDescrambler->removePid(pid, optionalSourceFilter);
+    if (!status.isOk()) {
+        ALOGW("[vts] removePid failed.");
+        return failure();
+    }
+
+    return success();
+}
+
+AssertionResult DescramblerTests::closeDescrambler() {
+    ndk::ScopedAStatus status;
+    if (!mDescrambler) {
+        ALOGW("[vts] Descrambler is not opened yet.");
+        return failure();
+    }
+
+    status = mDescrambler->close();
+    mDescrambler = nullptr;
+    if (!status.isOk()) {
+        ALOGW("[vts] close Descrambler failed.");
+        return failure();
+    }
+
+    return success();
+}
+
+AssertionResult DescramblerTests::getDemuxPidFromFilterSettings(DemuxFilterType type,
+                                                                const DemuxFilterSettings& settings,
+                                                                DemuxPid& pid) {
+    switch (type.mainType) {
+        case DemuxFilterMainType::TS:
+            if (type.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>() ==
+                        DemuxTsFilterType::AUDIO ||
+                type.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>() ==
+                        DemuxTsFilterType::VIDEO) {
+                pid.set<DemuxPid::Tag::tPid>(settings.get<DemuxFilterSettings::Tag::ts>().tpid);
+            } else {
+                ALOGW("[vts] Not a media ts filter!");
+                return failure();
+            }
+            break;
+        case DemuxFilterMainType::MMTP:
+            if (type.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>() ==
+                        DemuxMmtpFilterType::AUDIO ||
+                type.subType.get<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>() ==
+                        DemuxMmtpFilterType::VIDEO) {
+                pid.set<DemuxPid::Tag::mmtpPid>(
+                        settings.get<DemuxFilterSettings::Tag::mmtp>().mmtpPid);
+            } else {
+                ALOGW("[vts] Not a media mmtp filter!");
+                return failure();
+            }
+            break;
+        default:
+            ALOGW("[vts] Not a media filter!");
+            return failure();
+    }
+    return success();
+}
diff --git a/tv/tuner/aidl/vts/functional/DescramblerTests.h b/tv/tuner/aidl/vts/functional/DescramblerTests.h
new file mode 100644
index 0000000..f0b7691
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/DescramblerTests.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2021 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 <gtest/gtest.h>
+#include <log/log.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <fstream>
+#include <iostream>
+#include <map>
+
+#include <android/hardware/cas/1.0/types.h>
+#include <android/hardware/cas/1.2/ICas.h>
+#include <android/hardware/cas/1.2/ICasListener.h>
+#include <android/hardware/cas/1.2/IMediaCasService.h>
+#include <android/hardware/cas/1.2/types.h>
+
+#include <aidl/android/hardware/tv/tuner/IDescrambler.h>
+#include <aidl/android/hardware/tv/tuner/IDvr.h>
+#include <aidl/android/hardware/tv/tuner/IDvrCallback.h>
+#include <aidl/android/hardware/tv/tuner/ITuner.h>
+
+using android::Condition;
+using android::Mutex;
+using android::sp;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::cas::V1_2::ICas;
+using android::hardware::cas::V1_2::ICasListener;
+using android::hardware::cas::V1_2::IMediaCasService;
+using android::hardware::cas::V1_2::ScramblingMode;
+using android::hardware::cas::V1_2::SessionIntent;
+using android::hardware::cas::V1_2::Status;
+using android::hardware::cas::V1_2::StatusEvent;
+
+using ::testing::AssertionResult;
+
+using namespace aidl::android::hardware::tv::tuner;
+
+class MediaCasListener : public ICasListener {
+  public:
+    virtual Return<void> onEvent(int32_t /*event*/, int32_t /*arg*/,
+                                 const hidl_vec<uint8_t>& /*data*/) override {
+        return Void();
+    }
+
+    virtual Return<void> onSessionEvent(const hidl_vec<uint8_t>& /*sessionId*/, int32_t /*event*/,
+                                        int32_t /*arg*/,
+                                        const hidl_vec<uint8_t>& /*data*/) override {
+        return Void();
+    }
+
+    virtual Return<void> onStatusUpdate(StatusEvent /*event*/, int32_t /*arg*/) override {
+        return Void();
+    }
+};
+
+class DescramblerTests {
+  public:
+    void setService(std::shared_ptr<ITuner> tuner) { mService = tuner; }
+    void setCasService(sp<IMediaCasService> casService) { mMediaCasService = casService; }
+
+    AssertionResult setKeyToken(std::vector<uint8_t>& token);
+    AssertionResult openDescrambler(int32_t demuxId);
+    AssertionResult addPid(DemuxPid pid, std::shared_ptr<IFilter> optionalSourceFilter);
+    AssertionResult removePid(DemuxPid pid, std::shared_ptr<IFilter> optionalSourceFilter);
+    AssertionResult closeDescrambler();
+    AssertionResult getKeyToken(int32_t caSystemId, std::string& provisonStr,
+                                std::vector<uint8_t>& hidlPvtData, std::vector<uint8_t>& token);
+    AssertionResult getDemuxPidFromFilterSettings(DemuxFilterType type,
+                                                  const DemuxFilterSettings& settings,
+                                                  DemuxPid& pid);
+
+  protected:
+    static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+    static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+    std::shared_ptr<ITuner> mService;
+    std::shared_ptr<IDescrambler> mDescrambler;
+    android::sp<ICas> mCas;
+    android::sp<IMediaCasService> mMediaCasService;
+    android::sp<MediaCasListener> mCasListener;
+
+  private:
+    AssertionResult openCasSession(std::vector<uint8_t>& sessionId,
+                                   std::vector<uint8_t>& hidlPvtData);
+    AssertionResult createCasPlugin(int32_t caSystemId);
+};
diff --git a/tv/tuner/aidl/vts/functional/DvrTests.cpp b/tv/tuner/aidl/vts/functional/DvrTests.cpp
new file mode 100644
index 0000000..e356099
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/DvrTests.cpp
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2021 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 "DvrTests.h"
+
+#include <aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.h>
+
+void DvrCallback::startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings,
+                                           MQDesc& playbackMQDescriptor) {
+    mInputDataFile = dataInputFile;
+    mPlaybackSettings = settings;
+    mPlaybackMQ = std::make_unique<FilterMQ>(playbackMQDescriptor, true /* resetPointers */);
+    EXPECT_TRUE(mPlaybackMQ);
+    pthread_create(&mPlaybackThread, NULL, __threadLoopPlayback, this);
+    pthread_setname_np(mPlaybackThread, "test_playback_input_loop");
+}
+
+void DvrCallback::stopPlaybackThread() {
+    mPlaybackThreadRunning = false;
+    mKeepWritingPlaybackFMQ = false;
+
+    android::Mutex::Autolock autoLock(mPlaybackThreadLock);
+}
+
+void* DvrCallback::__threadLoopPlayback(void* user) {
+    DvrCallback* const self = static_cast<DvrCallback*>(user);
+    self->playbackThreadLoop();
+    return 0;
+}
+
+void DvrCallback::playbackThreadLoop() {
+    android::Mutex::Autolock autoLock(mPlaybackThreadLock);
+    mPlaybackThreadRunning = true;
+
+    // Create the EventFlag that is used to signal the HAL impl that data have been
+    // written into the Playback FMQ
+    EventFlag* playbackMQEventFlag;
+    EXPECT_TRUE(EventFlag::createEventFlag(mPlaybackMQ->getEventFlagWord(), &playbackMQEventFlag) ==
+                android::OK);
+
+    int fd = open(mInputDataFile.c_str(), O_RDONLY | O_LARGEFILE);
+    int readBytes;
+    uint32_t regionSize = 0;
+    int8_t* buffer;
+    ALOGW("[vts] playback thread loop start %s", mInputDataFile.c_str());
+    if (fd < 0) {
+        mPlaybackThreadRunning = false;
+        ALOGW("[vts] Error %s", strerror(errno));
+    }
+
+    while (mPlaybackThreadRunning) {
+        while (mKeepWritingPlaybackFMQ) {
+            int totalWrite = mPlaybackMQ->availableToWrite();
+            if (totalWrite * 4 < mPlaybackMQ->getQuantumCount()) {
+                // Wait for the HAL implementation to read more data then write.
+                continue;
+            }
+            AidlMessageQueue<int8_t, SynchronizedReadWrite>::MemTransaction memTx;
+            if (!mPlaybackMQ->beginWrite(totalWrite, &memTx)) {
+                ALOGW("[vts] Fail to write into Playback fmq.");
+                mPlaybackThreadRunning = false;
+                break;
+            }
+            auto first = memTx.getFirstRegion();
+            buffer = first.getAddress();
+            regionSize = first.getLength();
+
+            if (regionSize > 0) {
+                readBytes = read(fd, buffer, regionSize);
+                if (readBytes <= 0) {
+                    if (readBytes < 0) {
+                        ALOGW("[vts] Read from %s failed.", mInputDataFile.c_str());
+                    } else {
+                        ALOGW("[vts] playback input EOF.");
+                    }
+                    mPlaybackThreadRunning = false;
+                    break;
+                }
+            }
+            if (regionSize == 0 || (readBytes == regionSize && regionSize < totalWrite)) {
+                auto second = memTx.getSecondRegion();
+                buffer = second.getAddress();
+                regionSize = second.getLength();
+                int ret = read(fd, buffer, regionSize);
+                if (ret <= 0) {
+                    if (ret < 0) {
+                        ALOGW("[vts] Read from %s failed.", mInputDataFile.c_str());
+                    } else {
+                        ALOGW("[vts] playback input EOF.");
+                    }
+                    mPlaybackThreadRunning = false;
+                    break;
+                }
+                readBytes += ret;
+            }
+            if (!mPlaybackMQ->commitWrite(readBytes)) {
+                ALOGW("[vts] Failed to commit write playback fmq.");
+                mPlaybackThreadRunning = false;
+                break;
+            }
+            playbackMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+        }
+    }
+
+    mPlaybackThreadRunning = false;
+    ALOGW("[vts] Playback thread end.");
+    close(fd);
+}
+
+void DvrCallback::testRecordOutput() {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (mDataOutputBuffer.empty()) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "record output matching pid does not output within timeout";
+            stopRecordThread();
+            return;
+        }
+    }
+    stopRecordThread();
+    ALOGW("[vts] record pass and stop");
+}
+
+void DvrCallback::startRecordOutputThread(RecordSettings recordSettings,
+                                          MQDesc& recordMQDescriptor) {
+    mRecordMQ = std::make_unique<FilterMQ>(recordMQDescriptor, true /* resetPointers */);
+    EXPECT_TRUE(mRecordMQ);
+    struct RecordThreadArgs* threadArgs =
+            (struct RecordThreadArgs*)malloc(sizeof(struct RecordThreadArgs));
+    threadArgs->user = this;
+    threadArgs->recordSettings = &recordSettings;
+    threadArgs->keepReadingRecordFMQ = &mKeepReadingRecordFMQ;
+
+    pthread_create(&mRecordThread, NULL, __threadLoopRecord, (void*)threadArgs);
+    pthread_setname_np(mRecordThread, "test_record_input_loop");
+}
+
+void* DvrCallback::__threadLoopRecord(void* threadArgs) {
+    DvrCallback* const self =
+            static_cast<DvrCallback*>(((struct RecordThreadArgs*)threadArgs)->user);
+    self->recordThreadLoop(((struct RecordThreadArgs*)threadArgs)->recordSettings,
+                           ((struct RecordThreadArgs*)threadArgs)->keepReadingRecordFMQ);
+    return 0;
+}
+
+void DvrCallback::recordThreadLoop(RecordSettings* /*recordSettings*/, bool* keepReadingRecordFMQ) {
+    ALOGD("[vts] DvrCallback record threadLoop start.");
+    android::Mutex::Autolock autoLock(mRecordThreadLock);
+    mRecordThreadRunning = true;
+    mKeepReadingRecordFMQ = true;
+
+    // Create the EventFlag that is used to signal the HAL impl that data have been
+    // read from the Record FMQ
+    EventFlag* recordMQEventFlag;
+    EXPECT_TRUE(EventFlag::createEventFlag(mRecordMQ->getEventFlagWord(), &recordMQEventFlag) ==
+                android::OK);
+
+    while (mRecordThreadRunning) {
+        while (*keepReadingRecordFMQ) {
+            uint32_t efState = 0;
+            android::status_t status = recordMQEventFlag->wait(
+                    static_cast<int32_t>(DemuxQueueNotifyBits::DATA_READY), &efState, WAIT_TIMEOUT,
+                    true /* retry on spurious wake */);
+            if (status != android::OK) {
+                ALOGD("[vts] wait for data ready on the record FMQ");
+                continue;
+            }
+            // Our current implementation filter the data and write it into the filter FMQ
+            // immediately after the DATA_READY from the VTS/framework
+            if (!readRecordFMQ()) {
+                ALOGD("[vts] record data failed to be filtered. Ending thread");
+                mRecordThreadRunning = false;
+                break;
+            }
+        }
+    }
+
+    mRecordThreadRunning = false;
+    ALOGD("[vts] record thread ended.");
+}
+
+bool DvrCallback::readRecordFMQ() {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    bool result = false;
+    int readSize = mRecordMQ->availableToRead();
+    mDataOutputBuffer.clear();
+    mDataOutputBuffer.resize(readSize);
+    result = mRecordMQ->read(mDataOutputBuffer.data(), readSize);
+    EXPECT_TRUE(result) << "can't read from Record MQ";
+    mMsgCondition.signal();
+    return result;
+}
+
+void DvrCallback::stopRecordThread() {
+    mKeepReadingRecordFMQ = false;
+    mRecordThreadRunning = false;
+}
+
+AssertionResult DvrTests::openDvrInDemux(DvrType type, int32_t bufferSize) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+
+    // Create dvr callback
+    if (type == DvrType::PLAYBACK) {
+        mDvrPlaybackCallback = ndk::SharedRefBase::make<DvrCallback>();
+        status = mDemux->openDvr(type, bufferSize, mDvrPlaybackCallback, &mDvrPlayback);
+        if (status.isOk()) {
+            mDvrPlaybackCallback->setDvr(mDvrPlayback);
+        }
+    }
+
+    if (type == DvrType::RECORD) {
+        mDvrRecordCallback = ndk::SharedRefBase::make<DvrCallback>();
+        status = mDemux->openDvr(type, bufferSize, mDvrRecordCallback, &mDvrRecord);
+        if (status.isOk()) {
+            mDvrRecordCallback->setDvr(mDvrRecord);
+        }
+    }
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::configDvrPlayback(DvrSettings setting) {
+    ndk::ScopedAStatus status = mDvrPlayback->configure(setting);
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::configDvrRecord(DvrSettings setting) {
+    ndk::ScopedAStatus status = mDvrRecord->configure(setting);
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::getDvrPlaybackMQDescriptor() {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first.";
+
+    status = mDvrPlayback->getQueueDesc(&mDvrPlaybackMQDescriptor);
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::getDvrRecordMQDescriptor() {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
+
+    status = mDvrRecord->getQueueDesc(&mDvrRecordMQDescriptor);
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::attachFilterToDvr(std::shared_ptr<IFilter> filter) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
+
+    status = mDvrRecord->attachFilter(filter);
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::detachFilterToDvr(std::shared_ptr<IFilter> filter) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
+
+    status = mDvrRecord->detachFilter(filter);
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::startDvrPlayback() {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first.";
+
+    status = mDvrPlayback->start();
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::stopDvrPlayback() {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrPlayback) << "Test with openDvr first.";
+
+    status = mDvrPlayback->stop();
+
+    return AssertionResult(status.isOk());
+}
+
+void DvrTests::closeDvrPlayback() {
+    ASSERT_TRUE(mDemux);
+    ASSERT_TRUE(mDvrPlayback);
+    ASSERT_TRUE(mDvrPlayback->close().isOk());
+}
+
+AssertionResult DvrTests::startDvrRecord() {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
+
+    status = mDvrRecord->start();
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult DvrTests::stopDvrRecord() {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mDvrRecord) << "Test with openDvr first.";
+
+    status = mDvrRecord->stop();
+
+    return AssertionResult(status.isOk());
+}
+
+void DvrTests::closeDvrRecord() {
+    ASSERT_TRUE(mDemux);
+    ASSERT_TRUE(mDvrRecord);
+    ASSERT_TRUE(mDvrRecord->close().isOk());
+}
diff --git a/tv/tuner/aidl/vts/functional/DvrTests.h b/tv/tuner/aidl/vts/functional/DvrTests.h
new file mode 100644
index 0000000..bda57b3
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/DvrTests.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2021 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 <fcntl.h>
+#include <fmq/AidlMessageQueue.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <fstream>
+#include <iostream>
+#include <map>
+
+#include <aidl/android/hardware/tv/tuner/BnDvrCallback.h>
+#include <aidl/android/hardware/tv/tuner/IDvr.h>
+#include <aidl/android/hardware/tv/tuner/ITuner.h>
+
+#include "FilterTests.h"
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::Condition;
+using ::android::Mutex;
+using ::android::hardware::EventFlag;
+
+using namespace aidl::android::hardware::tv::tuner;
+using namespace std;
+
+#define WAIT_TIMEOUT 3000000000
+
+class DvrCallback : public BnDvrCallback {
+  public:
+    virtual ::ndk::ScopedAStatus onRecordStatus(RecordStatus status) override {
+        ALOGD("[vts] record status %hhu", status);
+        switch (status) {
+            case RecordStatus::DATA_READY:
+                break;
+            case RecordStatus::LOW_WATER:
+                break;
+            case RecordStatus::HIGH_WATER:
+            case RecordStatus::OVERFLOW:
+                ALOGD("[vts] record overflow. Flushing.");
+                EXPECT_TRUE(mDvr) << "Dvr callback is not set with an IDvr";
+                if (mDvr) {
+                    ndk::ScopedAStatus result = mDvr->flush();
+                    ALOGD("[vts] Flushing result %s.", result.getMessage());
+                }
+                break;
+        }
+        return ndk::ScopedAStatus::ok();
+    }
+
+    virtual ::ndk::ScopedAStatus onPlaybackStatus(PlaybackStatus status) override {
+        // android::Mutex::Autolock autoLock(mMsgLock);
+        ALOGD("[vts] playback status %d", status);
+        switch (status) {
+            case PlaybackStatus::SPACE_EMPTY:
+            case PlaybackStatus::SPACE_ALMOST_EMPTY:
+                ALOGD("[vts] keep playback inputing %d", status);
+                mKeepWritingPlaybackFMQ = true;
+                break;
+            case PlaybackStatus::SPACE_ALMOST_FULL:
+            case PlaybackStatus::SPACE_FULL:
+                ALOGD("[vts] stop playback inputing %d", status);
+                mKeepWritingPlaybackFMQ = false;
+                break;
+        }
+        return ndk::ScopedAStatus::ok();
+    }
+
+    void stopPlaybackThread();
+    void testRecordOutput();
+    void stopRecordThread();
+
+    void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings,
+                                  MQDesc& playbackMQDescriptor);
+    void startRecordOutputThread(RecordSettings recordSettings, MQDesc& recordMQDescriptor);
+    static void* __threadLoopPlayback(void* user);
+    static void* __threadLoopRecord(void* threadArgs);
+    void playbackThreadLoop();
+    void recordThreadLoop(RecordSettings* recordSetting, bool* keepWritingPlaybackFMQ);
+
+    bool readRecordFMQ();
+
+    void setDvr(std::shared_ptr<IDvr> dvr) { mDvr = dvr; }
+
+  private:
+    struct RecordThreadArgs {
+        DvrCallback* user;
+        RecordSettings* recordSettings;
+        bool* keepReadingRecordFMQ;
+    };
+    // uint16_t mDataLength = 0;
+    std::vector<int8_t> mDataOutputBuffer;
+
+    std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterMQ;
+    std::unique_ptr<FilterMQ> mPlaybackMQ;
+    std::unique_ptr<FilterMQ> mRecordMQ;
+    std::map<uint32_t, EventFlag*> mFilterMQEventFlag;
+
+    android::Mutex mMsgLock;
+    android::Mutex mPlaybackThreadLock;
+    android::Mutex mRecordThreadLock;
+    android::Condition mMsgCondition;
+
+    bool mKeepWritingPlaybackFMQ = true;
+    bool mKeepReadingRecordFMQ = true;
+    bool mPlaybackThreadRunning;
+    bool mRecordThreadRunning;
+    pthread_t mPlaybackThread;
+    pthread_t mRecordThread;
+    string mInputDataFile;
+    PlaybackSettings mPlaybackSettings;
+
+    std::shared_ptr<IDvr> mDvr = nullptr;
+
+    // int mPidFilterOutputCount = 0;
+};
+
+class DvrTests {
+  public:
+    void setService(std::shared_ptr<ITuner> tuner) { mService = tuner; }
+    void setDemux(std::shared_ptr<IDemux> demux) { mDemux = demux; }
+
+    void startPlaybackInputThread(string& dataInputFile, PlaybackSettings& settings) {
+        mDvrPlaybackCallback->startPlaybackInputThread(dataInputFile, settings,
+                                                       mDvrPlaybackMQDescriptor);
+    };
+
+    void startRecordOutputThread(RecordSettings settings) {
+        mDvrRecordCallback->startRecordOutputThread(settings, mDvrRecordMQDescriptor);
+    };
+
+    void stopPlaybackThread() { mDvrPlaybackCallback->stopPlaybackThread(); }
+    void testRecordOutput() { mDvrRecordCallback->testRecordOutput(); }
+    void stopRecordThread() { mDvrRecordCallback->stopRecordThread(); }
+
+    AssertionResult openDvrInDemux(DvrType type, int32_t bufferSize);
+    AssertionResult configDvrPlayback(DvrSettings setting);
+    AssertionResult configDvrRecord(DvrSettings setting);
+    AssertionResult getDvrPlaybackMQDescriptor();
+    AssertionResult getDvrRecordMQDescriptor();
+    AssertionResult attachFilterToDvr(std::shared_ptr<IFilter> filter);
+    AssertionResult detachFilterToDvr(std::shared_ptr<IFilter> filter);
+    AssertionResult stopDvrPlayback();
+    AssertionResult startDvrPlayback();
+    AssertionResult stopDvrRecord();
+    AssertionResult startDvrRecord();
+    void closeDvrPlayback();
+    void closeDvrRecord();
+
+  protected:
+    static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+    static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+    std::shared_ptr<ITuner> mService;
+    std::shared_ptr<IDvr> mDvrPlayback;
+    std::shared_ptr<IDvr> mDvrRecord;
+    std::shared_ptr<IDemux> mDemux;
+    std::shared_ptr<DvrCallback> mDvrPlaybackCallback;
+    std::shared_ptr<DvrCallback> mDvrRecordCallback;
+    MQDesc mDvrPlaybackMQDescriptor;
+    MQDesc mDvrRecordMQDescriptor;
+};
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.cpp b/tv/tuner/aidl/vts/functional/FilterTests.cpp
new file mode 100644
index 0000000..381475a
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/FilterTests.cpp
@@ -0,0 +1,362 @@
+/*
+ * Copyright 2021 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"
+
+#include <inttypes.h>
+
+#include <aidl/android/hardware/tv/tuner/DemuxFilterMonitorEventType.h>
+#include <aidlcommonsupport/NativeHandle.h>
+
+using ::aidl::android::hardware::common::NativeHandle;
+
+void FilterCallback::testFilterDataOutput() {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (mPidFilterOutputCount < 1) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "filter output matching pid does not output within timeout";
+            return;
+        }
+    }
+    mPidFilterOutputCount = 0;
+    ALOGW("[vts] pass and stop");
+}
+
+void FilterCallback::testFilterScramblingEvent() {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (mScramblingStatusEvent < 1) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "scrambling event does not output within timeout";
+            return;
+        }
+    }
+    mScramblingStatusEvent = 0;
+    ALOGW("[vts] pass and stop");
+}
+
+void FilterCallback::testFilterIpCidEvent() {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (mIpCidEvent < 1) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "ip cid change event does not output within timeout";
+            return;
+        }
+    }
+    mIpCidEvent = 0;
+    ALOGW("[vts] pass and stop");
+}
+
+void FilterCallback::testStartIdAfterReconfigure() {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (!mStartIdReceived) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "does not receive start id within timeout";
+            return;
+        }
+    }
+    mStartIdReceived = false;
+    ALOGW("[vts] pass and stop");
+}
+
+void FilterCallback::readFilterEventsData(const vector<DemuxFilterEvent>& events) {
+    ALOGW("[vts] reading filter event");
+    // todo separate filter handlers
+    for (int i = 0; i < events.size(); i++) {
+        switch (events[i].getTag()) {
+            case DemuxFilterEvent::Tag::media:
+                ALOGD("[vts] Media filter event, avMemHandle numFds=%zu.",
+                      events[i].get<DemuxFilterEvent::Tag::media>().avMemory.fds.size());
+                dumpAvData(events[i].get<DemuxFilterEvent::Tag::media>());
+                break;
+            case DemuxFilterEvent::Tag::tsRecord:
+                ALOGD("[vts] TS record filter event, pts=%" PRIu64 ", firstMbInSlice=%d",
+                      events[i].get<DemuxFilterEvent::Tag::tsRecord>().pts,
+                      events[i].get<DemuxFilterEvent::Tag::tsRecord>().firstMbInSlice);
+                break;
+            case DemuxFilterEvent::Tag::mmtpRecord:
+                ALOGD("[vts] MMTP record filter event, pts=%" PRIu64
+                      ", firstMbInSlice=%d, mpuSequenceNumber=%d, tsIndexMask=%d",
+                      events[i].get<DemuxFilterEvent::Tag::mmtpRecord>().pts,
+                      events[i].get<DemuxFilterEvent::Tag::mmtpRecord>().firstMbInSlice,
+                      events[i].get<DemuxFilterEvent::Tag::mmtpRecord>().mpuSequenceNumber,
+                      events[i].get<DemuxFilterEvent::Tag::mmtpRecord>().tsIndexMask);
+                break;
+            case DemuxFilterEvent::Tag::monitorEvent:
+                switch (events[i].get<DemuxFilterEvent::Tag::monitorEvent>().getTag()) {
+                    case DemuxFilterMonitorEvent::Tag::scramblingStatus:
+                        mScramblingStatusEvent++;
+                        break;
+                    case DemuxFilterMonitorEvent::Tag::cid:
+                        mIpCidEvent++;
+                        break;
+                    default:
+                        break;
+                }
+                break;
+            case DemuxFilterEvent::Tag::startId:
+                ALOGD("[vts] Restart filter event, startId=%d",
+                      events[i].get<DemuxFilterEvent::Tag::startId>());
+                mStartIdReceived = true;
+                break;
+            default:
+                break;
+        }
+    }
+}
+
+bool FilterCallback::dumpAvData(const DemuxFilterMediaEvent& event) {
+    int32_t length = event.dataLength;
+    int32_t offset = event.offset;
+    int av_fd;
+    // read data from buffer pointed by a handle
+    if (event.avMemory.fds.size() == 0) {
+        if (mAvSharedHandle == nullptr) {
+            return false;
+        }
+        av_fd = mAvSharedHandle->data[0];
+    } else {
+        av_fd = event.avMemory.fds[0].get();
+    }
+    uint8_t* buffer = static_cast<uint8_t*>(
+            mmap(NULL, length + offset, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0));
+    if (buffer == MAP_FAILED) {
+        ALOGE("[vts] fail to allocate av buffer, errno=%d", errno);
+        return false;
+    }
+    uint8_t output[length + 1];
+    memcpy(output, buffer + offset, length);
+    // print buffer and check with golden output.
+    return true;
+}
+
+AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type, int32_t bufferSize) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+
+    // Create demux callback
+    mFilterCallback = ndk::SharedRefBase::make<FilterCallback>();
+
+    // Add filter to the local demux
+    status = mDemux->openFilter(type, bufferSize, mFilterCallback, &mFilter);
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::getNewlyOpenedFilterId_64bit(int64_t& filterId) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mDemux) << "Test with openDemux first.";
+    EXPECT_TRUE(mFilter) << "Test with openFilterInDemux first.";
+    EXPECT_TRUE(mFilterCallback) << "Test with openFilterInDemux first.";
+
+    status = mFilter->getId64Bit(&mFilterId);
+    if (status.isOk()) {
+        mFilterCallback->setFilterId(mFilterId);
+        mFilterCallback->setFilterInterface(mFilter);
+        mUsedFilterIds.insert(mUsedFilterIds.end(), mFilterId);
+        mFilters[mFilterId] = mFilter;
+        mFilterCallbacks[mFilterId] = mFilterCallback;
+        filterId = mFilterId;
+
+        // Check getId() too.
+        int32_t filterId32Bit;
+        status = mFilter->getId(&filterId32Bit);
+    }
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::getSharedAvMemoryHandle(int64_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Open media filter first.";
+    NativeHandle avMemory;
+    int64_t avMemSize;
+    ndk::ScopedAStatus status = mFilters[filterId]->getAvSharedHandle(&avMemory, &avMemSize);
+    if (status.isOk()) {
+        mAvSharedHandle = android::dupFromAidl(avMemory);
+        mFilterCallbacks[mFilterId]->setSharedHandle(mAvSharedHandle);
+        mFilterCallbacks[mFilterId]->setMemSize(avMemSize);
+    }
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::releaseShareAvHandle(int64_t filterId) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mFilters[filterId]) << "Open media filter first.";
+    EXPECT_TRUE(mAvSharedHandle) << "No shared av handle to release.";
+    status = mFilters[filterId]->releaseAvHandle(::android::makeToAidl(mAvSharedHandle),
+                                                 0 /*dataId*/);
+    native_handle_close(mAvSharedHandle);
+    native_handle_delete(mAvSharedHandle);
+    mAvSharedHandle = nullptr;
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, int64_t filterId) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    status = mFilters[filterId]->configure(setting);
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::configAvFilterStreamType(AvStreamType type, int64_t filterId) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+
+    status = mFilters[filterId]->configureAvStreamType(type);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::configIpFilterCid(int32_t ipCid, int64_t filterId) {
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mFilters[filterId]) << "Open Ip filter first.";
+
+    status = mFilters[filterId]->configureIpCid(ipCid);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::getFilterMQDescriptor(int64_t filterId, bool getMqDesc) {
+    if (!getMqDesc) {
+        ALOGE("[vts] Filter does not need FMQ.");
+        return success();
+    }
+    ndk::ScopedAStatus status;
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
+
+    status = mFilters[filterId]->getQueueDesc(&mFilterMQDescriptor);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::startFilter(int64_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+
+    ndk::ScopedAStatus status = mFilters[filterId]->start();
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::stopFilter(int64_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+
+    ndk::ScopedAStatus status = mFilters[filterId]->stop();
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::closeFilter(int64_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    ndk::ScopedAStatus status = mFilters[filterId]->close();
+    if (status.isOk()) {
+        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.isOk());
+}
+
+AssertionResult FilterTests::configureMonitorEvent(int64_t filterId, int32_t monitorEventTypes) {
+    EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    ndk::ScopedAStatus status;
+
+    status = mFilters[filterId]->configureMonitorEvent(monitorEventTypes);
+    if (monitorEventTypes & static_cast<int32_t>(DemuxFilterMonitorEventType::SCRAMBLING_STATUS)) {
+        mFilterCallbacks[filterId]->testFilterScramblingEvent();
+    }
+    if (monitorEventTypes & static_cast<int32_t>(DemuxFilterMonitorEventType::IP_CID_CHANGE)) {
+        mFilterCallbacks[filterId]->testFilterIpCidEvent();
+    }
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::startIdTest(int64_t filterId) {
+    EXPECT_TRUE(mFilterCallbacks[filterId]) << "Test with getNewlyOpenedFilterId first.";
+    mFilterCallbacks[filterId]->testStartIdAfterReconfigure();
+    return AssertionResult(true);
+}
+
+AssertionResult FilterTests::openTimeFilterInDemux() {
+    if (!mDemux) {
+        ALOGW("[vts] Test with openDemux first.");
+        return failure();
+    }
+
+    // Add time filter to the local demux
+    auto status = mDemux->openTimeFilter(&mTimeFilter);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::setTimeStamp(int64_t timeStamp) {
+    if (!mTimeFilter) {
+        ALOGW("[vts] Test with openTimeFilterInDemux first.");
+        return failure();
+    }
+
+    mBeginTimeStamp = timeStamp;
+    return AssertionResult(mTimeFilter->setTimeStamp(timeStamp).isOk());
+}
+
+AssertionResult FilterTests::getTimeStamp() {
+    if (!mTimeFilter) {
+        ALOGW("[vts] Test with openTimeFilterInDemux first.");
+        return failure();
+    }
+
+    int64_t timeStamp;
+    auto status = mTimeFilter->getTimeStamp(&timeStamp);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::setFilterDataSource(int64_t sourceFilterId, int64_t sinkFilterId) {
+    if (!mFilters[sourceFilterId] || !mFilters[sinkFilterId]) {
+        ALOGE("[vts] setFilterDataSource filter not opened.");
+        return failure();
+    }
+
+    auto status = mFilters[sinkFilterId]->setDataSource(mFilters[sourceFilterId]);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::setFilterDataSourceToDemux(int64_t filterId) {
+    if (!mFilters[filterId]) {
+        ALOGE("[vts] setFilterDataSourceToDemux filter not opened.");
+        return failure();
+    }
+
+    auto status = mFilters[filterId]->setDataSource(nullptr);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FilterTests::clearTimeStamp() {
+    if (!mTimeFilter) {
+        ALOGW("[vts] Test with openTimeFilterInDemux first.");
+        return failure();
+    }
+
+    return AssertionResult(mTimeFilter->clearTimeStamp().isOk());
+}
+
+AssertionResult FilterTests::closeTimeFilter() {
+    if (!mTimeFilter) {
+        ALOGW("[vts] Test with openTimeFilterInDemux first.");
+        return failure();
+    }
+
+    return AssertionResult(mTimeFilter->close().isOk());
+}
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.h b/tv/tuner/aidl/vts/functional/FilterTests.h
new file mode 100644
index 0000000..91a0a4a
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/FilterTests.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnFilterCallback.h>
+#include <aidl/android/hardware/tv/tuner/IDemux.h>
+#include <aidl/android/hardware/tv/tuner/IFilter.h>
+#include <aidl/android/hardware/tv/tuner/ITuner.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <map>
+
+#include <fmq/AidlMessageQueue.h>
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::Condition;
+using ::android::Mutex;
+using ::android::hardware::EventFlag;
+
+using ::testing::AssertionResult;
+
+using namespace aidl::android::hardware::tv::tuner;
+using namespace std;
+
+enum FilterEventType : uint8_t {
+    UNDEFINED,
+    SECTION,
+    MEDIA,
+    PES,
+    RECORD,
+    MMTPRECORD,
+    DOWNLOAD,
+    TEMI,
+};
+
+using FilterMQ = AidlMessageQueue<int8_t, SynchronizedReadWrite>;
+using MQDesc = MQDescriptor<int8_t, SynchronizedReadWrite>;
+
+#define WAIT_TIMEOUT 3000000000
+
+class FilterCallback : public BnFilterCallback {
+  public:
+    virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override {
+        android::Mutex::Autolock autoLock(mMsgLock);
+        // Temprarily we treat the first coming back filter data on the matching pid a success
+        // once all of the MQ are cleared, means we got all the expected output
+        readFilterEventsData(events);
+        mPidFilterOutputCount++;
+        mMsgCondition.signal();
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    virtual ::ndk::ScopedAStatus onFilterStatus(const DemuxFilterStatus /*status*/) override {
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    void setFilterId(int32_t filterId) { mFilterId = filterId; }
+    void setFilterInterface(std::shared_ptr<IFilter> filter) { mFilter = filter; }
+    void setFilterEventType(FilterEventType type) { mFilterEventType = type; }
+    void setSharedHandle(native_handle_t* sharedHandle) { mAvSharedHandle = sharedHandle; }
+    void setMemSize(uint64_t size) { mAvSharedMemSize = size; }
+
+    void testFilterDataOutput();
+    void testFilterScramblingEvent();
+    void testFilterIpCidEvent();
+    void testStartIdAfterReconfigure();
+
+    void readFilterEventsData(const vector<DemuxFilterEvent>& events);
+    bool dumpAvData(const DemuxFilterMediaEvent& event);
+
+  private:
+    int32_t mFilterId;
+    std::shared_ptr<IFilter> mFilter;
+    FilterEventType mFilterEventType;
+
+    native_handle_t* mAvSharedHandle = nullptr;
+    uint64_t mAvSharedMemSize = -1;
+
+    android::Mutex mMsgLock;
+    android::Mutex mFilterOutputLock;
+    android::Condition mMsgCondition;
+
+    int mPidFilterOutputCount = 0;
+    int mScramblingStatusEvent = 0;
+    int mIpCidEvent = 0;
+    bool mStartIdReceived = false;
+};
+
+class FilterTests {
+  public:
+    void setService(std::shared_ptr<ITuner> tuner) { mService = tuner; }
+    void setDemux(std::shared_ptr<IDemux> demux) { mDemux = demux; }
+    std::shared_ptr<IFilter> getFilterById(int64_t filterId) { return mFilters[filterId]; }
+
+    map<int64_t, std::shared_ptr<FilterCallback>> getFilterCallbacks() { return mFilterCallbacks; }
+
+    AssertionResult openFilterInDemux(DemuxFilterType type, int32_t bufferSize);
+    AssertionResult getNewlyOpenedFilterId_64bit(int64_t& filterId);
+    AssertionResult getSharedAvMemoryHandle(int64_t filterId);
+    AssertionResult releaseShareAvHandle(int64_t filterId);
+    AssertionResult configFilter(DemuxFilterSettings setting, int64_t filterId);
+    AssertionResult configAvFilterStreamType(AvStreamType type, int64_t filterId);
+    AssertionResult configIpFilterCid(int32_t ipCid, int64_t filterId);
+    AssertionResult configureMonitorEvent(int64_t filterId, int32_t monitorEventTypes);
+    AssertionResult getFilterMQDescriptor(int64_t filterId, bool getMqDesc);
+    AssertionResult startFilter(int64_t filterId);
+    AssertionResult stopFilter(int64_t filterId);
+    AssertionResult closeFilter(int64_t filterId);
+    AssertionResult startIdTest(int64_t filterId);
+
+    AssertionResult openTimeFilterInDemux();
+    AssertionResult setTimeStamp(int64_t timeStamp);
+    AssertionResult getTimeStamp();
+    AssertionResult setFilterDataSource(int64_t sourceFilterId, int64_t sinkFilterId);
+    AssertionResult setFilterDataSourceToDemux(int64_t filterId);
+    AssertionResult clearTimeStamp();
+    AssertionResult closeTimeFilter();
+
+  protected:
+    static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+    static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+    std::shared_ptr<ITuner> mService;
+    std::shared_ptr<IFilter> mFilter;
+    std::shared_ptr<IDemux> mDemux;
+    std::shared_ptr<ITimeFilter> mTimeFilter;
+    map<int64_t, std::shared_ptr<IFilter>> mFilters;
+    map<int64_t, std::shared_ptr<FilterCallback>> mFilterCallbacks;
+
+    std::shared_ptr<FilterCallback> mFilterCallback;
+    MQDesc mFilterMQDescriptor;
+    vector<int64_t> mUsedFilterIds;
+
+    native_handle_t* mAvSharedHandle = nullptr;
+    int64_t mFilterId = -1;
+    int64_t mBeginTimeStamp;
+};
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
new file mode 100644
index 0000000..93b7976
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -0,0 +1,486 @@
+/*
+ * Copyright 2021 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"
+
+ndk::ScopedAStatus FrontendCallback::onEvent(FrontendEventType frontendEventType) {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    ALOGD("[vts] frontend event received. Type: %d", frontendEventType);
+    mEventReceived = true;
+    mMsgCondition.signal();
+    switch (frontendEventType) {
+        case FrontendEventType::LOCKED:
+            mLockMsgReceived = true;
+            mLockMsgCondition.signal();
+            break;
+        default:
+            // do nothing
+            break;
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus FrontendCallback::onScanMessage(FrontendScanMessageType type,
+                                                   const FrontendScanMessage& message) {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (!mScanMsgProcessed) {
+        mMsgCondition.wait(mMsgLock);
+    }
+    ALOGD("[vts] frontend scan message. Type: %d", type);
+    switch (message.getTag()) {
+        case FrontendScanMessage::modulation:
+            readFrontendScanMessage_Modulation(message.get<FrontendScanMessage::Tag::modulation>());
+            break;
+        case FrontendScanMessage::Tag::isHighPriority:
+            ALOGD("[vts] frontend scan message high priority: %d",
+                  message.get<FrontendScanMessage::Tag::isHighPriority>());
+            break;
+        case FrontendScanMessage::Tag::annex:
+            ALOGD("[vts] frontend scan message dvbc annex: %hhu",
+                  message.get<FrontendScanMessage::Tag::annex>());
+            break;
+        default:
+            break;
+    }
+    mScanMessageReceived = true;
+    mScanMsgProcessed = false;
+    mScanMessageType = type;
+    mScanMessage = message;
+    mMsgCondition.signal();
+    return ndk::ScopedAStatus::ok();
+}
+
+void FrontendCallback::readFrontendScanMessage_Modulation(FrontendModulation modulation) {
+    switch (modulation.getTag()) {
+        case FrontendModulation::Tag::dvbc:
+            ALOGD("[vts] frontend scan message modulation dvbc: %d",
+                  modulation.get<FrontendModulation::Tag::dvbc>());
+            break;
+        case FrontendModulation::Tag::dvbs:
+            ALOGD("[vts] frontend scan message modulation dvbs: %d",
+                  modulation.get<FrontendModulation::Tag::dvbs>());
+            break;
+        case FrontendModulation::Tag::isdbs:
+            ALOGD("[vts] frontend scan message modulation isdbs: %d",
+                  modulation.get<FrontendModulation::Tag::isdbs>());
+            break;
+        case FrontendModulation::Tag::isdbs3:
+            ALOGD("[vts] frontend scan message modulation isdbs3: %d",
+                  modulation.get<FrontendModulation::Tag::isdbs3>());
+            break;
+        case FrontendModulation::Tag::isdbt:
+            ALOGD("[vts] frontend scan message modulation isdbt: %d",
+                  modulation.get<FrontendModulation::Tag::isdbt>());
+            break;
+        case FrontendModulation::Tag::atsc:
+            ALOGD("[vts] frontend scan message modulation atsc: %d",
+                  modulation.get<FrontendModulation::Tag::atsc>());
+            break;
+        case FrontendModulation::Tag::atsc3:
+            ALOGD("[vts] frontend scan message modulation atsc3: %d",
+                  modulation.get<FrontendModulation::Tag::atsc3>());
+            break;
+        case FrontendModulation::Tag::dvbt:
+            ALOGD("[vts] frontend scan message modulation dvbt: %d",
+                  modulation.get<FrontendModulation::Tag::dvbt>());
+            break;
+        default:
+            break;
+    }
+}
+
+void FrontendCallback::tuneTestOnLock(std::shared_ptr<IFrontend>& frontend,
+                                      FrontendSettings settings) {
+    ndk::ScopedAStatus result = frontend->tune(settings);
+    EXPECT_TRUE(result.isOk());
+
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (!mLockMsgReceived) {
+        if (-ETIMEDOUT == mLockMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "Event LOCKED not received within timeout";
+            mLockMsgReceived = false;
+            return;
+        }
+    }
+    mLockMsgReceived = false;
+}
+
+void FrontendCallback::scanTest(std::shared_ptr<IFrontend>& frontend, FrontendConfig config,
+                                FrontendScanType type) {
+    int32_t targetFrequency = getTargetFrequency(config.settings);
+    if (type == FrontendScanType::SCAN_BLIND) {
+        // reset the frequency in the scan configuration to test blind scan. The settings param of
+        // passed in means the real input config on the transponder connected to the DUT.
+        // We want the blind the test to start from lower frequency than this to check the blind
+        // scan implementation.
+        resetBlindScanStartingFrequency(config, targetFrequency - 100);
+    }
+
+    ndk::ScopedAStatus result = frontend->scan(config.settings, type);
+    EXPECT_TRUE(result.isOk());
+
+    bool scanMsgLockedReceived = false;
+    bool targetFrequencyReceived = false;
+
+    android::Mutex::Autolock autoLock(mMsgLock);
+wait:
+    while (!mScanMessageReceived) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "Scan message not received within timeout";
+            mScanMessageReceived = false;
+            mScanMsgProcessed = true;
+            return;
+        }
+    }
+
+    if (mScanMessageType != FrontendScanMessageType::END) {
+        if (mScanMessageType == FrontendScanMessageType::LOCKED) {
+            scanMsgLockedReceived = true;
+            result = frontend->scan(config.settings, type);
+            EXPECT_TRUE(result.isOk());
+        }
+
+        if (mScanMessageType == FrontendScanMessageType::FREQUENCY) {
+            targetFrequencyReceived =
+                    mScanMessage.get<FrontendScanMessage::Tag::frequencies>().size() > 0 &&
+                    mScanMessage.get<FrontendScanMessage::Tag::frequencies>()[0] == targetFrequency;
+        }
+
+        if (mScanMessageType == FrontendScanMessageType::PROGRESS_PERCENT) {
+            ALOGD("[vts] Scan in progress...[%d%%]",
+                  mScanMessage.get<FrontendScanMessage::Tag::progressPercent>());
+        }
+
+        mScanMessageReceived = false;
+        mScanMsgProcessed = true;
+        mMsgCondition.signal();
+        goto wait;
+    }
+
+    EXPECT_TRUE(scanMsgLockedReceived) << "Scan message LOCKED not received before END";
+    EXPECT_TRUE(targetFrequencyReceived) << "frequency not received before LOCKED on blindScan";
+    mScanMessageReceived = false;
+    mScanMsgProcessed = true;
+}
+
+int32_t FrontendCallback::getTargetFrequency(FrontendSettings& settings) {
+    switch (settings.getTag()) {
+        case FrontendSettings::Tag::analog:
+            return settings.get<FrontendSettings::Tag::analog>().frequency;
+        case FrontendSettings::Tag::atsc:
+            return settings.get<FrontendSettings::Tag::atsc>().frequency;
+        case FrontendSettings::Tag::atsc3:
+            return settings.get<FrontendSettings::Tag::atsc3>().frequency;
+        case FrontendSettings::Tag::dvbc:
+            return settings.get<FrontendSettings::Tag::dvbc>().frequency;
+        case FrontendSettings::Tag::dvbs:
+            return settings.get<FrontendSettings::Tag::dvbs>().frequency;
+        case FrontendSettings::Tag::dvbt:
+            return settings.get<FrontendSettings::Tag::dvbt>().frequency;
+        case FrontendSettings::Tag::isdbs:
+            return settings.get<FrontendSettings::Tag::isdbs>().frequency;
+        case FrontendSettings::Tag::isdbs3:
+            return settings.get<FrontendSettings::Tag::isdbs3>().frequency;
+        case FrontendSettings::Tag::isdbt:
+            return settings.get<FrontendSettings::Tag::isdbt>().frequency;
+        default:
+            return 0;
+    }
+}
+
+void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig& config,
+                                                       int32_t resetingFreq) {
+    switch (config.settings.getTag()) {
+        case FrontendSettings::Tag::analog:
+            config.settings.get<FrontendSettings::Tag::analog>().frequency = resetingFreq;
+            break;
+        case FrontendSettings::Tag::atsc:
+            config.settings.get<FrontendSettings::Tag::atsc>().frequency = resetingFreq;
+            break;
+        case FrontendSettings::Tag::atsc3:
+            config.settings.get<FrontendSettings::Tag::atsc3>().frequency = resetingFreq;
+            break;
+        case FrontendSettings::Tag::dvbc:
+            config.settings.get<FrontendSettings::Tag::dvbc>().frequency = resetingFreq;
+            break;
+        case FrontendSettings::Tag::dvbs:
+            config.settings.get<FrontendSettings::Tag::dvbs>().frequency = resetingFreq;
+            break;
+        case FrontendSettings::Tag::dvbt:
+            config.settings.get<FrontendSettings::Tag::dvbt>().frequency = resetingFreq;
+            break;
+        case FrontendSettings::Tag::isdbs:
+            config.settings.get<FrontendSettings::Tag::isdbs>().frequency = resetingFreq;
+            break;
+        case FrontendSettings::Tag::isdbs3:
+            config.settings.get<FrontendSettings::Tag::isdbs3>().frequency = resetingFreq;
+            break;
+        case FrontendSettings::Tag::isdbt:
+            config.settings.get<FrontendSettings::Tag::isdbt>().frequency = resetingFreq;
+            break;
+        default:
+            break;
+    }
+}
+
+AssertionResult FrontendTests::getFrontendIds() {
+    ndk::ScopedAStatus status;
+    status = mService->getFrontendIds(&mFeIds);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FrontendTests::getFrontendInfo(int32_t frontendId) {
+    ndk::ScopedAStatus status;
+    status = mService->getFrontendInfo(frontendId, &mFrontendInfo);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FrontendTests::openFrontendById(int32_t frontendId) {
+    ndk::ScopedAStatus status;
+    status = mService->openFrontendById(frontendId, &mFrontend);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FrontendTests::setFrontendCallback() {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+    mFrontendCallback = ndk::SharedRefBase::make<FrontendCallback>();
+    auto callbackStatus = mFrontend->setCallback(mFrontendCallback);
+    return AssertionResult(callbackStatus.isOk());
+}
+
+AssertionResult FrontendTests::scanFrontend(FrontendConfig config, FrontendScanType type) {
+    EXPECT_TRUE(mFrontendCallback)
+            << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
+
+    EXPECT_TRUE(mFrontendInfo.type == config.type)
+            << "FrontendConfig does not match the frontend info of the given id.";
+
+    mFrontendCallback->scanTest(mFrontend, config, type);
+    return AssertionResult(true);
+}
+
+AssertionResult FrontendTests::stopScanFrontend() {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+    ndk::ScopedAStatus status;
+    status = mFrontend->stopScan();
+
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FrontendTests::setLnb(int32_t lnbId) {
+    if (!mFrontendCallback) {
+        ALOGW("[vts] open and set frontend callback first.");
+        return failure();
+    }
+    return AssertionResult(mFrontend->setLnb(lnbId).isOk());
+}
+
+AssertionResult FrontendTests::linkCiCam(int32_t ciCamId) {
+    ndk::ScopedAStatus status;
+    int32_t ltsId;
+    status = mFrontend->linkCiCam(ciCamId, &ltsId);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FrontendTests::unlinkCiCam(int32_t ciCamId) {
+    ndk::ScopedAStatus status = mFrontend->unlinkCiCam(ciCamId);
+    return AssertionResult(status.isOk());
+}
+
+void FrontendTests::verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
+                                         vector<FrontendStatus> expectStatuses) {
+    ASSERT_TRUE(mFrontend) << "Frontend is not opened yet.";
+    ndk::ScopedAStatus status;
+    vector<FrontendStatus> realStatuses;
+
+    status = mFrontend->getStatus(statusTypes, &realStatuses);
+    ASSERT_TRUE(status.isOk() && realStatuses.size() == statusTypes.size());
+
+    for (int i = 0; i < statusTypes.size(); i++) {
+        FrontendStatusType type = statusTypes[i];
+        switch (type) {
+            case FrontendStatusType::MODULATIONS: {
+                // TODO: verify modulations
+                break;
+            }
+            case FrontendStatusType::BERS: {
+                ASSERT_TRUE(std::equal(realStatuses[i].get<FrontendStatus::Tag::bers>().begin(),
+                                       realStatuses[i].get<FrontendStatus::Tag::bers>().end(),
+                                       expectStatuses[i].get<FrontendStatus::Tag::bers>().begin()));
+                break;
+            }
+            case FrontendStatusType::CODERATES: {
+                ASSERT_TRUE(std::equal(
+                        realStatuses[i].get<FrontendStatus::Tag::codeRates>().begin(),
+                        realStatuses[i].get<FrontendStatus::Tag::codeRates>().end(),
+                        expectStatuses[i].get<FrontendStatus::Tag::codeRates>().begin()));
+                break;
+            }
+            case FrontendStatusType::GUARD_INTERVAL: {
+                // TODO: verify interval
+                break;
+            }
+            case FrontendStatusType::TRANSMISSION_MODE: {
+                // TODO: verify tranmission mode
+                break;
+            }
+            case FrontendStatusType::UEC: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::uec>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::uec>());
+                break;
+            }
+            case FrontendStatusType::T2_SYSTEM_ID: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::systemId>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::systemId>());
+                break;
+            }
+            case FrontendStatusType::INTERLEAVINGS: {
+                ASSERT_TRUE(std::equal(
+                        realStatuses[i].get<FrontendStatus::Tag::interleaving>().begin(),
+                        realStatuses[i].get<FrontendStatus::Tag::interleaving>().end(),
+                        expectStatuses[i].get<FrontendStatus::Tag::interleaving>().begin()));
+                break;
+            }
+            case FrontendStatusType::ISDBT_SEGMENTS: {
+                ASSERT_TRUE(std::equal(
+                        realStatuses[i].get<FrontendStatus::Tag::isdbtSegment>().begin(),
+                        realStatuses[i].get<FrontendStatus::Tag::isdbtSegment>().end(),
+                        expectStatuses[i].get<FrontendStatus::Tag::isdbtSegment>().begin()));
+                break;
+            }
+            case FrontendStatusType::TS_DATA_RATES: {
+                ASSERT_TRUE(std::equal(
+                        realStatuses[i].get<FrontendStatus::Tag::tsDataRate>().begin(),
+                        realStatuses[i].get<FrontendStatus::Tag::tsDataRate>().end(),
+                        expectStatuses[i].get<FrontendStatus::Tag::tsDataRate>().begin()));
+                break;
+            }
+            case FrontendStatusType::ROLL_OFF: {
+                // TODO: verify roll off
+                break;
+            }
+            case FrontendStatusType::IS_MISO: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isMiso>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::isMiso>());
+                break;
+            }
+            case FrontendStatusType::IS_LINEAR: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isLinear>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::isLinear>());
+                break;
+            }
+            case FrontendStatusType::IS_SHORT_FRAMES: {
+                ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isShortFrames>() ==
+                            expectStatuses[i].get<FrontendStatus::Tag::isShortFrames>());
+                break;
+            }
+            default: {
+                continue;
+            }
+        }
+    }
+    ASSERT_TRUE(status.isOk());
+}
+
+AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWithDemux) {
+    EXPECT_TRUE(mFrontendCallback)
+            << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
+
+    EXPECT_TRUE(mFrontendInfo.type == config.type)
+            << "FrontendConfig does not match the frontend info of the given id.";
+
+    mIsSoftwareFe = config.isSoftwareFe;
+    if (mIsSoftwareFe && testWithDemux) {
+        if (getDvrTests()->openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) != success()) {
+            ALOGW("[vts] Software frontend dvr configure openDvr failed.");
+            return failure();
+        }
+        if (getDvrTests()->configDvrPlayback(mDvrConfig.settings) != success()) {
+            ALOGW("[vts] Software frontend dvr configure Dvr playback failed.");
+            return failure();
+        }
+        if (getDvrTests()->getDvrPlaybackMQDescriptor() != success()) {
+            ALOGW("[vts] Software frontend dvr configure get MQDesc failed.");
+            return failure();
+        }
+        getDvrTests()->startPlaybackInputThread(
+                mDvrConfig.playbackInputFile,
+                mDvrConfig.settings.get<DvrSettings::Tag::playback>());
+    }
+    mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
+    return AssertionResult(true);
+}
+
+AssertionResult FrontendTests::stopTuneFrontend(bool testWithDemux) {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+    ndk::ScopedAStatus status;
+    status = mFrontend->stopTune();
+    if (mIsSoftwareFe && testWithDemux) {
+        getDvrTests()->stopPlaybackThread();
+        getDvrTests()->closeDvrPlayback();
+    }
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult FrontendTests::closeFrontend() {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+    ndk::ScopedAStatus status;
+    status = mFrontend->close();
+    mFrontend = nullptr;
+    mFrontendCallback = nullptr;
+    return AssertionResult(status.isOk());
+}
+
+void FrontendTests::getFrontendIdByType(FrontendType feType, int32_t& feId) {
+    ASSERT_TRUE(getFrontendIds());
+    ASSERT_TRUE(mFeIds.size() > 0);
+    for (size_t i = 0; i < mFeIds.size(); i++) {
+        ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+        if (mFrontendInfo.type != feType) {
+            continue;
+        }
+        feId = mFeIds[i];
+        return;
+    }
+    feId = INVALID_ID;
+}
+
+void FrontendTests::tuneTest(FrontendConfig frontendConf) {
+    int32_t feId;
+    getFrontendIdByType(frontendConf.type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(openFrontendById(feId));
+    ASSERT_TRUE(setFrontendCallback());
+    if (frontendConf.canConnectToCiCam) {
+        ASSERT_TRUE(linkCiCam(frontendConf.ciCamId));
+        ASSERT_TRUE(unlinkCiCam(frontendConf.ciCamId));
+    }
+    ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
+    verifyFrontendStatus(frontendConf.tuneStatusTypes, frontendConf.expectTuneStatuses);
+    ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
+    ASSERT_TRUE(closeFrontend());
+}
+
+void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanType) {
+    int32_t feId;
+    getFrontendIdByType(frontendConf.type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(openFrontendById(feId));
+    ASSERT_TRUE(setFrontendCallback());
+    ASSERT_TRUE(scanFrontend(frontendConf, scanType));
+    ASSERT_TRUE(stopScanFrontend());
+    ASSERT_TRUE(closeFrontend());
+}
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.h b/tv/tuner/aidl/vts/functional/FrontendTests.h
new file mode 100644
index 0000000..b65704f
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnFrontendCallback.h>
+#include <aidl/android/hardware/tv/tuner/IFrontend.h>
+#include <aidl/android/hardware/tv/tuner/ITuner.h>
+
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+
+#include "DvrTests.h"
+#include "VtsHalTvTunerTestConfigurations.h"
+
+#define WAIT_TIMEOUT 3000000000
+#define INVALID_ID -1
+
+using android::Condition;
+using android::Mutex;
+
+using ::testing::AssertionResult;
+
+using namespace aidl::android::hardware::tv::tuner;
+using namespace std;
+
+#define INVALID_ID -1
+#define WAIT_TIMEOUT 3000000000
+
+class FrontendCallback : public BnFrontendCallback {
+  public:
+    virtual ndk::ScopedAStatus onEvent(FrontendEventType frontendEventType) override;
+    virtual ndk::ScopedAStatus onScanMessage(FrontendScanMessageType type,
+                                             const FrontendScanMessage& message) override;
+
+    void tuneTestOnLock(std::shared_ptr<IFrontend>& frontend, FrontendSettings settings);
+    void scanTest(std::shared_ptr<IFrontend>& frontend, FrontendConfig config,
+                  FrontendScanType type);
+
+    // Helper methods
+    int32_t getTargetFrequency(FrontendSettings& settings);
+    void resetBlindScanStartingFrequency(FrontendConfig& config, int32_t resetingFreq);
+
+  private:
+    void readFrontendScanMessage_Modulation(FrontendModulation modulation);
+
+    bool mEventReceived = false;
+    bool mScanMessageReceived = false;
+    bool mLockMsgReceived = false;
+    bool mScanMsgProcessed = true;
+    FrontendScanMessageType mScanMessageType;
+    FrontendScanMessage mScanMessage;
+    vector<int8_t> mEventMessage;
+    android::Mutex mMsgLock;
+    android::Condition mMsgCondition;
+    android::Condition mLockMsgCondition;
+};
+
+class FrontendTests {
+  public:
+    void setService(std::shared_ptr<ITuner> tuner) {
+        mService = tuner;
+        getDvrTests()->setService(tuner);
+        getDefaultSoftwareFrontendPlaybackConfig(mDvrConfig);
+    }
+
+    AssertionResult getFrontendIds();
+    AssertionResult getFrontendInfo(int32_t frontendId);
+    AssertionResult openFrontendById(int32_t frontendId);
+    AssertionResult setFrontendCallback();
+    AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
+    AssertionResult stopScanFrontend();
+    AssertionResult setLnb(int32_t lnbId);
+    AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux);
+    void verifyFrontendStatus(vector<FrontendStatusType> statusTypes,
+                              vector<FrontendStatus> expectStatuses);
+    AssertionResult stopTuneFrontend(bool testWithDemux);
+    AssertionResult closeFrontend();
+
+    AssertionResult linkCiCam(int32_t ciCamId);
+    AssertionResult unlinkCiCam(int32_t ciCamId);
+
+    void getFrontendIdByType(FrontendType feType, int32_t& feId);
+    void tuneTest(FrontendConfig frontendConf);
+    void scanTest(FrontendConfig frontend, FrontendScanType type);
+
+    void setDvrTests(DvrTests* dvrTests) { mExternalDvrTests = dvrTests; }
+    void setDemux(std::shared_ptr<IDemux> demux) { getDvrTests()->setDemux(demux); }
+    void setSoftwareFrontendDvrConfig(DvrConfig conf) { mDvrConfig = conf; }
+
+  protected:
+    static AssertionResult failure() { return ::testing::AssertionFailure(); }
+    static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+    void getDefaultSoftwareFrontendPlaybackConfig(DvrConfig& dvrConfig) {
+        PlaybackSettings playbackSettings{
+                .statusMask = 0xf,
+                .lowThreshold = 0x1000,
+                .highThreshold = 0x07fff,
+                .dataFormat = DataFormat::ES,
+                .packetSize = static_cast<int8_t>(188),
+        };
+        dvrConfig.type = DvrType::PLAYBACK;
+        dvrConfig.playbackInputFile = "/data/local/tmp/test.es";
+        dvrConfig.bufferSize = FMQ_SIZE_4M;
+        dvrConfig.settings.set<DvrSettings::playback>(playbackSettings);
+    }
+
+    DvrTests* getDvrTests() {
+        return (mExternalDvrTests != nullptr ? mExternalDvrTests : &mDvrTests);
+    }
+
+    std::shared_ptr<ITuner> mService;
+    std::shared_ptr<IFrontend> mFrontend;
+    FrontendInfo mFrontendInfo;
+    std::shared_ptr<FrontendCallback> mFrontendCallback;
+    vector<int32_t> mFeIds;
+
+    DvrTests mDvrTests;
+    DvrTests* mExternalDvrTests = nullptr;
+    bool mIsSoftwareFe = false;
+    DvrConfig mDvrConfig;
+};
diff --git a/tv/tuner/aidl/vts/functional/LnbTests.cpp b/tv/tuner/aidl/vts/functional/LnbTests.cpp
new file mode 100644
index 0000000..d62e58a
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/LnbTests.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2021 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 <log/log.h>
+
+#include "LnbTests.h"
+
+ndk::ScopedAStatus LnbCallback::onEvent(LnbEventType lnbEventType) {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    ALOGD("[vts] lnb event received. Type: %d", lnbEventType);
+    mEventReceived = true;
+    mMsgCondition.signal();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus LnbCallback::onDiseqcMessage(const vector<uint8_t>& diseqcMessage) {
+    string msg(diseqcMessage.begin(), diseqcMessage.end());
+    ALOGD("[vts] onDiseqcMessage %s", msg.c_str());
+    return ndk::ScopedAStatus::ok();
+}
+
+AssertionResult LnbTests::getLnbIds(vector<int32_t>& ids) {
+    ndk::ScopedAStatus status;
+    status = mService->getLnbIds(&ids);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult LnbTests::openLnbById(int32_t lnbId) {
+    ndk::ScopedAStatus status;
+    status = mService->openLnbById(lnbId, &mLnb);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult LnbTests::openLnbByName(string lnbName, int32_t& id) {
+    ndk::ScopedAStatus status;
+    vector<int32_t> ids;
+    status = mService->openLnbByName(lnbName, &ids, &mLnb);
+    if (status.isOk()) {
+        id = ids[0];
+    }
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult LnbTests::setLnbCallback() {
+    if (!mLnb) {
+        ALOGW("[vts] Open Lnb first");
+        return failure();
+    }
+    mLnbCallback = ndk::SharedRefBase::make<LnbCallback>();
+    auto callbackStatus = mLnb->setCallback(mLnbCallback);
+    return AssertionResult(callbackStatus.isOk());
+}
+
+AssertionResult LnbTests::setVoltage(LnbVoltage voltage) {
+    if (!mLnb) {
+        ALOGW("[vts] Open Lnb first");
+        return failure();
+    }
+    ndk::ScopedAStatus status = mLnb->setVoltage(voltage);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult LnbTests::setTone(LnbTone tone) {
+    if (!mLnb) {
+        ALOGW("[vts] Open Lnb first");
+        return failure();
+    }
+    ndk::ScopedAStatus status = mLnb->setTone(tone);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult LnbTests::setSatellitePosition(LnbPosition position) {
+    if (!mLnb) {
+        ALOGW("[vts] Open Lnb first");
+        return failure();
+    }
+    ndk::ScopedAStatus status = mLnb->setSatellitePosition(position);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult LnbTests::sendDiseqcMessage(vector<uint8_t> diseqcMsg) {
+    if (!mLnb) {
+        ALOGW("[vts] Open Lnb first");
+        return failure();
+    }
+    ndk::ScopedAStatus status = mLnb->sendDiseqcMessage(diseqcMsg);
+    return AssertionResult(status.isOk());
+}
+
+AssertionResult LnbTests::closeLnb() {
+    if (!mLnb) {
+        ALOGW("[vts] Open Lnb first");
+        return failure();
+    }
+    ndk::ScopedAStatus status = mLnb->close();
+    mLnb = nullptr;
+    mLnbCallback = nullptr;
+    return AssertionResult(status.isOk());
+}
diff --git a/tv/tuner/aidl/vts/functional/LnbTests.h b/tv/tuner/aidl/vts/functional/LnbTests.h
new file mode 100644
index 0000000..d6b5a25
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/LnbTests.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2021 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 <aidl/android/hardware/tv/tuner/BnLnbCallback.h>
+#include <aidl/android/hardware/tv/tuner/ILnb.h>
+#include <aidl/android/hardware/tv/tuner/ITuner.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+#include <map>
+
+using android::Condition;
+using android::Mutex;
+
+using ::testing::AssertionResult;
+
+using namespace aidl::android::hardware::tv::tuner;
+using namespace std;
+
+class LnbCallback : public BnLnbCallback {
+  public:
+    virtual ::ndk::ScopedAStatus onEvent(LnbEventType lnbEventType) override;
+    virtual ::ndk::ScopedAStatus onDiseqcMessage(
+            const std::vector<uint8_t>& diseqcMessage) override;
+
+  private:
+    bool mEventReceived = false;
+    android::Mutex mMsgLock;
+    android::Condition mMsgCondition;
+};
+
+class LnbTests {
+  public:
+    void setService(std::shared_ptr<ITuner> tuner) { mService = tuner; }
+
+    AssertionResult getLnbIds(vector<int32_t>& ids);
+    AssertionResult openLnbById(int32_t lnbId);
+    AssertionResult openLnbByName(string lnbName, int32_t& lnbId);
+    AssertionResult setLnbCallback();
+    AssertionResult setVoltage(LnbVoltage voltage);
+    AssertionResult setTone(LnbTone tone);
+    AssertionResult setSatellitePosition(LnbPosition position);
+    AssertionResult sendDiseqcMessage(vector<uint8_t> diseqcMsg);
+    AssertionResult closeLnb();
+
+  protected:
+    static AssertionResult failure() { return ::testing::AssertionFailure(); }
+
+    static AssertionResult success() { return ::testing::AssertionSuccess(); }
+
+    std::shared_ptr<ITuner> mService;
+    std::shared_ptr<ILnb> mLnb;
+    std::shared_ptr<LnbCallback> mLnbCallback;
+    vector<int32_t> mLnbIds;
+};
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
new file mode 100644
index 0000000..85e5c68
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -0,0 +1,878 @@
+/*
+ * Copyright 2021 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 "VtsHalTvTunerTargetTest.h"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+namespace {
+
+AssertionResult TunerBroadcastAidlTest::filterDataOutputTest() {
+    return filterDataOutputTestBase(mFilterTests);
+}
+
+AssertionResult TunerPlaybackAidlTest::filterDataOutputTest() {
+    return filterDataOutputTestBase(mFilterTests);
+}
+
+AssertionResult TunerDescramblerAidlTest::filterDataOutputTest() {
+    return filterDataOutputTestBase(mFilterTests);
+}
+
+void TunerFilterAidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf,
+                                                        FrontendConfig frontendConf) {
+    int32_t feId;
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    int64_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));
+    if (filterConf.type.mainType == DemuxFilterMainType::IP) {
+        ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId));
+    }
+    if (filterConf.monitorEventTypes > 0) {
+        ASSERT_TRUE(mFilterTests.configureMonitorEvent(filterId, filterConf.monitorEventTypes));
+    }
+    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
+void TunerFilterAidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterConf,
+                                                          FilterConfig filterReconf,
+                                                          FrontendConfig frontendConf) {
+    int32_t feId;
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    int64_t filterId;
+
+    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+    if (frontendConf.isSoftwareFe) {
+        mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]);
+    }
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFrontendTests.setDemux(demux);
+    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, filterConf.getMqDesc));
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterReconf.settings, filterId));
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+    ASSERT_TRUE(mFilterTests.startIdTest(filterId));
+    ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
+void TunerFilterAidlTest::testTimeFilter(TimeFilterConfig filterConf) {
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    DemuxCapabilities caps;
+
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.getDemuxCaps(caps));
+    ASSERT_TRUE(caps.bTimeFilter);
+    mFilterTests.setDemux(demux);
+    ASSERT_TRUE(mFilterTests.openTimeFilterInDemux());
+    ASSERT_TRUE(mFilterTests.setTimeStamp(filterConf.timeStamp));
+    ASSERT_TRUE(mFilterTests.getTimeStamp());
+    ASSERT_TRUE(mFilterTests.clearTimeStamp());
+    ASSERT_TRUE(mFilterTests.closeTimeFilter());
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+}
+
+void TunerBroadcastAidlTest::broadcastSingleFilterTest(FilterConfig filterConf,
+                                                       FrontendConfig frontendConf) {
+    int32_t feId;
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    int64_t filterId;
+
+    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+    if (mLnbId) {
+        ASSERT_TRUE(mFrontendTests.setLnb(*mLnbId));
+    }
+    if (frontendConf.isSoftwareFe) {
+        mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]);
+    }
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFrontendTests.setDemux(demux);
+    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, filterConf.getMqDesc));
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    // tune test
+    ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+    ASSERT_TRUE(filterDataOutputTest());
+    ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
+void TunerBroadcastAidlTest::broadcastSingleFilterTestWithLnb(FilterConfig filterConf,
+                                                              FrontendConfig frontendConf,
+                                                              LnbConfig lnbConf) {
+    if (lnbConf.name.compare(emptyHardwareId) == 0) {
+        vector<int32_t> ids;
+        ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+        ASSERT_TRUE(ids.size() > 0);
+        ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+        mLnbId = &ids[0];
+    } else {
+        mLnbId = (int32_t*)malloc(sizeof(int32_t));
+        ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId));
+    }
+    ASSERT_TRUE(mLnbTests.setLnbCallback());
+    ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage));
+    ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone));
+    ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConf.position));
+    broadcastSingleFilterTest(filterConf, frontendConf);
+    ASSERT_TRUE(mLnbTests.closeLnb());
+    mLnbId = nullptr;
+}
+
+void TunerBroadcastAidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf,
+                                                              FrontendConfig frontendConf) {
+    int32_t feId;
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    int64_t filterId;
+
+    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+    if (frontendConf.isSoftwareFe) {
+        mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[live.dvrSoftwareFeId]);
+    }
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFrontendTests.setDemux(demux);
+    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.getSharedAvMemoryHandle(filterId));
+    ASSERT_TRUE(mFilterTests.configAvFilterStreamType(filterConf.streamType, filterId));
+    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    // tune test
+    ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+    ASSERT_TRUE(filterDataOutputTest());
+    ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mFilterTests.releaseShareAvHandle(filterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
+void TunerPlaybackAidlTest::playbackSingleFilterTest(FilterConfig filterConf, DvrConfig dvrConf) {
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    int64_t filterId;
+
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    mFilterTests.setDemux(demux);
+    mDvrTests.setDemux(demux);
+    ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
+    ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrConf.settings));
+    ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+    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, filterConf.getMqDesc));
+    mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile,
+                                       dvrConf.settings.get<DvrSettings::Tag::playback>());
+    ASSERT_TRUE(mDvrTests.startDvrPlayback());
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    ASSERT_TRUE(filterDataOutputTest());
+    mDvrTests.stopPlaybackThread();
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    mDvrTests.closeDvrPlayback();
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+}
+
+void TunerRecordAidlTest::recordSingleFilterTestWithLnb(FilterConfig filterConf,
+                                                        FrontendConfig frontendConf,
+                                                        DvrConfig dvrConf, LnbConfig lnbConf) {
+    if (lnbConf.name.compare(emptyHardwareId) == 0) {
+        vector<int32_t> ids;
+        ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+        ASSERT_TRUE(ids.size() > 0);
+        ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+        mLnbId = &ids[0];
+    } else {
+        mLnbId = (int32_t*)malloc(sizeof(int32_t));
+        ASSERT_TRUE(mLnbTests.openLnbByName(lnbConf.name, *mLnbId));
+    }
+    ASSERT_TRUE(mLnbTests.setLnbCallback());
+    ASSERT_TRUE(mLnbTests.setVoltage(lnbConf.voltage));
+    ASSERT_TRUE(mLnbTests.setTone(lnbConf.tone));
+    ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbConf.position));
+    for (auto msgName : lnbRecord.diseqcMsgs) {
+        ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
+    }
+    recordSingleFilterTest(filterConf, frontendConf, dvrConf);
+    ASSERT_TRUE(mLnbTests.closeLnb());
+    mLnbId = nullptr;
+}
+
+void TunerRecordAidlTest::attachSingleFilterToRecordDvrTest(FilterConfig filterConf,
+                                                            FrontendConfig frontendConf,
+                                                            DvrConfig dvrConf) {
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    mDvrTests.setDemux(demux);
+
+    DvrConfig dvrSourceConfig;
+    if (record.hasFrontendConnection) {
+        int32_t feId;
+        mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+        ASSERT_TRUE(feId != INVALID_ID);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    } else {
+        dvrSourceConfig = dvrMap[record.dvrSourceId];
+        ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+        ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+        ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+    }
+
+    int64_t filterId;
+    std::shared_ptr<IFilter> filter;
+    mFilterTests.setDemux(demux);
+
+    ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
+    ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
+    ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
+
+    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, filterConf.getMqDesc));
+    filter = mFilterTests.getFilterById(filterId);
+    ASSERT_TRUE(filter != nullptr);
+    ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter));
+    ASSERT_TRUE(mDvrTests.startDvrRecord());
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mDvrTests.stopDvrRecord());
+    ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter));
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    mDvrTests.closeDvrRecord();
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+
+    if (record.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    }
+}
+
+void TunerRecordAidlTest::recordSingleFilterTest(FilterConfig filterConf,
+                                                 FrontendConfig frontendConf, DvrConfig dvrConf) {
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    mDvrTests.setDemux(demux);
+
+    DvrConfig dvrSourceConfig;
+    if (record.hasFrontendConnection) {
+        int32_t feId;
+        mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+        ASSERT_TRUE(feId != INVALID_ID);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        if (frontendConf.isSoftwareFe) {
+            mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[record.dvrSoftwareFeId]);
+        }
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+        mFrontendTests.setDvrTests(&mDvrTests);
+    } else {
+        dvrSourceConfig = dvrMap[record.dvrSourceId];
+        ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+        ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+        ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+    }
+
+    int64_t filterId;
+    std::shared_ptr<IFilter> filter;
+    mFilterTests.setDemux(demux);
+    ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
+    ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
+    ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
+    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, filterConf.getMqDesc));
+    filter = mFilterTests.getFilterById(filterId);
+    ASSERT_TRUE(filter != nullptr);
+    mDvrTests.startRecordOutputThread(dvrConf.settings.get<DvrSettings::Tag::record>());
+    ASSERT_TRUE(mDvrTests.attachFilterToDvr(filter));
+    ASSERT_TRUE(mDvrTests.startDvrRecord());
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+
+    if (record.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+    } else {
+        // Start DVR Source
+        mDvrTests.startPlaybackInputThread(
+                dvrSourceConfig.playbackInputFile,
+                dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
+        ASSERT_TRUE(mDvrTests.startDvrPlayback());
+    }
+
+    mDvrTests.testRecordOutput();
+    mDvrTests.stopRecordThread();
+
+    if (record.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+    } else {
+        mDvrTests.stopPlaybackThread();
+        ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+    }
+
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mDvrTests.stopDvrRecord());
+    ASSERT_TRUE(mDvrTests.detachFilterToDvr(filter));
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    mDvrTests.closeDvrRecord();
+
+    if (record.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    } else {
+        mDvrTests.closeDvrPlayback();
+    }
+
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+}
+
+void TunerDescramblerAidlTest::scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
+                                                      FrontendConfig frontendConf,
+                                                      DescramblerConfig descConfig) {
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+
+    DvrConfig dvrSourceConfig;
+    if (descrambling.hasFrontendConnection) {
+        int32_t feId;
+        mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        if (frontendConf.isSoftwareFe) {
+            mFrontendTests.setSoftwareFrontendDvrConfig(dvrMap[descrambling.dvrSoftwareFeId]);
+        }
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+        mFrontendTests.setDemux(demux);
+    } else {
+        dvrSourceConfig = dvrMap[descrambling.dvrSourceId];
+        mDvrTests.setDemux(demux);
+        ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrSourceConfig.type, dvrSourceConfig.bufferSize));
+        ASSERT_TRUE(mDvrTests.configDvrPlayback(dvrSourceConfig.settings));
+        ASSERT_TRUE(mDvrTests.getDvrPlaybackMQDescriptor());
+    }
+
+    set<int64_t> filterIds;
+    int64_t filterId;
+    set<struct FilterConfig>::iterator config;
+    set<int64_t>::iterator id;
+    mFilterTests.setDemux(demux);
+    for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) {
+        ASSERT_TRUE(mFilterTests.openFilterInDemux((*config).type, (*config).bufferSize));
+        ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
+        ASSERT_TRUE(mFilterTests.configFilter((*config).settings, filterId));
+        filterIds.insert(filterId);
+    }
+    ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId));
+    vector<uint8_t> token;
+    ASSERT_TRUE(mDescramblerTests.getKeyToken(descConfig.casSystemId, descConfig.provisionStr,
+                                              descConfig.hidlPvtData, token));
+    mDescramblerTests.setKeyToken(token);
+    vector<DemuxPid> pids;
+    DemuxPid pid;
+    for (config = mediaFilterConfs.begin(); config != mediaFilterConfs.end(); config++) {
+        ASSERT_TRUE(mDescramblerTests.getDemuxPidFromFilterSettings((*config).type,
+                                                                    (*config).settings, pid));
+        pids.push_back(pid);
+        ASSERT_TRUE(mDescramblerTests.addPid(pid, nullptr));
+    }
+    for (id = filterIds.begin(); id != filterIds.end(); id++) {
+        ASSERT_TRUE(mFilterTests.startFilter(*id));
+    }
+
+    if (descrambling.hasFrontendConnection) {
+        // tune test
+        ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+    } else {
+        // Start DVR Source
+        mDvrTests.startPlaybackInputThread(
+                dvrSourceConfig.playbackInputFile,
+                dvrSourceConfig.settings.get<DvrSettings::Tag::playback>());
+        ASSERT_TRUE(mDvrTests.startDvrPlayback());
+    }
+
+    ASSERT_TRUE(filterDataOutputTest());
+
+    if (descrambling.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+    } else {
+        mDvrTests.stopPlaybackThread();
+        ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+    }
+
+    for (id = filterIds.begin(); id != filterIds.end(); id++) {
+        ASSERT_TRUE(mFilterTests.stopFilter(*id));
+    }
+    for (auto pid : pids) {
+        ASSERT_TRUE(mDescramblerTests.removePid(pid, nullptr));
+    }
+    ASSERT_TRUE(mDescramblerTests.closeDescrambler());
+    for (id = filterIds.begin(); id != filterIds.end(); id++) {
+        ASSERT_TRUE(mFilterTests.closeFilter(*id));
+    }
+
+    if (descrambling.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    } else {
+        mDvrTests.closeDvrPlayback();
+    }
+
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+}
+
+TEST_P(TunerLnbAidlTest, SendDiseqcMessageToLnb) {
+    description("Open and configure an Lnb with specific settings then send a diseqc msg to it.");
+    if (!lnbLive.support) {
+        return;
+    }
+    if (lnbMap[lnbLive.lnbId].name.compare(emptyHardwareId) == 0) {
+        vector<int32_t> ids;
+        ASSERT_TRUE(mLnbTests.getLnbIds(ids));
+        ASSERT_TRUE(ids.size() > 0);
+        ASSERT_TRUE(mLnbTests.openLnbById(ids[0]));
+    } else {
+        int32_t id;
+        ASSERT_TRUE(mLnbTests.openLnbByName(lnbMap[lnbLive.lnbId].name, id));
+    }
+    ASSERT_TRUE(mLnbTests.setLnbCallback());
+    ASSERT_TRUE(mLnbTests.setVoltage(lnbMap[lnbLive.lnbId].voltage));
+    ASSERT_TRUE(mLnbTests.setTone(lnbMap[lnbLive.lnbId].tone));
+    ASSERT_TRUE(mLnbTests.setSatellitePosition(lnbMap[lnbLive.lnbId].position));
+    for (auto msgName : lnbLive.diseqcMsgs) {
+        ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
+    }
+    ASSERT_TRUE(mLnbTests.closeLnb());
+}
+
+TEST_P(TunerDemuxAidlTest, openDemux) {
+    description("Open and close a Demux.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    int32_t feId;
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].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));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
+TEST_P(TunerDemuxAidlTest, getAvSyncTime) {
+    description("Get the A/V sync time from a PCR filter.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    if (live.pcrFilterId.compare(emptyHardwareId) == 0) {
+        return;
+    }
+    int32_t feId;
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    int64_t mediaFilterId;
+    int64_t pcrFilterId;
+    int32_t avSyncHwId;
+    std::shared_ptr<IFilter> mediaFilter;
+
+    mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].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(filterMap[live.videoFilterId].type,
+                                               filterMap[live.videoFilterId].bufferSize));
+    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.videoFilterId].settings, mediaFilterId));
+    mediaFilter = mFilterTests.getFilterById(mediaFilterId);
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterMap[live.pcrFilterId].type,
+                                               filterMap[live.pcrFilterId].bufferSize));
+    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterMap[live.pcrFilterId].settings, pcrFilterId));
+    ASSERT_TRUE(mDemuxTests.getAvSyncId(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(TunerFilterAidlTest, StartFilterInDemux) {
+    description("Open and start a filter in Demux.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    // TODO use parameterized tests
+    configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerFilterAidlTest, ConfigIpFilterInDemuxWithCid) {
+    description("Open and configure an ip filter in Demux.");
+    // TODO use parameterized tests
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    if (live.ipFilterId.compare(emptyHardwareId) == 0) {
+        return;
+    }
+    configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerFilterAidlTest, ReconfigFilterToReceiveStartId) {
+    description("Recofigure and restart a filter to test start id.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    // TODO use parameterized tests
+    reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId], filterMap[live.videoFilterId],
+                                    frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerFilterAidlTest, SetFilterLinkage) {
+    description("Pick up all the possible linkages from the demux caps and set them up.");
+    DemuxCapabilities caps;
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.getDemuxCaps(caps));
+    mFilterTests.setDemux(demux);
+    for (int i = 0; i < caps.linkCaps.size(); i++) {
+        uint32_t bitMask = 1;
+        for (int j = 0; j < FILTER_MAIN_TYPE_BIT_COUNT; j++) {
+            if (caps.linkCaps[i] & (bitMask << j)) {
+                int64_t sourceFilterId;
+                int64_t sinkFilterId;
+                ASSERT_TRUE(mFilterTests.openFilterInDemux(getLinkageFilterType(i), FMQ_SIZE_16M));
+                ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(sourceFilterId));
+                ASSERT_TRUE(mFilterTests.openFilterInDemux(getLinkageFilterType(j), FMQ_SIZE_16M));
+                ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(sinkFilterId));
+                ASSERT_TRUE(mFilterTests.setFilterDataSource(sourceFilterId, sinkFilterId));
+                ASSERT_TRUE(mFilterTests.setFilterDataSourceToDemux(sinkFilterId));
+                ASSERT_TRUE(mFilterTests.closeFilter(sinkFilterId));
+                ASSERT_TRUE(mFilterTests.closeFilter(sourceFilterId));
+            }
+        }
+    }
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+}
+
+TEST_P(TunerFilterAidlTest, testTimeFilter) {
+    description("Open a timer filter in Demux and set time stamp.");
+    if (!timeFilter.support) {
+        return;
+    }
+    // TODO use parameterized tests
+    testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
+}
+
+TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) {
+    description("Feed ts data from playback and configure Ts section filter to get output");
+    if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) {
+        return;
+    }
+    playbackSingleFilterTest(filterMap[playback.sectionFilterId], dvrMap[playback.dvrId]);
+}
+
+TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsAudioFilterTest) {
+    description("Feed ts data from playback and configure Ts audio filter to get output");
+    if (!playback.support) {
+        return;
+    }
+    playbackSingleFilterTest(filterMap[playback.audioFilterId], dvrMap[playback.dvrId]);
+}
+
+TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsVideoFilterTest) {
+    description("Feed ts data from playback and configure Ts video filter to get output");
+    if (!playback.support) {
+        return;
+    }
+    playbackSingleFilterTest(filterMap[playback.videoFilterId], dvrMap[playback.dvrId]);
+}
+
+TEST_P(TunerRecordAidlTest, RecordDataFlowWithTsRecordFilterTest) {
+    description("Feed ts data from frontend to recording and test with ts record filter");
+    if (!record.support) {
+        return;
+    }
+    recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
+                           dvrMap[record.dvrRecordId]);
+}
+
+TEST_P(TunerRecordAidlTest, AttachFiltersToRecordTest) {
+    description("Attach a single filter to the record dvr test.");
+    // TODO use parameterized tests
+    if (!record.support) {
+        return;
+    }
+    attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
+                                      frontendMap[record.frontendId], dvrMap[record.dvrRecordId]);
+}
+
+TEST_P(TunerRecordAidlTest, LnbRecordDataFlowWithTsRecordFilterTest) {
+    description("Feed ts data from Fe with Lnb to recording and test with ts record filter");
+    if (!lnbRecord.support) {
+        return;
+    }
+    recordSingleFilterTestWithLnb(filterMap[lnbRecord.recordFilterId],
+                                  frontendMap[lnbRecord.frontendId], dvrMap[lnbRecord.dvrRecordId],
+                                  lnbMap[lnbRecord.lnbId]);
+}
+
+TEST_P(TunerFrontendAidlTest, TuneFrontend) {
+    description("Tune one Frontend with specific setting and check Lock event");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerFrontendAidlTest, AutoScanFrontend) {
+    description("Run an auto frontend scan with specific setting and check lock scanMessage");
+    if (!scan.hasFrontendConnection) {
+        return;
+    }
+    mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_AUTO);
+}
+
+TEST_P(TunerFrontendAidlTest, BlindScanFrontend) {
+    description("Run an blind frontend scan with specific setting and check lock scanMessage");
+    if (!scan.hasFrontendConnection) {
+        return;
+    }
+    mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+}
+
+TEST_P(TunerFrontendAidlTest, TuneFrontendWithFrontendSettings) {
+    description("Tune one Frontend with setting and check Lock event");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerFrontendAidlTest, BlindScanFrontendWithEndFrequency) {
+    description("Run an blind frontend scan with setting and check lock scanMessage");
+    if (!scan.hasFrontendConnection) {
+        return;
+    }
+    mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
+}
+
+TEST_P(TunerFrontendAidlTest, LinkToCiCam) {
+    description("Test Frontend link to CiCam");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    if (!frontendMap[live.frontendId].canConnectToCiCam) {
+        return;
+    }
+    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowVideoFilterTest) {
+    description("Test Video Filter functionality in Broadcast use case.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowAudioFilterTest) {
+    description("Test Audio Filter functionality in Broadcast use case.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowSectionFilterTest) {
+    description("Test Section Filter functionality in Broadcast use case.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    if (live.sectionFilterId.compare(emptyHardwareId) == 0) {
+        return;
+    }
+    broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerBroadcastAidlTest, IonBufferTest) {
+    description("Test the av filter data bufferring.");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerBroadcastAidlTest, LnbBroadcastDataFlowVideoFilterTest) {
+    description("Test Video Filter functionality in Broadcast with Lnb use case.");
+    if (!lnbLive.support) {
+        return;
+    }
+    broadcastSingleFilterTestWithLnb(filterMap[lnbLive.videoFilterId],
+                                     frontendMap[lnbLive.frontendId], lnbMap[lnbLive.lnbId]);
+}
+
+TEST_P(TunerBroadcastAidlTest, MediaFilterWithSharedMemoryHandle) {
+    description("Test the Media Filter with shared memory handle");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerDescramblerAidlTest, CreateDescrambler) {
+    description("Create Descrambler");
+    if (!descrambling.support) {
+        return;
+    }
+    int32_t demuxId;
+    std::shared_ptr<IDemux> demux;
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+
+    if (descrambling.hasFrontendConnection) {
+        int32_t feId;
+        mFrontendTests.getFrontendIdByType(frontendMap[descrambling.frontendId].type, feId);
+        ASSERT_TRUE(feId != INVALID_ID);
+        ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+        ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+        ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    }
+
+    ASSERT_TRUE(mDescramblerTests.openDescrambler(demuxId));
+    ASSERT_TRUE(mDescramblerTests.closeDescrambler());
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+
+    if (descrambling.hasFrontendConnection) {
+        ASSERT_TRUE(mFrontendTests.closeFrontend());
+    }
+}
+
+TEST_P(TunerDescramblerAidlTest, ScrambledBroadcastDataFlowMediaFiltersTest) {
+    description("Test ts audio filter in scrambled broadcast use case");
+    if (!descrambling.support) {
+        return;
+    }
+    set<FilterConfig> filterConfs;
+    filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.audioFilterId]));
+    filterConfs.insert(static_cast<FilterConfig>(filterMap[descrambling.videoFilterId]));
+    scrambledBroadcastTest(filterConfs, frontendMap[descrambling.frontendId],
+                           descramblerMap[descrambling.descramblerId]);
+}
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TunerBroadcastAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)),
+                         android::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TunerFrontendAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)),
+                         android::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TunerFilterAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)),
+                         android::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TunerRecordAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)),
+                         android::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TunerLnbAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)),
+                         android::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TunerDemuxAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)),
+                         android::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TunerPlaybackAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)),
+                         android::PrintInstanceNameToString);
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, TunerDescramblerAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ITuner::descriptor)),
+                         android::PrintInstanceNameToString);
+
+}  // namespace
+
+// Start thread pool to receive callbacks from AIDL service.
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
new file mode 100644
index 0000000..e5cee76
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2021 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/binder_manager.h>
+
+#include "DemuxTests.h"
+#include "DescramblerTests.h"
+#include "DvrTests.h"
+#include "FrontendTests.h"
+#include "LnbTests.h"
+
+using android::sp;
+
+namespace {
+
+bool initConfiguration() {
+    TunerTestingConfigAidlReader1_0::setConfigFilePath(configFilePath);
+    if (!TunerTestingConfigAidlReader1_0::checkConfigFileExists()) {
+        return false;
+    }
+    initFrontendConfig();
+    initFilterConfig();
+    initDvrConfig();
+    connectHardwaresToTestCases();
+    if (!validateConnections()) {
+        ALOGW("[vts] failed to validate connections.");
+        return false;
+    }
+    return true;
+}
+
+static AssertionResult success() {
+    return ::testing::AssertionSuccess();
+}
+
+AssertionResult filterDataOutputTestBase(FilterTests& tests) {
+    // Data Verify Module
+    std::map<int64_t, std::shared_ptr<FilterCallback>>::iterator it;
+    std::map<int64_t, std::shared_ptr<FilterCallback>> filterCallbacks = tests.getFilterCallbacks();
+    for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) {
+        it->second->testFilterDataOutput();
+    }
+    return success();
+}
+
+class TunerLnbAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            mService = ITuner::fromBinder(binder);
+        } else {
+            mService = nullptr;
+        }
+        ASSERT_NE(mService, nullptr);
+        ASSERT_TRUE(initConfiguration());
+
+        mLnbTests.setService(mService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    std::shared_ptr<ITuner> mService;
+    LnbTests mLnbTests;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerLnbAidlTest);
+
+class TunerDemuxAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            mService = ITuner::fromBinder(binder);
+        } else {
+            mService = nullptr;
+        }
+        ASSERT_NE(mService, nullptr);
+        ASSERT_TRUE(initConfiguration());
+
+        mFrontendTests.setService(mService);
+        mDemuxTests.setService(mService);
+        mFilterTests.setService(mService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    std::shared_ptr<ITuner> mService;
+    FrontendTests mFrontendTests;
+    DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxAidlTest);
+
+class TunerFilterAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            mService = ITuner::fromBinder(binder);
+        } else {
+            mService = nullptr;
+        }
+        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);
+    void reconfigSingleFilterInDemuxTest(FilterConfig filterConf, FilterConfig filterReconf,
+                                         FrontendConfig frontendConf);
+    void testTimeFilter(TimeFilterConfig filterConf);
+
+    DemuxFilterType getLinkageFilterType(int bit) {
+        DemuxFilterType type;
+        type.mainType = static_cast<DemuxFilterMainType>(1 << bit);
+        switch (type.mainType) {
+            case DemuxFilterMainType::TS:
+                type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                        DemuxTsFilterType::UNDEFINED);
+                break;
+            case DemuxFilterMainType::MMTP:
+                type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>(
+                        DemuxMmtpFilterType::UNDEFINED);
+                break;
+            case DemuxFilterMainType::IP:
+                type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::ipFilterType>(
+                        DemuxIpFilterType::UNDEFINED);
+                break;
+            case DemuxFilterMainType::TLV:
+                type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tlvFilterType>(
+                        DemuxTlvFilterType::UNDEFINED);
+                break;
+            case DemuxFilterMainType::ALP:
+                type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::alpFilterType>(
+                        DemuxAlpFilterType::UNDEFINED);
+                break;
+            default:
+                break;
+        }
+        return type;
+    }
+    std::shared_ptr<ITuner> mService;
+    FrontendTests mFrontendTests;
+    DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterAidlTest);
+
+class TunerPlaybackAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            mService = ITuner::fromBinder(binder);
+        } else {
+            mService = nullptr;
+        }
+        ASSERT_NE(mService, nullptr);
+        ASSERT_TRUE(initConfiguration());
+
+        mFrontendTests.setService(mService);
+        mDemuxTests.setService(mService);
+        mFilterTests.setService(mService);
+        mDvrTests.setService(mService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    std::shared_ptr<ITuner> mService;
+    FrontendTests mFrontendTests;
+    DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
+    DvrTests mDvrTests;
+
+    AssertionResult filterDataOutputTest();
+
+    void playbackSingleFilterTest(FilterConfig filterConf, DvrConfig dvrConf);
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerPlaybackAidlTest);
+
+class TunerRecordAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            mService = ITuner::fromBinder(binder);
+        } else {
+            mService = nullptr;
+        }
+        ASSERT_NE(mService, nullptr);
+        initConfiguration();
+
+        mFrontendTests.setService(mService);
+        mDemuxTests.setService(mService);
+        mFilterTests.setService(mService);
+        mDvrTests.setService(mService);
+        mLnbTests.setService(mService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    void attachSingleFilterToRecordDvrTest(FilterConfig filterConf, FrontendConfig frontendConf,
+                                           DvrConfig dvrConf);
+    void recordSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf,
+                                       DvrConfig dvrConf, LnbConfig lnbConf);
+    void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf,
+                                DvrConfig dvrConf);
+
+    std::shared_ptr<ITuner> mService;
+    FrontendTests mFrontendTests;
+    DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
+    DvrTests mDvrTests;
+    LnbTests mLnbTests;
+
+  private:
+    int32_t* mLnbId = nullptr;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerRecordAidlTest);
+
+class TunerFrontendAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            mService = ITuner::fromBinder(binder);
+        } else {
+            mService = nullptr;
+        }
+        ASSERT_NE(mService, nullptr);
+        initConfiguration();
+
+        mFrontendTests.setService(mService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    std::shared_ptr<ITuner> mService;
+    FrontendTests mFrontendTests;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFrontendAidlTest);
+
+class TunerBroadcastAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            mService = ITuner::fromBinder(binder);
+        } else {
+            mService = nullptr;
+        }
+        ASSERT_NE(mService, nullptr);
+        initConfiguration();
+
+        mFrontendTests.setService(mService);
+        mDemuxTests.setService(mService);
+        mFilterTests.setService(mService);
+        mLnbTests.setService(mService);
+        mDvrTests.setService(mService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    std::shared_ptr<ITuner> mService;
+    FrontendTests mFrontendTests;
+    DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
+    LnbTests mLnbTests;
+    DvrTests mDvrTests;
+
+    AssertionResult filterDataOutputTest();
+
+    void broadcastSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf);
+    void broadcastSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf,
+                                          LnbConfig lnbConf);
+    void mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf);
+
+  private:
+    int32_t* mLnbId = nullptr;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerBroadcastAidlTest);
+
+class TunerDescramblerAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        if (AServiceManager_isDeclared(GetParam().c_str())) {
+            ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
+            mService = ITuner::fromBinder(binder);
+        } else {
+            mService = nullptr;
+        }
+        mCasService = IMediaCasService::getService();
+        ASSERT_NE(mService, nullptr);
+        ASSERT_NE(mCasService, nullptr);
+        ASSERT_TRUE(initConfiguration());
+
+        mFrontendTests.setService(mService);
+        mDemuxTests.setService(mService);
+        mDvrTests.setService(mService);
+        mDescramblerTests.setService(mService);
+        mDescramblerTests.setCasService(mCasService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    void scrambledBroadcastTest(set<struct FilterConfig> mediaFilterConfs,
+                                FrontendConfig frontendConf, DescramblerConfig descConfig);
+    AssertionResult filterDataOutputTest();
+
+    std::shared_ptr<ITuner> mService;
+    android::sp<IMediaCasService> mCasService;
+    FrontendTests mFrontendTests;
+    DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
+    DescramblerTests mDescramblerTests;
+    DvrTests mDvrTests;
+};
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDescramblerAidlTest);
+
+}  // namespace
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
new file mode 100644
index 0000000..1ddb641
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2021 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 <binder/MemoryDealer.h>
+
+#include "../../../config/TunerTestingConfigAidlReaderV1_0.h"
+
+#include <aidl/android/hardware/tv/tuner/DataFormat.h>
+#include <aidl/android/hardware/tv/tuner/DemuxAlpFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterMainType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterMonitorEventType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterSettings.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxIpAddress.h>
+#include <aidl/android/hardware/tv/tuner/DemuxIpFilterSettings.h>
+#include <aidl/android/hardware/tv/tuner/DemuxIpFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxMmtpFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxTsFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DvrSettings.h>
+#include <aidl/android/hardware/tv/tuner/DvrType.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtBandwidth.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtCoderate.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtConstellation.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtGuardInterval.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtHierarchy.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtSettings.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtStandard.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.h>
+#include <aidl/android/hardware/tv/tuner/FrontendSettings.h>
+#include <aidl/android/hardware/tv/tuner/FrontendType.h>
+#include <aidl/android/hardware/tv/tuner/PlaybackSettings.h>
+#include <aidl/android/hardware/tv/tuner/RecordSettings.h>
+
+using namespace std;
+using namespace aidl::android::hardware::tv::tuner;
+using namespace android::media::tuner::testing::configuration::V1_0;
+
+const int32_t FMQ_SIZE_4M = 0x400000;
+const int32_t FMQ_SIZE_16M = 0x1000000;
+
+const string configFilePath = "/vendor/etc/tuner_vts_config_1_1.xml";
+
+#define FILTER_MAIN_TYPE_BIT_COUNT 5
+
+// Hardware configs
+static map<string, FrontendConfig> frontendMap;
+static map<string, FilterConfig> filterMap;
+static map<string, DvrConfig> dvrMap;
+static map<string, LnbConfig> lnbMap;
+static map<string, TimeFilterConfig> timeFilterMap;
+static map<string, vector<uint8_t>> diseqcMsgMap;
+static map<string, DescramblerConfig> descramblerMap;
+
+// Hardware and test cases connections
+static LiveBroadcastHardwareConnections live;
+static ScanHardwareConnections scan;
+static DvrPlaybackHardwareConnections playback;
+static DvrRecordHardwareConnections record;
+static DescramblingHardwareConnections descrambling;
+static LnbLiveHardwareConnections lnbLive;
+static LnbRecordHardwareConnections lnbRecord;
+static TimeFilterHardwareConnections timeFilter;
+
+/** Config all the frontends that would be used in the tests */
+inline void initFrontendConfig() {
+    // The test will use the internal default fe when default fe is connected to any data flow
+    // without overriding in the xml config.
+    string defaultFeId = "FE_DEFAULT";
+    FrontendDvbtSettings dvbtSettings{
+            .frequency = 578000,
+            .transmissionMode = FrontendDvbtTransmissionMode::AUTO,
+            .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ,
+            .isHighPriority = true,
+    };
+    frontendMap[defaultFeId].type = FrontendType::DVBT;
+    frontendMap[defaultFeId].settings.set<FrontendSettings::Tag::dvbt>(dvbtSettings);
+
+    vector<FrontendStatusType> types;
+    types.push_back(FrontendStatusType::UEC);
+    types.push_back(FrontendStatusType::IS_MISO);
+
+    vector<FrontendStatus> statuses;
+    FrontendStatus status;
+    status.set<FrontendStatus::Tag::uec>(4);
+    statuses.push_back(status);
+    status.set<FrontendStatus::Tag::isMiso>(true);
+    statuses.push_back(status);
+
+    frontendMap[defaultFeId].tuneStatusTypes = types;
+    frontendMap[defaultFeId].expectTuneStatuses = statuses;
+    frontendMap[defaultFeId].isSoftwareFe = true;
+    frontendMap[defaultFeId].canConnectToCiCam = true;
+    frontendMap[defaultFeId].ciCamId = 0;
+    FrontendDvbtSettings dvbt;
+    dvbt.transmissionMode = FrontendDvbtTransmissionMode::MODE_8K_E;
+    frontendMap[defaultFeId].settings.set<FrontendSettings::Tag::dvbt>(dvbt);
+    // Read customized config
+    TunerTestingConfigAidlReader1_0::readFrontendConfig1_0(frontendMap);
+};
+
+inline void initFilterConfig() {
+    // The test will use the internal default filter when default filter is connected to any
+    // data flow without overriding in the xml config.
+    string defaultAudioFilterId = "FILTER_AUDIO_DEFAULT";
+    string defaultVideoFilterId = "FILTER_VIDEO_DEFAULT";
+
+    filterMap[defaultVideoFilterId].type.mainType = DemuxFilterMainType::TS;
+    filterMap[defaultVideoFilterId]
+            .type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                    DemuxTsFilterType::VIDEO);
+    filterMap[defaultVideoFilterId].bufferSize = FMQ_SIZE_16M;
+    filterMap[defaultVideoFilterId].settings =
+            DemuxFilterSettings::make<DemuxFilterSettings::Tag::ts>();
+    filterMap[defaultVideoFilterId].settings.get<DemuxFilterSettings::Tag::ts>().tpid = 256;
+    DemuxFilterAvSettings video;
+    video.isPassthrough = false;
+    filterMap[defaultVideoFilterId]
+            .settings.get<DemuxFilterSettings::Tag::ts>()
+            .filterSettings.set<DemuxTsFilterSettingsFilterSettings::Tag::av>(video);
+    filterMap[defaultVideoFilterId].monitorEventTypes =
+            static_cast<int32_t>(DemuxFilterMonitorEventType::SCRAMBLING_STATUS) |
+            static_cast<int32_t>(DemuxFilterMonitorEventType::IP_CID_CHANGE);
+    filterMap[defaultVideoFilterId].streamType.set<AvStreamType::Tag::video>(
+            VideoStreamType::MPEG1);
+
+    filterMap[defaultAudioFilterId].type.mainType = DemuxFilterMainType::TS;
+    filterMap[defaultAudioFilterId]
+            .type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                    DemuxTsFilterType::AUDIO);
+    filterMap[defaultAudioFilterId].bufferSize = FMQ_SIZE_16M;
+    filterMap[defaultAudioFilterId].settings =
+            DemuxFilterSettings::make<DemuxFilterSettings::Tag::ts>();
+    filterMap[defaultAudioFilterId].settings.get<DemuxFilterSettings::Tag::ts>().tpid = 256;
+    DemuxFilterAvSettings audio;
+    audio.isPassthrough = false;
+    filterMap[defaultAudioFilterId]
+            .settings.get<DemuxFilterSettings::Tag::ts>()
+            .filterSettings.set<DemuxTsFilterSettingsFilterSettings::Tag::av>(audio);
+    filterMap[defaultAudioFilterId].monitorEventTypes =
+            static_cast<int32_t>(DemuxFilterMonitorEventType::SCRAMBLING_STATUS) |
+            static_cast<int32_t>(DemuxFilterMonitorEventType::IP_CID_CHANGE);
+    filterMap[defaultAudioFilterId].streamType.set<AvStreamType::Tag::audio>(AudioStreamType::MP3);
+    // Read customized config
+    TunerTestingConfigAidlReader1_0::readFilterConfig1_0(filterMap);
+};
+
+/** Config all the dvrs that would be used in the tests */
+inline void initDvrConfig() {
+    // Read customized config
+    TunerTestingConfigAidlReader1_0::readDvrConfig1_0(dvrMap);
+};
+
+/** Read the vendor configurations of which hardware to use for each test cases/data flows */
+inline void connectHardwaresToTestCases() {
+    TunerTestingConfigAidlReader1_0::connectLiveBroadcast(live);
+    TunerTestingConfigAidlReader1_0::connectScan(scan);
+    TunerTestingConfigAidlReader1_0::connectDvrRecord(record);
+};
+
+inline bool validateConnections() {
+    if (record.support && !record.hasFrontendConnection &&
+        record.dvrSourceId.compare(emptyHardwareId) == 0) {
+        ALOGW("[vts config] Record must support either a DVR source or a Frontend source.");
+        return false;
+    }
+    bool feIsValid = frontendMap.find(live.frontendId) != frontendMap.end() &&
+                     frontendMap.find(scan.frontendId) != frontendMap.end();
+    feIsValid &= record.support ? frontendMap.find(record.frontendId) != frontendMap.end() : true;
+
+    if (!feIsValid) {
+        ALOGW("[vts config] dynamic config fe connection is invalid.");
+        return false;
+    }
+
+    bool dvrIsValid = frontendMap[live.frontendId].isSoftwareFe
+                              ? dvrMap.find(live.dvrSoftwareFeId) != dvrMap.end()
+                              : true;
+
+    if (record.support) {
+        if (record.hasFrontendConnection) {
+            if (frontendMap[record.frontendId].isSoftwareFe) {
+                dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end();
+            }
+        } else {
+            dvrIsValid &= dvrMap.find(record.dvrSourceId) != dvrMap.end();
+        }
+        dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end();
+    }
+
+    if (!dvrIsValid) {
+        ALOGW("[vts config] dynamic config dvr connection is invalid.");
+        return false;
+    }
+
+    bool filterIsValid = filterMap.find(live.audioFilterId) != filterMap.end() &&
+                         filterMap.find(live.videoFilterId) != filterMap.end();
+    filterIsValid &=
+            record.support ? filterMap.find(record.recordFilterId) != filterMap.end() : true;
+
+    if (!filterIsValid) {
+        ALOGW("[vts config] dynamic config filter connection is invalid.");
+        return false;
+    }
+
+    return true;
+}
diff --git a/tv/tuner/config/OWNERS b/tv/tuner/config/OWNERS
index 1b3d095..bf2b609 100644
--- a/tv/tuner/config/OWNERS
+++ b/tv/tuner/config/OWNERS
@@ -1,4 +1,3 @@
-nchalko@google.com
-amyjojo@google.com
+hgchen@google.com
 shubang@google.com
 quxiangfang@google.com
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
new file mode 100644
index 0000000..8525b4f
--- /dev/null
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -0,0 +1,1000 @@
+/*
+ * Copyright 2021 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 <android_media_tuner_testing_configuration_V1_0.h>
+#include <android_media_tuner_testing_configuration_V1_0_enums.h>
+
+#include <aidl/android/hardware/tv/tuner/DataFormat.h>
+#include <aidl/android/hardware/tv/tuner/DemuxAlpFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterAvSettings.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterEvent.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterMainType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterRecordSettings.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterSettings.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxIpAddress.h>
+#include <aidl/android/hardware/tv/tuner/DemuxIpFilterSettings.h>
+#include <aidl/android/hardware/tv/tuner/DemuxIpFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxMmtpFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxRecordScIndexType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxTlvFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DemuxTsFilterType.h>
+#include <aidl/android/hardware/tv/tuner/DvrSettings.h>
+#include <aidl/android/hardware/tv/tuner/DvrType.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbsSettings.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtBandwidth.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtCoderate.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtConstellation.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtGuardInterval.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtHierarchy.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtPlpMode.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtSettings.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtStandard.h>
+#include <aidl/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.h>
+#include <aidl/android/hardware/tv/tuner/FrontendSettings.h>
+#include <aidl/android/hardware/tv/tuner/FrontendStatus.h>
+#include <aidl/android/hardware/tv/tuner/FrontendStatusType.h>
+#include <aidl/android/hardware/tv/tuner/FrontendType.h>
+#include <aidl/android/hardware/tv/tuner/LnbPosition.h>
+#include <aidl/android/hardware/tv/tuner/LnbTone.h>
+#include <aidl/android/hardware/tv/tuner/LnbVoltage.h>
+#include <aidl/android/hardware/tv/tuner/PlaybackSettings.h>
+#include <aidl/android/hardware/tv/tuner/RecordSettings.h>
+
+using namespace std;
+using namespace aidl::android::hardware::tv::tuner;
+using namespace android::media::tuner::testing::configuration::V1_0;
+
+const string emptyHardwareId = "";
+
+static string mConfigFilePath;
+
+#define PROVISION_STR                                      \
+    "{                                                   " \
+    "  \"id\": 21140844,                                 " \
+    "  \"name\": \"Test Title\",                         " \
+    "  \"lowercase_organization_name\": \"Android\",     " \
+    "  \"asset_key\": {                                  " \
+    "  \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\"  " \
+    "  },                                                " \
+    "  \"cas_type\": 1,                                  " \
+    "  \"track_types\": [ ]                              " \
+    "}                                                   "
+
+struct FrontendConfig {
+    bool isSoftwareFe;
+    FrontendType type;
+    bool canConnectToCiCam;
+    int32_t ciCamId;
+    FrontendSettings settings;
+    vector<FrontendStatusType> tuneStatusTypes;
+    vector<FrontendStatus> expectTuneStatuses;
+};
+
+struct FilterConfig {
+    int32_t bufferSize;
+    DemuxFilterType type;
+    DemuxFilterSettings settings;
+    bool getMqDesc;
+    AvStreamType streamType;
+    int32_t ipCid;
+    int32_t monitorEventTypes;
+
+    bool operator<(const FilterConfig& /*c*/) const { return false; }
+};
+
+struct DvrConfig {
+    DvrType type;
+    int32_t bufferSize;
+    DvrSettings settings;
+    string playbackInputFile;
+};
+
+struct LnbConfig {
+    string name;
+    LnbVoltage voltage;
+    LnbTone tone;
+    LnbPosition position;
+};
+
+struct TimeFilterConfig {
+    int64_t timeStamp;
+};
+
+struct DescramblerConfig {
+    int32_t casSystemId;
+    string provisionStr;
+    vector<uint8_t> hidlPvtData;
+};
+
+struct LiveBroadcastHardwareConnections {
+    bool hasFrontendConnection;
+    string frontendId;
+    string dvrSoftwareFeId;
+    string audioFilterId;
+    string videoFilterId;
+    string sectionFilterId;
+    string ipFilterId;
+    string pcrFilterId;
+    /* list string of extra filters; */
+};
+
+struct ScanHardwareConnections {
+    bool hasFrontendConnection;
+    string frontendId;
+};
+
+struct DvrPlaybackHardwareConnections {
+    bool support;
+    string frontendId;
+    string dvrId;
+    string audioFilterId;
+    string videoFilterId;
+    string sectionFilterId;
+    /* list string of extra filters; */
+};
+
+struct DvrRecordHardwareConnections {
+    bool support;
+    bool hasFrontendConnection;
+    string frontendId;
+    string dvrRecordId;
+    string dvrSoftwareFeId;
+    string recordFilterId;
+    string dvrSourceId;
+};
+
+struct DescramblingHardwareConnections {
+    bool support;
+    bool hasFrontendConnection;
+    string frontendId;
+    string dvrSoftwareFeId;
+    string audioFilterId;
+    string videoFilterId;
+    string descramblerId;
+    string dvrSourceId;
+    /* list string of extra filters; */
+};
+
+struct LnbLiveHardwareConnections {
+    bool support;
+    string frontendId;
+    string audioFilterId;
+    string videoFilterId;
+    string lnbId;
+    vector<string> diseqcMsgs;
+    /* list string of extra filters; */
+};
+
+struct LnbRecordHardwareConnections {
+    bool support;
+    string frontendId;
+    string dvrRecordId;
+    string recordFilterId;
+    string lnbId;
+    vector<string> diseqcMsgs;
+    /* list string of extra filters; */
+};
+
+struct TimeFilterHardwareConnections {
+    bool support;
+    string timeFilterId;
+};
+
+struct TunerTestingConfigAidlReader1_0 {
+  public:
+    static void setConfigFilePath(string path) { mConfigFilePath = path; }
+
+    static bool checkConfigFileExists() {
+        auto res = read(mConfigFilePath.c_str());
+        if (res == nullopt) {
+            ALOGW("[ConfigReader] Couldn't read %s."
+                  "Please check tuner_testing_dynamic_configuration.xsd"
+                  "and sample_tuner_vts_config.xml for more details on how to config Tune VTS.",
+                  mConfigFilePath.c_str());
+        }
+        return (res != nullopt);
+    }
+
+    static TunerConfiguration getTunerConfig() { return *read(mConfigFilePath.c_str()); }
+
+    static DataFlowConfiguration getDataFlowConfiguration() {
+        return *getTunerConfig().getFirstDataFlowConfiguration();
+    }
+
+    static HardwareConfiguration getHardwareConfig() {
+        return *getTunerConfig().getFirstHardwareConfiguration();
+    }
+
+    static void readFrontendConfig1_0(map<string, FrontendConfig>& frontendMap) {
+        auto hardwareConfig = getHardwareConfig();
+        if (hardwareConfig.hasFrontends()) {
+            // TODO: b/182519645 complete the tune status config
+            vector<FrontendStatusType> types;
+            vector<FrontendStatus> statuses;
+
+            types.push_back(FrontendStatusType::DEMOD_LOCK);
+            types.push_back(FrontendStatusType::UEC);
+            types.push_back(FrontendStatusType::IS_MISO);
+
+            FrontendStatus status;
+            status.set<FrontendStatus::Tag::isDemodLocked>(true);
+            statuses.push_back(status);
+            status.set<FrontendStatus::Tag::uec>(4);
+            statuses.push_back(status);
+            status.set<FrontendStatus::Tag::isMiso>(true);
+            statuses.push_back(status);
+
+            auto frontends = *hardwareConfig.getFirstFrontends();
+            for (auto feConfig : frontends.getFrontend()) {
+                string id = feConfig.getId();
+                if (id.compare(string("FE_DEFAULT")) == 0) {
+                    // overrid default
+                    frontendMap.erase(string("FE_DEFAULT"));
+                }
+                FrontendType type;
+                switch (feConfig.getType()) {
+                    case FrontendTypeEnum::UNDEFINED:
+                        type = FrontendType::UNDEFINED;
+                        break;
+                    // TODO: b/182519645 finish all other frontend settings
+                    case FrontendTypeEnum::ANALOG:
+                        type = FrontendType::ANALOG;
+                        break;
+                    case FrontendTypeEnum::ATSC:
+                        type = FrontendType::ATSC;
+                        break;
+                    case FrontendTypeEnum::ATSC3:
+                        type = FrontendType::ATSC3;
+                        break;
+                    case FrontendTypeEnum::DVBC:
+                        type = FrontendType::DVBC;
+                        break;
+                    case FrontendTypeEnum::DVBS:
+                        type = FrontendType::DVBS;
+                        frontendMap[id].settings.set<FrontendSettings::Tag::dvbs>(
+                                readDvbsFrontendSettings(feConfig));
+                        break;
+                    case FrontendTypeEnum::DVBT: {
+                        type = FrontendType::DVBT;
+                        frontendMap[id].settings.set<FrontendSettings::Tag::dvbt>(
+                                readDvbtFrontendSettings(feConfig));
+                        break;
+                    }
+                    case FrontendTypeEnum::ISDBS:
+                        type = FrontendType::ISDBS;
+                        break;
+                    case FrontendTypeEnum::ISDBS3:
+                        type = FrontendType::ISDBS3;
+                        break;
+                    case FrontendTypeEnum::ISDBT:
+                        type = FrontendType::ISDBT;
+                        break;
+                    case FrontendTypeEnum::DTMB:
+                        type = FrontendType::DTMB;
+                        break;
+                    case FrontendTypeEnum::UNKNOWN:
+                        ALOGW("[ConfigReader] invalid frontend type");
+                        return;
+                    default:
+                        ALOGW("[ConfigReader] fe already handled in 1_0 reader.");
+                        break;
+                }
+                frontendMap[id].type = type;
+                frontendMap[id].isSoftwareFe = feConfig.getIsSoftwareFrontend();
+                // TODO: b/182519645 complete the tune status config
+                frontendMap[id].tuneStatusTypes = types;
+                frontendMap[id].expectTuneStatuses = statuses;
+                getCiCamInfo(feConfig, frontendMap[id].canConnectToCiCam, frontendMap[id].ciCamId);
+            }
+        }
+    }
+
+    static void readFilterConfig1_0(map<string, FilterConfig>& filterMap) {
+        auto hardwareConfig = getHardwareConfig();
+        if (hardwareConfig.hasFilters()) {
+            auto filters = *hardwareConfig.getFirstFilters();
+            for (auto filterConfig : filters.getFilter()) {
+                string id = filterConfig.getId();
+                if (id.compare(string("FILTER_AUDIO_DEFAULT")) == 0) {
+                    // overrid default
+                    filterMap.erase(string("FILTER_AUDIO_DEFAULT"));
+                }
+                if (id.compare(string("FILTER_VIDEO_DEFAULT")) == 0) {
+                    // overrid default
+                    filterMap.erase(string("FILTER_VIDEO_DEFAULT"));
+                }
+
+                DemuxFilterType type;
+                DemuxFilterSettings settings;
+                if (!readFilterTypeAndSettings(filterConfig, type, settings)) {
+                    ALOGW("[ConfigReader] invalid filter type");
+                    return;
+                }
+                filterMap[id].type = type;
+                filterMap[id].bufferSize = filterConfig.getBufferSize();
+                filterMap[id].getMqDesc = filterConfig.getUseFMQ();
+                filterMap[id].settings = settings;
+
+                if (filterConfig.hasMonitorEventTypes()) {
+                    filterMap[id].monitorEventTypes = (uint32_t)filterConfig.getMonitorEventTypes();
+                }
+                if (filterConfig.hasAvFilterSettings_optional()) {
+                    auto av = filterConfig.getFirstAvFilterSettings_optional();
+                    if (av->hasAudioStreamType_optional()) {
+                        filterMap[id].streamType.set<AvStreamType::Tag::audio>(
+                                static_cast<AudioStreamType>(av->getAudioStreamType_optional()));
+                    }
+                    if (av->hasVideoStreamType_optional()) {
+                        filterMap[id].streamType.set<AvStreamType::Tag::video>(
+                                static_cast<VideoStreamType>(av->getVideoStreamType_optional()));
+                    }
+                }
+                if (filterConfig.hasIpFilterConfig_optional()) {
+                    auto ip = filterConfig.getFirstIpFilterConfig_optional();
+                    if (ip->hasIpCid()) {
+                        filterMap[id].ipCid = ip->getIpCid();
+                    }
+                }
+            }
+        }
+    }
+
+    static void readDvrConfig1_0(map<string, DvrConfig>& dvrMap) {
+        auto hardwareConfig = getHardwareConfig();
+        if (hardwareConfig.hasDvrs()) {
+            auto dvrs = *hardwareConfig.getFirstDvrs();
+            for (auto dvrConfig : dvrs.getDvr()) {
+                string id = dvrConfig.getId();
+                DvrType type;
+                switch (dvrConfig.getType()) {
+                    case DvrTypeEnum::PLAYBACK:
+                        type = DvrType::PLAYBACK;
+                        dvrMap[id].settings.set<DvrSettings::Tag::playback>(
+                                readPlaybackSettings(dvrConfig));
+                        break;
+                    case DvrTypeEnum::RECORD:
+                        type = DvrType::RECORD;
+                        dvrMap[id].settings.set<DvrSettings::Tag::record>(
+                                readRecordSettings(dvrConfig));
+                        break;
+                    case DvrTypeEnum::UNKNOWN:
+                        ALOGW("[ConfigReader] invalid DVR type");
+                        return;
+                }
+                dvrMap[id].type = type;
+                dvrMap[id].bufferSize = static_cast<uint32_t>(dvrConfig.getBufferSize());
+                if (dvrConfig.hasInputFilePath()) {
+                    dvrMap[id].playbackInputFile = dvrConfig.getInputFilePath();
+                }
+            }
+        }
+    }
+
+    static void readLnbConfig1_0(map<string, LnbConfig>& lnbMap) {
+        auto hardwareConfig = getHardwareConfig();
+        if (hardwareConfig.hasLnbs()) {
+            auto lnbs = *hardwareConfig.getFirstLnbs();
+            for (auto lnbConfig : lnbs.getLnb()) {
+                string id = lnbConfig.getId();
+                if (lnbConfig.hasName()) {
+                    lnbMap[id].name = lnbConfig.getName();
+                } else {
+                    lnbMap[id].name = emptyHardwareId;
+                }
+                lnbMap[id].voltage = static_cast<LnbVoltage>(lnbConfig.getVoltage());
+                lnbMap[id].tone = static_cast<LnbTone>(lnbConfig.getTone());
+                lnbMap[id].position = static_cast<LnbPosition>(lnbConfig.getPosition());
+            }
+        }
+    }
+
+    static void readDescramblerConfig1_0(map<string, DescramblerConfig>& descramblerMap) {
+        auto hardwareConfig = getHardwareConfig();
+        if (hardwareConfig.hasDescramblers()) {
+            auto descramblers = *hardwareConfig.getFirstDescramblers();
+            for (auto descramblerConfig : descramblers.getDescrambler()) {
+                string id = descramblerConfig.getId();
+                descramblerMap[id].casSystemId =
+                        static_cast<uint32_t>(descramblerConfig.getCasSystemId());
+                if (descramblerConfig.hasProvisionStr()) {
+                    descramblerMap[id].provisionStr = descramblerConfig.getProvisionStr();
+                } else {
+                    descramblerMap[id].provisionStr = PROVISION_STR;
+                }
+                if (descramblerConfig.hasSesstionPrivatData()) {
+                    auto privateData = descramblerConfig.getSesstionPrivatData();
+                    int size = privateData.size();
+                    descramblerMap[id].hidlPvtData.resize(size);
+                    memcpy(descramblerMap[id].hidlPvtData.data(), privateData.data(), size);
+                } else {
+                    descramblerMap[id].hidlPvtData.resize(256);
+                }
+            }
+        }
+    }
+
+    static void readDiseqcMessages(map<string, vector<uint8_t>>& diseqcMsgMap) {
+        auto hardwareConfig = getHardwareConfig();
+        if (hardwareConfig.hasDiseqcMessages()) {
+            auto msgs = *hardwareConfig.getFirstDiseqcMessages();
+            for (auto msgConfig : msgs.getDiseqcMessage()) {
+                string name = msgConfig.getMsgName();
+                for (uint8_t atom : msgConfig.getMsgBody()) {
+                    diseqcMsgMap[name].push_back(atom);
+                }
+            }
+        }
+    }
+
+    static void readTimeFilterConfig1_0(map<string, TimeFilterConfig>& timeFilterMap) {
+        auto hardwareConfig = getHardwareConfig();
+        if (hardwareConfig.hasTimeFilters()) {
+            auto timeFilters = *hardwareConfig.getFirstTimeFilters();
+            for (auto timeFilterConfig : timeFilters.getTimeFilter()) {
+                string id = timeFilterConfig.getId();
+                timeFilterMap[id].timeStamp =
+                        static_cast<uint64_t>(timeFilterConfig.getTimeStamp());
+            }
+        }
+    }
+
+    static void connectLiveBroadcast(LiveBroadcastHardwareConnections& live) {
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasClearLiveBroadcast()) {
+            live.hasFrontendConnection = true;
+        } else {
+            live.hasFrontendConnection = false;
+            return;
+        }
+        auto liveConfig = *dataFlow.getFirstClearLiveBroadcast();
+        live.frontendId = liveConfig.getFrontendConnection();
+
+        live.audioFilterId = liveConfig.getAudioFilterConnection();
+        live.videoFilterId = liveConfig.getVideoFilterConnection();
+        if (liveConfig.hasPcrFilterConnection()) {
+            live.pcrFilterId = liveConfig.getPcrFilterConnection();
+        } else {
+            live.pcrFilterId = emptyHardwareId;
+        }
+        if (liveConfig.hasSectionFilterConnection()) {
+            live.sectionFilterId = liveConfig.getSectionFilterConnection();
+        } else {
+            live.sectionFilterId = emptyHardwareId;
+        }
+        if (liveConfig.hasDvrSoftwareFeConnection()) {
+            live.dvrSoftwareFeId = liveConfig.getDvrSoftwareFeConnection();
+        }
+        if (liveConfig.hasIpFilterConnection()) {
+            live.ipFilterId = liveConfig.getIpFilterConnection();
+        } else {
+            live.ipFilterId = emptyHardwareId;
+        }
+    }
+
+    static void connectScan(ScanHardwareConnections& scan) {
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasScan()) {
+            scan.hasFrontendConnection = true;
+        } else {
+            scan.hasFrontendConnection = false;
+            return;
+        }
+        auto scanConfig = *dataFlow.getFirstScan();
+        scan.frontendId = scanConfig.getFrontendConnection();
+    }
+
+    static void connectDvrPlayback(DvrPlaybackHardwareConnections& playback) {
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasDvrPlayback()) {
+            playback.support = true;
+        } else {
+            playback.support = false;
+            return;
+        }
+        auto playbackConfig = *dataFlow.getFirstDvrPlayback();
+        playback.dvrId = playbackConfig.getDvrConnection();
+        playback.audioFilterId = playbackConfig.getAudioFilterConnection();
+        playback.videoFilterId = playbackConfig.getVideoFilterConnection();
+        if (playbackConfig.hasSectionFilterConnection()) {
+            playback.sectionFilterId = playbackConfig.getSectionFilterConnection();
+        } else {
+            playback.sectionFilterId = emptyHardwareId;
+        }
+    }
+
+    static void connectDvrRecord(DvrRecordHardwareConnections& record) {
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasDvrRecord()) {
+            record.support = true;
+        } else {
+            record.support = false;
+            return;
+        }
+        auto recordConfig = *dataFlow.getFirstDvrRecord();
+        record.recordFilterId = recordConfig.getRecordFilterConnection();
+        record.dvrRecordId = recordConfig.getDvrRecordConnection();
+        if (recordConfig.hasDvrSoftwareFeConnection()) {
+            record.dvrSoftwareFeId = recordConfig.getDvrSoftwareFeConnection();
+        }
+        if (recordConfig.getHasFrontendConnection()) {
+            record.hasFrontendConnection = true;
+            record.dvrSourceId = emptyHardwareId;
+            record.frontendId = recordConfig.getFrontendConnection();
+        } else {
+            record.hasFrontendConnection = false;
+            record.dvrSourceId = recordConfig.getDvrSourceConnection();
+        }
+    }
+
+    static void connectDescrambling(DescramblingHardwareConnections& descrambling) {
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasDescrambling()) {
+            descrambling.support = true;
+        } else {
+            descrambling.support = false;
+            return;
+        }
+        auto descConfig = *dataFlow.getFirstDescrambling();
+        descrambling.descramblerId = descConfig.getDescramblerConnection();
+        descrambling.audioFilterId = descConfig.getAudioFilterConnection();
+        descrambling.videoFilterId = descConfig.getVideoFilterConnection();
+        if (descConfig.hasDvrSoftwareFeConnection()) {
+            descrambling.dvrSoftwareFeId = descConfig.getDvrSoftwareFeConnection();
+        }
+        if (descConfig.getHasFrontendConnection()) {
+            descrambling.hasFrontendConnection = true;
+            descrambling.dvrSourceId = emptyHardwareId;
+            descrambling.frontendId = descConfig.getFrontendConnection();
+        } else {
+            descrambling.hasFrontendConnection = false;
+            descrambling.dvrSourceId = descConfig.getDvrSourceConnection();
+        }
+    }
+
+    static void connectLnbLive(LnbLiveHardwareConnections& lnbLive) {
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasLnbLive()) {
+            lnbLive.support = true;
+        } else {
+            lnbLive.support = false;
+            return;
+        }
+        auto lnbLiveConfig = *dataFlow.getFirstLnbLive();
+        lnbLive.frontendId = lnbLiveConfig.getFrontendConnection();
+        lnbLive.audioFilterId = lnbLiveConfig.getAudioFilterConnection();
+        lnbLive.videoFilterId = lnbLiveConfig.getVideoFilterConnection();
+        lnbLive.lnbId = lnbLiveConfig.getLnbConnection();
+        if (lnbLiveConfig.hasDiseqcMsgSender()) {
+            for (auto msgName : lnbLiveConfig.getDiseqcMsgSender()) {
+                lnbLive.diseqcMsgs.push_back(msgName);
+            }
+        }
+    }
+
+    static void connectLnbRecord(LnbRecordHardwareConnections& lnbRecord) {
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasLnbRecord()) {
+            lnbRecord.support = true;
+        } else {
+            lnbRecord.support = false;
+            return;
+        }
+        auto lnbRecordConfig = *dataFlow.getFirstLnbRecord();
+        lnbRecord.frontendId = lnbRecordConfig.getFrontendConnection();
+        lnbRecord.recordFilterId = lnbRecordConfig.getRecordFilterConnection();
+        lnbRecord.dvrRecordId = lnbRecordConfig.getDvrRecordConnection();
+        lnbRecord.lnbId = lnbRecordConfig.getLnbConnection();
+        if (lnbRecordConfig.hasDiseqcMsgSender()) {
+            for (auto msgName : lnbRecordConfig.getDiseqcMsgSender()) {
+                lnbRecord.diseqcMsgs.push_back(msgName);
+            }
+        }
+    }
+
+    static void connectTimeFilter(TimeFilterHardwareConnections& timeFilter) {
+        auto dataFlow = getDataFlowConfiguration();
+        if (dataFlow.hasTimeFilter()) {
+            timeFilter.support = true;
+        } else {
+            timeFilter.support = false;
+            return;
+        }
+        auto timeFilterConfig = *dataFlow.getFirstTimeFilter();
+        timeFilter.timeFilterId = timeFilterConfig.getTimeFilterConnection();
+    }
+
+  private:
+    static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) {
+        ALOGW("[ConfigReader] fe type is dvbt");
+        FrontendDvbtSettings dvbtSettings{
+                .frequency = (int32_t)feConfig.getFrequency(),
+        };
+        if (!feConfig.hasDvbtFrontendSettings_optional()) {
+            ALOGW("[ConfigReader] no more dvbt settings");
+            return dvbtSettings;
+        }
+        auto dvbt = feConfig.getFirstDvbtFrontendSettings_optional();
+        uint32_t trans = static_cast<uint32_t>(dvbt->getTransmissionMode());
+        dvbtSettings.transmissionMode = static_cast<FrontendDvbtTransmissionMode>(trans);
+        dvbtSettings.bandwidth = static_cast<FrontendDvbtBandwidth>(dvbt->getBandwidth());
+        dvbtSettings.isHighPriority = dvbt->getIsHighPriority();
+        dvbtSettings.hierarchy = static_cast<FrontendDvbtHierarchy>(dvbt->getHierarchy());
+        dvbtSettings.hpCoderate = static_cast<FrontendDvbtCoderate>(dvbt->getHpCoderate());
+        dvbtSettings.lpCoderate = static_cast<FrontendDvbtCoderate>(dvbt->getLpCoderate());
+        dvbtSettings.guardInterval =
+                static_cast<FrontendDvbtGuardInterval>(dvbt->getGuardInterval());
+        dvbtSettings.standard = static_cast<FrontendDvbtStandard>(dvbt->getStandard());
+        dvbtSettings.isMiso = dvbt->getIsMiso();
+        dvbtSettings.plpMode = static_cast<FrontendDvbtPlpMode>(dvbt->getPlpMode());
+        dvbtSettings.plpId = dvbt->getPlpId();
+        dvbtSettings.plpGroupId = dvbt->getPlpGroupId();
+        if (dvbt->hasConstellation()) {
+            dvbtSettings.constellation =
+                    static_cast<FrontendDvbtConstellation>(dvbt->getConstellation());
+        }
+        return dvbtSettings;
+    }
+
+    static FrontendDvbsSettings readDvbsFrontendSettings(Frontend feConfig) {
+        ALOGW("[ConfigReader] fe type is dvbs");
+        FrontendDvbsSettings dvbsSettings{
+                .frequency = (int32_t)feConfig.getFrequency(),
+        };
+        if (!feConfig.hasDvbsFrontendSettings_optional()) {
+            ALOGW("[ConfigReader] no more dvbs settings");
+            return dvbsSettings;
+        }
+        dvbsSettings.symbolRate = static_cast<uint32_t>(
+                feConfig.getFirstDvbsFrontendSettings_optional()->getSymbolRate());
+        dvbsSettings.inputStreamId = static_cast<uint32_t>(
+                feConfig.getFirstDvbsFrontendSettings_optional()->getInputStreamId());
+        auto dvbs = feConfig.getFirstDvbsFrontendSettings_optional();
+        if (dvbs->hasScanType()) {
+            dvbsSettings.scanType = static_cast<FrontendDvbsScanType>(dvbs->getScanType());
+        }
+        if (dvbs->hasIsDiseqcRxMessage()) {
+            dvbsSettings.isDiseqcRxMessage = dvbs->getIsDiseqcRxMessage();
+        }
+        return dvbsSettings;
+    }
+
+    static bool readFilterTypeAndSettings(Filter filterConfig, DemuxFilterType& type,
+                                          DemuxFilterSettings& settings) {
+        auto mainType = filterConfig.getMainType();
+        auto subType = filterConfig.getSubType();
+
+        switch (mainType) {
+            case FilterMainTypeEnum::TS: {
+                ALOGW("[ConfigReader] filter main type is ts");
+                type.mainType = DemuxFilterMainType::TS;
+                DemuxTsFilterSettings ts;
+                bool isTsSet = false;
+                switch (subType) {
+                    case FilterSubTypeEnum::UNDEFINED:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                                DemuxTsFilterType::UNDEFINED);
+                        break;
+                    case FilterSubTypeEnum::SECTION:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                                DemuxTsFilterType::SECTION);
+                        ts.filterSettings.set<DemuxTsFilterSettingsFilterSettings::Tag::section>(
+                                readSectionFilterSettings(filterConfig));
+                        isTsSet = true;
+                        break;
+                    case FilterSubTypeEnum::PES:
+                        // TODO: b/182519645 support all the filter settings
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                                DemuxTsFilterType::PES);
+                        break;
+                    case FilterSubTypeEnum::TS:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                                DemuxTsFilterType::TS);
+                        ts.filterSettings.set<DemuxTsFilterSettingsFilterSettings::Tag::noinit>(
+                                true);
+                        isTsSet = true;
+                        break;
+                    case FilterSubTypeEnum::PCR:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                                DemuxTsFilterType::PCR);
+                        ts.filterSettings.set<DemuxTsFilterSettingsFilterSettings::Tag::noinit>(
+                                true);
+                        isTsSet = true;
+                        break;
+                    case FilterSubTypeEnum::TEMI:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                                DemuxTsFilterType::TEMI);
+                        ts.filterSettings.set<DemuxTsFilterSettingsFilterSettings::Tag::noinit>(
+                                true);
+                        isTsSet = true;
+                        break;
+                    case FilterSubTypeEnum::AUDIO:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                                DemuxTsFilterType::AUDIO);
+                        ts.filterSettings.set<DemuxTsFilterSettingsFilterSettings::Tag::av>(
+                                readAvFilterSettings(filterConfig));
+                        isTsSet = true;
+                        break;
+                    case FilterSubTypeEnum::VIDEO:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                                DemuxTsFilterType::VIDEO);
+                        ts.filterSettings.set<DemuxTsFilterSettingsFilterSettings::Tag::av>(
+                                readAvFilterSettings(filterConfig));
+                        isTsSet = true;
+                        break;
+                    case FilterSubTypeEnum::RECORD:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::tsFilterType>(
+                                DemuxTsFilterType::RECORD);
+                        ts.filterSettings.set<DemuxTsFilterSettingsFilterSettings::Tag::record>(
+                                readRecordFilterSettings(filterConfig));
+                        isTsSet = true;
+                        break;
+                    default:
+                        ALOGW("[ConfigReader] ts subtype is not supported");
+                        return false;
+                }
+                if (filterConfig.hasPid()) {
+                    ts.tpid = static_cast<int32_t>(filterConfig.getPid());
+                    isTsSet = true;
+                }
+                if (isTsSet) {
+                    settings.set<DemuxFilterSettings::Tag::ts>(ts);
+                }
+                break;
+            }
+            case FilterMainTypeEnum::MMTP: {
+                ALOGW("[ConfigReader] filter main type is mmtp");
+                type.mainType = DemuxFilterMainType::MMTP;
+                DemuxMmtpFilterSettings mmtp;
+                bool isMmtpSet = false;
+                switch (subType) {
+                    case FilterSubTypeEnum::UNDEFINED:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>(
+                                DemuxMmtpFilterType::UNDEFINED);
+                        break;
+                    case FilterSubTypeEnum::SECTION:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>(
+                                DemuxMmtpFilterType::SECTION);
+                        mmtp.filterSettings
+                                .set<DemuxMmtpFilterSettingsFilterSettings::Tag::section>(
+                                        readSectionFilterSettings(filterConfig));
+                        isMmtpSet = true;
+                        break;
+                    case FilterSubTypeEnum::PES:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>(
+                                DemuxMmtpFilterType::PES);
+                        // TODO: b/182519645 support all the filter settings
+                        break;
+                    case FilterSubTypeEnum::MMTP:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>(
+                                DemuxMmtpFilterType::MMTP);
+                        mmtp.filterSettings.set<DemuxMmtpFilterSettingsFilterSettings::Tag::noinit>(
+                                true);
+                        isMmtpSet = true;
+                        break;
+                    case FilterSubTypeEnum::AUDIO:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>(
+                                DemuxMmtpFilterType::AUDIO);
+                        mmtp.filterSettings.set<DemuxMmtpFilterSettingsFilterSettings::Tag::av>(
+                                readAvFilterSettings(filterConfig));
+                        isMmtpSet = true;
+                        break;
+                    case FilterSubTypeEnum::VIDEO:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>(
+                                DemuxMmtpFilterType::VIDEO);
+                        mmtp.filterSettings.set<DemuxMmtpFilterSettingsFilterSettings::Tag::av>(
+                                readAvFilterSettings(filterConfig));
+                        isMmtpSet = true;
+                        break;
+                    case FilterSubTypeEnum::RECORD:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>(
+                                DemuxMmtpFilterType::RECORD);
+                        mmtp.filterSettings.set<DemuxMmtpFilterSettingsFilterSettings::Tag::record>(
+                                readRecordFilterSettings(filterConfig));
+                        isMmtpSet = true;
+                        break;
+                    case FilterSubTypeEnum::DOWNLOAD:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::mmtpFilterType>(
+                                DemuxMmtpFilterType::DOWNLOAD);
+                        // TODO: b/182519645 support all the filter settings
+                        break;
+                    default:
+                        ALOGW("[ConfigReader] mmtp subtype is not supported");
+                        return false;
+                }
+                if (filterConfig.hasPid()) {
+                    mmtp.mmtpPid = static_cast<int32_t>(filterConfig.getPid());
+                    isMmtpSet = true;
+                }
+                if (isMmtpSet) {
+                    settings.set<DemuxFilterSettings::Tag::mmtp>(mmtp);
+                }
+                break;
+            }
+            case FilterMainTypeEnum::IP: {
+                ALOGW("[ConfigReader] filter main type is ip");
+                type.mainType = DemuxFilterMainType::IP;
+                DemuxIpFilterSettings ip;
+                switch (subType) {
+                    case FilterSubTypeEnum::UNDEFINED:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::ipFilterType>(
+                                DemuxIpFilterType::UNDEFINED);
+                        break;
+                    case FilterSubTypeEnum::SECTION:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::ipFilterType>(
+                                DemuxIpFilterType::SECTION);
+                        ip.filterSettings.set<DemuxIpFilterSettingsFilterSettings::Tag::section>(
+                                readSectionFilterSettings(filterConfig));
+                        settings.set<DemuxFilterSettings::Tag::ip>(ip);
+                        break;
+                    case FilterSubTypeEnum::NTP:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::ipFilterType>(
+                                DemuxIpFilterType::NTP);
+                        ip.filterSettings.set<DemuxIpFilterSettingsFilterSettings::Tag::noinit>(
+                                true);
+                        settings.set<DemuxFilterSettings::Tag::ip>(ip);
+                        break;
+                    case FilterSubTypeEnum::IP: {
+                        ip.ipAddr = readIpAddress(filterConfig),
+                        ip.filterSettings
+                                .set<DemuxIpFilterSettingsFilterSettings::Tag::bPassthrough>(
+                                        readPassthroughSettings(filterConfig));
+                        settings.set<DemuxFilterSettings::Tag::ip>(ip);
+                        break;
+                    }
+                    case FilterSubTypeEnum::IP_PAYLOAD:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::ipFilterType>(
+                                DemuxIpFilterType::IP_PAYLOAD);
+                        ip.filterSettings.set<DemuxIpFilterSettingsFilterSettings::Tag::noinit>(
+                                true);
+                        settings.set<DemuxFilterSettings::Tag::ip>(ip);
+                        break;
+                    case FilterSubTypeEnum::PAYLOAD_THROUGH:
+                        type.subType.set<DemuxFilterTypeDemuxFilterSubType::Tag::ipFilterType>(
+                                DemuxIpFilterType::PAYLOAD_THROUGH);
+                        ip.filterSettings.set<DemuxIpFilterSettingsFilterSettings::Tag::noinit>(
+                                true);
+                        settings.set<DemuxFilterSettings::Tag::ip>(ip);
+                        break;
+                    default:
+                        ALOGW("[ConfigReader] mmtp subtype is not supported");
+                        return false;
+                }
+                break;
+            }
+            default:
+                // TODO: b/182519645 support all the filter configs
+                ALOGW("[ConfigReader] filter main type is not supported in dynamic config");
+                return false;
+        }
+        return true;
+    }
+
+    static DemuxIpAddress readIpAddress(Filter filterConfig) {
+        DemuxIpAddress ipAddress;
+        vector<uint8_t> data;
+        if (!filterConfig.hasIpFilterConfig_optional()) {
+            return ipAddress;
+        }
+        auto ipFilterConfig = filterConfig.getFirstIpFilterConfig_optional();
+        if (ipFilterConfig->hasSrcPort()) {
+            ipAddress.srcPort = ipFilterConfig->getSrcPort();
+        }
+        if (ipFilterConfig->hasDestPort()) {
+            ipAddress.dstPort = ipFilterConfig->getDestPort();
+        }
+        if (ipFilterConfig->getFirstSrcIpAddress()->getIsIpV4()) {
+            data.resize(4);
+            memcpy(data.data(), ipFilterConfig->getFirstSrcIpAddress()->getIp().data(), 4);
+            ipAddress.srcIpAddress.set<DemuxIpAddressIpAddress::Tag::v4>(data);
+        } else {
+            data.resize(6);
+            memcpy(data.data(), ipFilterConfig->getFirstSrcIpAddress()->getIp().data(), 6);
+            ipAddress.srcIpAddress.set<DemuxIpAddressIpAddress::Tag::v6>(data);
+        }
+        if (ipFilterConfig->getFirstDestIpAddress()->getIsIpV4()) {
+            data.resize(4);
+            memcpy(data.data(), ipFilterConfig->getFirstDestIpAddress()->getIp().data(), 4);
+            ipAddress.dstIpAddress.set<DemuxIpAddressIpAddress::Tag::v4>(data);
+        } else {
+            data.resize(6);
+            memcpy(data.data(), ipFilterConfig->getFirstDestIpAddress()->getIp().data(), 6);
+            ipAddress.dstIpAddress.set<DemuxIpAddressIpAddress::Tag::v6>(data);
+        }
+        return ipAddress;
+    }
+
+    static bool readPassthroughSettings(Filter filterConfig) {
+        if (!filterConfig.hasIpFilterConfig_optional()) {
+            return false;
+        }
+        auto ipFilterConfig = filterConfig.getFirstIpFilterConfig_optional();
+        if (ipFilterConfig->hasDataPassthrough()) {
+            return ipFilterConfig->getDataPassthrough();
+        }
+        return false;
+    }
+
+    static DemuxFilterSectionSettings readSectionFilterSettings(Filter filterConfig) {
+        DemuxFilterSectionSettings settings;
+        if (!filterConfig.hasSectionFilterSettings_optional()) {
+            return settings;
+        }
+        auto section = filterConfig.getFirstSectionFilterSettings_optional();
+        settings.isCheckCrc = section->getIsCheckCrc();
+        settings.isRepeat = section->getIsRepeat();
+        settings.isRaw = section->getIsRaw();
+        return settings;
+    }
+
+    static DemuxFilterAvSettings readAvFilterSettings(Filter filterConfig) {
+        DemuxFilterAvSettings settings;
+        if (!filterConfig.hasAvFilterSettings_optional()) {
+            return settings;
+        }
+        auto av = filterConfig.getFirstAvFilterSettings_optional();
+        settings.isPassthrough = av->getIsPassthrough();
+        return settings;
+    }
+
+    static DemuxFilterRecordSettings readRecordFilterSettings(Filter filterConfig) {
+        DemuxFilterRecordSettings settings;
+        if (!filterConfig.hasRecordFilterSettings_optional()) {
+            return settings;
+        }
+        auto record = filterConfig.getFirstRecordFilterSettings_optional();
+        settings.tsIndexMask = record->getTsIndexMask();
+        settings.scIndexType = static_cast<DemuxRecordScIndexType>(record->getScIndexType());
+        return settings;
+    }
+
+    static PlaybackSettings readPlaybackSettings(Dvr dvrConfig) {
+        ALOGW("[ConfigReader] dvr type is playback");
+        PlaybackSettings playbackSettings{
+                .statusMask = static_cast<uint8_t>(dvrConfig.getStatusMask()),
+                .lowThreshold = static_cast<int32_t>(dvrConfig.getLowThreshold()),
+                .highThreshold = static_cast<int32_t>(dvrConfig.getHighThreshold()),
+                .dataFormat = static_cast<DataFormat>(dvrConfig.getDataFormat()),
+                .packetSize = static_cast<int8_t>(dvrConfig.getPacketSize()),
+        };
+        return playbackSettings;
+    }
+
+    static RecordSettings readRecordSettings(Dvr dvrConfig) {
+        ALOGW("[ConfigReader] dvr type is record");
+        RecordSettings recordSettings{
+                .statusMask = static_cast<uint8_t>(dvrConfig.getStatusMask()),
+                .lowThreshold = static_cast<int32_t>(dvrConfig.getLowThreshold()),
+                .highThreshold = static_cast<int32_t>(dvrConfig.getHighThreshold()),
+                .dataFormat = static_cast<DataFormat>(dvrConfig.getDataFormat()),
+                .packetSize = static_cast<int8_t>(dvrConfig.getPacketSize()),
+        };
+        return recordSettings;
+    }
+
+    static void getCiCamInfo(Frontend feConfig, bool& canConnectToCiCam, int32_t& ciCamId) {
+        if (!feConfig.hasConnectToCicamId()) {
+            canConnectToCiCam = false;
+            ciCamId = -1;
+        }
+        canConnectToCiCam = true;
+        ciCamId = static_cast<int32_t>(feConfig.getConnectToCicamId());
+    }
+};
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index c56bd9a..553d7f0 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -60,9 +60,10 @@
     android::enum_range<CompositePrimitive>().begin(),
     android::enum_range<CompositePrimitive>().end()};
 
-const std::vector<CompositePrimitive> kOptionalPrimitives = {
-    CompositePrimitive::THUD,
-    CompositePrimitive::SPIN,
+const std::vector<CompositePrimitive> kRequiredPrimitives = {
+        CompositePrimitive::CLICK,      CompositePrimitive::LIGHT_TICK,
+        CompositePrimitive::QUICK_RISE, CompositePrimitive::SLOW_RISE,
+        CompositePrimitive::QUICK_FALL,
 };
 
 const std::vector<CompositePrimitive> kInvalidPrimitives = {
@@ -393,11 +394,11 @@
         for (auto primitive : kCompositePrimitives) {
             bool isPrimitiveSupported =
                 std::find(supported.begin(), supported.end(), primitive) != supported.end();
-            bool isPrimitiveOptional =
-                std::find(kOptionalPrimitives.begin(), kOptionalPrimitives.end(), primitive) !=
-                kOptionalPrimitives.end();
+            bool isPrimitiveRequired =
+                    std::find(kRequiredPrimitives.begin(), kRequiredPrimitives.end(), primitive) !=
+                    kRequiredPrimitives.end();
 
-            EXPECT_TRUE(isPrimitiveSupported || isPrimitiveOptional) << toString(primitive);
+            EXPECT_TRUE(isPrimitiveSupported || !isPrimitiveRequired) << toString(primitive);
         }
     }
 }
diff --git a/wifi/1.5/default/ringbuffer.cpp b/wifi/1.5/default/ringbuffer.cpp
index 26971ff..f554111 100644
--- a/wifi/1.5/default/ringbuffer.cpp
+++ b/wifi/1.5/default/ringbuffer.cpp
@@ -47,6 +47,11 @@
     return data_;
 }
 
+void Ringbuffer::clear() {
+    data_.clear();
+    size_ = 0;
+}
+
 }  // namespace implementation
 }  // namespace V1_5
 }  // namespace wifi
diff --git a/wifi/1.5/default/ringbuffer.h b/wifi/1.5/default/ringbuffer.h
index d8b87f2..03fb37a 100644
--- a/wifi/1.5/default/ringbuffer.h
+++ b/wifi/1.5/default/ringbuffer.h
@@ -37,6 +37,7 @@
     // within |maxSize_|.
     void append(const std::vector<uint8_t>& input);
     const std::list<std::vector<uint8_t>>& getData() const;
+    void clear();
 
    private:
     std::list<std::vector<uint8_t>> data_;
diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp
index 6fa9601..82d794c 100644
--- a/wifi/1.5/default/wifi_chip.cpp
+++ b/wifi/1.5/default/wifi_chip.cpp
@@ -1948,8 +1948,8 @@
     // write ringbuffers to file
     {
         std::unique_lock<std::mutex> lk(lock_t);
-        for (const auto& item : ringbuffer_map_) {
-            const Ringbuffer& cur_buffer = item.second;
+        for (auto& item : ringbuffer_map_) {
+            Ringbuffer& cur_buffer = item.second;
             if (cur_buffer.getData().empty()) {
                 continue;
             }
@@ -1967,6 +1967,7 @@
                     PLOG(ERROR) << "Error writing to file";
                 }
             }
+            cur_buffer.clear();
         }
         // unique_lock unlocked here
     }