Merge "Use a different timesource in recurrent timer."
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index a9bd970..5d35569 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -1244,7 +1244,7 @@
             "defaultValue": {
                 "floatValues": [
                     66.19999694824219,
-                    49.0,
+                    "VehicleUnit::FAHRENHEIT",
                     19.0,
                     66.5
                 ]
@@ -1264,12 +1264,12 @@
             "property": "VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS",
             "defaultValue": {
                 "int32Values": [
-                    49
+                    "VehicleUnit::FAHRENHEIT"
                 ]
             },
             "configArray": [
-                49,
-                48
+                "VehicleUnit::FAHRENHEIT",
+                "VehicleUnit::CELSIUS"
             ]
         },
         {
@@ -1456,22 +1456,22 @@
                 {
                     "areaId": "Constants::WINDOW_1_LEFT",
                     "minInt32Value": 0,
-                    "maxInt32Value": 10,
+                    "maxInt32Value": 10
                 },
                 {
                     "areaId": "Constants::WINDOW_1_RIGHT",
                     "minInt32Value": 0,
-                    "maxInt32Value": 10,
+                    "maxInt32Value": 10
                 },
                 {
                     "areaId": "Constants::WINDOW_2_LEFT",
                     "minInt32Value": 0,
-                    "maxInt32Value": 10,
+                    "maxInt32Value": 10
                 },
                 {
                     "areaId": "Constants::WINDOW_2_RIGHT",
                     "minInt32Value": 0,
-                    "maxInt32Value": 10,
+                    "maxInt32Value": 10
                 },
                 {
                     "areaId": "Constants::WINDOW_ROOF_TOP_1",
@@ -1703,13 +1703,13 @@
             "property": "VehicleProperty::CURRENT_POWER_POLICY"
         },
         {
-            "property": "VehicleProperty::ANDROID_EPOCH_TIME",
+            "property": "VehicleProperty::ANDROID_EPOCH_TIME"
         },
         {
-            "property": "VehicleProperty::WATCHDOG_ALIVE",
+            "property": "VehicleProperty::WATCHDOG_ALIVE"
         },
         {
-            "property": "VehicleProperty::WATCHDOG_TERMINATED_PROCESS",
+            "property": "VehicleProperty::WATCHDOG_TERMINATED_PROCESS"
         },
         {
             "property": "VehicleProperty::VHAL_HEARTBEAT"
@@ -1739,7 +1739,7 @@
                 ]
             },
             "comment":
