Merge "Start adding documentation for IFingerprint"
diff --git a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
index b09e9bf..dc5d3d3 100644
--- a/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehicleHalManager.cpp
@@ -78,6 +78,7 @@
         } else {
             ALOGW("Requested config for undefined property: 0x%x", prop);
             _hidl_cb(StatusCode::INVALID_ARG, hidl_vec<VehiclePropConfig>());
+            return Void();
         }
     }
 
diff --git a/automotive/vehicle/2.0/utils/UserHalHelper.cpp b/automotive/vehicle/2.0/utils/UserHalHelper.cpp
index fcfe4bf..abf59b7 100644
--- a/automotive/vehicle/2.0/utils/UserHalHelper.cpp
+++ b/automotive/vehicle/2.0/utils/UserHalHelper.cpp
@@ -141,11 +141,6 @@
 template <typename T>
 Result<T> verifyAndCast(int32_t value) {
     T castValue = static_cast<T>(value);
-    const auto iter = hidl_enum_range<T>();
-    if (castValue < *iter.begin() || castValue > *std::prev(iter.end())) {
-        return Error() << "Value " << value << " not in range [" << toString(*iter.begin()) << ", "
-                       << toString(*std::prev(iter.end())) << "]";
-    }
     for (const auto& v : hidl_enum_range<T>()) {
         if (castValue == v) {
             return castValue;
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 832c419..aa5c48f 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -1670,7 +1670,7 @@
     Return<void> ret;
     ::android::sp<ICameraDevice> device3_x;
     bool retVal = false;
-    if (getCameraDeviceVersion(mProviderType, name) == CAMERA_DEVICE_API_VERSION_1_0) {
+    if (getCameraDeviceVersion(name, mProviderType) == CAMERA_DEVICE_API_VERSION_1_0) {
         return false;
     }
     ret = provider->getCameraDeviceInterface_V3_x(name, [&](auto status, const auto& device) {
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 9d4e55c..d22aa68 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -98,7 +98,6 @@
         "compatibility_matrix.current.xml",
     ],
     kernel_configs: [
-        "kernel_config_current_4.14",
         "kernel_config_current_4.19",
         "kernel_config_current_5.4",
     ],
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
index e5e012c..5e1266e 100644
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ b/compatibility_matrices/compatibility_matrix.4.xml
@@ -432,6 +432,7 @@
     <hal format="hidl" optional="true">
         <name>android.hardware.tv.cec</name>
         <version>1.0</version>
+        <version>2.0</version>
         <interface>
             <name>IHdmiCec</name>
             <instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index e772b6f..8bc663d 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -467,6 +467,7 @@
     <hal format="hidl" optional="true">
         <name>android.hardware.tv.cec</name>
         <version>1.0</version>
+        <version>2.0</version>
         <interface>
             <name>IHdmiCec</name>
             <instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index f4f846b..bb26bd3 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -477,6 +477,7 @@
     <hal format="hidl" optional="true">
         <name>android.hardware.tv.cec</name>
         <version>1.0</version>
+        <version>2.0</version>
         <interface>
             <name>IHdmiCec</name>
             <instance>default</instance>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index ce25a19..20b7281 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -43,25 +43,22 @@
     };
 
     static std::vector<std::string> excluded_exact{
-            // TODO(b/110261831): reduce items in this list
-            "android.hardware.audio@7.0",
-            "android.hardware.audio.effect@7.0",
-            "android.hardware.fastboot@1.0",
-            "android.hardware.media.bufferpool@1.0",
-            "android.hardware.media.bufferpool@2.0",
-            "android.hardware.tv.cec@2.0",
-            "android.hardware.tv.tuner@1.0",
-
             // Packages without top level interfaces (including types-only packages) are exempted.
             // HIDL
             "android.hardware.cas.native@1.0",
             "android.hardware.gnss.visibility_control@1.0",
+            "android.hardware.media.bufferpool@1.0",
+            "android.hardware.media.bufferpool@2.0",
             "android.hardware.radio.config@1.2",
             // AIDL
             "android.hardware.biometrics.common",
             "android.hardware.common",
             "android.hardware.graphics.common",
             "android.hardware.keymaster",
+
+            // Fastboot HAL is only used by recovery. Recovery is owned by OEM. Framework
+            // does not depend on this HAL, hence it is not declared in any manifests or matrices.
+            "android.hardware.fastboot@1.0",
     };
 
     auto package_has_prefix = [&](const std::string& prefix) {
diff --git a/current.txt b/current.txt
index b929f7d..9c5091b 100644
--- a/current.txt
+++ b/current.txt
@@ -780,3 +780,4 @@
 57d183b10b13ec0a8e542c0b3d61991ae541c60e85dbbc5499bb21dfd068cbb8 android.hardware.wifi.supplicant@1.4::types
 17818b6b1952a75e4364ae82c534b9d2f5c0a9765a56256b16faa5a5cf45d3a8 android.hardware.wifi.supplicant@1.4::ISupplicant
 8342b5f6ec8f48ad2b741128aede010995d0b5709257b7ec09bb469b4f61ef1a android.hardware.wifi.supplicant@1.4::ISupplicantStaIface
+6f969b191f0b699ceab0573548f1ac505853e56e704711edc51b51976d4f87ad android.hardware.wifi.supplicant@1.4::ISupplicantStaNetwork
diff --git a/tv/tuner/1.1/Android.bp b/tv/tuner/1.1/Android.bp
index 92769f0..6cf47f5 100644
--- a/tv/tuner/1.1/Android.bp
+++ b/tv/tuner/1.1/Android.bp
@@ -4,7 +4,6 @@
     name: "android.hardware.tv.tuner@1.1",
     root: "android.hardware",
     srcs: [
-        "IDemux.hal",
         "IFilter.hal",
         "IFrontend.hal",
         "IFilterCallback.hal",
diff --git a/tv/tuner/1.1/IDemux.hal b/tv/tuner/1.1/IDemux.hal
deleted file mode 100644
index 434ecbd..0000000
--- a/tv/tuner/1.1/IDemux.hal
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.tv.tuner@1.1;
-
-import @1.0::IDemux;
-import @1.0::IFilter;
-import @1.0::Result;
-
-/**
- * Demultiplexer(Demux) takes a single multiplexed input and splits it into
- * one or more output.
- */
-interface IDemux extends @1.0::IDemux {
-    /**
-     * Get a 64-bit hardware sync ID for audio and video.
-     *
-     * It is used by the client to get the hardware sync ID for audio and video.
-     *
-     * @param filter the v1_1 filter instance.
-     * @return result Result status of the operation.
-     *         SUCCESS if successful,
-     *         INVALID_ARGUMENT if failed for a wrong filter ID.
-     *         UNKNOWN_ERROR if failed for other reasons.
-     * @return avSyncHwId the id of hardware A/V sync.
-     */
-    getAvSyncHwId64Bit(IFilter filter) generates (Result result, uint64_t avSyncHwId);
-};
\ No newline at end of file
diff --git a/tv/tuner/1.1/IFilter.hal b/tv/tuner/1.1/IFilter.hal
index 6c4d8a5..2ba9bb7 100644
--- a/tv/tuner/1.1/IFilter.hal
+++ b/tv/tuner/1.1/IFilter.hal
@@ -40,4 +40,34 @@
      * @return filterId the hardware resource Id for the filter.
      */
     getId64Bit() generates (Result result, uint64_t filterId);
+
+    /**
+     * Configure additional Context ID on the IP filter.
+     *
+     * @param ipCid Context Id of the IP filter.
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         INVALID_STATE if failed for wrong state.
+     *         UNKNOWN_ERROR if failed for other reasons.
+     */
+    configureIpCid(uint32_t ipCid) generates (Result result);
+
+    /**
+     * Get the shared AV memory handle. Use IFilter.releaseAvHandle to release the handle.
+     *
+     * When media filters are opened, call this API to initialize the share memory handle if it's
+     * needed.
+     *
+     * If DemuxFilterMediaEvent.avMemory contains file descriptor, share memory should be ignored.
+     *
+     * @return avMemory A handle associated to the shared memory for audio or video.
+     *         avMemory.data[0] is normally an fd for ION memory. When the avMemory->numFd is 0, the
+     *         share memory is not initialized and does not contain valid fd.
+     *         avMemory.data[avMemory.numFds] is an index used as a parameter of
+     *         C2DataIdInfo to build C2 buffer in Codec. No C2 buffer would be created if the index
+     *         does not exist.
+     * @return avMemSize the size of the shared av memory. It should be ignored when the share
+     *         memory is not initialized.
+     */
+    getAvSharedHandle() generates (Result result, handle avMemory, uint64_t avMemSize);
 };
diff --git a/tv/tuner/1.1/IFilterCallback.hal b/tv/tuner/1.1/IFilterCallback.hal
index 3e5f047..9960a23 100644
--- a/tv/tuner/1.1/IFilterCallback.hal
+++ b/tv/tuner/1.1/IFilterCallback.hal
@@ -18,7 +18,7 @@
 
 import @1.0::IFilterCallback;
 import @1.0::DemuxFilterEvent;
-import @1.1::DemuxFilterEventExt;
+import DemuxFilterEventExt;
 
 interface IFilterCallback extends @1.0::IFilterCallback {
     /**
diff --git a/tv/tuner/1.1/IFrontend.hal b/tv/tuner/1.1/IFrontend.hal
index 0b0ce39..9858d4b 100644
--- a/tv/tuner/1.1/IFrontend.hal
+++ b/tv/tuner/1.1/IFrontend.hal
@@ -45,7 +45,8 @@
      *         INVALID_STATE if tuning can't be applied at current stage,
      *         UNKNOWN_ERROR if tuning failed for other reasons.
      */
-    tune_1_1(FrontendSettings settings, FrontendSettingsExt settingsExt) generates (Result result);
+    tune_1_1(FrontendSettings settings, FrontendSettingsExt settingsExt)
+        generates (Result result);
 
     /**
      * Scan the frontend to use the settings given.
@@ -66,7 +67,7 @@
      *         UNKNOWN_ERROR if tuning failed for other reasons.
      */
     scan_1_1(FrontendSettings settings, FrontendScanType type, FrontendSettingsExt settingsExt)
-            generates (Result result);
+        generates (Result result);
 
     /**
      * Link Conditional Access Modules (CAM) to Frontend support Common Interface (CI) bypass mode.
diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp
index 007d5eb..66c95dc 100644
--- a/tv/tuner/1.1/default/Demux.cpp
+++ b/tv/tuner/1.1/default/Demux.cpp
@@ -34,49 +34,6 @@
 
 Demux::~Demux() {}
 
-Return<void> Demux::getAvSyncHwId64Bit(const sp<IFilter>& filter, getAvSyncHwId64Bit_cb _hidl_cb) {
-    ALOGV("%s", __FUNCTION__);
-
-    uint64_t avSyncHwId = -1;
-    uint64_t id;
-    Result status;
-
-    sp<V1_1::IFilter> filter_v1_1 = V1_1::IFilter::castFrom(filter);
-    if (filter_v1_1 != NULL) {
-        filter_v1_1->getId64Bit([&](Result result, uint64_t filterId) {
-            id = filterId;
-            status = result;
-        });
-    } else {
-        filter->getId([&](Result result, uint32_t filterId) {
-            id = filterId;
-            status = result;
-        });
-    }
-
-    if (status != Result::SUCCESS) {
-        ALOGE("[Demux] Can't get 64-bit filter Id.");
-        _hidl_cb(Result::INVALID_STATE, avSyncHwId);
-        return Void();
-    }
-
-    if (!mFilters[id]->isMediaFilter()) {
-        ALOGE("[Demux] Given filter is not a media filter.");
-        _hidl_cb(Result::INVALID_ARGUMENT, avSyncHwId);
-        return Void();
-    }
-
-    if (!mPcrFilterIds.empty()) {
-        // Return the lowest pcr filter id in the default implementation as the av sync id
-        _hidl_cb(Result::SUCCESS, *mPcrFilterIds.begin());
-        return Void();
-    }
-
-    ALOGE("[Demux] No PCR filter opened.");
-    _hidl_cb(Result::INVALID_STATE, avSyncHwId);
-    return Void();
-}
-
 Return<Result> Demux::setFrontendDataSource(uint32_t frontendId) {
     ALOGV("%s", __FUNCTION__);
 
diff --git a/tv/tuner/1.1/default/Demux.h b/tv/tuner/1.1/default/Demux.h
index 3623d0f..5212eae 100644
--- a/tv/tuner/1.1/default/Demux.h
+++ b/tv/tuner/1.1/default/Demux.h
@@ -17,7 +17,6 @@
 #ifndef ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_
 #define ANDROID_HARDWARE_TV_TUNER_V1_1_DEMUX_H_
 
-#include <android/hardware/tv/tuner/1.1/IDemux.h>
 #include <fmq/MessageQueue.h>
 #include <math.h>
 #include <set>
@@ -49,15 +48,12 @@
 class TimeFilter;
 class Tuner;
 
-class Demux : public V1_1::IDemux {
+class Demux : public IDemux {
   public:
     Demux(uint32_t demuxId, sp<Tuner> tuner);
 
     ~Demux();
 
-    virtual Return<void> getAvSyncHwId64Bit(const sp<IFilter>& filter,
-                                            getAvSyncHwId64Bit_cb _hidl_cb) override;
-
     virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
 
     virtual Return<void> openFilter(const DemuxFilterType& type, uint32_t bufferSize,
diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
index fae83a2..c69beca 100644
--- a/tv/tuner/1.1/default/Filter.cpp
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -163,8 +163,17 @@
     return Result::SUCCESS;
 }
 
-Return<Result> Filter::releaseAvHandle(const hidl_handle& /*avMemory*/, uint64_t avDataId) {
+Return<Result> Filter::releaseAvHandle(const hidl_handle& avMemory, uint64_t avDataId) {
     ALOGV("%s", __FUNCTION__);
+
+    if ((avMemory.getNativeHandle()->numFds > 0) &&
+        (mSharedAvMemHandle.getNativeHandle()->numFds > 0) &&
+        (sameFile(avMemory.getNativeHandle()->data[0],
+                  mSharedAvMemHandle.getNativeHandle()->data[0]))) {
+        freeSharedAvHandle();
+        return Result::SUCCESS;
+    }
+
     if (mDataId2Avfd.find(avDataId) == mDataId2Avfd.end()) {
         return Result::INVALID_ARGUMENT;
     }
@@ -179,6 +188,46 @@
     return mDemux->removeFilter(mFilterId);
 }
 
+Return<Result> Filter::configureIpCid(uint32_t ipCid) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (mType.mainType != DemuxFilterMainType::IP) {
+        return Result::INVALID_STATE;
+    }
+
+    mCid = ipCid;
+    return Result::SUCCESS;
+}
+
+Return<void> Filter::getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    if (!mIsMediaFilter) {
+        _hidl_cb(Result::INVALID_STATE, NULL, BUFFER_SIZE_16M);
+        return Void();
+    }
+
+    if (mSharedAvMemHandle.getNativeHandle() != nullptr) {
+        _hidl_cb(Result::SUCCESS, mSharedAvMemHandle, BUFFER_SIZE_16M);
+        return Void();
+    }
+
+    int av_fd = createAvIonFd(BUFFER_SIZE_16M);
+    if (av_fd == -1) {
+        _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0);
+    }
+
+    native_handle_t* nativeHandle = createNativeHandle(av_fd);
+    if (nativeHandle == NULL) {
+        _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0);
+    }
+    mSharedAvMemHandle.setTo(nativeHandle, /*shouldOwn=*/true);
+    ::close(av_fd);
+
+    _hidl_cb(Result::SUCCESS, mSharedAvMemHandle, BUFFER_SIZE_16M);
+    return Void();
+}
+
 bool Filter::createFilterMQ() {
     ALOGV("%s", __FUNCTION__);
 
@@ -302,10 +351,19 @@
     }
     for (int i = 0; i < mFilterEvent.events.size(); i++) {
         ::close(mFilterEvent.events[i].media().avMemory.getNativeHandle()->data[0]);
-        native_handle_close(mFilterEvent.events[i].media().avMemory.getNativeHandle());
+        native_handle_delete(const_cast<native_handle_t*>(
+                mFilterEvent.events[i].media().avMemory.getNativeHandle()));
     }
 }
 
+void Filter::freeSharedAvHandle() {
+    if (!mIsMediaFilter) {
+        return;
+    }
+    ::close(mSharedAvMemHandle.getNativeHandle()->data[0]);
+    native_handle_delete(const_cast<native_handle_t*>(mSharedAvMemHandle.getNativeHandle()));
+}
+
 void Filter::maySendFilterStatusCallback() {
     if (!mIsUsingFMQ) {
         return;
@@ -498,8 +556,8 @@
         return Result::SUCCESS;
     }
 
+    Result result;
     if (mPts) {
-        Result result;
         result = createMediaFilterEventWithIon(mFilterOutput);
         if (result == Result::SUCCESS) {
             mFilterOutput.clear();
@@ -540,7 +598,10 @@
             continue;
         }
 
-        createMediaFilterEventWithIon(mPesOutput);
+        result = createMediaFilterEventWithIon(mPesOutput);
+        if (result != Result::SUCCESS) {
+            return result;
+        }
     }
 
     mFilterOutput.clear();
@@ -549,51 +610,14 @@
 }
 
 Result Filter::createMediaFilterEventWithIon(vector<uint8_t> output) {
-    int av_fd = createAvIonFd(output.size());
-    if (av_fd == -1) {
-        return Result::UNKNOWN_ERROR;
+    if (mUsingSharedAvMem) {
+        if (mSharedAvMemHandle.getNativeHandle() == nullptr) {
+            return Result::UNKNOWN_ERROR;
+        }
+        return createShareMemMediaEvents(output);
     }
-    // copy the filtered data to the buffer
-    uint8_t* avBuffer = getIonBuffer(av_fd, output.size());
-    if (avBuffer == NULL) {
-        return Result::UNKNOWN_ERROR;
-    }
-    memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t));
 
-    native_handle_t* nativeHandle = createNativeHandle(av_fd);
-    if (nativeHandle == NULL) {
-        return Result::UNKNOWN_ERROR;
-    }
-    hidl_handle handle;
-    handle.setTo(nativeHandle, /*shouldOwn=*/true);
-
-    // Create a dataId and add a <dataId, av_fd> pair into the dataId2Avfd map
-    uint64_t dataId = mLastUsedDataId++ /*createdUID*/;
-    mDataId2Avfd[dataId] = dup(av_fd);
-
-    // Create mediaEvent and send callback
-    DemuxFilterMediaEvent mediaEvent;
-    mediaEvent = {
-            .avMemory = std::move(handle),
-            .dataLength = static_cast<uint32_t>(output.size()),
-            .avDataId = dataId,
-    };
-    if (mPts) {
-        mediaEvent.pts = mPts;
-        mPts = 0;
-    }
-    int size = mFilterEvent.events.size();
-    mFilterEvent.events.resize(size + 1);
-    mFilterEvent.events[size].media(mediaEvent);
-
-    // Clear and log
-    output.clear();
-    mAvBufferCopyCount = 0;
-    ::close(av_fd);
-    if (DEBUG_FILTER) {
-        ALOGD("[Filter] av data length %d", mediaEvent.dataLength);
-    }
-    return Result::SUCCESS;
+    return createIndependentMediaEvents(output);
 }
 
 Result Filter::startRecordFilterHandler() {
@@ -702,15 +726,119 @@
 }
 
 native_handle_t* Filter::createNativeHandle(int fd) {
-    // Create a native handle to pass the av fd via the callback event.
-    native_handle_t* nativeHandle = native_handle_create(/*numFd*/ 1, 0);
+    native_handle_t* nativeHandle;
+    if (fd < 0) {
+        nativeHandle = native_handle_create(/*numFd*/ 0, 0);
+    } else {
+        // Create a native handle to pass the av fd via the callback event.
+        nativeHandle = native_handle_create(/*numFd*/ 1, 0);
+    }
     if (nativeHandle == NULL) {
         ALOGE("[Filter] Failed to create native_handle %d", errno);
         return NULL;
     }
-    nativeHandle->data[0] = dup(fd);
+    if (nativeHandle->numFds > 0) {
+        nativeHandle->data[0] = dup(fd);
+    }
     return nativeHandle;
 }
