Extend 1.0 dynamic config reader to read 1.1 Tuner HAL types

Test: atest VtsHalTvTunerV1_1TargetTest
Test: atest VtsHalTvTunerV1_0TargetTest
Bug: 182519645
CTS-Coverage-Bug: 184077478
Change-Id: I0438fff48a6a763b88ed20e34d8ace66a6211302
diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReaderV1_0.h
similarity index 84%
rename from tv/tuner/config/TunerTestingConfigReader.h
rename to tv/tuner/config/TunerTestingConfigReaderV1_0.h
index 90499c4..cff4af1 100644
--- a/tv/tuner/config/TunerTestingConfigReader.h
+++ b/tv/tuner/config/TunerTestingConfigReaderV1_0.h
@@ -36,6 +36,8 @@
 using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
 using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
 using android::hardware::tv::tuner::V1_0::DemuxFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxIpAddress;
+using android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings;
 using android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
 using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
 using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType;
@@ -63,9 +65,10 @@
 using android::hardware::tv::tuner::V1_0::PlaybackSettings;
 using android::hardware::tv::tuner::V1_0::RecordSettings;
 
-const string configFilePath = "/vendor/etc/tuner_vts_config.xml";
 const string emptyHardwareId = "";
 
+static string mConfigFilePath;
+
 #define PROVISION_STR                                      \
     "{                                                   " \
     "  \"id\": 21140844,                                 " \
@@ -125,6 +128,7 @@
     string audioFilterId;
     string videoFilterId;
     string sectionFilterId;
+    string ipFilterId;
     string pcrFilterId;
     /* list string of extra filters; */
 };
@@ -186,14 +190,17 @@
     string timeFilterId;
 };
 
-struct TunerTestingConfigReader {
+struct TunerTestingConfigReader1_0 {
   public:
+    static void setConfigFilePath(string path) { mConfigFilePath = path; }
+
     static bool checkConfigFileExists() {
-        auto res = read(configFilePath.c_str());
+        auto res = read(mConfigFilePath.c_str());
         if (res == nullopt) {
-            ALOGW("[ConfigReader] Couldn't read /vendor/etc/tuner_vts_config.xml."
+            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.");
+                  "and sample_tuner_vts_config.xml for more details on how to config Tune VTS.",
+                  mConfigFilePath.c_str());
         }
         return (res != nullopt);
     }
@@ -413,6 +420,11 @@
         if (liveConfig.hasDvrSoftwareFeConnection()) {
             live.dvrSoftwareFeId = liveConfig.getDvrSoftwareFeConnection();
         }
+        if (liveConfig.hasIpFilterConnection()) {
+            live.ipFilterId = liveConfig.getIpFilterConnection();
+        } else {
+            live.ipFilterId = emptyHardwareId;
+        }
     }
 
     static void connectScan(ScanHardwareConnections& scan) {
@@ -520,6 +532,10 @@
         timeFilter.timeFilterId = timeFilterConfig.getTimeFilterConnection();
     }
 
+    static HardwareConfiguration getHardwareConfig() {
+        return *getTunerConfig().getFirstHardwareConfiguration();
+    }
+
   private:
     static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) {
         ALOGW("[ConfigReader] fe type is dvbt");
@@ -530,12 +546,17 @@
             ALOGW("[ConfigReader] no more dvbt settings");
             return dvbtSettings;
         }
-        dvbtSettings.transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
-                feConfig.getFirstDvbtFrontendSettings_optional()->getTransmissionMode());
-        dvbtSettings.bandwidth = static_cast<FrontendDvbtBandwidth>(
-                feConfig.getFirstDvbtFrontendSettings_optional()->getBandwidth());
-        dvbtSettings.isHighPriority =
-                feConfig.getFirstDvbtFrontendSettings_optional()->getIsHighPriority();
+        auto dvbt = feConfig.getFirstDvbtFrontendSettings_optional();
+        uint32_t trans = static_cast<uint32_t>(dvbt->getTransmissionMode());
+        if (trans <= (uint32_t)FrontendDvbtTransmissionMode::MODE_32K) {
+            dvbtSettings.transmissionMode = static_cast<FrontendDvbtTransmissionMode>(trans);
+        }
+        dvbtSettings.bandwidth = static_cast<FrontendDvbtBandwidth>(dvbt->getBandwidth());
+        dvbtSettings.isHighPriority = dvbt->getIsHighPriority();
+        if (dvbt->hasConstellation()) {
+            dvbtSettings.constellation =
+                    static_cast<FrontendDvbtConstellation>(dvbt->getConstellation());
+        }
         return dvbtSettings;
     }
 