-                    "Value means: 0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1, -1, -1 /* Insets */",
+                    "Value means: 0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1, -1, -1 /* Insets */"
         },
         {
             "property": "VehicleProperty::CLUSTER_REPORT_STATE",
@@ -1756,10 +1756,10 @@
             ]
         },
         {
-            "property": "VehicleProperty::CLUSTER_REQUEST_DISPLAY",
+            "property": "VehicleProperty::CLUSTER_REQUEST_DISPLAY"
         },
         {
-            "property": "VehicleProperty::CLUSTER_NAVIGATION_STATE",
+            "property": "VehicleProperty::CLUSTER_NAVIGATION_STATE"
         },
         {
             "property": "VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT",
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
index fbe8686..d2fdf02 100644
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ b/camera/common/1.0/default/HandleImporter.cpp
@@ -18,6 +18,7 @@
 #include "HandleImporter.h"
 
 #include <gralloctypes/Gralloc4.h>
+#include "aidl/android/hardware/graphics/common/Smpte2086.h"
 #include <log/log.h>
 
 namespace android {
@@ -30,6 +31,7 @@
 using aidl::android::hardware::graphics::common::PlaneLayout;
 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using aidl::android::hardware::graphics::common::Smpte2086;
 using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
 using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
 using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
@@ -127,16 +129,35 @@
 bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf,
         MetadataType metadataType) {
     auto buffer = const_cast<native_handle_t*>(buf);
-    mapper->get(buffer, metadataType, [] (const auto& tmpError,
+    bool ret = false;
+    hidl_vec<uint8_t> vec;
+    mapper->get(buffer, metadataType, [&] (const auto& tmpError,
                 const auto& tmpMetadata) {
                     if (tmpError == MapperErrorV4::NONE) {
-                        return tmpMetadata.size() > 0;
+                        vec = tmpMetadata;
                     } else {
                         ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError);
-                        return false;
                     }});
 
-    return false;
+    if (vec.size() > 0) {
+            if (metadataType == gralloc4::MetadataType_Smpte2086){
+                std::optional<Smpte2086> realSmpte2086;
+                gralloc4::decodeSmpte2086(vec, &realSmpte2086);
+                ret = realSmpte2086.has_value();
+            } else if (metadataType == gralloc4::MetadataType_Smpte2094_10) {
+                std::optional<std::vector<uint8_t>> realSmpte2094_10;
+                gralloc4::decodeSmpte2094_10(vec, &realSmpte2094_10);
+                ret = realSmpte2094_10.has_value();
+            } else if (metadataType == gralloc4::MetadataType_Smpte2094_40) {
+                std::optional<std::vector<uint8_t>> realSmpte2094_40;
+                gralloc4::decodeSmpte2094_40(vec, &realSmpte2094_40);
+                ret = realSmpte2094_40.has_value();
+            } else {
+                ALOGE("%s: Unknown metadata type!", __FUNCTION__);
+            }
+    }
+
+    return ret;
 }
 
 std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) {
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index fe03732..70ab7a0 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -1739,6 +1739,10 @@
 
         std::list<PixelFormat> pixelFormats = {PixelFormat::YCBCR_420_888, PixelFormat::RAW16};
         for (PixelFormat format : pixelFormats) {
+            previewStream.usage =
+                static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+                        GRALLOC1_CONSUMER_USAGE_CPU_READ);
+            previewStream.dataSpace = Dataspace::UNKNOWN;
             configureStreams(name, mProvider, format, &mSession, &previewStream, &halStreams,
                              &supportsPartialResults, &partialResultCount, &useHalBufManager, &cb,
                              0, /*maxResolution*/ true);
@@ -1843,7 +1847,6 @@
 TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) {
     std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
     int64_t bufferId = 1;
-    int32_t frameNumber = 1;
     CameraMetadata settings;
 
     for (const auto& name : cameraDeviceNames) {
@@ -1866,7 +1869,7 @@
         CameraMetadata req;
         android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings;
         ndk::ScopedAStatus ret =
-                mSession->constructDefaultRequestSettings(RequestTemplate::STILL_CAPTURE, &req);
+                mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &req);
         ASSERT_TRUE(ret.isOk());
 
         const camera_metadata_t* metadata =
@@ -1896,6 +1899,10 @@
         Stream previewStream;
         std::shared_ptr<DeviceCb> cb;
         for (const auto& profile : profileList) {
+            previewStream.usage =
+                static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+                        GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
+            previewStream.dataSpace = getDataspace(PixelFormat::IMPLEMENTATION_DEFINED);
             configureStreams(name, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, &mSession,
                              &previewStream, &halStreams, &supportsPartialResults,
                              &partialResultCount, &useHalBufManager, &cb, 0,
@@ -1916,63 +1923,75 @@
                 // Don't use the queue onwards.
             }
 
-            std::vector<buffer_handle_t> graphicBuffers;
-            graphicBuffers.reserve(halStreams.size());
+            mInflightMap.clear();
+            // Stream as long as needed to fill the Hal inflight queue
+            std::vector<CaptureRequest> requests(halStreams[0].maxBuffers);
 
-            std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
-                    static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
-                    partialResultCount, std::unordered_set<std::string>(), resultQueue);
+            for (int32_t frameNumber = 0; frameNumber < requests.size(); frameNumber++) {
+                std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
+                        static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
+                        partialResultCount, std::unordered_set<std::string>(), resultQueue);
 
-            std::vector<CaptureRequest> requests(1);
-            CaptureRequest& request = requests[0];
-            std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
-            outputBuffers.resize(halStreams.size());
+                CaptureRequest& request = requests[frameNumber];
+                std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
+                outputBuffers.resize(halStreams.size());
 
-            size_t k = 0;
-            for (const auto& halStream : halStreams) {
-                buffer_handle_t buffer_handle;
-                if (useHalBufManager) {
-                    outputBuffers[k] = {halStream.id,   0,
-                                        NativeHandle(), BufferStatus::OK,
-                                        NativeHandle(), NativeHandle()};
-                } else {
-                    allocateGraphicBuffer(previewStream.width, previewStream.height,
-                                          android_convertGralloc1To0Usage(
-                                                  static_cast<uint64_t>(halStream.producerUsage),
-                                                  static_cast<uint64_t>(halStream.consumerUsage)),
-                                          halStream.overrideFormat, &buffer_handle);
+                size_t k = 0;
+                inflightReq->mOutstandingBufferIds.resize(halStreams.size());
+                std::vector<buffer_handle_t> graphicBuffers;
+                graphicBuffers.reserve(halStreams.size());
 
-                    graphicBuffers.push_back(buffer_handle);
-                    outputBuffers[k] = {
-                            halStream.id,     bufferId,       android::makeToAidl(buffer_handle),
-                            BufferStatus::OK, NativeHandle(), NativeHandle()};
-                    bufferId++;
+                for (const auto& halStream : halStreams) {
+                    buffer_handle_t buffer_handle;
+                    if (useHalBufManager) {
+                        outputBuffers[k] = {halStream.id,   0,
+                                            NativeHandle(), BufferStatus::OK,
+                                            NativeHandle(), NativeHandle()};
+                    } else {
+                        auto usage = android_convertGralloc1To0Usage(
+                                static_cast<uint64_t>(halStream.producerUsage),
+                                static_cast<uint64_t>(halStream.consumerUsage));
+                        allocateGraphicBuffer(previewStream.width, previewStream.height, usage,
+                                              halStream.overrideFormat, &buffer_handle);
+
+                        inflightReq->mOutstandingBufferIds[halStream.id][bufferId] = buffer_handle;
+                        graphicBuffers.push_back(buffer_handle);
+                        outputBuffers[k] = {halStream.id, bufferId,
+                            android::makeToAidl(buffer_handle), BufferStatus::OK, NativeHandle(),
+                            NativeHandle()};
+                        bufferId++;
+                    }
+                    k++;
                 }
-                k++;
-            }
 
-            request.inputBuffer = {
-                    -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
-            request.frameNumber = frameNumber;
-            request.fmqSettingsSize = 0;
-            request.settings = settings;
-            request.inputWidth = 0;
-            request.inputHeight = 0;
+                request.inputBuffer = {
+                        -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
+                request.frameNumber = frameNumber;
+                request.fmqSettingsSize = 0;
+                request.settings = settings;
+                request.inputWidth = 0;
+                request.inputHeight = 0;
 
-            {
-                std::unique_lock<std::mutex> l(mLock);
-                mInflightMap.clear();
-                mInflightMap[frameNumber] = inflightReq;
+                {
+                    std::unique_lock<std::mutex> l(mLock);
+                    mInflightMap[frameNumber] = inflightReq;
+                }
+
             }
 
             int32_t numRequestProcessed = 0;
             std::vector<BufferCache> cachesToRemove;
             ndk::ScopedAStatus returnStatus =
-                    mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
+                mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
             ASSERT_TRUE(returnStatus.isOk());
-            ASSERT_EQ(numRequestProcessed, 1u);
+            ASSERT_EQ(numRequestProcessed, requests.size());
 
-            {
+            returnStatus = mSession->repeatingRequestEnd(requests.size() - 1,
+                    std::vector<int32_t> {halStreams[0].id});
+            ASSERT_TRUE(returnStatus.isOk());
+
+            for (int32_t frameNumber = 0; frameNumber < requests.size(); frameNumber++) {
+                const auto& inflightReq = mInflightMap[frameNumber];
                 std::unique_lock<std::mutex> l(mLock);
                 while (!inflightReq->errorCodeValid &&
                        ((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) {
@@ -1985,6 +2004,7 @@
                 ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
                 verify10BitMetadata(mHandleImporter, *inflightReq, profile);
             }
+
             if (useHalBufManager) {
                 std::vector<int32_t> streamIds(halStreams.size());
                 for (size_t i = 0; i < streamIds.size(); i++) {
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index c11fc0c..20f32bf 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -2639,8 +2639,20 @@
 
     outputStreams.clear();
     Size maxSize;
-    auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution);
-    ASSERT_EQ(Status::OK, rc);
+    if (maxResolution) {
+        auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution);
+        ASSERT_EQ(Status::OK, rc);
+    } else {
+        AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+            static_cast<int32_t>(format)};
+        auto rc = getAvailableOutputStreams(staticMeta, outputStreams, &previewThreshold);
+
+        ASSERT_EQ(Status::OK, rc);
+        ASSERT_FALSE(outputStreams.empty());
+        maxSize.width = outputStreams[0].width;
+        maxSize.height = outputStreams[0].height;
+    }
+
 
     std::vector<Stream> streams(1);
     streams[0] = {0,
@@ -2648,9 +2660,8 @@
                   maxSize.width,
                   maxSize.height,
                   format,
-                  static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
-                          GRALLOC1_CONSUMER_USAGE_CPU_READ),
-                  Dataspace::UNKNOWN,
+                  previewStream->usage,
+                  previewStream->dataSpace,
                   StreamRotation::ROTATION_0,
                   "",
                   0,
@@ -2736,7 +2747,8 @@
         HandleImporter& importer, const InFlightRequest& request,
         aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap
                 profile) {
-    for (const auto& b : request.resultOutputBuffers) {
+    for (auto b : request.resultOutputBuffers) {
+        importer.importBuffer(b.buffer.buffer);
         bool smpte2086Present = importer.isSmpte2086Present(b.buffer.buffer);
         bool smpte2094_10Present = importer.isSmpte2094_10Present(b.buffer.buffer);
         bool smpte2094_40Present = importer.isSmpte2094_40Present(b.buffer.buffer);
@@ -2753,7 +2765,6 @@
                 ASSERT_FALSE(smpte2094_40Present);
                 break;
             case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
-                ASSERT_FALSE(smpte2086Present);
                 ASSERT_FALSE(smpte2094_10Present);
                 ASSERT_TRUE(smpte2094_40Present);
                 break;
@@ -2774,6 +2785,7 @@
                       profile);
                 ADD_FAILURE();
         }
+        importer.freeBuffer(b.buffer.buffer);
     }
 }
 
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index ac4b2c9..d828cee 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -399,6 +399,10 @@
         // Result metadata
         ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult;
 
+        // Inflight buffers
+        using OutstandingBuffers = std::unordered_map<uint64_t, buffer_handle_t>;
+        std::vector<OutstandingBuffers> mOutstandingBufferIds;
+
         // A copy-able StreamBuffer using buffer_handle_t instead of AIDLs NativeHandle
         struct NativeStreamBuffer {
             int32_t streamId;
diff --git a/camera/provider/aidl/vts/device_cb.cpp b/camera/provider/aidl/vts/device_cb.cpp
index e5f2f1e..4698b4a 100644
--- a/camera/provider/aidl/vts/device_cb.cpp
+++ b/camera/provider/aidl/vts/device_cb.cpp
@@ -155,7 +155,7 @@
                     BufferStatus::OK, NativeHandle(), NativeHandle(),
             };
 
-            mOutstandingBufferIds[idx][mNextBufferId++] = ::android::dupToAidl(handle);
+            mOutstandingBufferIds[idx][mNextBufferId++] = handle;
         }
         atLeastOneStreamOk = true;
         bufRets[i].streamId = stream.id;
@@ -427,9 +427,13 @@
         }
 
         CameraAidlTest::InFlightRequest::StreamBufferAndTimestamp streamBufferAndTimestamp;
+        auto outstandingBuffers = mUseHalBufManager ? mOutstandingBufferIds :
+            request->mOutstandingBufferIds;
+        auto outputBuffer = outstandingBuffers.empty() ? ::android::makeFromAidl(buffer.buffer) :
+            outstandingBuffers[buffer.streamId][buffer.bufferId];
         streamBufferAndTimestamp.buffer = {buffer.streamId,
                                            buffer.bufferId,
-                                           ::android::makeFromAidl(buffer.buffer),
+                                           outputBuffer,
                                            buffer.status,
                                            ::android::makeFromAidl(buffer.acquireFence),
                                            ::android::makeFromAidl(buffer.releaseFence)};
diff --git a/camera/provider/aidl/vts/device_cb.h b/camera/provider/aidl/vts/device_cb.h
index 82ca10d..3ae7d10 100644
--- a/camera/provider/aidl/vts/device_cb.h
+++ b/camera/provider/aidl/vts/device_cb.h
@@ -73,7 +73,7 @@
     std::vector<Stream> mStreams;
     std::vector<HalStream> mHalStreams;
     int64_t mNextBufferId = 1;
-    using OutstandingBuffers = std::unordered_map<uint64_t, NativeHandle>;
+    using OutstandingBuffers = std::unordered_map<uint64_t, buffer_handle_t>;
     // size == mStreams.size(). Tracking each streams outstanding buffers
     std::vector<OutstandingBuffers> mOutstandingBufferIds;
     std::condition_variable mFlushedCondition;
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 35cd6f0..ffc268e 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -599,15 +599,6 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.sensors</name>
-        <version>1.0</version>
-        <version>2.0-1</version>
-        <interface>
-            <name>ISensors</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" optional="true">
          <name>android.hardware.soundtrigger3</name>
          <version>1</version>
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
index ddd45b7..9e8c768 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
@@ -23,7 +23,6 @@
 parcelable ChangedCompositionTypes {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
index ba6fe97..ea54a89 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithBrightness.aidl
@@ -23,7 +23,6 @@
 parcelable ClientTargetPropertyWithBrightness {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
index b6df147..4f69aee 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -26,7 +26,6 @@
 parcelable DisplayCommand {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
index 27fe1e6..3a50b6e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -34,7 +34,6 @@
 
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
index 244b4e5..b757656 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
@@ -20,7 +20,6 @@
 parcelable PresentFence {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
index 5ae8940..e15dbf2 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -20,7 +20,6 @@
 parcelable PresentOrValidate {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
 
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
index 459a042..58649d5 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
@@ -20,7 +20,6 @@
 parcelable ReleaseFences {
     /**
      * The display which this commands refers to.
-     * @see IComposer.createDisplay
      */
     long display;
     @VintfStability
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 8739668..4d176ab 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -260,7 +260,9 @@
     for (auto msgName : lnbRecord.diseqcMsgs) {
         ASSERT_TRUE(mLnbTests.sendDiseqcMessage(diseqcMsgMap[msgName]));
     }
-    recordSingleFilterTest(filterConf, frontendConf, dvrConf);
+    if (!frontendConf.isSoftwareFe) {
+        recordSingleFilterTest(filterConf, frontendConf, dvrConf, Dataflow_Context::LNBRECORD);
+    }
     ASSERT_TRUE(mLnbTests.closeLnb());
     mLnbId = INVALID_LNB_ID;
 }
@@ -318,29 +320,47 @@
 }
 
 void TunerRecordAidlTest::recordSingleFilterTest(FilterConfig filterConf,
-                                                 FrontendConfig frontendConf, DvrConfig dvrConf) {
+                                                 FrontendConfig frontendConf, DvrConfig dvrConf,
+                                                 Dataflow_Context context) {
     int32_t demuxId;
     std::shared_ptr<IDemux> demux;
     ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
     mDvrTests.setDemux(demux);
 
     DvrConfig dvrSourceConfig;
-    if (record.hasFrontendConnection) {
+    if (context == Dataflow_Context::RECORD) {
+        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());
+        }
+    } else if (context == Dataflow_Context::LNBRECORD) {
+        // If function arrives here, frontend should not be software, so no need to configure a dvr
+        // source or dvr fe connection that might be used for recording without an Lnb
         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]);
+        if (mLnbId != INVALID_LNB_ID) {
+            ASSERT_TRUE(mFrontendTests.setLnb(mLnbId));
+        } else {
+            FAIL();
         }
         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;
@@ -360,24 +380,31 @@
     ASSERT_TRUE(mDvrTests.startDvrRecord());
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
 
-    if (record.hasFrontendConnection) {
+    if (context == Dataflow_Context::RECORD) {
+        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());
+        }
+    } else if (context == Dataflow_Context::LNBRECORD) {
         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) {
+    if (context == Dataflow_Context::RECORD) {
+        if (record.hasFrontendConnection) {
+            ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+        } else {
+            mDvrTests.stopPlaybackThread();
+            ASSERT_TRUE(mDvrTests.stopDvrPlayback());
+        }
+    } else if (context == Dataflow_Context::LNBRECORD) {
         ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
-    } else {
-        mDvrTests.stopPlaybackThread();
-        ASSERT_TRUE(mDvrTests.stopDvrPlayback());
     }
 
     ASSERT_TRUE(mFilterTests.stopFilter(filterId));
@@ -386,10 +413,14 @@
     ASSERT_TRUE(mFilterTests.closeFilter(filterId));
     mDvrTests.closeDvrRecord();
 
-    if (record.hasFrontendConnection) {
+    if (context == Dataflow_Context::RECORD) {
+        if (record.hasFrontendConnection) {
+            ASSERT_TRUE(mFrontendTests.closeFrontend());
+        } else {
+            mDvrTests.closeDvrPlayback();
+        }
+    } else if (context == Dataflow_Context::LNBRECORD) {
         ASSERT_TRUE(mFrontendTests.closeFrontend());
-    } else {
-        mDvrTests.closeDvrPlayback();
     }
 
     ASSERT_TRUE(mDemuxTests.closeDemux());
@@ -526,17 +557,21 @@
     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());
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        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) {
@@ -544,40 +579,45 @@
     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;
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        if (live.pcrFilterId.compare(emptyHardwareId) == 0) {
+            continue;
+        }
+        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());
+        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) {
@@ -586,7 +626,11 @@
         return;
     }
     // TODO use parameterized tests
-    configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFilterAidlTest, ConfigIpFilterInDemuxWithCid) {
@@ -595,10 +639,14 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    if (live.ipFilterId.compare(emptyHardwareId) == 0) {
-        return;
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        if (live.ipFilterId.compare(emptyHardwareId) == 0) {
+            continue;
+        }
+        configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]);
     }
-    configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerFilterAidlTest, ReconfigFilterToReceiveStartId) {
@@ -607,8 +655,13 @@
         return;
     }
     // TODO use parameterized tests
-    reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId], filterMap[live.videoFilterId],
-                                    frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId],
+                                        filterMap[live.videoFilterId],
+                                        frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFilterAidlTest, SetFilterLinkage) {
@@ -645,7 +698,11 @@
         return;
     }
     // TODO use parameterized tests