+
+Result Filter::createIndependentMediaEvents(vector<uint8_t> output) {
+    int av_fd = createAvIonFd(output.size());
+    if (av_fd == -1) {
+        return Result::UNKNOWN_ERROR;
+    }
+    // copy the filtered data to the buffer
+    uint8_t* avBuffer = getIonBuffer(av_fd, output.size());
+    if (avBuffer == NULL) {
+        return Result::UNKNOWN_ERROR;
+    }
+    memcpy(avBuffer, output.data(), output.size() * sizeof(uint8_t));
+
+    native_handle_t* nativeHandle = createNativeHandle(av_fd);
+    if (nativeHandle == NULL) {
+        return Result::UNKNOWN_ERROR;
+    }
+    hidl_handle handle;
+    handle.setTo(nativeHandle, /*shouldOwn=*/true);
+
+    // Create a dataId and add a <dataId, av_fd> pair into the dataId2Avfd map
+    uint64_t dataId = mLastUsedDataId++ /*createdUID*/;
+    mDataId2Avfd[dataId] = dup(av_fd);
+
+    // Create mediaEvent and send callback
+    DemuxFilterMediaEvent mediaEvent;
+    mediaEvent = {
+            .avMemory = std::move(handle),
+            .dataLength = static_cast<uint32_t>(output.size()),
+            .avDataId = dataId,
+    };
+    if (mPts) {
+        mediaEvent.pts = mPts;
+        mPts = 0;
+    }
+    int size = mFilterEvent.events.size();
+    mFilterEvent.events.resize(size + 1);
+    mFilterEvent.events[size].media(mediaEvent);
+
+    // Clear and log
+    output.clear();
+    mAvBufferCopyCount = 0;
+    ::close(av_fd);
+    if (DEBUG_FILTER) {
+        ALOGD("[Filter] av data length %d", mediaEvent.dataLength);
+    }
+    return Result::SUCCESS;
+}
+
+Result Filter::createShareMemMediaEvents(vector<uint8_t> output) {
+    // copy the filtered data to the shared buffer
+    uint8_t* sharedAvBuffer = getIonBuffer(mSharedAvMemHandle.getNativeHandle()->data[0],
+                                           output.size() + mSharedAvMemOffset);
+    if (sharedAvBuffer == NULL) {
+        return Result::UNKNOWN_ERROR;
+    }
+    memcpy(sharedAvBuffer + mSharedAvMemOffset, output.data(), output.size() * sizeof(uint8_t));
+
+    // Create a memory handle with numFds == 0
+    native_handle_t* nativeHandle = createNativeHandle(-1);
+    if (nativeHandle == NULL) {
+        return Result::UNKNOWN_ERROR;
+    }
+    hidl_handle handle;
+    handle.setTo(nativeHandle, /*shouldOwn=*/true);
+
+    // Create mediaEvent and send callback
+    DemuxFilterMediaEvent mediaEvent;
+    mediaEvent = {
+            .offset = static_cast<uint32_t>(mSharedAvMemOffset),
+            .dataLength = static_cast<uint32_t>(output.size()),
+            .avMemory = handle,
+    };
+    mSharedAvMemOffset += output.size();
+    if (mPts) {
+        mediaEvent.pts = mPts;
+        mPts = 0;
+    }
+    int size = mFilterEvent.events.size();
+    mFilterEvent.events.resize(size + 1);
+    mFilterEvent.events[size].media(mediaEvent);
+
+    // Clear and log
+    output.clear();
+    if (DEBUG_FILTER) {
+        ALOGD("[Filter] shared av data length %d", mediaEvent.dataLength);
+    }
+    return Result::SUCCESS;
+}
+
+bool Filter::sameFile(int fd1, int fd2) {
+    struct stat stat1, stat2;
+    if (fstat(fd1, &stat1) < 0 || fstat(fd2, &stat2) < 0) {
+        return false;
+    }
+    return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
+}
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace tuner
diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h
index fa52f96..f677666 100644
--- a/tv/tuner/1.1/default/Filter.h
+++ b/tv/tuner/1.1/default/Filter.h
@@ -23,6 +23,7 @@
 #include <inttypes.h>
 #include <ion/ion.h>
 #include <math.h>