@@ -559,13 +580,13 @@
                                           DemuxFilterSettings& settings) {
         auto mainType = filterConfig.getMainType();
         auto subType = filterConfig.getSubType();
-        uint32_t pid = static_cast<uint32_t>(filterConfig.getPid());
         switch (mainType) {
             case FilterMainTypeEnum::TS: {
                 ALOGW("[ConfigReader] filter main type is ts");
                 type.mainType = DemuxFilterMainType::TS;
                 switch (subType) {
                     case FilterSubTypeEnum::UNDEFINED:
+                        type.subType.tsFilterType(DemuxTsFilterType::UNDEFINED);
                         break;
                     case FilterSubTypeEnum::SECTION:
                         type.subType.tsFilterType(DemuxTsFilterType::SECTION);
@@ -606,7 +627,9 @@
                         ALOGW("[ConfigReader] ts subtype is not supported");
                         return false;
                 }
-                settings.ts().tpid = pid;
+                if (filterConfig.hasPid()) {
+                    settings.ts().tpid = static_cast<uint32_t>(filterConfig.getPid());
+                }
                 break;
             }
             case FilterMainTypeEnum::MMTP: {
@@ -614,6 +637,7 @@
                 type.mainType = DemuxFilterMainType::MMTP;
                 switch (subType) {
                     case FilterSubTypeEnum::UNDEFINED:
+                        type.subType.mmtpFilterType(DemuxMmtpFilterType::UNDEFINED);
                         break;
                     case FilterSubTypeEnum::SECTION:
                         type.subType.mmtpFilterType(DemuxMmtpFilterType::SECTION);
@@ -652,7 +676,47 @@
                         ALOGW("[ConfigReader] mmtp subtype is not supported");
                         return false;
                 }
-                settings.mmtp().mmtpPid = pid;
+                if (filterConfig.hasPid()) {
+                    settings.mmtp().mmtpPid = static_cast<uint32_t>(filterConfig.getPid());
+                }
+                break;
+            }
+            case FilterMainTypeEnum::IP: {
+                ALOGW("[ConfigReader] filter main type is ip");
+                type.mainType = DemuxFilterMainType::IP;
+                switch (subType) {
+                    case FilterSubTypeEnum::UNDEFINED:
+                        type.subType.ipFilterType(DemuxIpFilterType::UNDEFINED);
+                        break;
+                    case FilterSubTypeEnum::SECTION:
+                        type.subType.ipFilterType(DemuxIpFilterType::SECTION);
+                        settings.ip().filterSettings.section(
+                                readSectionFilterSettings(filterConfig));
+                        break;
+                    case FilterSubTypeEnum::NTP:
+                        type.subType.ipFilterType(DemuxIpFilterType::NTP);
+                        settings.ip().filterSettings.noinit();
+                        break;
+                    case FilterSubTypeEnum::IP: {
+                        DemuxIpFilterSettings ip{
+                                .ipAddr = readIpAddress(filterConfig),
+                        };
+                        ip.filterSettings.bPassthrough(readPassthroughSettings(filterConfig));
+                        settings.ip(ip);
+                        break;
+                    }
+                    case FilterSubTypeEnum::IP_PAYLOAD:
+                        type.subType.ipFilterType(DemuxIpFilterType::IP_PAYLOAD);
+                        settings.ip().filterSettings.noinit();
+                        break;
+                    case FilterSubTypeEnum::PAYLOAD_THROUGH:
+                        type.subType.ipFilterType(DemuxIpFilterType::PAYLOAD_THROUGH);
+                        settings.ip().filterSettings.noinit();
+                        break;
+                    default:
+                        ALOGW("[ConfigReader] mmtp subtype is not supported");
+                        return false;
+                }
                 break;
             }
             default:
@@ -663,6 +727,46 @@
         return true;
     }
 
+    static DemuxIpAddress readIpAddress(Filter filterConfig) {
+        DemuxIpAddress ipAddress;
+        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()) {
+            memcpy(ipAddress.srcIpAddress.v4().data(),
+                   ipFilterConfig->getFirstSrcIpAddress()->getIp().data(), 4);
+        } else {
+            memcpy(ipAddress.srcIpAddress.v6().data(),
+                   ipFilterConfig->getFirstSrcIpAddress()->getIp().data(), 6);
+        }
+        if (ipFilterConfig->getFirstDestIpAddress()->getIsIpV4()) {
+            memcpy(ipAddress.dstIpAddress.v4().data(),
+                   ipFilterConfig->getFirstDestIpAddress()->getIp().data(), 4);
+        } else {
+            memcpy(ipAddress.dstIpAddress.v6().data(),
+                   ipFilterConfig->getFirstDestIpAddress()->getIp().data(), 6);
+        }
+        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()) {
@@ -720,11 +824,7 @@
         return recordSettings;
     }
 