-    testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
+    auto timeFilter_configs = generateTimeFilterConfigurations();
+    for (auto& configuration : timeFilter_configs) {
+        timeFilter = configuration;
+        testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
+    }
 }
 
 static bool isEventProducingFilter(const FilterConfig& filterConfig) {
@@ -888,8 +945,12 @@
     if (!record.support) {
         return;
     }
-    recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
-                           dvrMap[record.dvrRecordId]);
+    auto record_configs = generateRecordConfigurations();
+    for (auto& configuration : record_configs) {
+        record = configuration;
+        recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
+                               dvrMap[record.dvrRecordId], Dataflow_Context::RECORD);
+    }
 }
 
 TEST_P(TunerRecordAidlTest, AttachFiltersToRecordTest) {
@@ -898,8 +959,13 @@
     if (!record.support) {
         return;
     }
-    attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
-                                      frontendMap[record.frontendId], dvrMap[record.dvrRecordId]);
+    auto record_configs = generateRecordConfigurations();
+    for (auto& configuration : record_configs) {
+        record = configuration;
+        attachSingleFilterToRecordDvrTest(filterMap[record.recordFilterId],
+                                          frontendMap[record.frontendId],
+                                          dvrMap[record.dvrRecordId]);
+    }
 }
 
 TEST_P(TunerRecordAidlTest, LnbRecordDataFlowWithTsRecordFilterTest) {
@@ -925,7 +991,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, AutoScanFrontend) {
@@ -957,7 +1027,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mFrontendTests.tuneTest(frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, BlindScanFrontendWithEndFrequency) {
@@ -977,10 +1051,14 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    if (!frontendMap[live.frontendId].canConnectToCiCam) {
-        return;
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        if (!frontendMap[live.frontendId].canConnectToCiCam) {
+            continue;
+        }
+        mFrontendTests.tuneTest(frontendMap[live.frontendId]);
     }
-    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerFrontendAidlTest, getHardwareInfo) {
@@ -988,7 +1066,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.debugInfoTest(frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mFrontendTests.debugInfoTest(frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerFrontendAidlTest, maxNumberOfFrontends) {
@@ -1004,7 +1086,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mFrontendTests.statusReadinessTest(frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mFrontendTests.statusReadinessTest(frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowVideoFilterTest) {
@@ -1012,7 +1098,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowAudioFilterTest) {
@@ -1020,7 +1110,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        broadcastSingleFilterTest(filterMap[live.audioFilterId], frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowSectionFilterTest) {
@@ -1028,10 +1122,14 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    if (live.sectionFilterId.compare(emptyHardwareId) == 0) {
-        return;
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        if (live.sectionFilterId.compare(emptyHardwareId) == 0) {
+            continue;
+        }
+        broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]);
     }
-    broadcastSingleFilterTest(filterMap[live.sectionFilterId], frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerBroadcastAidlTest, IonBufferTest) {
@@ -1039,7 +1137,11 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        broadcastSingleFilterTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerBroadcastAidlTest, LnbBroadcastDataFlowVideoFilterTest) {
@@ -1064,7 +1166,12 @@
     if (!live.hasFrontendConnection) {
         return;
     }
-    mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
+    auto live_configs = generateLiveConfigurations();
+    for (auto& configuration : live_configs) {
+        live = configuration;
+        mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId],
+                                         frontendMap[live.frontendId]);
+    }
 }
 
 TEST_P(TunerDescramblerAidlTest, CreateDescrambler) {
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
index 2e69821..fbb8693 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -68,7 +68,10 @@
     lnbIds.clear();
     diseqcMsgs.clear();
     frontendIds.clear();
+    ipFilterIds.clear();
+    pcrFilterIds.clear();
     recordDvrIds.clear();
+    timeFilterIds.clear();
     descramblerIds.clear();
     audioFilterIds.clear();
     videoFilterIds.clear();
@@ -77,6 +80,8 @@
     sectionFilterIds.clear();
 }
 
+enum class Dataflow_Context { LNBRECORD, RECORD };
+
 class TunerLnbAidlTest : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
@@ -153,7 +158,7 @@
             mService = nullptr;
         }
         ASSERT_NE(mService, nullptr);
-        initConfiguration();
+        ASSERT_TRUE(initConfiguration());
 
         mFrontendTests.setService(mService);
         mDemuxTests.setService(mService);
@@ -264,7 +269,7 @@
             mService = nullptr;
         }
         ASSERT_NE(mService, nullptr);
-        initConfiguration();
+        ASSERT_TRUE(initConfiguration());
 
         mFrontendTests.setService(mService);
         mDemuxTests.setService(mService);
@@ -288,7 +293,7 @@
     void recordSingleFilterTestWithLnb(FilterConfig filterConf, FrontendConfig frontendConf,
                                        DvrConfig dvrConf, LnbConfig lnbConf);
     void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf,
-                                DvrConfig dvrConf);
+                                DvrConfig dvrConf, Dataflow_Context context);
 
     std::shared_ptr<ITuner> mService;
     FrontendTests mFrontendTests;