+#include <sys/stat.h>
 #include <set>
 #include "Demux.h"
 #include "Dvr.h"
@@ -43,6 +44,7 @@
 using ::android::hardware::MQDescriptorSync;
 
 using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+const uint32_t BUFFER_SIZE_16M = 0x1000000;
 
 class Demux;
 class Dvr;
@@ -76,6 +78,10 @@
 
     virtual Return<Result> close() override;
 
+    virtual Return<Result> configureIpCid(uint32_t ipCid) override;
+
+    virtual Return<void> getAvSharedHandle(getAvSharedHandle_cb _hidl_cb) override;
+
     /**
      * To create a FilterMQ and its Event Flag.
      *
@@ -91,6 +97,7 @@
     void attachFilterToRecord(const sp<Dvr> dvr);
     void detachFilterFromRecord();
     void freeAvHandle();
+    void freeSharedAvHandle();
     bool isMediaFilter() { return mIsMediaFilter; };
     bool isPcrFilter() { return mIsPcrFilter; };
     bool isRecordFilter() { return mIsRecordFilter; };
@@ -111,6 +118,7 @@
     sp<V1_1::IFilterCallback> mCallback_1_1 = nullptr;
 
     uint64_t mFilterId;
+    uint32_t mCid = static_cast<uint32_t>(V1_1::Constant::INVALID_IP_FILTER_CONTEXT_ID);
     uint32_t mBufferSize;
     DemuxFilterType mType;
     bool mIsMediaFilter = false;
@@ -182,6 +190,9 @@
     uint8_t* getIonBuffer(int fd, int size);
     native_handle_t* createNativeHandle(int fd);
     Result createMediaFilterEventWithIon(vector<uint8_t> output);
+    Result createIndependentMediaEvents(vector<uint8_t> output);
+    Result createShareMemMediaEvents(vector<uint8_t> output);
+    bool sameFile(int fd1, int fd2);
 
     /**
      * Lock to protect writes to the FMQs
@@ -209,6 +220,11 @@
     std::map<uint64_t, int> mDataId2Avfd;
     uint64_t mLastUsedDataId = 1;
     int mAvBufferCopyCount = 0;
+
+    // Shared A/V memory handle
+    hidl_handle mSharedAvMemHandle;
+    bool mUsingSharedAvMem = true;
+    uint32_t mSharedAvMemOffset = 0;
 };
 
 }  // namespace implementation
diff --git a/tv/tuner/1.1/types.hal b/tv/tuner/1.1/types.hal
index 9e2f453..af8d628 100644
--- a/tv/tuner/1.1/types.hal
+++ b/tv/tuner/1.1/types.hal
@@ -20,6 +20,7 @@
 import @1.0::DemuxFilterMmtpRecordEvent;
 import @1.0::DemuxFilterTsRecordEvent;
 import @1.0::FrontendDvbcSpectralInversion;
+import @1.0::FrontendDvbtConstellation;
 import @1.0::FrontendDvbtTransmissionMode;
 import android.hidl.safe_union@1.0;
 import android.hidl.safe_union@1.0::Monostate;
@@ -34,6 +35,11 @@
      * An invalid frenquency that can be used as the default value of the frontend setting.
      */
     INVALID_FRONTEND_SETTING_FREQUENCY = 0xFFFFFFFF,
+    /**
+     * An invalid context id that can be used as the default value of the unconfigured id. It can
+     * be used to reset the configured ip context id.
+     */
+    INVALID_IP_FILTER_CONTEXT_ID = 0xFFFFFFFF,
 };
 
 @export
@@ -106,16 +112,6 @@
 };
 
 /**
- *  Rotation status for a DVBT Frontend.
- */
-@export
-enum FrontendDvbtRotation : uint32_t {
-    UNDEFINED,
-    NOT_ROTATED,
-    ROTATED,
-};
-
-/**
  * AFT flag for an Analog Frontend.
  */
 @export
@@ -131,13 +127,22 @@
 @export
 enum FrontendDvbtTransmissionMode : @1.0::FrontendDvbtTransmissionMode {
     MODE_8K_E = 1 << 7,
-
     MODE_16K_E = 1 << 8,
-
     MODE_32K_E = 1 << 9,
 };
 
 /**
+ *  Extended Constellation for DVBT.
+ */
+@export
+enum FrontendDvbtConstellation : @1.0::FrontendDvbtConstellation {
+    CONSTELLATION_QPSK_R = 1 << 5,
+    CONSTELLATION_16QAM_R = 1 << 6,
+    CONSTELLATION_64QAM_R = 1 << 7,
+    CONSTELLATION_256QAM_R = 1 << 8,
+};
+
+/**
  *  Extended Signal Settings for a DVBS Frontend.
  */
 struct FrontendDvbsSettingsExt {
@@ -148,7 +153,7 @@
  *  Extended Signal Settings for a DVBT Frontend.
  */
 struct FrontendDvbtSettingsExt {
-    FrontendDvbtRotation rotation;
+    FrontendDvbtConstellation constellation;
 
     FrontendDvbtTransmissionMode transmissionMode;
 };
diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.cpp b/tv/tuner/1.1/vts/functional/DemuxTests.cpp
index e0600b6..b1d8a0a 100644
--- a/tv/tuner/1.1/vts/functional/DemuxTests.cpp
+++ b/tv/tuner/1.1/vts/functional/DemuxTests.cpp
@@ -38,34 +38,4 @@
     auto status = mDemux->close();
     mDemux = nullptr;
     return AssertionResult(status.isOk());
-}
-
-AssertionResult DemuxTests::getAvSyncId_64bit(sp<IFilter> filter, uint64_t& avSyncHwId) {
-    EXPECT_TRUE(mDemux) << "Demux is not opened yet.";
-    Result status;
-
-    sp<android::hardware::tv::tuner::V1_1::IDemux> demux_v1_1 =
-            android::hardware::tv::tuner::V1_1::IDemux::castFrom(mDemux);
-    if (demux_v1_1 != NULL) {
-        demux_v1_1->getAvSyncHwId64Bit(filter, [&](Result result, uint64_t id) {
-            status = result;
-            avSyncHwId = id;
-        });
-    } else {
-        ALOGW("[vts] Can't cast IDemux into v1_1.");
-        return failure();
-    }
-
-    return AssertionResult(status == Result::SUCCESS);
-}
-
-AssertionResult DemuxTests::getAvSyncTime(uint32_t avSyncId) {
-    EXPECT_TRUE(mDemux) << "Demux is not opened yet.";
-    Result status;
-    uint64_t syncTime;
-    mDemux->getAvSyncTime(avSyncId, [&](Result result, uint64_t time) {
-        status = result;
-        syncTime = time;
-    });
-    return AssertionResult(status == Result::SUCCESS);
 }