-    static TunerConfiguration getTunerConfig() { return *read(configFilePath.c_str()); }
-
-    static HardwareConfiguration getHardwareConfig() {
-        return *getTunerConfig().getFirstHardwareConfiguration();
-    }
+    static TunerConfiguration getTunerConfig() { return *read(mConfigFilePath.c_str()); }
 
     static DataFlowConfiguration getDataFlowConfiguration() {
         return *getTunerConfig().getFirstDataFlowConfiguration();
diff --git a/tv/tuner/config/TunerTestingConfigReaderV1_1.h b/tv/tuner/config/TunerTestingConfigReaderV1_1.h
new file mode 100644
index 0000000..13d5303
--- /dev/null
+++ b/tv/tuner/config/TunerTestingConfigReaderV1_1.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include "TunerTestingConfigReaderV1_0.h"
+
+using android::hardware::tv::tuner::V1_1::AudioStreamType;
+using android::hardware::tv::tuner::V1_1::AvStreamType;
+using android::hardware::tv::tuner::V1_1::FrontendDvbsScanType;
+using android::hardware::tv::tuner::V1_1::FrontendDvbsSettingsExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendDvbtSettingsExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1;
+using android::hardware::tv::tuner::V1_1::VideoStreamType;
+
+struct FrontendConfig1_1 {
+    FrontendConfig config1_0;
+    bool canConnectToCiCam;
+    uint32_t ciCamId;
+    FrontendSettingsExt1_1 settingsExt1_1;
+    vector<FrontendStatusTypeExt1_1> tuneStatusTypes;
+    vector<FrontendStatusExt1_1> expectTuneStatuses;
+};
+
+struct FilterConfig1_1 {
+    FilterConfig config1_0;
+    AvStreamType streamType;
+    uint32_t ipCid;
+    uint32_t monitorEventTypes;
+
+    bool operator<(const FilterConfig& /*c*/) const { return false; }
+};
+
+struct TunerTestingConfigReader1_1 {
+  public:
+    static void readFrontendConfig1_1(map<string, FrontendConfig1_1>& frontendMap) {
+        map<string, FrontendConfig> frontendMap1_0;
+        TunerTestingConfigReader1_0::readFrontendConfig1_0(frontendMap1_0);
+        for (auto it = frontendMap1_0.begin(); it != frontendMap1_0.end(); it++) {
+            frontendMap[it->first].config1_0 = it->second;
+        }
+
+        auto hardwareConfig = TunerTestingConfigReader1_0::getHardwareConfig();
+        if (hardwareConfig.hasFrontends()) {
+            // TODO: b/182519645 complete the tune status config
+            vector<FrontendStatusTypeExt1_1> types;
+            types.push_back(FrontendStatusTypeExt1_1::UEC);
+            types.push_back(FrontendStatusTypeExt1_1::IS_MISO);
+            vector<FrontendStatusExt1_1> statuses;
+            FrontendStatusExt1_1 status;
+            status.uec(4);
+            statuses.push_back(status);
+            status.isMiso(true);
+            statuses.push_back(status);
+
+            auto frontends = *hardwareConfig.getFirstFrontends();
+
+            for (auto feConfig : frontends.getFrontend()) {
+                string id = feConfig.getId();
+                switch (feConfig.getType()) {
+                    case FrontendTypeEnum::DVBS:
+                        frontendMap[id].settingsExt1_1.settingExt.dvbs(
+                                readDvbsFrontendSettings1_1(feConfig));
+                        break;
+                    case FrontendTypeEnum::DVBT: {
+                        frontendMap[id].settingsExt1_1.settingExt.dvbt(
+                                readDvbtFrontendSettings1_1(feConfig));
+                        break;
+                    }
+                    case FrontendTypeEnum::DTMB:
+                        frontendMap[id].config1_0.type = static_cast<FrontendType>(
+                                android::hardware::tv::tuner::V1_1::FrontendType::DTMB);
+                        break;
+                    case FrontendTypeEnum::UNKNOWN:
+                        ALOGW("[ConfigReader] invalid frontend type");
+                        return;
+                    default:
+                        ALOGW("[ConfigReader] fe already handled in 1_0 reader.");
+                        break;
+                }
+                if (feConfig.hasEndFrequency()) {
+                    frontendMap[id].settingsExt1_1.endFrequency =
+                            (uint32_t)feConfig.getEndFrequency();
+                }
+                // 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_1(map<string, FilterConfig1_1>& filterMap) {
+        map<string, FilterConfig> filterMap1_0;
+        TunerTestingConfigReader1_0::readFilterConfig1_0(filterMap1_0);
+        for (auto it = filterMap1_0.begin(); it != filterMap1_0.end(); it++) {
+            filterMap[it->first].config1_0 = it->second;
+        }
+        auto hardwareConfig = TunerTestingConfigReader1_0::getHardwareConfig();
+        if (hardwareConfig.hasFilters()) {
+            auto filters = *hardwareConfig.getFirstFilters();
+            for (auto filterConfig : filters.getFilter()) {
+                string id = filterConfig.getId();
+                if (filterConfig.hasMonitorEventTypes()) {
+                    filterMap[id].monitorEventTypes = (uint32_t)filterConfig.getMonitorEventTypes();
+                }
+                if (filterConfig.hasAvFilterSettings_optional()) {
+                    AvStreamType type;
+                    auto av = filterConfig.getFirstAvFilterSettings_optional();
+                    if (av->hasAudioStreamType_optional()) {
+                        type.audio(static_cast<AudioStreamType>(av->getAudioStreamType_optional()));
+                        filterMap[id].streamType = type;
+                    }
+                    if (av->hasVideoStreamType_optional()) {
+                        type.video(static_cast<VideoStreamType>(av->getVideoStreamType_optional()));
+                        filterMap[id].streamType = type;
+                    }
+                }
+                if (filterConfig.hasIpFilterConfig_optional()) {
+                    auto ip = filterConfig.getFirstIpFilterConfig_optional();
+                    if (ip->hasIpCid()) {
+                        filterMap[id].ipCid = ip->getIpCid();
+                    }
+                }
+            }
+        }
+    }
+
+  private:
+    static void getCiCamInfo(Frontend feConfig, bool& canConnectToCiCam, uint32_t& ciCamId) {
+        if (!feConfig.hasConnectToCicamId()) {
+            canConnectToCiCam = false;
+            ciCamId = -1;
+        }
+        canConnectToCiCam = true;
+        ciCamId = static_cast<uint32_t>(feConfig.getConnectToCicamId());
+    }
+
+    static FrontendDvbsSettingsExt1_1 readDvbsFrontendSettings1_1(Frontend feConfig) {
+        FrontendDvbsSettingsExt1_1 dvbsSettings;
+        if (!feConfig.hasDvbsFrontendSettings_optional()) {
+            return dvbsSettings;
+        }
+        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 FrontendDvbtSettingsExt1_1 readDvbtFrontendSettings1_1(Frontend feConfig) {
+        FrontendDvbtSettingsExt1_1 dvbtSettings;
+        if (!feConfig.hasDvbtFrontendSettings_optional()) {
+            return dvbtSettings;
+        }
+        auto dvbt = feConfig.getFirstDvbtFrontendSettings_optional();
+        auto trans = dvbt->getTransmissionMode();
+        dvbtSettings.transmissionMode =
+                static_cast<android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode>(
+                        trans);
+        if (dvbt->hasConstellation()) {
+            dvbtSettings.constellation =
+                    static_cast<android::hardware::tv::tuner::V1_1::FrontendDvbtConstellation>(
+                            dvbt->getConstellation());
+        }
+        return dvbtSettings;
+    }
+};
\ No newline at end of file
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index 4255a60..a9602e7 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -3,8 +3,12 @@
 
   public class AvFilterSettings {
     ctor public AvFilterSettings();
+    method @Nullable public short getAudioStreamType_optional();
     method @Nullable public boolean getIsPassthrough();
+    method @Nullable public short getVideoStreamType_optional();
+    method public void setAudioStreamType_optional(@Nullable short);
     method public void setIsPassthrough(@Nullable boolean);
+    method public void setVideoStreamType_optional(@Nullable short);
   }
 
   public class DataFlowConfiguration {
@@ -32,12 +36,14 @@
     method @Nullable public String getAudioFilterConnection();
     method @Nullable public String getDvrSoftwareFeConnection();
     method @Nullable public String getFrontendConnection();
+    method @Nullable public String getIpFilterConnection();
     method @Nullable public String getPcrFilterConnection();
     method @Nullable public String getSectionFilterConnection();
     method @Nullable public String getVideoFilterConnection();
     method public void setAudioFilterConnection(@Nullable String);
     method public void setDvrSoftwareFeConnection(@Nullable String);
     method public void setFrontendConnection(@Nullable String);
+    method public void setIpFilterConnection(@Nullable String);
     method public void setPcrFilterConnection(@Nullable String);
     method public void setSectionFilterConnection(@Nullable String);
     method public void setVideoFilterConnection(@Nullable String);
@@ -144,17 +150,32 @@
   public class DvbsFrontendSettings {
     ctor public DvbsFrontendSettings();
     method @Nullable public java.math.BigInteger getInputStreamId();
+    method @Nullable public boolean getIsDiseqcRxMessage();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbsScanType getScanType();
     method @Nullable public java.math.BigInteger getSymbolRate();
     method public void setInputStreamId(@Nullable java.math.BigInteger);
+    method public void setIsDiseqcRxMessage(@Nullable boolean);
+    method public void setScanType(@Nullable android.media.tuner.testing.configuration.V1_0.DvbsScanType);
     method public void setSymbolRate(@Nullable java.math.BigInteger);
   }
 
+  public enum DvbsScanType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType DIRECT;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType DISEQC;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType JESS;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType UNDEFINED;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType UNICABLE;
+  }
+
   public class DvbtFrontendSettings {
     ctor public DvbtFrontendSettings();
     method @Nullable public java.math.BigInteger getBandwidth();
+    method @Nullable public java.math.BigInteger getConstellation();
     method @Nullable public java.math.BigInteger getIsHighPriority();
     method @Nullable public java.math.BigInteger getTransmissionMode();
     method public void setBandwidth(@Nullable java.math.BigInteger);
+    method public void setConstellation(@Nullable java.math.BigInteger);
     method public void setIsHighPriority(@Nullable java.math.BigInteger);
     method public void setTransmissionMode(@Nullable java.math.BigInteger);
   }
@@ -208,7 +229,9 @@
     method @Nullable public android.media.tuner.testing.configuration.V1_0.AvFilterSettings getAvFilterSettings_optional();
     method @Nullable public java.math.BigInteger getBufferSize();
     method @Nullable public String getId();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.IpFilterConfig getIpFilterConfig_optional();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum getMainType();
+    method @Nullable public java.math.BigInteger getMonitorEventTypes();
     method @Nullable public java.math.BigInteger getPid();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.RecordFilterSettings getRecordFilterSettings_optional();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.SectionFilterSettings getSectionFilterSettings_optional();
@@ -217,7 +240,9 @@
     method public void setAvFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AvFilterSettings);
     method public void setBufferSize(@Nullable java.math.BigInteger);
     method public void setId(@Nullable String);
+    method public void setIpFilterConfig_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IpFilterConfig);
     method public void setMainType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum);
+    method public void setMonitorEventTypes(@Nullable java.math.BigInteger);
     method public void setPid(@Nullable java.math.BigInteger);
     method public void setRecordFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.RecordFilterSettings);
     method public void setSectionFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.SectionFilterSettings);