@@ -313,7 +318,7 @@
             mService = nullptr;
         }
         ASSERT_NE(mService, nullptr);
-        initConfiguration();
+        ASSERT_TRUE(initConfiguration());
 
         mFrontendTests.setService(mService);
     }
@@ -344,7 +349,7 @@
             mService = nullptr;
         }
         ASSERT_NE(mService, nullptr);
-        initConfiguration();
+        ASSERT_TRUE(initConfiguration());
 
         mFrontendTests.setService(mService);
         mDemuxTests.setService(mService);
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index de12dc0..36b7646 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -131,28 +131,28 @@
 /*
  * index 0 - playback dvr
  * index 1 - audio filters
- * index 2 - video filters
- * index 3 - optional section filters
+ * index 2 - optional section filters
  */
 static inline vector<DvrPlaybackHardwareConnections> generatePlaybackCombinations() {
     vector<DvrPlaybackHardwareConnections> combinations;
     vector<string> sectionFilterIds_optional = sectionFilterIds;
     sectionFilterIds_optional.push_back(emptyHardwareId);
-    vector<vector<string>> deviceIds{playbackDvrIds, audioFilterIds, videoFilterIds,
-                                     sectionFilterIds_optional};
+    vector<vector<string>> deviceIds{playbackDvrIds, audioFilterIds, sectionFilterIds_optional};
 
     const int dvrIndex = 0;
     const int audioFilterIndex = 1;
-    const int videoFilterIndex = 2;
-    const int sectionFilterIndex = 3;
+    const int sectionFilterIndex = 2;
 
     auto idCombinations = generateIdCombinations(deviceIds);
     for (auto& combo : idCombinations) {
         DvrPlaybackHardwareConnections mPlayback;
         mPlayback.dvrId = combo[dvrIndex];
         mPlayback.audioFilterId = combo[audioFilterIndex];
-        mPlayback.videoFilterId = combo[videoFilterIndex];
         mPlayback.sectionFilterId = combo[sectionFilterIndex];
+        const int videoFilterIndex =
+                find(audioFilterIds.begin(), audioFilterIds.end(), mPlayback.audioFilterId) -
+                audioFilterIds.begin();
+        mPlayback.videoFilterId = videoFilterIds[videoFilterIndex];
         combinations.push_back(mPlayback);
     }
 
@@ -176,17 +176,15 @@
 /*
  * index 0 - frontends
  * index 1 - audio filters
- * index 2 - video filters
- * index 3 - lnbs
+ * index 2 - lnbs
  */
 static inline vector<LnbLiveHardwareConnections> generateLnbLiveCombinations() {
     vector<LnbLiveHardwareConnections> combinations;
-    vector<vector<string>> deviceIds{frontendIds, audioFilterIds, videoFilterIds, lnbIds};
+    vector<vector<string>> deviceIds{frontendIds, audioFilterIds, lnbIds};
 
     const int frontendIndex = 0;
     const int audioFilterIndex = 1;
-    const int videoFilterIndex = 2;
-    const int lnbIndex = 3;
+    const int lnbIndex = 2;
 
     // TODO: Find a better way to vary diseqcMsgs, if at all
     auto idCombinations = generateIdCombinations(deviceIds);
@@ -198,7 +196,10 @@
             LnbLiveHardwareConnections mLnbLive;
             mLnbLive.frontendId = feId;
             mLnbLive.audioFilterId = combo[audioFilterIndex];
-            mLnbLive.videoFilterId = combo[videoFilterIndex];
+            const int videoFilterIndex =
+                    find(audioFilterIds.begin(), audioFilterIds.end(), mLnbLive.audioFilterId) -
+                    audioFilterIds.begin();
+            mLnbLive.videoFilterId = videoFilterIds[videoFilterIndex];
             mLnbLive.lnbId = combo[lnbIndex];
             mLnbLive.diseqcMsgs = diseqcMsgs;
             combinations.push_back(mLnbLive);
@@ -301,9 +302,8 @@
  * index 0 - decramblers
  * index 1 - frontends
  * index 2 - audio filters
- * index 3 - video filters
- * index 4 - Dvr SW Fe Connections
- * index 5 - DVR Source Connections
+ * index 3 - Dvr SW Fe Connections
+ * index 4 - DVR Source Connections
  */
 static inline vector<DescramblingHardwareConnections> generateDescramblingCombinations() {
     vector<DescramblingHardwareConnections> combinations;
@@ -320,12 +320,11 @@
     const int descramblerIndex = 0;
     const int frontendIndex = 1;
     const int audioFilterIndex = 2;
-    const int videoFilterIndex = 3;
-    const int dvrFeIdIndex = 4;
-    const int dvrSourceIdIndex = 5;
+    const int dvrFeIdIndex = 3;
+    const int dvrSourceIdIndex = 4;
 
-    vector<vector<string>> deviceIds{descramblerIds, mfrontendIds,        audioFilterIds,
-                                     videoFilterIds, mDvrFeConnectionIds, mDvrSourceConnectionIds};
+    vector<vector<string>> deviceIds{descramblerIds, mfrontendIds, audioFilterIds,
+                                     mDvrFeConnectionIds, mDvrSourceConnectionIds};
     auto idCombinations = generateIdCombinations(deviceIds);
     for (auto& combo : idCombinations) {
         DescramblingHardwareConnections mDescrambling;
@@ -353,7 +352,10 @@
         }
         mDescrambling.frontendId = feId;
         mDescrambling.audioFilterId = combo[audioFilterIndex];
-        mDescrambling.videoFilterId = combo[videoFilterIndex];
+        const int videoFilterIndex =
+                find(audioFilterIds.begin(), audioFilterIds.end(), mDescrambling.audioFilterId) -
+                audioFilterIds.begin();
+        mDescrambling.videoFilterId = videoFilterIds[videoFilterIndex];
         mDescrambling.dvrSoftwareFeId = dvrSwFeId;
         mDescrambling.dvrSourceId = dvrSourceId;
         mDescrambling.descramblerId = combo[descramblerIndex];
@@ -378,6 +380,158 @@
     return descrambling_configs;
 }
 
+static inline vector<TimeFilterHardwareConnections> generateTimeFilterCombinations() {
+    vector<TimeFilterHardwareConnections> combinations;
+
+    for (auto& id : timeFilterIds) {
+        TimeFilterHardwareConnections mTimeFilter;
+        mTimeFilter.timeFilterId = id;
+        combinations.push_back(mTimeFilter);
+    }
+
+    return combinations;
+}
+
+static inline vector<TimeFilterHardwareConnections> generateTimeFilterConfigurations() {
+    vector<TimeFilterHardwareConnections> timeFilter_configs;
+    if (configuredTimeFilter) {
+        ALOGD("Using TimeFilter configuration provided.");
+        timeFilter_configs = {timeFilter};
+    } else {
+        ALOGD("TimeFilter not provided. Generating possible combinations. Consider adding it to "
+              "the "
+              "configuration file.");
+        timeFilter_configs = generateTimeFilterCombinations();
+    }
+
+    return timeFilter_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - record dvrs
+ * index 2 - record filters
+ */
+static inline vector<DvrRecordHardwareConnections> generateRecordCombinations() {
+    vector<DvrRecordHardwareConnections> combinations;
+
+    const int frontendIdIndex = 0;
+    const int recordDvrIndex = 1;
+    const int recordFilterIndex = 2;
+
+    vector<vector<string>> deviceIds{frontendIds, recordDvrIds, recordFilterIds};
+
+    auto idCombinations = generateIdCombinations(deviceIds);
+    for (auto& combo : idCombinations) {
+        DvrRecordHardwareConnections mRecord;
+        const string feId = combo[frontendIdIndex];
+        mRecord.hasFrontendConnection = true;
+        if (frontendMap[feId].isSoftwareFe) {
+            // If we have a software frontend, do not include configuration for testing.
+            continue;
+        }
+        mRecord.frontendId = feId;
+        mRecord.support = true;
+        mRecord.dvrSourceId = emptyHardwareId;
+        mRecord.dvrSoftwareFeId = emptyHardwareId;
+        mRecord.recordFilterId = combo[recordFilterIndex];
+        mRecord.dvrRecordId = combo[recordDvrIndex];
+        combinations.push_back(mRecord);
+    }
+
+    return combinations;
+}
+
+static inline vector<DvrRecordHardwareConnections> generateRecordConfigurations() {
+    vector<DvrRecordHardwareConnections> record_configs;
+    if (configuredRecord) {
+        ALOGD("Using Record configuration provided.");
+        record_configs = {record};
+    } else {
+        ALOGD("Record not provided. Generating possible combinations. Consider adding it to "
+              "the "
+              "configuration file.");
+        record_configs = generateRecordCombinations();
+    }
+
+    return record_configs;
+}
+
+/*
+ * index 0 - frontends
+ * index 1 - audio filters
+ * index 2 - playback dvrs
+ * index 3 - section Filters
+ */
+static inline vector<LiveBroadcastHardwareConnections> generateLiveCombinations() {
+    vector<LiveBroadcastHardwareConnections> combinations;
+    vector<string> mSectionFilterIds = sectionFilterIds;
+    vector<string> mDvrSwConnectionIds = playbackDvrIds;
+
+    // Adding the empty hardware id to cover cases where fields are optional
+    mSectionFilterIds.push_back(emptyHardwareId);
+    mDvrSwConnectionIds.push_back(emptyHardwareId);
+
+    const int frontendIdIndex = 0;
+    const int audioFilterIdIndex = 1;
+    const int dvrSwConnectionIdIndex = 2;
+    const int sectionFilterIdIndex = 3;
+
+    vector<vector<string>> deviceIds{frontendIds, audioFilterIds, mDvrSwConnectionIds,
+                                     mSectionFilterIds};
+
+    auto idCombinations = generateIdCombinations(deviceIds);
+    for (auto& combo : idCombinations) {
+        LiveBroadcastHardwareConnections mLive;
+        const string feId = combo[frontendIdIndex];
+        const string dvrSwConnectionId = combo[dvrSwConnectionIdIndex];
+        mLive.hasFrontendConnection = true;
+
+        if (frontendMap[feId].isSoftwareFe && dvrSwConnectionId.compare(emptyHardwareId) == 0) {
+            // If the frontend is a software frontend and there is no dvr playback connected, do not
+            // include configuration
+            continue;
+        }
+        mLive.frontendId = feId;
+        mLive.dvrSoftwareFeId = dvrSwConnectionId;
+        mLive.audioFilterId = combo[audioFilterIdIndex];
+        const int videoFilterIdIndex =
+                find(audioFilterIds.begin(), audioFilterIds.end(), mLive.audioFilterId) -
+                audioFilterIds.begin();
+        mLive.videoFilterId = videoFilterIds[videoFilterIdIndex];
+        mLive.sectionFilterId = combo[sectionFilterIdIndex];
+
+        if (pcrFilterIds.empty()) {
+            // If pcr Filters have not been provided, set it to empty hardware id
+            mLive.pcrFilterId = emptyHardwareId;
+        } else {
+            // If pcr Filters have been provided, use the first index if there is only 1, or choose
+            // the filter that corresponds to the correct audio and video filter pair
+            const int pcrFilterIdIndex = pcrFilterIds.size() == 1 ? 0 : videoFilterIdIndex;
+            mLive.pcrFilterId = pcrFilterIds[pcrFilterIdIndex];
+        }
+
+        combinations.push_back(mLive);
+    }
+
+    return combinations;
+}
+
+static inline vector<LiveBroadcastHardwareConnections> generateLiveConfigurations() {
+    vector<LiveBroadcastHardwareConnections> live_configs;
+    if (configuredLive) {
+        ALOGD("Using Live configuration provided.");
+        live_configs = {live};
+    } else {
+        ALOGD("Live not provided. Generating possible combinations. Consider adding it to "
+              "the "
+              "configuration file.");
+        live_configs = generateLiveCombinations();
+    }
+
+    return live_configs;
+}
+
 /** 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
@@ -701,6 +855,18 @@
         return false;
     }
 
+    if (audioFilterIds.size() != videoFilterIds.size()) {
+        ALOGW("[vts config] the number of audio and video filters should be equal");
+        return false;
+    }
+
+    if (!pcrFilterIds.empty() && pcrFilterIds.size() != 1 &&
+        pcrFilterIds.size() != audioFilterIds.size()) {
+        ALOGW("[vts config] When more than 1 pcr filter is configured, the number of pcr filters "
+              "must equal the number of audio and video filters.");
+        return false;
+    }
+
     bool timeFilterIsValid =
             timeFilter.support ? timeFilterMap.find(timeFilter.timeFilterId) != timeFilterMap.end()
                                : true;
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 6fafd59..bf3745c 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -79,7 +79,10 @@
 static string mConfigFilePath;
 
 static vector<string> playbackDvrIds;
+static vector<string> ipFilterIds;
 static vector<string> recordDvrIds;
+static vector<string> pcrFilterIds;
+static vector<string> timeFilterIds;
 static vector<string> audioFilterIds;
 static vector<string> videoFilterIds;
 static vector<string> recordFilterIds;
@@ -503,6 +506,7 @@
             auto timeFilters = *hardwareConfig.getFirstTimeFilters();
             for (auto timeFilterConfig : timeFilters.getTimeFilter()) {
                 string id = timeFilterConfig.getId();
+                timeFilterIds.push_back(id);
                 timeFilterMap[id].timeStamp = static_cast<int64_t>(timeFilterConfig.getTimeStamp());
             }
         }
@@ -851,6 +855,10 @@
             recordFilterIds.push_back(filterConfig.getId());
         } else if (subType == FilterSubTypeEnum::SECTION) {
             sectionFilterIds.push_back(filterConfig.getId());
+        } else if (subType == FilterSubTypeEnum::PCR) {
+            pcrFilterIds.push_back(filterConfig.getId());
+        } else if (subType == FilterSubTypeEnum::IP) {
+            ipFilterIds.push_back(filterConfig.getId());
         }
 
         switch (mainType) {