\ No newline at end of file
diff --git a/tv/tuner/1.1/vts/functional/DemuxTests.h b/tv/tuner/1.1/vts/functional/DemuxTests.h
index 393757c..c28d6ca 100644
--- a/tv/tuner/1.1/vts/functional/DemuxTests.h
+++ b/tv/tuner/1.1/vts/functional/DemuxTests.h
@@ -17,7 +17,6 @@
 #include <android-base/logging.h>
 #include <android/hardware/tv/tuner/1.0/IDemux.h>
 #include <android/hardware/tv/tuner/1.0/types.h>
-#include <android/hardware/tv/tuner/1.1/IDemux.h>
 #include <android/hardware/tv/tuner/1.1/IFilter.h>
 #include <android/hardware/tv/tuner/1.1/ITuner.h>
 #include <binder/MemoryDealer.h>
@@ -45,8 +44,6 @@
 
     AssertionResult openDemux(sp<IDemux>& demux, uint32_t& demuxId);
     AssertionResult setDemuxFrontendDataSource(uint32_t frontendId);
-    AssertionResult getAvSyncId_64bit(sp<IFilter> filter, uint64_t& avSyncHwId);
-    AssertionResult getAvSyncTime(uint32_t avSyncId);
     AssertionResult closeDemux();
 
   protected:
diff --git a/tv/tuner/1.1/vts/functional/FilterTests.cpp b/tv/tuner/1.1/vts/functional/FilterTests.cpp
index 24e1fa0..5a8985d 100644
--- a/tv/tuner/1.1/vts/functional/FilterTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FilterTests.cpp
@@ -16,22 +16,70 @@
 
 #include "FilterTests.h"
 
-bool FilterCallback::readFilterEventData() {
-    bool result = false;
-    ALOGW("[vts] reading from filter FMQ or buffer %d", mFilterId);
+void FilterCallback::testFilterDataOutput() {
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (mPidFilterOutputCount < 1) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "filter output matching pid does not output within timeout";
+            return;
+        }
+    }
+    mPidFilterOutputCount = 0;
+    ALOGW("[vts] pass and stop");
+}
+
+void FilterCallback::readFilterEventData() {
+    ALOGW("[vts] reading filter event");
     // todo separate filter handlers
+    for (int i = 0; i < mFilterEvent.events.size(); i++) {
+        auto event = mFilterEvent.events[i];
+        switch (event.getDiscriminator()) {
+            case DemuxFilterEvent::Event::hidl_discriminator::media:
+                ALOGD("[vts] Media filter event, avMemHandle numFds=%d.",
+                      event.media().avMemory.getNativeHandle()->numFds);
+                dumpAvData(event.media());
+                break;
+            default:
+                break;
+        }
+    }
     for (int i = 0; i < mFilterEventExt.events.size(); i++) {
         auto eventExt = mFilterEventExt.events[i];
         switch (eventExt.getDiscriminator()) {
             case DemuxFilterEventExt::Event::hidl_discriminator::tsRecord:
-                ALOGW("[vts] Extended TS record filter event, pts=%" PRIu64 ".",
+                ALOGD("[vts] Extended TS record filter event, pts=%" PRIu64 ".",
                       eventExt.tsRecord().pts);
                 break;
             default:
                 break;
         }
     }
-    return result;
+}
+
+bool FilterCallback::dumpAvData(DemuxFilterMediaEvent event) {
+    uint32_t length = event.dataLength;
+    uint32_t offset = event.offset;
+    // read data from buffer pointed by a handle
+    hidl_handle handle = event.avMemory;
+    if (handle.getNativeHandle()->numFds == 0) {
+        if (mAvSharedHandle == NULL) {
+            return false;
+        }
+        handle = mAvSharedHandle;
+    }
+
+    int av_fd = handle.getNativeHandle()->data[0];
+    uint8_t* buffer =
+            static_cast<uint8_t*>(mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, av_fd, 0));
+    if (buffer == MAP_FAILED) {
+        ALOGE("[vts] fail to allocate av buffer, errno=%d", errno);
+        return false;
+    }
+    uint8_t output[length + 1];
+    memcpy(output, buffer + offset, length);
+    // print buffer and check with golden output.
+    ::close(av_fd);
+    return true;
 }
 
 AssertionResult FilterTests::openFilterInDemux(DemuxFilterType type, uint32_t bufferSize) {
@@ -81,6 +129,33 @@
     return AssertionResult(status == Result::SUCCESS);
 }
 
+AssertionResult FilterTests::getSharedAvMemoryHandle(uint64_t filterId) {
+    EXPECT_TRUE(mFilters[filterId]) << "Open media filter first.";
+    Result status = Result::UNKNOWN_ERROR;
+    sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
+            android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]);
+    if (filter_v1_1 != NULL) {
+        filter_v1_1->getAvSharedHandle([&](Result r, hidl_handle avMemory, uint64_t avMemSize) {
+            status = r;
+            if (status == Result::SUCCESS) {
+                mFilterCallbacks[mFilterId]->setSharedHandle(avMemory);
+                mFilterCallbacks[mFilterId]->setMemSize(avMemSize);
+                mAvSharedHandle = avMemory;
+            }
+        });
+    }
+    return AssertionResult(status == Result::SUCCESS);
+}
+
+AssertionResult FilterTests::releaseShareAvHandle(uint64_t filterId) {
+    Result status;
+    EXPECT_TRUE(mFilters[filterId]) << "Open media filter first.";
+    EXPECT_TRUE(mAvSharedHandle) << "No shared av handle to release.";
+    status = mFilters[filterId]->releaseAvHandle(mAvSharedHandle, 0 /*dataId*/);
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
 AssertionResult FilterTests::configFilter(DemuxFilterSettings setting, uint64_t filterId) {
     Result status;
     EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
@@ -89,6 +164,22 @@
     return AssertionResult(status == Result::SUCCESS);
 }
 
+AssertionResult FilterTests::configIpFilterCid(uint32_t ipCid, uint64_t filterId) {
+    Result status;
+    EXPECT_TRUE(mFilters[filterId]) << "Open Ip filter first.";
+
+    sp<android::hardware::tv::tuner::V1_1::IFilter> filter_v1_1 =
+            android::hardware::tv::tuner::V1_1::IFilter::castFrom(mFilters[filterId]);
+    if (filter_v1_1 != NULL) {
+        status = filter_v1_1->configureIpCid(ipCid);
+    } else {
+        ALOGW("[vts] Can't cast IFilter into v1_1.");
+        return failure();
+    }
+
+    return AssertionResult(status == Result::SUCCESS);
+}
+
 AssertionResult FilterTests::getFilterMQDescriptor(uint64_t filterId) {
     Result status;
     EXPECT_TRUE(mFilters[filterId]) << "Test with getNewlyOpenedFilterId first.";
diff --git a/tv/tuner/1.1/vts/functional/FilterTests.h b/tv/tuner/1.1/vts/functional/FilterTests.h
index 721e419..bc6db86 100644
--- a/tv/tuner/1.1/vts/functional/FilterTests.h
+++ b/tv/tuner/1.1/vts/functional/FilterTests.h
@@ -46,6 +46,7 @@
 using android::hardware::Void;
 using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
 using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
+using android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent;
 using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
 using android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
 using android::hardware::tv::tuner::V1_0::DemuxFilterType;
@@ -93,7 +94,14 @@
     }
 
     virtual Return<void> onFilterEvent(
-            const android::hardware::tv::tuner::V1_0::DemuxFilterEvent& /*filterEvent*/) override {
+            const android::hardware::tv::tuner::V1_0::DemuxFilterEvent& filterEvent) override {
+        android::Mutex::Autolock autoLock(mMsgLock);
+        // Temprarily we treat the first coming back filter data on the matching pid a success
+        // once all of the MQ are cleared, means we got all the expected output
+        mFilterEvent = filterEvent;
+        readFilterEventData();
+        mPidFilterOutputCount++;
+        mMsgCondition.signal();
         return Void();
     }
 
@@ -104,8 +112,13 @@
     void setFilterId(uint32_t filterId) { mFilterId = filterId; }
     void setFilterInterface(sp<IFilter> filter) { mFilter = filter; }
     void setFilterEventType(FilterEventType type) { mFilterEventType = type; }
+    void setSharedHandle(hidl_handle sharedHandle) { mAvSharedHandle = sharedHandle; }
+    void setMemSize(uint64_t size) { mAvSharedMemSize = size; }
 
-    bool readFilterEventData();
+    void testFilterDataOutput();
+
+    void readFilterEventData();
+    bool dumpAvData(DemuxFilterMediaEvent event);
 
   private:
     uint32_t mFilterId;
@@ -114,6 +127,9 @@
     DemuxFilterEvent mFilterEvent;
     DemuxFilterEventExt mFilterEventExt;
 
+    hidl_handle mAvSharedHandle = NULL;
+    uint64_t mAvSharedMemSize = -1;
+
     android::Mutex mMsgLock;
     android::Mutex mFilterOutputLock;
     android::Condition mMsgCondition;
@@ -127,11 +143,14 @@
     void setDemux(sp<IDemux> demux) { mDemux = demux; }
     sp<IFilter> getFilterById(uint64_t filterId) { return mFilters[filterId]; }
 
-    std::map<uint64_t, sp<FilterCallback>> getFilterCallbacks() { return mFilterCallbacks; }
+    map<uint64_t, sp<FilterCallback>> getFilterCallbacks() { return mFilterCallbacks; }
 
     AssertionResult openFilterInDemux(DemuxFilterType type, uint32_t bufferSize);
     AssertionResult getNewlyOpenedFilterId_64bit(uint64_t& filterId);
+    AssertionResult getSharedAvMemoryHandle(uint64_t filterId);
+    AssertionResult releaseShareAvHandle(uint64_t filterId);
     AssertionResult configFilter(DemuxFilterSettings setting, uint64_t filterId);
+    AssertionResult configIpFilterCid(uint32_t ipCid, uint64_t filterId);
     AssertionResult getFilterMQDescriptor(uint64_t filterId);
     AssertionResult startFilter(uint64_t filterId);
     AssertionResult stopFilter(uint64_t filterId);
@@ -192,12 +211,14 @@
     sp<ITuner> mService;
     sp<IFilter> mFilter;
     sp<IDemux> mDemux;
-    std::map<uint64_t, sp<IFilter>> mFilters;
-    std::map<uint64_t, sp<FilterCallback>> mFilterCallbacks;
+    map<uint64_t, sp<IFilter>> mFilters;
+    map<uint64_t, sp<FilterCallback>> mFilterCallbacks;
 
     sp<FilterCallback> mFilterCallback;
     MQDesc mFilterMQDescriptor;
     vector<uint64_t> mUsedFilterIds;
 
+    hidl_handle mAvSharedHandle = NULL;
+
     uint64_t mFilterId = -1;
 };
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
index c3df078..f87fa3c 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
@@ -18,6 +18,10 @@
 
 namespace {
 
+AssertionResult TunerBroadcastHidlTest::filterDataOutputTest() {
+    return filterDataOutputTestBase(mFilterTests);
+}
+
 void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf,
                                                         FrontendConfig frontendConf) {
     uint32_t feId;
@@ -35,6 +39,9 @@
     ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
     ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+    if (filterConf.type.mainType == DemuxFilterMainType::IP) {
+        ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId));
+    }
     ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
     ASSERT_TRUE(mFilterTests.stopFilter(filterId));