@@ -227,6 +252,7 @@
 
   public enum FilterMainTypeEnum {
     method @NonNull public String getRawName();
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum IP;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum MMTP;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum TS;
   }
@@ -235,7 +261,11 @@
     method @NonNull public String getRawName();
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum AUDIO;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum DOWNLOAD;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum IP;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum IP_PAYLOAD;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum MMTP;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum NTP;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PAYLOAD_THROUGH;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PCR;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PES;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum RECORD;
@@ -334,6 +364,30 @@
     method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.TimeFilter> getTimeFilter();
   }
 
+  public class IpAddress {
+    ctor public IpAddress();
+    method @Nullable public java.util.List<java.lang.Short> getIp();
+    method @Nullable public boolean getIsIpV4();
+    method public void setIp(@Nullable java.util.List<java.lang.Short>);
+    method public void setIsIpV4(@Nullable boolean);
+  }
+
+  public class IpFilterConfig {
+    ctor public IpFilterConfig();
+    method @Nullable public boolean getDataPassthrough();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.IpAddress getDestIpAddress();
+    method @Nullable public long getDestPort();
+    method @Nullable public java.math.BigInteger getIpCid();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.IpAddress getSrcIpAddress();
+    method @Nullable public long getSrcPort();
+    method public void setDataPassthrough(@Nullable boolean);
+    method public void setDestIpAddress(@Nullable android.media.tuner.testing.configuration.V1_0.IpAddress);
+    method public void setDestPort(@Nullable long);
+    method public void setIpCid(@Nullable java.math.BigInteger);
+    method public void setSrcIpAddress(@Nullable android.media.tuner.testing.configuration.V1_0.IpAddress);
+    method public void setSrcPort(@Nullable long);
+  }
+
   public class Lnb {
     ctor public Lnb();
     method @Nullable public String getId();
diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config_1_0.xml
similarity index 100%
rename from tv/tuner/config/sample_tuner_vts_config.xml
rename to tv/tuner/config/sample_tuner_vts_config_1_0.xml
diff --git a/tv/tuner/config/sample_tuner_vts_config_1_1.xml b/tv/tuner/config/sample_tuner_vts_config_1_1.xml
new file mode 100644
index 0000000..191e51c
--- /dev/null
+++ b/tv/tuner/config/sample_tuner_vts_config_1_1.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.
+-->
+
+<!-- The Sample Tuner Testing Configuration.
+    Name the customized xml with "tuner_vts_config.xml" and push into the device
+    "/vendor/etc" path. Please use "tuner_testing_dynamic_configuration.xsd" to verify the xml.
+    The version section contains a “version” tag in the form “major.minor” e.g version=”1.0”
+    This shows the tuner dynamic configuration version. -->
+<TunerConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- Hardware Configuration section contains the configurations of all the hardwares
+        that would be used in the tests. In the "dataFlowConfiguration" section, each data flow
+        under test has its required/optional hardwares. The ids configured in the
+        "dataFlowConfiguration" would be used to connect the hardware to each data flow test. -->
+    <hardwareConfiguration>
+        <!-- Frontends section:
+            This section contains configurations of all the frontends that would be used
+                in the tests.
+                - This section is optional and can be skipped to use the default fe settings.
+                - The default settings can be found in the sample_tuner_vts_configurations.xml.
+                - The users can also override the default frontend settings using id="FE_DEFAULT".
+                - The users can configure 1 or more frontend elements in the frontends sections.
+
+            Each frontend element contain the following attributes:
+                "id": unique id of the frontend that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "type": the frontend type. The enums are defined in the xsd.
+                "isSoftwareFrontend": if the test environment is using hardware or software
+                    frontend. If using software, a ts input file path needs to be configured.
+                "softwareFeInputPath": used as the source of the software frontend.
+                "connectToCicamId": if the device supports frontend connecting to cicam, the target
+                    cicam id needs to be configured here. Supported in Tuner 1.1 or higher.
+                "frequency": the frequency used to configure tune and scan.
+                "endFrequency": the end frequency of scan. Supported in Tuner 1.1 or higher.
+
+            Each frontend element also contains one and only one type-related "frontendSettings".
+                - The settings type should match the frontend "type" attribute.
+                - For example, when frontend type="DVBT", dvbtFrontendSettings can be configured.
+                - This is optional and skipping the settings would pass a setting with frequency
+                    config only to the hal.
+        -->
+        <frontends>
+            <frontend id="FE_DEFAULT" type="DVBT" isSoftwareFrontend="true"
+                      connectToCicamId="0" frequency="578000" endFrequency="800000">
+                <dvbtFrontendSettings bandwidth="8" transmissionMode="128" isHighPriority="1"/>
+            </frontend>
+            <frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
+                      connectToCicamId="0" frequency="578000" endFrequency="800000">
+            </frontend>
+        </frontends>
+        <!-- Filter section:
+            This section contains configurations of all the filters that would be used in the tests.
+                - This section is optional and can be skipped to use the default filter settings.
+                - The default settings can be found in the sample_tuner_vts_configurations.xml.
+                - The users can also override the default filter settings using
+                - id="FILTER_AUDIO_DEFAULT" or "FILTER_VIDEO_DEFAULT".
+                - The users can configure 1 or more filter elements in the filters sections.
+
+            Each filter element contain the following attributes:
+                "id": unique id of the filter that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "mainType": the main filter type. The enums are defined in the xsd.
+                "subType": the sub filter type. The enums are defined in the xsd.
+                "bufferSize": the buffer size of the filter in hex.
+                "pid": the pid that would be used to configure the filter.
+                "useFMQ": if the filter uses FMQ.
+
+            Each filter element also contains at most one type-related "filterSettings".
+                - The settings type should match the filter "subType" attribute.
+                - For example, when filter subType is audio or video, the avFilterSettings can be
+                    configured.
+                - This is optional and skipping the settings would pass a setting with tpid config
+                    only to the hal.
+        -->
+        <filters>
+            <filter id="FILTER_AUDIO_DEFAULT" mainType="TS" subType="AUDIO"
+                    bufferSize="16777216" pid="257" useFMQ="false" monitorEventTypes="3">
+                <avFilterSettings isPassthrough="false">
+                    <audioStreamType>2</audioStreamType>
+                </avFilterSettings>
+            </filter>
+            <filter id="FILTER_VIDEO_DEFAULT" mainType="TS" subType="VIDEO"
+                    bufferSize="16777216" pid="256" useFMQ="false" monitorEventTypes="3">
+                <avFilterSettings isPassthrough="false">
+                    <videoStreamType>2</videoStreamType>
+                </avFilterSettings>
+            </filter>
+            <filter id="FILTER_TS_RECORD_0" mainType="TS" subType="RECORD"
+                    bufferSize="16777216" pid="257" useFMQ="false">
+                <recordFilterSettings tsIndexMask="1" scIndexType="NONE"/>
+            </filter>
+            <filter id="FILTER_IP_IP_0" mainType="IP" subType="IP" bufferSize="16777216" useFMQ="false">
+                <ipFilterConfig ipCid="1">
+                    <srcIpAddress isIpV4="true" ip="192 168 1 1"/>
+                    <destIpAddress isIpV4="true" ip="192 168 1 1"/>
+                </ipFilterConfig>
+            </filter>
+        </filters>
+        <!-- Dvr section:
+            This section contains configurations of all the dvrs that would be used in the tests.
+                - This section is optional and can be skipped if DVR is not supported.
+                - The users can configure 1 or more dvr elements in the dvrs sections.
+
+            Each dvr element contain the following attributes:
+                "id": unique id of the dvr that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "type": the dvr type.
+                "bufferSize": the dvr buffer size.
+                "statusMask": register callbacks of specific status.
+                "lowThreshold": the dvr status low threshold.
+                "highThreshold": the dvr status high threshold.
+                "dataFormat": the dvr data format.
+                "packetSize": the dvr packet size.
+                "inputFilePath": the dvr playback input file path. Only required in playback dvr.
+        -->
+        <dvrs>
+            <dvr id="DVR_PLAYBACK_0" type="PLAYBACK" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="TS" packetSize="188" inputFilePath="/data/local/tmp/segment000000.ts"/>
+            <dvr id="DVR_RECORD_0" type="RECORD" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="TS" packetSize="188"/>
+            <dvr id="DVR_PLAYBACK_1" type="PLAYBACK" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="ES" packetSize="188" inputFilePath="/data/local/tmp/test.es"/>
+        </dvrs>
+    </hardwareConfiguration>
+
+    <!-- Data flow configuration section connects each data flow under test to the ids of the
+        hardwares that would be used during the tests. -->
+    <dataFlowConfiguration>
+        <clearLiveBroadcast frontendConnection="FE_DEFAULT"
+                            audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                            videoFilterConnection="FILTER_VIDEO_DEFAULT"
+                            ipFilterConnection="FILTER_IP_IP_0"
+                            dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
+        <scan frontendConnection="FE_DEFAULT"/>
+        <dvrPlayback dvrConnection="DVR_PLAYBACK_0"
+                     audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                     videoFilterConnection="FILTER_VIDEO_DEFAULT"/>
+        <dvrRecord frontendConnection="FE_DEFAULT"
+                   recordFilterConnection="FILTER_TS_RECORD_0"
+                   dvrRecordConnection="DVR_RECORD_0"
+                   dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
+    </dataFlowConfiguration>
+</TunerConfiguration>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 3fe93ff..3303657 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -49,15 +49,27 @@
             <xs:enumeration value="DTMB"/>
         </xs:restriction>
     </xs:simpleType>
+    <xs:simpleType name="dvbsScanType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="UNDEFINED" />
+            <xs:enumeration value="DIRECT" />
+            <xs:enumeration value="DISEQC" />
+            <xs:enumeration value="UNICABLE"/>
+            <xs:enumeration value="JESS"/>
+        </xs:restriction>
+    </xs:simpleType>
 
     <xs:complexType name="dvbtFrontendSettings">
         <xs:attribute name="bandwidth" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="transmissionMode" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="isHighPriority" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="constellation" type="xs:nonNegativeInteger" use="optional"/>
     </xs:complexType>
     <xs:complexType name="dvbsFrontendSettings">
         <xs:attribute name="inputStreamId" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="symbolRate" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="scanType" type="dvbsScanType" use="optional"/>
+        <xs:attribute name="isDiseqcRxMessage" type="xs:boolean" use="optional"/>
     </xs:complexType>
 
     <xs:complexType name="frontend">
@@ -137,13 +149,19 @@
             <xs:enumeration value="SC_HEVC"/>
         </xs:restriction>
     </xs:simpleType>
+    <xs:simpleType name="monitoEvents">
+        <xs:restriction base="xs:integer">
+            <xs:minInclusive value="0"/>
+            <xs:maxInclusive value="3"/>
+        </xs:restriction>
+    </xs:simpleType>
 
     <xs:simpleType name="filterMainTypeEnum">
         <xs:restriction base="xs:string">
             <xs:enumeration value="TS" />
             <xs:enumeration value="MMTP" />
-            <!-- TODO: b/182519645 Support IP/TLV/ALP filter config
             <xs:enumeration value="IP"/>
+            <!-- TODO: b/182519645 Support TLV/ALP filter config
             <xs:enumeration value="TLV"/>
             <xs:enumeration value="ALP"/-->
         </xs:restriction>
@@ -161,10 +179,37 @@
             <xs:enumeration value="TEMI"/>
             <xs:enumeration value="MMTP"/>
             <xs:enumeration value="DOWNLOAD"/>
+            <xs:enumeration value="IP"/>
+            <xs:enumeration value="NTP"/>
+            <xs:enumeration value="IP_PAYLOAD"/>
+            <xs:enumeration value="PAYLOAD_THROUGH"/>            
         </xs:restriction>
     </xs:simpleType>
 
+    <xs:simpleType name="ip">
+        <xs:list itemType="xs:unsignedByte"/>
+    </xs:simpleType>
+    <xs:complexType name="ipAddress">
+        <xs:attribute name="isIpV4" type="xs:boolean" use="required"/>
+        <xs:attribute name="ip" type="ip" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="ipFilterConfig">
+        <xs:sequence>
+            <xs:element name="srcIpAddress" type="ipAddress" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="destIpAddress" type="ipAddress" minOccurs="1" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="srcPort" type="xs:unsignedInt" use="optional"/>
+        <xs:attribute name="destPort" type="xs:unsignedInt" use="optional"/>
+        <!-- True if the ip filter data goes to the next filter directly -->
+        <xs:attribute name="dataPassthrough" type="xs:boolean" use="optional"/>
+        <xs:attribute name="ipCid" type="xs:nonNegativeInteger" use="optional"/>
+    </xs:complexType>
+
     <xs:complexType name="avFilterSettings">
+        <xs:choice minOccurs="0" maxOccurs="1">
+            <xs:element name="audioStreamType" type="xs:unsignedByte"/>
+            <xs:element name="videoStreamType" type="xs:unsignedByte"/>
+        </xs:choice>
         <xs:attribute name="isPassthrough" type="xs:boolean" use="required"/>
     </xs:complexType>
     <xs:complexType name="sectionFilterSettings">
@@ -197,20 +242,28 @@
                         config only to the hal.
             </xs:documentation>
         </xs:annotation>
-        <xs:choice minOccurs="0" maxOccurs="1">
-            <!-- TODO: b/182519645 finish all the filter settings structures. -->
-            <xs:element name="sectionFilterSettings" type="sectionFilterSettings"/>
-            <xs:element name="avFilterSettings" type="avFilterSettings"/>
-            <xs:element name="recordFilterSettings" type="recordFilterSettings"/>
-            <!--xs:element name="pes" type="pesFilterSettings"/>
-            <xs:element name="download" type="downloadFilterSettings"/-->
-        </xs:choice>
+        <xs:sequence>
+            <!-- Main filter type related config -->
+            <xs:choice minOccurs="0" maxOccurs="1">
+                <xs:element name="ipFilterConfig" type="ipFilterConfig"/>
+            </xs:choice>
+            <!-- Sub filter type related config -->
+            <xs:choice minOccurs="0" maxOccurs="1">
+                <!-- TODO: b/182519645 finish all the filter settings structures. -->
+                <xs:element name="sectionFilterSettings" type="sectionFilterSettings"/>
+                <xs:element name="avFilterSettings" type="avFilterSettings"/>
+                <xs:element name="recordFilterSettings" type="recordFilterSettings"/>
+                <!--xs:element name="pes" type="pesFilterSettings"/>
+                <xs:element name="download" type="downloadFilterSettings"/-->
+            </xs:choice>
+        </xs:sequence>
         <xs:attribute name="id" type="filterId" use="required"/>
         <xs:attribute name="mainType" type="filterMainTypeEnum" use="required"/>
         <xs:attribute name="subType" type="filterSubTypeEnum" use="required"/>
         <xs:attribute name="bufferSize" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="pid" type="xs:nonNegativeInteger" use="optional"/>
         <xs:attribute name="useFMQ" type="xs:boolean" use="required"/>
+        <xs:attribute name="monitorEventTypes" type="monitoEvents" use="optional"/>
     </xs:complexType>
 
     <!-- DVR SESSION -->
@@ -396,7 +449,7 @@
         </xs:annotation>
         <xs:attribute name="id" type="descramblerId" use="required"/>
         <xs:attribute name="casSystemId" type="xs:nonNegativeInteger" use="required"/>
-        <xs:attribute name="provisionStr" type="xs:string" use="required"/>
+        <xs:attribute name="provisionStr" type="xs:string" use="optional"/>
         <xs:attribute name="sesstionPrivatData" type="sessionPrivateData" use="optional"/>
     </xs:complexType>
 
@@ -541,6 +594,7 @@
                     <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
                     <xs:attribute name="pcrFilterConnection" type="filterId" use="optional"/>
                     <xs:attribute name="sectionFilterConnection" type="filterId" use="optional"/>
+                    <xs:attribute name="ipFilterConnection" type="filterId" use="optional"/>
                     <!-- TODO: b/182519645 allow the users to insert extra filters -->
                     <!-- DVR is only required when the frontend is using the software input -->
                     <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>