@@ -43,6 +50,38 @@
     ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
 
+void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf,
+                                                              FrontendConfig frontendConf) {
+    uint32_t feId;
+    uint32_t demuxId;
+    sp<IDemux> demux;
+    uint64_t filterId;
+
+    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFrontendTests.setDemux(demux);
+    mFilterTests.setDemux(demux);
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
+    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
+    ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId));
+    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    // tune test
+    ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
+    ASSERT_TRUE(filterDataOutputTest());
+    ASSERT_TRUE(mFrontendTests.stopTuneFrontend(true /*testWithDemux*/));
+    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    ASSERT_TRUE(mFilterTests.releaseShareAvHandle(filterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
 void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
                                                  FrontendConfig frontendConf, DvrConfig dvrConf) {
     uint32_t feId;
@@ -86,47 +125,18 @@
     ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
 
-TEST_P(TunerDemuxHidlTest, getAvSyncTime) {
-    description("Get the A/V sync time from a PCR filter.");
-    uint32_t feId;
-    uint32_t demuxId;
-    sp<IDemux> demux;
-    uint64_t mediaFilterId;
-    uint64_t pcrFilterId;
-    uint64_t avSyncHwId;
-    sp<IFilter> mediaFilter;
-
-    mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
-    ASSERT_TRUE(feId != INVALID_ID);
-    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
-    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
-    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
-    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
-    mFilterTests.setDemux(demux);
-    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type,
-                                               filterArray[TS_VIDEO1].bufferSize));
-    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(mediaFilterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, mediaFilterId));
-    mediaFilter = mFilterTests.getFilterById(mediaFilterId);
-    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_PCR0].type,
-                                               filterArray[TS_PCR0].bufferSize));
-    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(pcrFilterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_PCR0].settings, pcrFilterId));
-    ASSERT_TRUE(mDemuxTests.getAvSyncId_64bit(mediaFilter, avSyncHwId));
-    ASSERT_TRUE(pcrFilterId == avSyncHwId);
-    ASSERT_TRUE(mDemuxTests.getAvSyncTime(pcrFilterId));
-    ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId));
-    ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId));
-    ASSERT_TRUE(mDemuxTests.closeDemux());
-    ASSERT_TRUE(mFrontendTests.closeFrontend());
-}
-
 TEST_P(TunerFilterHidlTest, StartFilterInDemux) {
     description("Open and start a filter in Demux.");
     // TODO use parameterized tests
     configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[DVBT]);
 }
 
+TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) {
+    description("Open and configure an ip filter in Demux.");
+    // TODO use parameterized tests
+    configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[DVBT]);
+}
+
 TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) {
     description("Feed ts data from frontend to recording and test with ts record filter");
     recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[DVBT], dvrArray[DVR_RECORD0]);
@@ -142,6 +152,16 @@
     mFrontendTests.scanTest(frontendScanArray[SCAN_DVBT], FrontendScanType::SCAN_BLIND);
 }
 
+TEST_P(TunerBroadcastHidlTest, MediaFilterWithSharedMemoryHandle) {
+    description("Test the Media Filter with shared memory handle");
+    mediaFilterUsingSharedMemoryTest(filterArray[TS_VIDEO0], frontendArray[DVBT]);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, TunerBroadcastHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, TunerFrontendHidlTest,
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
@@ -153,11 +173,6 @@
         android::hardware::PrintInstanceNameToString);
 
 INSTANTIATE_TEST_SUITE_P(
-        PerInstance, TunerDemuxHidlTest,
-        testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
-        android::hardware::PrintInstanceNameToString);
-
-INSTANTIATE_TEST_SUITE_P(
         PerInstance, TunerRecordHidlTest,
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(ITuner::descriptor)),
         android::hardware::PrintInstanceNameToString);
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
index 505e35a..f77a740 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
@@ -26,6 +26,20 @@
     initDvrConfig();
 }
 
+static AssertionResult success() {
+    return ::testing::AssertionSuccess();
+}
+
+AssertionResult filterDataOutputTestBase(FilterTests tests) {
+    // Data Verify Module
+    std::map<uint64_t, sp<FilterCallback>>::iterator it;
+    std::map<uint64_t, sp<FilterCallback>> filterCallbacks = tests.getFilterCallbacks();
+    for (it = filterCallbacks.begin(); it != filterCallbacks.end(); it++) {
+        it->second->testFilterDataOutput();
+    }
+    return success();
+}
+
 class TunerFilterHidlTest : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
@@ -53,31 +67,6 @@
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFilterHidlTest);
 
-class TunerDemuxHidlTest : public testing::TestWithParam<std::string> {
-  public:
-    virtual void SetUp() override {
-        mService = ITuner::getService(GetParam());
-        ASSERT_NE(mService, nullptr);
-        initConfiguration();
-
-        mFrontendTests.setService(mService);
-        mDemuxTests.setService(mService);
-        mFilterTests.setService(mService);
-    }
-
-  protected:
-    static void description(const std::string& description) {
-        RecordProperty("description", description);
-    }
-
-    sp<ITuner> mService;
-    FrontendTests mFrontendTests;
-    DemuxTests mDemuxTests;
-    FilterTests mFilterTests;
-};
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerDemuxHidlTest);
-
 class TunerRecordHidlTest : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
@@ -128,4 +117,34 @@
 };
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerFrontendHidlTest);
+
+class TunerBroadcastHidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        mService = ITuner::getService(GetParam());
+        ASSERT_NE(mService, nullptr);
+        initConfiguration();
+
+        mFrontendTests.setService(mService);
+        mDemuxTests.setService(mService);
+        mFilterTests.setService(mService);
+    }
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    sp<ITuner> mService;
+    FrontendTests mFrontendTests;
+    DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
+
+    AssertionResult filterDataOutputTest();
+
+    void mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf);
+};
+
+// TODO remove from the allow list once the cf tv target is enabled for testing
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TunerBroadcastHidlTest);
 }  // namespace
\ No newline at end of file
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
index 34418d1..36b4bd2 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
@@ -26,6 +26,8 @@
 using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
 using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
 using android::hardware::tv::tuner::V1_0::DemuxFilterType;
+using android::hardware::tv::tuner::V1_0::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;
@@ -64,6 +66,7 @@
     TS_SECTION0,
     TS_TS0,
     TS_RECORD0,
+    IP_IP0,
     FILTER_MAX,
 } Filter;
 
@@ -88,6 +91,7 @@
     uint32_t bufferSize;
     DemuxFilterType type;
     DemuxFilterSettings settings;
+    uint32_t ipCid;
 
     bool operator<(const FilterConfig& /*c*/) const { return false; }
 };
@@ -227,6 +231,19 @@
     filterArray[TS_RECORD0].settings.ts().filterSettings.record({
             .scIndexType = DemuxRecordScIndexType::NONE,
     });
+    // IP filter setting
+    filterArray[IP_IP0].type.mainType = DemuxFilterMainType::IP;
+    filterArray[IP_IP0].type.subType.ipFilterType(DemuxIpFilterType::IP);
+    uint8_t src[4] = {192, 168, 1, 1};
+    uint8_t dest[4] = {192, 168, 1, 2};
+    DemuxIpAddress ipAddress;
+    ipAddress.srcIpAddress.v4(src);
+    ipAddress.dstIpAddress.v4(dest);
+    DemuxIpFilterSettings ipSettings{
+            .ipAddr = ipAddress,
+    };
+    filterArray[IP_IP0].settings.ip(ipSettings);
+    filterArray[IP_IP0].ipCid = 1;
 };
 
 /** Configuration array for the dvr test */
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_call_util.h b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_call_util.h
index ec7ebee..b4b0ea6 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_call_util.h
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_call_util.h
@@ -95,6 +95,14 @@
     EXPECT_TRUE(res.isOk());
     return result_buffer.saved_values;
 }
+
+// Invokes |void method| on |object| without arguments.
+template <typename MethodT, typename ObjectT>
+void invokeVoidMethodWithoutArguments(MethodT method, ObjectT object) {
+    const auto& res = ((*object).*method)();
+    EXPECT_TRUE(res.isOk());
+}
+
 }  // namespace detail
 }  // namespace
 
@@ -123,3 +131,9 @@
         std::remove_reference<decltype(*strong_pointer)>::type::method##_cb>( \
         &std::remove_reference<decltype(*strong_pointer)>::type::method,      \
         strong_pointer, ##__VA_ARGS__))
+
+// Invokes |void method| on |strong_pointer| without arguments.
+#define HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(strong_pointer, method)       \
+    (detail::invokeVoidMethodWithoutArguments(                           \
+        &std::remove_reference<decltype(*strong_pointer)>::type::method, \
+        strong_pointer))
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
index 82c257b..1b4eea6 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
@@ -55,7 +55,10 @@
         ASSERT_NE(hostapd_.get(), nullptr);
     }
 
-    virtual void TearDown() override { stopHostapd(wifi_instance_name_); }
+    virtual void TearDown() override {
+        HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate);
+        stopHostapd(wifi_instance_name_);
+    }
 
    protected:
     std::string getPrimaryWlanIfaceName() {
diff --git a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp
index 3944a3a..32bbe72 100644
--- a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp
@@ -60,7 +60,10 @@
         ASSERT_NE(hostapd_.get(), nullptr);
     }
 
-    virtual void TearDown() override { stopHostapd(wifi_instance_name_); }
+    virtual void TearDown() override {
+        HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate);
+        stopHostapd(wifi_instance_name_);
+    }
 
    protected:
     std::string getPrimaryWlanIfaceName() {
diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
index 62e3c16..99784a4 100644
--- a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
@@ -72,7 +72,10 @@
             "wifi_softap_wpa3_sae_supported");
     }
 
-    virtual void TearDown() override { stopHostapd(wifi_instance_name_); }
+    virtual void TearDown() override {
+        HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate);
+        stopHostapd(wifi_instance_name_);
+    }
 
    protected:
     bool isWpa3SaeSupport_ = false;
diff --git a/wifi/hostapd/1.3/IHostapdCallback.hal b/wifi/hostapd/1.3/IHostapdCallback.hal
index 98cde67..a098d87 100644
--- a/wifi/hostapd/1.3/IHostapdCallback.hal
+++ b/wifi/hostapd/1.3/IHostapdCallback.hal
@@ -38,9 +38,10 @@
      * @param freq The operational frequency of the AP.
      * @param bandwidth The operational bandwidth of the AP.
      * @param generation The operational mode of the AP (e.g. 11ac, 11ax).
+     * @param apIfaceInstanceMacAddress MAC Address of the apIfaceInstance.
      */
     oneway onApInstanceInfoChanged(string ifaceName, string apIfaceInstance, uint32_t freq,
-        Bandwidth bandwidth, Generation generation);
+        Bandwidth bandwidth, Generation generation, MacAddress apIfaceInstanceMacAddress);
 
     /**
      * Invoked when a client connects/disconnects from the hotspot.
@@ -51,7 +52,7 @@
      * will have two instances in dual AP mode. The apIfaceInstance can be used
      * to identify which instance the callback is from.
      * Note: The apIfaceInstance must be same as ifaceName in single AP mode.
-     * @param clientAddress Mac Address of hotspot client.
+     * @param clientAddress MAC Address of hotspot client.
      * @param isConnected true when client connected, false when client
      * disconnected.
      */
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index a44298a..da3996b 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -275,3 +275,17 @@
         });
     return !operation_failed;
 }
+
+bool waitForFrameworkReady() {
+    int waitCount = 10;
+    do {
+        // Check whether package service is ready or not.
+        if (!testing::checkSubstringInCommandOutput(
+                "/system/bin/service check package", ": not found")) {
+            return true;
+        }
+        LOG(INFO) << "Framework is not ready";
+        sleep(1);
+    } while (waitCount-- > 0);
+    return false;
+}
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
index 1ccf091..33945cc 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
@@ -17,6 +17,8 @@
 #ifndef SUPPLICANT_HIDL_TEST_UTILS_H
 #define SUPPLICANT_HIDL_TEST_UTILS_H
 
+#include <VtsCoreUtil.h>
+#include <android-base/logging.h>
 #include <android/hardware/wifi/supplicant/1.0/ISupplicant.h>
 #include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pIface.h>
 #include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIface.h>
@@ -62,4 +64,51 @@
 
 bool turnOnExcessiveLogging();
 
+bool waitForFrameworkReady();
+
+class SupplicantHidlTestBase
+    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+   public:
+    virtual void SetUp() override {
+        // should always be v1.0 wifi
+        wifi_v1_0_instance_name_ = std::get<0>(GetParam());
+        supplicant_instance_name_ = std::get<1>(GetParam());
+        std::system("/system/bin/start");
+        ASSERT_TRUE(waitForFrameworkReady());
+
+        isP2pOn_ =
+            testing::deviceSupportsFeature("android.hardware.wifi.direct");
+        // Stop Framework
+        std::system("/system/bin/stop");
+        stopSupplicant(wifi_v1_0_instance_name_);
+        startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
+                                             supplicant_instance_name_);
+        LOG(INFO) << "SupplicantHidlTestBase isP2pOn_: " << isP2pOn_;
+    }
+
+    virtual void TearDown() override {
+        stopSupplicant(wifi_v1_0_instance_name_);
+        // Start Framework
+        std::system("/system/bin/start");
+    }
+
+   protected:
+    bool isP2pOn_ = false;
+    std::string wifi_v1_0_instance_name_;
+    std::string supplicant_instance_name_;
+};
+
+class SupplicantHidlTestBaseV1_0 : public SupplicantHidlTestBase {
+   public:
+    virtual void SetUp() override {
+        SupplicantHidlTestBase::SetUp();
+        supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_);
+        ASSERT_NE(supplicant_.get(), nullptr);
+        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+    }
+
+   protected:
+    android::sp<android::hardware::wifi::supplicant::V1_0::ISupplicant>
+        supplicant_;
+};
 #endif /* SUPPLICANT_HIDL_TEST_UTILS_H */
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 616869b..e74fd59 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -71,21 +71,13 @@
 constexpr SupplicantNetworkId kTestNetworkId = 5;
 }  // namespace
 
-class SupplicantP2pIfaceHidlTest
-    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_0 {
    public:
     virtual void SetUp() override {
-        wifi_instance_name_ = std::get<0>(GetParam());
-        supplicant_instance_name_ = std::get<1>(GetParam());
-        isP2pOn_ =
-            testing::deviceSupportsFeature("android.hardware.wifi.direct");
-        // Stop Framework
-        std::system("/system/bin/stop");
-        stopSupplicant(wifi_instance_name_);
-        startSupplicantAndWaitForHidlService(wifi_instance_name_,
-                                             supplicant_instance_name_);
-        supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_);
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_0::SetUp();
+        if (!isP2pOn_) {
+            GTEST_SKIP() << "Wi-Fi Direct is not supported, skip this test.";
+        }
         p2p_iface_ = getSupplicantP2pIface(supplicant_);
         ASSERT_NE(p2p_iface_.get(), nullptr);
 
@@ -93,22 +85,11 @@
         memcpy(peer_mac_addr_.data(), kTestPeerMacAddr, peer_mac_addr_.size());
     }
 
-    virtual void TearDown() override {
-        stopSupplicant(wifi_instance_name_);
-        // Start Framework
-        std::system("/system/bin/start");
-    }
-
    protected:
-    bool isP2pOn_ = false;
-    sp<ISupplicant> supplicant_;
-    // ISupplicantP2pIface object used for all tests in this fixture.
     sp<ISupplicantP2pIface> p2p_iface_;
     // MAC address to use for various tests.
     std::array<uint8_t, 6> mac_addr_;
     std::array<uint8_t, 6> peer_mac_addr_;
-    std::string wifi_instance_name_;
-    std::string supplicant_instance_name_;
 };
 
 class IfaceCallback : public ISupplicantP2pIfaceCallback {
@@ -201,8 +182,8 @@
  * successfully created.
  */
 TEST_P(SupplicantP2pIfaceHidlTest, Create) {
-    stopSupplicant(wifi_instance_name_);
-    startSupplicantAndWaitForHidlService(wifi_instance_name_,
+    stopSupplicant(wifi_v1_0_instance_name_);
+    startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
                                          supplicant_instance_name_);
     sp<ISupplicantP2pIface> p2p_iface = getSupplicantP2pIface(
         getSupplicant(supplicant_instance_name_, isP2pOn_));
@@ -301,8 +282,8 @@
         mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
         kTestConnectPin, false, false, kTestConnectGoIntent,
         [](const SupplicantStatus& status, const hidl_string& /* pin */) {
-            // This is not going to work with fake values.
-            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+            // After enabling auto-join, it will succeed always.
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
         });
 }
 
@@ -314,12 +295,12 @@
         mac_addr_, ISupplicantP2pIface::WpsProvisionMethod::PBC,
         kTestConnectPin, false, false, kTestConnectGoIntent,
         [](const SupplicantStatus& status, const hidl_string& /* pin */) {
-            // This is not going to work with fake values.
-            EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+            // After enabling auto-join, it will succeed always.
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
         });
 
     p2p_iface_->cancelConnect([](const SupplicantStatus& status) {
-        EXPECT_EQ(SupplicantStatusCode::FAILURE_UNKNOWN, status.code);
+        EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
     });
 }
 
@@ -655,4 +636,4 @@
             android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
             ISupplicant::descriptor))),
-    android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file
+    android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
index e4fe52c..6b85e00 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -66,42 +66,22 @@
 constexpr uint16_t kTestWpsConfigMethods = 0xffff;
 }  // namespace
 
-class SupplicantStaIfaceHidlTest
-    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_0 {
    public:
     virtual void SetUp() override {
-        wifi_instance_name_ = std::get<0>(GetParam());
-        supplicant_instance_name_ = std::get<1>(GetParam());
-        isP2pOn_ =
-            testing::deviceSupportsFeature("android.hardware.wifi.direct");
-        // Stop Framework
-        std::system("/system/bin/stop");
-        stopSupplicant(wifi_instance_name_);
-        startSupplicantAndWaitForHidlService(wifi_instance_name_,
-                                             supplicant_instance_name_);
-        supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_);
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_0::SetUp();
         sta_iface_ = getSupplicantStaIface(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
 
         memcpy(mac_addr_.data(), kTestMacAddr, mac_addr_.size());
     }
 
-    virtual void TearDown() override {
-        stopSupplicant(wifi_instance_name_);
-        // Start Framework
-        std::system("/system/bin/start");
-    }
-
    protected:
     bool isP2pOn_ = false;
-    sp<ISupplicant> supplicant_;
     // ISupplicantStaIface object used for all tests in this fixture.
     sp<ISupplicantStaIface> sta_iface_;
     // MAC address to use for various tests.
     std::array<uint8_t, 6> mac_addr_;
-    std::string wifi_instance_name_;
-    std::string supplicant_instance_name_;
 };
 
 class IfaceCallback : public ISupplicantStaIfaceCallback {
@@ -183,8 +163,8 @@
  * successfully created.
  */
 TEST_P(SupplicantStaIfaceHidlTest, Create) {
-    stopSupplicant(wifi_instance_name_);
-    startSupplicantAndWaitForHidlService(wifi_instance_name_,
+    stopSupplicant(wifi_v1_0_instance_name_);
+    startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
                                          supplicant_instance_name_);
     EXPECT_NE(nullptr, getSupplicantStaIface(
                            getSupplicant(supplicant_instance_name_, isP2pOn_))
@@ -566,4 +546,4 @@
             android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
             ISupplicant::descriptor))),
-    android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file
+    android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
index 7e93c5f..2b4d681 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -79,21 +79,10 @@
      ISupplicantStaNetwork::PairwiseCipherMask::TKIP);
 }  // namespace
 
-class SupplicantStaNetworkHidlTest
-    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_0 {
    public:
     virtual void SetUp() override {
-        wifi_instance_name_ = std::get<0>(GetParam());
-        supplicant_instance_name_ = std::get<1>(GetParam());
-        isP2pOn_ =
-            testing::deviceSupportsFeature("android.hardware.wifi.direct");
-        // Stop Framework
-        std::system("/system/bin/stop");
-        stopSupplicant(wifi_instance_name_);
-        startSupplicantAndWaitForHidlService(wifi_instance_name_,
-                                             supplicant_instance_name_);
-        supplicant_ = getSupplicant(supplicant_instance_name_, isP2pOn_);
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_0::SetUp();
         sta_network_ = createSupplicantStaNetwork(supplicant_);
         ASSERT_NE(sta_network_.get(), nullptr);
         /* variable used to check if the underlying HAL version is 1.3 or
@@ -105,12 +94,6 @@
         ssid_.assign(kTestSsidStr, kTestSsidStr + strlen(kTestSsidStr));
     }
 
-    virtual void TearDown() override {
-        stopSupplicant(wifi_instance_name_);
-        // Start Framework
-        std::system("/system/bin/start");
-    }
-
    protected:
     void removeNetwork() {
         sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface(supplicant_);
@@ -128,14 +111,10 @@
 
     sp<::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork>
         v1_3 = nullptr;
-    bool isP2pOn_ = false;
-    sp<ISupplicant> supplicant_;
     // ISupplicantStaNetwork object used for all tests in this fixture.
     sp<ISupplicantStaNetwork> sta_network_;
     // SSID to use for various tests.
     std::vector<uint8_t> ssid_;
-    std::string wifi_instance_name_;
-    std::string supplicant_instance_name_;
 };
 
 class NetworkCallback : public ISupplicantStaNetworkCallback {
@@ -158,8 +137,8 @@
  * successfully created.
  */
 TEST_P(SupplicantStaNetworkHidlTest, Create) {
-    stopSupplicant(wifi_instance_name_);
-    startSupplicantAndWaitForHidlService(wifi_instance_name_,
+    stopSupplicant(wifi_v1_0_instance_name_);
+    startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
                                          supplicant_instance_name_);
     sp<ISupplicant> supplicant =
         getSupplicant(supplicant_instance_name_, isP2pOn_);
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
index 0e404e7..3c4d06b 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test.cpp
@@ -35,9 +35,9 @@
 using ::android::hardware::wifi::supplicant::V1_1::ISupplicant;
 using ::android::sp;
 
-class SupplicantHidlTest : public SupplicantHidlTestBase {
+class SupplicantHidlTest : public SupplicantHidlTestBaseV1_1 {
    public:
-    virtual void SetUp() override { SupplicantHidlTestBase::SetUp(); }
+    virtual void SetUp() override { SupplicantHidlTestBaseV1_1::SetUp(); }
 
    protected:
     std::string getWlan0IfaceName() {
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h
index 2104794..b6feb41 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_hidl_test_utils_1_1.h
@@ -36,34 +36,15 @@
     const android::sp<android::hardware::wifi::supplicant::V1_1::ISupplicant>&
         supplicant);
 
-class SupplicantHidlTestBase
-    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+class SupplicantHidlTestBaseV1_1 : public SupplicantHidlTestBase {
    public:
     virtual void SetUp() override {
-        wifi_v1_0_instance_name_ = std::get<0>(GetParam());
-        supplicant_v1_1_instance_name_ = std::get<1>(GetParam());
-        isP2pOn_ =
-            testing::deviceSupportsFeature("android.hardware.wifi.direct");
-        // Stop Framework
-        std::system("/system/bin/stop");
-        stopSupplicant(wifi_v1_0_instance_name_);
-        startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
-                                             supplicant_v1_1_instance_name_);
-        supplicant_ =
-            getSupplicant_1_1(supplicant_v1_1_instance_name_, isP2pOn_);
+        SupplicantHidlTestBase::SetUp();
+        supplicant_ = getSupplicant_1_1(supplicant_instance_name_, isP2pOn_);
         ASSERT_NE(supplicant_.get(), nullptr);
     }
 
-    virtual void TearDown() override {
-        stopSupplicant(wifi_v1_0_instance_name_);
-        // Start Framework
-        std::system("/system/bin/start");
-    }
-
    protected:
     android::sp<android::hardware::wifi::supplicant::V1_1::ISupplicant>
         supplicant_;
-    bool isP2pOn_ = false;
-    std::string wifi_v1_0_instance_name_;
-    std::string supplicant_v1_1_instance_name_;
 };
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 2fade44..db6323c 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -39,11 +39,10 @@
 using ::android::hardware::wifi::supplicant::V1_1::ISupplicantStaIface;
 using ::android::hardware::wifi::supplicant::V1_1::ISupplicantStaIfaceCallback;
 
-class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBase {
+class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_1 {
    public:
     virtual void SetUp() override {
-        SupplicantHidlTestBase::SetUp();
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_1::SetUp();
         sta_iface_ = getSupplicantStaIface_1_1(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
     }
@@ -149,4 +148,4 @@
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
             android::hardware::wifi::supplicant::V1_1::ISupplicant::
                 descriptor))),
-    android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file
+    android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp
index bd8a2ab..37641a4 100644
--- a/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.1/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -37,11 +37,10 @@
 constexpr uint8_t kTestEncryptedIdentity[] = {0x35, 0x37, 0x58, 0x57, 0x26};
 }  // namespace
 
-class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBase {
+class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_1 {
    public:
     virtual void SetUp() override {
-        SupplicantHidlTestBase::SetUp();
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_1::SetUp();
         sta_network_ = createSupplicantStaNetwork_1_1(supplicant_);
         ASSERT_NE(sta_network_.get(), nullptr);
     }
@@ -59,9 +58,9 @@
 TEST_P(SupplicantStaNetworkHidlTest, Create) {
     stopSupplicant(wifi_v1_0_instance_name_);
     startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
-                                         supplicant_v1_1_instance_name_);
+                                         supplicant_instance_name_);
     sp<ISupplicant> supplicant =
-        getSupplicant_1_1(supplicant_v1_1_instance_name_, isP2pOn_);
+        getSupplicant_1_1(supplicant_instance_name_, isP2pOn_);
     EXPECT_NE(nullptr, createSupplicantStaNetwork_1_1(supplicant).get());
 }
 
@@ -102,4 +101,4 @@
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
             android::hardware::wifi::supplicant::V1_1::ISupplicant::
                 descriptor))),
-    android::hardware::PrintInstanceTupleNameToString<>);
\ No newline at end of file
+    android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h
index 2a432d0..b9c5ade 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_hidl_test_utils_1_2.h
@@ -42,35 +42,16 @@
     const android::sp<android::hardware::wifi::supplicant::V1_2::ISupplicant>&
         supplicant);
 
-class SupplicantHidlTestBase
-    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+class SupplicantHidlTestBaseV1_2 : public SupplicantHidlTestBase {
    public:
     virtual void SetUp() override {
-        wifi_v1_0_instance_name_ = std::get<0>(GetParam());
-        supplicant_v1_2_instance_name_ = std::get<1>(GetParam());
-        isP2pOn_ =
-            testing::deviceSupportsFeature("android.hardware.wifi.direct");
-        // Stop Framework
-        std::system("/system/bin/stop");
-        stopSupplicant(wifi_v1_0_instance_name_);
-        startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
-                                             supplicant_v1_2_instance_name_);
-        supplicant_ =
-            getSupplicant_1_2(supplicant_v1_2_instance_name_, isP2pOn_);
+        SupplicantHidlTestBase::SetUp();
+        supplicant_ = getSupplicant_1_2(supplicant_instance_name_, isP2pOn_);
         ASSERT_NE(supplicant_.get(), nullptr);
         EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
     }
 
-    virtual void TearDown() override {
-        stopSupplicant(wifi_v1_0_instance_name_);
-        // Start Framework
-        std::system("/system/bin/start");
-    }
-
    protected:
     android::sp<android::hardware::wifi::supplicant::V1_2::ISupplicant>
         supplicant_;
-    bool isP2pOn_ = false;
-    std::string wifi_v1_0_instance_name_;
-    std::string supplicant_v1_2_instance_name_;
 };
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
index 75512d7..7884cc6 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_p2p_iface_hidl_test.cpp
@@ -38,11 +38,10 @@
 constexpr uint8_t kTestZeroMacAddr[] = {[0 ... 5] = 0x0};
 }  // namespace
 
-class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBase {
+class SupplicantP2pIfaceHidlTest : public SupplicantHidlTestBaseV1_2 {
    public:
     virtual void SetUp() override {
-        SupplicantHidlTestBase::SetUp();
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_2::SetUp();
         if (!isP2pOn_) {
             GTEST_SKIP() << "Wi-Fi Direct is not supported, skip this test.";
         }
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 184543b..cd08468 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -53,11 +53,10 @@
 #define TIMEOUT_PERIOD 60
 class IfaceDppCallback;
 
-class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBase {
+class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_2 {
    public:
     virtual void SetUp() override {
-        SupplicantHidlTestBase::SetUp();
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_2::SetUp();
         sta_iface_ = getSupplicantStaIface_1_2(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
         count_ = 0;
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp
index 5a2f808..ee5de69 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -37,10 +37,10 @@
 // constexpr uint8_t kTestEncryptedIdentity[] = {0x35, 0x37, 0x58, 0x57, 0x26};
 //}  // namespace
 
-class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBase {
+class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_2 {
    public:
     virtual void SetUp() override {
-        SupplicantHidlTestBase::SetUp();
+        SupplicantHidlTestBaseV1_2::SetUp();
         sta_network_ = createSupplicantStaNetwork_1_2(supplicant_);
         ASSERT_NE(sta_network_.get(), nullptr);
     }
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.h b/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.h
index 69fc598..b28c5a4 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.h
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_hidl_test_utils_1_3.h
@@ -34,4 +34,17 @@
 bool isFilsSupported(
     android::sp<android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface>
         sta_iface);
+
+class SupplicantHidlTestBaseV1_3 : public SupplicantHidlTestBase {
+   public:
+    virtual void SetUp() override {
+        SupplicantHidlTestBase::SetUp();
+        supplicant_ = getSupplicant_1_3(supplicant_instance_name_, isP2pOn_);
+        ASSERT_NE(supplicant_.get(), nullptr);
+    }
+
+   protected:
+    android::sp<android::hardware::wifi::supplicant::V1_3::ISupplicant>
+        supplicant_;
+};
 #endif /* SUPPLICANT_HIDL_TEST_UTILS_1_3_H */
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 221c393..6dc267c 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -55,33 +55,14 @@
 #define TIMEOUT_PERIOD 60
 class IfaceDppCallback;
 
-class SupplicantStaIfaceHidlTest
-    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_3 {
    public:
     virtual void SetUp() override {
-        wifi_v1_0_instance_name_ = std::get<0>(GetParam());
-        supplicant_v1_3_instance_name_ = std::get<1>(GetParam());
-        isP2pOn_ =
-            testing::deviceSupportsFeature("android.hardware.wifi.direct");
-        // Stop Framework
-        std::system("/system/bin/stop");
-
-        stopSupplicant(wifi_v1_0_instance_name_);
-        startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
-                                             supplicant_v1_3_instance_name_);
-        supplicant_ =
-            getSupplicant_1_3(supplicant_v1_3_instance_name_, isP2pOn_);
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_3::SetUp();
         sta_iface_ = getSupplicantStaIface_1_3(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
     }
 
-    virtual void TearDown() override {
-        stopSupplicant(wifi_v1_0_instance_name_);
-        // Start Framework
-        std::system("/system/bin/start");
-    }
-
     int64_t pmkCacheExpirationTimeInSec;
     std::vector<uint8_t> serializedPmkCacheEntry;
 
@@ -127,10 +108,6 @@
    protected:
     // ISupplicantStaIface object used for all tests in this fixture.
     sp<ISupplicantStaIface> sta_iface_;
-    sp<ISupplicant> supplicant_;
-    bool isP2pOn_ = false;
-    std::string wifi_v1_0_instance_name_;
-    std::string supplicant_v1_3_instance_name_;
 
     bool isDppSupported() {
         uint32_t keyMgmtMask = 0;
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp
index 11c55a6..12d8d0d 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -43,43 +43,20 @@
 constexpr OcspType kTestInvalidOcspType = (OcspType)-1;
 }  // namespace
 
-class SupplicantStaNetworkHidlTest
-    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+class SupplicantStaNetworkHidlTest : public SupplicantHidlTestBaseV1_3 {
    public:
     virtual void SetUp() override {
-        wifi_v1_0_instance_name_ = std::get<0>(GetParam());
-        supplicant_v1_3_instance_name_ = std::get<1>(GetParam());
-        isP2pOn_ =
-            testing::deviceSupportsFeature("android.hardware.wifi.direct");
-        // Stop Framework
-        std::system("/system/bin/stop");
-
-        stopSupplicant(wifi_v1_0_instance_name_);
-        startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
-                                             supplicant_v1_3_instance_name_);
-        supplicant_ =
-            getSupplicant_1_3(supplicant_v1_3_instance_name_, isP2pOn_);
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_3::SetUp();
         sta_iface_ = getSupplicantStaIface_1_3(supplicant_);
         ASSERT_NE(nullptr, sta_iface_.get());
         sta_network_ = createSupplicantStaNetwork_1_3(supplicant_);
         ASSERT_NE(sta_network_.get(), nullptr);
     }
 
-    virtual void TearDown() override {
-        stopSupplicant(wifi_v1_0_instance_name_);
-        // Start Framework
-        std::system("/system/bin/start");
-    }
-
    protected:
     sp<ISupplicantStaIface> sta_iface_;
     // ISupplicantStaNetwork object used for all tests in this fixture.
     sp<ISupplicantStaNetwork> sta_network_;
-    sp<ISupplicant> supplicant_;
-    bool isP2pOn_ = false;
-    std::string wifi_v1_0_instance_name_;
-    std::string supplicant_v1_3_instance_name_;
 
     bool isWapiSupported() {
         uint32_t keyMgmtMask = 0;
diff --git a/wifi/supplicant/1.4/Android.bp b/wifi/supplicant/1.4/Android.bp
index f3a7cf8..df0b23a 100644
--- a/wifi/supplicant/1.4/Android.bp
+++ b/wifi/supplicant/1.4/Android.bp
@@ -7,6 +7,7 @@
         "types.hal",
         "ISupplicant.hal",
         "ISupplicantStaIface.hal",
+        "ISupplicantStaNetwork.hal",
     ],
     interfaces: [
         "android.hardware.wifi.supplicant@1.0",
diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
new file mode 100644
index 0000000..7b043d0
--- /dev/null
+++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant@1.4;
+
+import @1.3::ISupplicantStaNetwork;
+import @1.0::SupplicantStatus;
+
+/**
+ * Interface exposed by the supplicant for each station mode network
+ * configuration it controls.
+ */
+interface ISupplicantStaNetwork extends @1.3::ISupplicantStaNetwork {
+    /**
+     * Possible mask of values for PairwiseCipher param.
+     */
+    enum PairwiseCipherMask : @1.3::ISupplicantStaNetwork.PairwiseCipherMask {
+        /**
+         * GCMP-128 Pairwise Cipher
+         */
+        GCMP_128 = 1 << 9,
+    };
+
+    /**
+     * Possible mask of values for GroupCipher param.
+     */
+    enum GroupCipherMask : @1.3::ISupplicantStaNetwork.GroupCipherMask {
+        /**
+         * GCMP-128 Group Cipher
+         */
+        GCMP_128 = 1 << 9,
+    };
+
+    /**
+     * Set group cipher mask for the network.
+     *
+     * @param groupCipherMask value to set.
+     *        Combination of |ProtoMask| values.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    setGroupCipher_1_4(bitfield<GroupCipherMask> groupCipherMask)
+        generates (SupplicantStatus status);
+
+    /**
+     * Get the group cipher mask set for the network.
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     * @return groupCipherMask Combination of |GroupCipherMask| values.
+     */
+    getGroupCipher_1_4()
+        generates (SupplicantStatus status, bitfield<GroupCipherMask> groupCipherMask);
+
+    /**
+     * Set pairwise cipher mask for the network.
+     *
+     * @param pairwiseCipherMask value to set.
+     *        Combination of |ProtoMask| values.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    setPairwiseCipher_1_4(bitfield<PairwiseCipherMask> pairwiseCipherMask)
+        generates (SupplicantStatus status);
+
+    /**
+     * Get the pairwise cipher mask set for the network.
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     * @return pairwiseCipherMask Combination of |PairwiseCipherMask| values.
+     */
+    getPairwiseCipher_1_4()
+        generates (SupplicantStatus status, bitfield<PairwiseCipherMask> pairwiseCipherMask);
+
+    /**
+     * Set whether to enable enhanced directional multi-gigabit (802.11ay EDMG).
+     * Only allowed if hw mode is |HOSTAPD_MODE_IEEE80211AD|
+     *
+     * @param enable true to set, false otherwise.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    setEdmg(bool enable) generates (SupplicantStatus status);
+
+    /**
+     * Get whether enhanced directional multi-gigabit (802.11ay EDMG) is enabled for this network.
+     *
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     * @return enabled true if set, false otherwise.
+     */
+    getEdmg() generates (SupplicantStatus status, bool enabled);
+};
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h
index bea4dc1..60fe1dc 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_hidl_test_utils_1_4.h
@@ -27,4 +27,17 @@
 android::sp<android::hardware::wifi::supplicant::V1_4::ISupplicant>
 getSupplicant_1_4(const std::string& supplicant_instance_name, bool isP2pOn);
 
+class SupplicantHidlTestBaseV1_4 : public SupplicantHidlTestBase {
+   public:
+    virtual void SetUp() override {
+        SupplicantHidlTestBase::SetUp();
+        supplicant_ = getSupplicant_1_4(supplicant_instance_name_, isP2pOn_);
+        ASSERT_NE(supplicant_.get(), nullptr);
+        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+    }
+
+   protected:
+    android::sp<android::hardware::wifi::supplicant::V1_4::ISupplicant>
+        supplicant_;
+};
 #endif /* SUPPLICANT_HIDL_TEST_UTILS_1_4_H */
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 0a20455..5b9c750 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -40,36 +40,17 @@
 using ::android::hardware::wifi::supplicant::V1_4::ISupplicant;
 using ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface;
 
-class SupplicantStaIfaceHidlTest
-    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
+class SupplicantStaIfaceHidlTest : public SupplicantHidlTestBaseV1_4 {
    public:
     virtual void SetUp() override {
-        wifi_v1_0_instance_name_ = std::get<0>(GetParam());
-        supplicant_v1_4_instance_name_ = std::get<1>(GetParam());
-        isP2pOn_ =
-            testing::deviceSupportsFeature("android.hardware.wifi.direct");
-
-        stopSupplicant(wifi_v1_0_instance_name_);
-        startSupplicantAndWaitForHidlService(wifi_v1_0_instance_name_,
-                                             supplicant_v1_4_instance_name_);
-        supplicant_ =
-            getSupplicant_1_4(supplicant_v1_4_instance_name_, isP2pOn_);
-        EXPECT_TRUE(turnOnExcessiveLogging(supplicant_));
+        SupplicantHidlTestBaseV1_4::SetUp();
         sta_iface_ = getSupplicantStaIface_1_4(supplicant_);
         ASSERT_NE(sta_iface_.get(), nullptr);
     }
 
-    virtual void TearDown() override {
-        stopSupplicant(wifi_v1_0_instance_name_);
-    }
-
    protected:
     // ISupplicantStaIface object used for all tests in this fixture.
     sp<ISupplicantStaIface> sta_iface_;
-    sp<ISupplicant> supplicant_;
-    bool isP2pOn_ = false;
-    std::string wifi_v1_0_instance_name_;
-    std::string supplicant_v1_4_instance_name_;
 };
 
 /*